Merge changes from topic 'kb-layout'
* changes: Always show enabled keyboards. Bandaid over broken keyboard layout selection process.
This commit is contained in:
committed by
Android (Google) Code Review
commit
0de19dfa47
@@ -49,11 +49,12 @@ interface IInputManager {
|
||||
|
||||
// Keyboard layouts configuration.
|
||||
KeyboardLayout[] getKeyboardLayouts();
|
||||
KeyboardLayout[] getKeyboardLayoutsForInputDevice(in InputDeviceIdentifier identifier);
|
||||
KeyboardLayout getKeyboardLayout(String keyboardLayoutDescriptor);
|
||||
String getCurrentKeyboardLayoutForInputDevice(in InputDeviceIdentifier identifier);
|
||||
void setCurrentKeyboardLayoutForInputDevice(in InputDeviceIdentifier identifier,
|
||||
String keyboardLayoutDescriptor);
|
||||
String[] getKeyboardLayoutsForInputDevice(in InputDeviceIdentifier identifier);
|
||||
String[] getEnabledKeyboardLayoutsForInputDevice(in InputDeviceIdentifier identifier);
|
||||
void addKeyboardLayoutForInputDevice(in InputDeviceIdentifier identifier,
|
||||
String keyboardLayoutDescriptor);
|
||||
void removeKeyboardLayoutForInputDevice(in InputDeviceIdentifier identifier,
|
||||
|
||||
@@ -473,6 +473,29 @@ public final class InputManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets information about all supported keyboard layouts appropriate
|
||||
* for a specific input device.
|
||||
* <p>
|
||||
* The input manager consults the built-in keyboard layouts as well
|
||||
* as all keyboard layouts advertised by applications using a
|
||||
* {@link #ACTION_QUERY_KEYBOARD_LAYOUTS} broadcast receiver.
|
||||
* </p>
|
||||
*
|
||||
* @return A list of all supported keyboard layouts for a specific
|
||||
* input device.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public KeyboardLayout[] getKeyboardLayoutsForInputDevice(InputDeviceIdentifier identifier) {
|
||||
try {
|
||||
return mIm.getKeyboardLayoutsForInputDevice(identifier);
|
||||
} catch (RemoteException ex) {
|
||||
Log.w(TAG, "Could not get list of keyboard layouts for input device.", ex);
|
||||
return new KeyboardLayout[0];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the keyboard layout with the specified descriptor.
|
||||
*
|
||||
@@ -551,13 +574,13 @@ public final class InputManager {
|
||||
* @return The keyboard layout descriptors.
|
||||
* @hide
|
||||
*/
|
||||
public String[] getKeyboardLayoutsForInputDevice(InputDeviceIdentifier identifier) {
|
||||
public String[] getEnabledKeyboardLayoutsForInputDevice(InputDeviceIdentifier identifier) {
|
||||
if (identifier == null) {
|
||||
throw new IllegalArgumentException("inputDeviceDescriptor must not be null");
|
||||
}
|
||||
|
||||
try {
|
||||
return mIm.getKeyboardLayoutsForInputDevice(identifier);
|
||||
return mIm.getEnabledKeyboardLayoutsForInputDevice(identifier);
|
||||
} catch (RemoteException ex) {
|
||||
Log.w(TAG, "Could not get keyboard layouts for input device.", ex);
|
||||
return ArrayUtils.emptyArray(String.class);
|
||||
|
||||
@@ -19,6 +19,8 @@ package android.hardware.input;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Describes a keyboard layout.
|
||||
*
|
||||
@@ -30,6 +32,9 @@ public final class KeyboardLayout implements Parcelable,
|
||||
private final String mLabel;
|
||||
private final String mCollection;
|
||||
private final int mPriority;
|
||||
private final Locale[] mLocales;
|
||||
private final int mVendorId;
|
||||
private final int mProductId;
|
||||
|
||||
public static final Parcelable.Creator<KeyboardLayout> CREATOR =
|
||||
new Parcelable.Creator<KeyboardLayout>() {
|
||||
@@ -41,11 +46,19 @@ public final class KeyboardLayout implements Parcelable,
|
||||
}
|
||||
};
|
||||
|
||||
public KeyboardLayout(String descriptor, String label, String collection, int priority) {
|
||||
public KeyboardLayout(String descriptor, String label, String collection, int priority,
|
||||
Locale[] locales, int vid, int pid) {
|
||||
mDescriptor = descriptor;
|
||||
mLabel = label;
|
||||
mCollection = collection;
|
||||
mPriority = priority;
|
||||
if (locales != null) {
|
||||
mLocales = locales;
|
||||
} else {
|
||||
mLocales = new Locale[0];
|
||||
}
|
||||
mVendorId = vid;
|
||||
mProductId = pid;
|
||||
}
|
||||
|
||||
private KeyboardLayout(Parcel source) {
|
||||
@@ -53,6 +66,13 @@ public final class KeyboardLayout implements Parcelable,
|
||||
mLabel = source.readString();
|
||||
mCollection = source.readString();
|
||||
mPriority = source.readInt();
|
||||
int N = source.readInt();
|
||||
mLocales = new Locale[N];
|
||||
for (int i = 0; i < N; i++) {
|
||||
mLocales[i] = Locale.forLanguageTag(source.readString());
|
||||
}
|
||||
mVendorId = source.readInt();
|
||||
mProductId = source.readInt();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -83,6 +103,33 @@ public final class KeyboardLayout implements Parcelable,
|
||||
return mCollection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the locales that this keyboard layout is intended for.
|
||||
* This may be empty if a locale has not been assigned to this keyboard layout.
|
||||
* @return The keyboard layout's intended locale.
|
||||
*/
|
||||
public Locale[] getLocales() {
|
||||
return mLocales;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the vendor ID of the hardware device this keyboard layout is intended for.
|
||||
* Returns -1 if this is not specific to any piece of hardware.
|
||||
* @return The hardware vendor ID of the keyboard layout's intended device.
|
||||
*/
|
||||
public int getVendorId() {
|
||||
return mVendorId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the product ID of the hardware device this keyboard layout is intended for.
|
||||
* Returns -1 if this is not specific to any piece of hardware.
|
||||
* @return The hardware product ID of the keyboard layout's intended device.
|
||||
*/
|
||||
public int getProductId() {
|
||||
return mProductId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
@@ -94,6 +141,16 @@ public final class KeyboardLayout implements Parcelable,
|
||||
dest.writeString(mLabel);
|
||||
dest.writeString(mCollection);
|
||||
dest.writeInt(mPriority);
|
||||
if (mLocales != null) {
|
||||
dest.writeInt(mLocales.length);
|
||||
for (Locale l : mLocales) {
|
||||
dest.writeString(l.toLanguageTag());
|
||||
}
|
||||
} else {
|
||||
dest.writeInt(0);
|
||||
}
|
||||
dest.writeInt(mVendorId);
|
||||
dest.writeInt(mProductId);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -7860,6 +7860,12 @@ i
|
||||
<attr name="label" />
|
||||
<!-- The key character map file resource. -->
|
||||
<attr name="keyboardLayout" format="reference" />
|
||||
<!-- The locales the given keyboard layout corresponds to. -->
|
||||
<attr name="locale" format="string" />
|
||||
<!-- The vendor ID of the hardware the given layout corresponds to. @hide -->
|
||||
<attr name="vendorId" format="integer" />
|
||||
<!-- The product ID of the hardware the given layout corresponds to. @hide -->
|
||||
<attr name="productId" format="integer" />
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="MediaRouteButton">
|
||||
|
||||
@@ -70,7 +70,7 @@ import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.provider.Settings.SettingNotFoundException;
|
||||
import android.util.Log;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
import android.util.Xml;
|
||||
@@ -97,9 +97,11 @@ import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import libcore.io.Streams;
|
||||
import libcore.util.Objects;
|
||||
@@ -720,40 +722,35 @@ public class InputManagerService extends IInputManager.Stub
|
||||
mTempInputDevicesChangedListenersToNotify.clear();
|
||||
|
||||
// Check for missing keyboard layouts.
|
||||
if (mNotificationManager != null) {
|
||||
final int numFullKeyboards = mTempFullKeyboards.size();
|
||||
boolean missingLayoutForExternalKeyboard = false;
|
||||
boolean missingLayoutForExternalKeyboardAdded = false;
|
||||
boolean multipleMissingLayoutsForExternalKeyboardsAdded = false;
|
||||
InputDevice keyboardMissingLayout = null;
|
||||
synchronized (mDataStore) {
|
||||
for (int i = 0; i < numFullKeyboards; i++) {
|
||||
final InputDevice inputDevice = mTempFullKeyboards.get(i);
|
||||
final String layout =
|
||||
getCurrentKeyboardLayoutForInputDevice(inputDevice.getIdentifier());
|
||||
if (layout == null) {
|
||||
missingLayoutForExternalKeyboard = true;
|
||||
if (i < numFullKeyboardsAdded) {
|
||||
missingLayoutForExternalKeyboardAdded = true;
|
||||
if (keyboardMissingLayout == null) {
|
||||
keyboardMissingLayout = inputDevice;
|
||||
} else {
|
||||
multipleMissingLayoutsForExternalKeyboardsAdded = true;
|
||||
}
|
||||
}
|
||||
List<InputDevice> keyboardsMissingLayout = new ArrayList<>();
|
||||
final int numFullKeyboards = mTempFullKeyboards.size();
|
||||
synchronized (mDataStore) {
|
||||
for (int i = 0; i < numFullKeyboards; i++) {
|
||||
final InputDevice inputDevice = mTempFullKeyboards.get(i);
|
||||
String layout =
|
||||
getCurrentKeyboardLayoutForInputDevice(inputDevice.getIdentifier());
|
||||
if (layout == null) {
|
||||
layout = getDefaultKeyboardLayout(inputDevice);
|
||||
if (layout != null) {
|
||||
setCurrentKeyboardLayoutForInputDevice(
|
||||
inputDevice.getIdentifier(), layout);
|
||||
}
|
||||
}
|
||||
if (layout == null) {
|
||||
keyboardsMissingLayout.add(inputDevice);
|
||||
}
|
||||
}
|
||||
if (missingLayoutForExternalKeyboard) {
|
||||
if (missingLayoutForExternalKeyboardAdded) {
|
||||
if (multipleMissingLayoutsForExternalKeyboardsAdded) {
|
||||
// We have more than one keyboard missing a layout, so drop the
|
||||
// user at the generic input methods page so they can pick which
|
||||
// one to set.
|
||||
showMissingKeyboardLayoutNotification(null);
|
||||
} else {
|
||||
showMissingKeyboardLayoutNotification(keyboardMissingLayout);
|
||||
}
|
||||
}
|
||||
|
||||
if (mNotificationManager != null) {
|
||||
if (!keyboardsMissingLayout.isEmpty()) {
|
||||
if (keyboardsMissingLayout.size() > 1) {
|
||||
// We have more than one keyboard missing a layout, so drop the
|
||||
// user at the generic input methods page so they can pick which
|
||||
// one to set.
|
||||
showMissingKeyboardLayoutNotification(null);
|
||||
} else {
|
||||
showMissingKeyboardLayoutNotification(keyboardsMissingLayout.get(0));
|
||||
}
|
||||
} else if (mKeyboardLayoutNotificationShown) {
|
||||
hideMissingKeyboardLayoutNotification();
|
||||
@@ -762,6 +759,78 @@ public class InputManagerService extends IInputManager.Stub
|
||||
mTempFullKeyboards.clear();
|
||||
}
|
||||
|
||||
private String getDefaultKeyboardLayout(final InputDevice d) {
|
||||
final Locale systemLocale = mContext.getResources().getConfiguration().locale;
|
||||
// If our locale doesn't have a language for some reason, then we don't really have a
|
||||
// reasonable default.
|
||||
if (TextUtils.isEmpty(systemLocale.getLanguage())) {
|
||||
return null;
|
||||
}
|
||||
final List<KeyboardLayout> layouts = new ArrayList<>();
|
||||
visitAllKeyboardLayouts(new KeyboardLayoutVisitor() {
|
||||
@Override
|
||||
public void visitKeyboardLayout(Resources resources,
|
||||
int keyboardLayoutResId, KeyboardLayout layout) {
|
||||
// Only select a default when we know the layout is appropriate. For now, this
|
||||
// means its a custom layout for a specific keyboard.
|
||||
if (layout.getVendorId() != d.getVendorId()
|
||||
|| layout.getProductId() != d.getProductId()) {
|
||||
return;
|
||||
}
|
||||
for (Locale l : layout.getLocales()) {
|
||||
if (isCompatibleLocale(systemLocale, l)) {
|
||||
layouts.add(layout);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (layouts.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// First sort so that ones with higher priority are listed at the top
|
||||
Collections.sort(layouts);
|
||||
// Next we want to try to find an exact match of language, country and variant.
|
||||
final int N = layouts.size();
|
||||
for (int i = 0; i < N; i++) {
|
||||
KeyboardLayout layout = layouts.get(i);
|
||||
for (Locale l : layout.getLocales()) {
|
||||
if (l.getCountry().equals(systemLocale.getCountry())
|
||||
&& l.getVariant().equals(systemLocale.getVariant())) {
|
||||
return layout.getDescriptor();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Then try an exact match of language and country
|
||||
for (int i = 0; i < N; i++) {
|
||||
KeyboardLayout layout = layouts.get(i);
|
||||
for (Locale l : layout.getLocales()) {
|
||||
if (l.getCountry().equals(systemLocale.getCountry())) {
|
||||
return layout.getDescriptor();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Give up and just use the highest priority layout with matching language
|
||||
return layouts.get(0).getDescriptor();
|
||||
}
|
||||
|
||||
private static boolean isCompatibleLocale(Locale systemLocale, Locale keyboardLocale) {
|
||||
// Different languages are never compatible
|
||||
if (!systemLocale.getLanguage().equals(keyboardLocale.getLanguage())) {
|
||||
return false;
|
||||
}
|
||||
// If both the system and the keyboard layout have a country specifier, they must be equal.
|
||||
if (!TextUtils.isEmpty(systemLocale.getCountry())
|
||||
&& !TextUtils.isEmpty(keyboardLocale.getCountry())
|
||||
&& !systemLocale.getCountry().equals(keyboardLocale.getCountry())) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override // Binder call & native callback
|
||||
public TouchCalibration getTouchCalibrationForInputDevice(String inputDeviceDescriptor,
|
||||
int surfaceRotation) {
|
||||
@@ -911,9 +980,9 @@ public class InputManagerService extends IInputManager.Stub
|
||||
final HashSet<String> availableKeyboardLayouts = new HashSet<String>();
|
||||
visitAllKeyboardLayouts(new KeyboardLayoutVisitor() {
|
||||
@Override
|
||||
public void visitKeyboardLayout(Resources resources, String descriptor, String label,
|
||||
String collection, int keyboardLayoutResId, int priority) {
|
||||
availableKeyboardLayouts.add(descriptor);
|
||||
public void visitKeyboardLayout(Resources resources,
|
||||
int keyboardLayoutResId, KeyboardLayout layout) {
|
||||
availableKeyboardLayouts.add(layout.getDescriptor());
|
||||
}
|
||||
});
|
||||
synchronized (mDataStore) {
|
||||
@@ -945,14 +1014,63 @@ public class InputManagerService extends IInputManager.Stub
|
||||
final ArrayList<KeyboardLayout> list = new ArrayList<KeyboardLayout>();
|
||||
visitAllKeyboardLayouts(new KeyboardLayoutVisitor() {
|
||||
@Override
|
||||
public void visitKeyboardLayout(Resources resources, String descriptor, String label,
|
||||
String collection, int keyboardLayoutResId, int priority) {
|
||||
list.add(new KeyboardLayout(descriptor, label, collection, priority));
|
||||
public void visitKeyboardLayout(Resources resources,
|
||||
int keyboardLayoutResId, KeyboardLayout layout) {
|
||||
list.add(layout);
|
||||
}
|
||||
});
|
||||
return list.toArray(new KeyboardLayout[list.size()]);
|
||||
}
|
||||
|
||||
@Override // Binder call
|
||||
public KeyboardLayout[] getKeyboardLayoutsForInputDevice(
|
||||
final InputDeviceIdentifier identifier) {
|
||||
final String[] enabledLayoutDescriptors =
|
||||
getEnabledKeyboardLayoutsForInputDevice(identifier);
|
||||
final ArrayList<KeyboardLayout> enabledLayouts =
|
||||
new ArrayList<KeyboardLayout>(enabledLayoutDescriptors.length);
|
||||
final ArrayList<KeyboardLayout> potentialLayouts = new ArrayList<KeyboardLayout>();
|
||||
visitAllKeyboardLayouts(new KeyboardLayoutVisitor() {
|
||||
boolean mHasSeenDeviceSpecificLayout;
|
||||
|
||||
@Override
|
||||
public void visitKeyboardLayout(Resources resources,
|
||||
int keyboardLayoutResId, KeyboardLayout layout) {
|
||||
// First check if it's enabled. If the keyboard layout is enabled then we always
|
||||
// want to return it as a possible layout for the device.
|
||||
for (String s : enabledLayoutDescriptors) {
|
||||
if (s != null && s.equals(layout.getDescriptor())) {
|
||||
enabledLayouts.add(layout);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Next find any potential layouts that aren't yet enabled for the device. For
|
||||
// devices that have special layouts we assume there's a reason that the generic
|
||||
// layouts don't work for them so we don't want to return them since it's likely
|
||||
// to result in a poor user experience.
|
||||
if (layout.getVendorId() == identifier.getVendorId()
|
||||
&& layout.getProductId() == identifier.getProductId()) {
|
||||
if (!mHasSeenDeviceSpecificLayout) {
|
||||
mHasSeenDeviceSpecificLayout = true;
|
||||
potentialLayouts.clear();
|
||||
}
|
||||
potentialLayouts.add(layout);
|
||||
} else if (layout.getVendorId() == -1 && layout.getProductId() == -1
|
||||
&& !mHasSeenDeviceSpecificLayout) {
|
||||
potentialLayouts.add(layout);
|
||||
}
|
||||
}
|
||||
});
|
||||
final int enabledLayoutSize = enabledLayouts.size();
|
||||
final int potentialLayoutSize = potentialLayouts.size();
|
||||
KeyboardLayout[] layouts = new KeyboardLayout[enabledLayoutSize + potentialLayoutSize];
|
||||
enabledLayouts.toArray(layouts);
|
||||
for (int i = 0; i < potentialLayoutSize; i++) {
|
||||
layouts[enabledLayoutSize + i] = potentialLayouts.get(i);
|
||||
}
|
||||
return layouts;
|
||||
}
|
||||
|
||||
@Override // Binder call
|
||||
public KeyboardLayout getKeyboardLayout(String keyboardLayoutDescriptor) {
|
||||
if (keyboardLayoutDescriptor == null) {
|
||||
@@ -962,13 +1080,13 @@ public class InputManagerService extends IInputManager.Stub
|
||||
final KeyboardLayout[] result = new KeyboardLayout[1];
|
||||
visitKeyboardLayout(keyboardLayoutDescriptor, new KeyboardLayoutVisitor() {
|
||||
@Override
|
||||
public void visitKeyboardLayout(Resources resources, String descriptor,
|
||||
String label, String collection, int keyboardLayoutResId, int priority) {
|
||||
result[0] = new KeyboardLayout(descriptor, label, collection, priority);
|
||||
public void visitKeyboardLayout(Resources resources,
|
||||
int keyboardLayoutResId, KeyboardLayout layout) {
|
||||
result[0] = layout;
|
||||
}
|
||||
});
|
||||
if (result[0] == null) {
|
||||
Log.w(TAG, "Could not get keyboard layout with descriptor '"
|
||||
Slog.w(TAG, "Could not get keyboard layout with descriptor '"
|
||||
+ keyboardLayoutDescriptor + "'.");
|
||||
}
|
||||
return result[0];
|
||||
@@ -1010,7 +1128,7 @@ public class InputManagerService extends IInputManager.Stub
|
||||
|
||||
int configResId = metaData.getInt(InputManager.META_DATA_KEYBOARD_LAYOUTS);
|
||||
if (configResId == 0) {
|
||||
Log.w(TAG, "Missing meta-data '" + InputManager.META_DATA_KEYBOARD_LAYOUTS
|
||||
Slog.w(TAG, "Missing meta-data '" + InputManager.META_DATA_KEYBOARD_LAYOUTS
|
||||
+ "' on receiver " + receiver.packageName + "/" + receiver.name);
|
||||
return;
|
||||
}
|
||||
@@ -1047,8 +1165,16 @@ public class InputManagerService extends IInputManager.Stub
|
||||
int keyboardLayoutResId = a.getResourceId(
|
||||
com.android.internal.R.styleable.KeyboardLayout_keyboardLayout,
|
||||
0);
|
||||
String languageTags = a.getString(
|
||||
com.android.internal.R.styleable.KeyboardLayout_locale);
|
||||
Locale[] locales = getLocalesFromLanguageTags(languageTags);
|
||||
int vid = a.getInt(
|
||||
com.android.internal.R.styleable.KeyboardLayout_vendorId, -1);
|
||||
int pid = a.getInt(
|
||||
com.android.internal.R.styleable.KeyboardLayout_productId, -1);
|
||||
|
||||
if (name == null || label == null || keyboardLayoutResId == 0) {
|
||||
Log.w(TAG, "Missing required 'name', 'label' or 'keyboardLayout' "
|
||||
Slog.w(TAG, "Missing required 'name', 'label' or 'keyboardLayout' "
|
||||
+ "attributes in keyboard layout "
|
||||
+ "resource from receiver "
|
||||
+ receiver.packageName + "/" + receiver.name);
|
||||
@@ -1056,15 +1182,18 @@ public class InputManagerService extends IInputManager.Stub
|
||||
String descriptor = KeyboardLayoutDescriptor.format(
|
||||
receiver.packageName, receiver.name, name);
|
||||
if (keyboardName == null || name.equals(keyboardName)) {
|
||||
visitor.visitKeyboardLayout(resources, descriptor,
|
||||
label, collection, keyboardLayoutResId, priority);
|
||||
KeyboardLayout layout = new KeyboardLayout(
|
||||
descriptor, label, collection, priority,
|
||||
locales, vid, pid);
|
||||
visitor.visitKeyboardLayout(
|
||||
resources, keyboardLayoutResId, layout);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
a.recycle();
|
||||
}
|
||||
} else {
|
||||
Log.w(TAG, "Skipping unrecognized element '" + element
|
||||
Slog.w(TAG, "Skipping unrecognized element '" + element
|
||||
+ "' in keyboard layout resource from receiver "
|
||||
+ receiver.packageName + "/" + receiver.name);
|
||||
}
|
||||
@@ -1073,11 +1202,23 @@ public class InputManagerService extends IInputManager.Stub
|
||||
parser.close();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
Log.w(TAG, "Could not parse keyboard layout resource from receiver "
|
||||
Slog.w(TAG, "Could not parse keyboard layout resource from receiver "
|
||||
+ receiver.packageName + "/" + receiver.name, ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static Locale[] getLocalesFromLanguageTags(String languageTags) {
|
||||
if (TextUtils.isEmpty(languageTags)) {
|
||||
return new Locale[0];
|
||||
}
|
||||
String[] tags = languageTags.split("\\|");
|
||||
Locale[] locales = new Locale[tags.length];
|
||||
for (int i = 0; i < tags.length; i++) {
|
||||
locales[i] = Locale.forLanguageTag(tags[i]);
|
||||
}
|
||||
return locales;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a layout descriptor for the vendor/product. This returns the
|
||||
* descriptor for ids that aren't useful (such as the default 0, 0).
|
||||
@@ -1143,7 +1284,7 @@ public class InputManagerService extends IInputManager.Stub
|
||||
}
|
||||
|
||||
@Override // Binder call
|
||||
public String[] getKeyboardLayoutsForInputDevice(InputDeviceIdentifier identifier) {
|
||||
public String[] getEnabledKeyboardLayoutsForInputDevice(InputDeviceIdentifier identifier) {
|
||||
String key = getLayoutDescriptor(identifier);
|
||||
synchronized (mDataStore) {
|
||||
String[] layouts = mDataStore.getKeyboardLayouts(key);
|
||||
@@ -1718,10 +1859,10 @@ public class InputManagerService extends IInputManager.Stub
|
||||
final String[] result = new String[2];
|
||||
visitKeyboardLayout(keyboardLayoutDescriptor, new KeyboardLayoutVisitor() {
|
||||
@Override
|
||||
public void visitKeyboardLayout(Resources resources, String descriptor, String label,
|
||||
String collection, int keyboardLayoutResId, int priority) {
|
||||
public void visitKeyboardLayout(Resources resources,
|
||||
int keyboardLayoutResId, KeyboardLayout layout) {
|
||||
try {
|
||||
result[0] = descriptor;
|
||||
result[0] = layout.getDescriptor();
|
||||
result[1] = Streams.readFully(new InputStreamReader(
|
||||
resources.openRawResource(keyboardLayoutResId)));
|
||||
} catch (IOException ex) {
|
||||
@@ -1730,7 +1871,7 @@ public class InputManagerService extends IInputManager.Stub
|
||||
}
|
||||
});
|
||||
if (result[0] == null) {
|
||||
Log.w(TAG, "Could not get keyboard layout with descriptor '"
|
||||
Slog.w(TAG, "Could not get keyboard layout with descriptor '"
|
||||
+ keyboardLayoutDescriptor + "'.");
|
||||
return null;
|
||||
}
|
||||
@@ -1883,8 +2024,8 @@ public class InputManagerService extends IInputManager.Stub
|
||||
}
|
||||
|
||||
private interface KeyboardLayoutVisitor {
|
||||
void visitKeyboardLayout(Resources resources, String descriptor, String label,
|
||||
String collection, int keyboardLayoutResId, int priority);
|
||||
void visitKeyboardLayout(Resources resources,
|
||||
int keyboardLayoutResId, KeyboardLayout layout);
|
||||
}
|
||||
|
||||
private final class InputDevicesChangedListenerRecord implements DeathRecipient {
|
||||
|
||||
Reference in New Issue
Block a user