Permalink
Browse files

Add support for switching between multiple keyboard layouts.

Also show a notification when an external keyboard is connected
and does not have a keyboard layout selected yet.

Bug: 6405203
Change-Id: Id0ac6d83b3b381f8a236b2244a04c9acb203db3c
  • Loading branch information...
1 parent 51f2430 commit cf39bdf3dff5e29447f6ce734b76dc3490385e58 @j9brown j9brown committed May 18, 2012
@@ -41,8 +41,13 @@ interface IInputManager {
// Keyboard layouts configuration.
KeyboardLayout[] getKeyboardLayouts();
KeyboardLayout getKeyboardLayout(String keyboardLayoutDescriptor);
- String getKeyboardLayoutForInputDevice(String inputDeviceDescriptor);
- void setKeyboardLayoutForInputDevice(String inputDeviceDescriptor,
+ String getCurrentKeyboardLayoutForInputDevice(String inputDeviceDescriptor);
+ void setCurrentKeyboardLayoutForInputDevice(String inputDeviceDescriptor,
+ String keyboardLayoutDescriptor);
+ String[] getKeyboardLayoutsForInputDevice(String inputDeviceDescriptor);
+ void addKeyboardLayoutForInputDevice(String inputDeviceDescriptor,
+ String keyboardLayoutDescriptor);
+ void removeKeyboardLayoutForInputDevice(String inputDeviceDescriptor,
String keyboardLayoutDescriptor);
// Registers an input devices changed listener.
@@ -16,6 +16,8 @@
package android.hardware.input;
+import com.android.internal.util.ArrayUtils;
+
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.content.Context;
@@ -217,6 +219,41 @@ public InputDevice getInputDevice(int id) {
}
/**
+ * Gets information about the input device with the specified descriptor.
+ * @param descriptor The input device descriptor.
+ * @return The input device or null if not found.
+ * @hide
+ */
+ public InputDevice getInputDeviceByDescriptor(String descriptor) {
+ if (descriptor == null) {
+ throw new IllegalArgumentException("descriptor must not be null.");
+ }
+
+ synchronized (mInputDevicesLock) {
+ populateInputDevicesLocked();
+
+ int numDevices = mInputDevices.size();
+ for (int i = 0; i < numDevices; i++) {
+ InputDevice inputDevice = mInputDevices.valueAt(i);
+ if (inputDevice == null) {
+ int id = mInputDevices.keyAt(i);
+ try {
+ inputDevice = mIm.getInputDevice(id);
+ } catch (RemoteException ex) {
+ // Ignore the problem for the purposes of this method.
+ continue;
+ }
+ mInputDevices.setValueAt(i, inputDevice);
+ }
+ if (descriptor.equals(inputDevice.getDescriptor())) {
+ return inputDevice;
+ }
+ }
+ return null;
+ }
+ }
+
+ /**
* Gets the ids of all input devices in the system.
* @return The input device ids.
*/
@@ -332,50 +369,129 @@ public KeyboardLayout getKeyboardLayout(String keyboardLayoutDescriptor) {
}
/**
- * Gets the keyboard layout descriptor for the specified input device.
+ * Gets the current keyboard layout descriptor for the specified input device.
*
* @param inputDeviceDescriptor The input device descriptor.
- * @return The keyboard layout descriptor, or null if unknown or if the default
- * keyboard layout will be used.
+ * @return The keyboard layout descriptor, or null if no keyboard layout has been set.
*
* @hide
*/
- public String getKeyboardLayoutForInputDevice(String inputDeviceDescriptor) {
+ public String getCurrentKeyboardLayoutForInputDevice(String inputDeviceDescriptor) {
if (inputDeviceDescriptor == null) {
throw new IllegalArgumentException("inputDeviceDescriptor must not be null");
}
try {
- return mIm.getKeyboardLayoutForInputDevice(inputDeviceDescriptor);
+ return mIm.getCurrentKeyboardLayoutForInputDevice(inputDeviceDescriptor);
} catch (RemoteException ex) {
- Log.w(TAG, "Could not get keyboard layout for input device.", ex);
+ Log.w(TAG, "Could not get current keyboard layout for input device.", ex);
return null;
}
}
/**
- * Sets the keyboard layout descriptor for the specified input device.
+ * Sets the current keyboard layout descriptor for the specified input device.
+ * <p>
+ * This method may have the side-effect of causing the input device in question
+ * to be reconfigured.
+ * </p>
+ *
+ * @param inputDeviceDescriptor The input device descriptor.
+ * @param keyboardLayoutDescriptor The keyboard layout descriptor to use, must not be null.
+ *
+ * @hide
+ */
+ public void setCurrentKeyboardLayoutForInputDevice(String inputDeviceDescriptor,
+ String keyboardLayoutDescriptor) {
+ if (inputDeviceDescriptor == null) {
+ throw new IllegalArgumentException("inputDeviceDescriptor must not be null");
+ }
+ if (keyboardLayoutDescriptor == null) {
+ throw new IllegalArgumentException("keyboardLayoutDescriptor must not be null");
+ }
+
+ try {
+ mIm.setCurrentKeyboardLayoutForInputDevice(inputDeviceDescriptor,
+ keyboardLayoutDescriptor);
+ } catch (RemoteException ex) {
+ Log.w(TAG, "Could not set current keyboard layout for input device.", ex);
+ }
+ }
+
+ /**
+ * Gets all keyboard layout descriptors that are enabled for the specified input device.
+ *
+ * @param inputDeviceDescriptor The input device descriptor.
+ * @return The keyboard layout descriptors.
+ *
+ * @hide
+ */
+ public String[] getKeyboardLayoutsForInputDevice(String inputDeviceDescriptor) {
+ if (inputDeviceDescriptor == null) {
+ throw new IllegalArgumentException("inputDeviceDescriptor must not be null");
+ }
+
+ try {
+ return mIm.getKeyboardLayoutsForInputDevice(inputDeviceDescriptor);
+ } catch (RemoteException ex) {
+ Log.w(TAG, "Could not get keyboard layouts for input device.", ex);
+ return ArrayUtils.emptyArray(String.class);
+ }
+ }
+
+ /**
+ * Adds the keyboard layout descriptor for the specified input device.
* <p>
* This method may have the side-effect of causing the input device in question
* to be reconfigured.
* </p>
*
* @param inputDeviceDescriptor The input device descriptor.
- * @param keyboardLayoutDescriptor The keyboard layout descriptor, or null to remove
- * the mapping so that the default keyboard layout will be used for the input device.
+ * @param keyboardLayoutDescriptor The descriptor of the keyboard layout to add.
*
* @hide
*/
- public void setKeyboardLayoutForInputDevice(String inputDeviceDescriptor,
+ public void addKeyboardLayoutForInputDevice(String inputDeviceDescriptor,
String keyboardLayoutDescriptor) {
if (inputDeviceDescriptor == null) {
throw new IllegalArgumentException("inputDeviceDescriptor must not be null");
}
+ if (keyboardLayoutDescriptor == null) {
+ throw new IllegalArgumentException("keyboardLayoutDescriptor must not be null");
+ }
+
+ try {
+ mIm.addKeyboardLayoutForInputDevice(inputDeviceDescriptor, keyboardLayoutDescriptor);
+ } catch (RemoteException ex) {
+ Log.w(TAG, "Could not add keyboard layout for input device.", ex);
+ }
+ }
+
+ /**
+ * Removes the keyboard layout descriptor for the specified input device.
+ * <p>
+ * This method may have the side-effect of causing the input device in question
+ * to be reconfigured.
+ * </p>
+ *
+ * @param inputDeviceDescriptor The input device descriptor.
+ * @param keyboardLayoutDescriptor The descriptor of the keyboard layout to remove.
+ *
+ * @hide
+ */
+ public void removeKeyboardLayoutForInputDevice(String inputDeviceDescriptor,
+ String keyboardLayoutDescriptor) {
+ if (inputDeviceDescriptor == null) {
+ throw new IllegalArgumentException("inputDeviceDescriptor must not be null");
+ }
+ if (keyboardLayoutDescriptor == null) {
+ throw new IllegalArgumentException("keyboardLayoutDescriptor must not be null");
+ }
try {
- mIm.setKeyboardLayoutForInputDevice(inputDeviceDescriptor, keyboardLayoutDescriptor);
+ mIm.removeKeyboardLayoutForInputDevice(inputDeviceDescriptor, keyboardLayoutDescriptor);
} catch (RemoteException ex) {
- Log.w(TAG, "Could not set keyboard layout for input device.", ex);
+ Log.w(TAG, "Could not remove keyboard layout for input device.", ex);
}
}
@@ -386,6 +386,12 @@ public FakeWindow addFakeWindow(Looper looper,
*/
public InputChannel monitorInput(String name);
+ /**
+ * Switch the keyboard layout for the given device.
+ * Direction should be +1 or -1 to go to the next or previous keyboard layout.
+ */
+ public void switchKeyboardLayout(int deviceId, int direction);
+
public void shutdown();
public void rebootSafeMode();
}
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -1489,6 +1489,8 @@
<java-symbol type="string" name="low_internal_storage_view_title" />
<java-symbol type="string" name="report" />
<java-symbol type="string" name="select_input_method" />
+ <java-symbol type="string" name="select_keyboard_layout_notification_title" />
+ <java-symbol type="string" name="select_keyboard_layout_notification_message" />
<java-symbol type="string" name="smv_application" />
<java-symbol type="string" name="smv_process" />
<java-symbol type="string" name="tethered_notification_message" />
@@ -1580,6 +1582,7 @@
<java-symbol type="drawable" name="expander_ic_minimized" />
<java-symbol type="drawable" name="ic_menu_archive" />
<java-symbol type="drawable" name="ic_menu_goto" />
+ <java-symbol type="drawable" name="ic_settings_language" />
<java-symbol type="drawable" name="title_bar_medium" />
<java-symbol type="id" name="body" />
<java-symbol type="string" name="fast_scroll_alphabet" />
@@ -3092,6 +3092,11 @@
<!-- Title of the physical keyboard category in the input method selector [CHAR LIMIT=10] -->
<string name="hardware">Hardware</string>
+ <!-- Title of the notification to prompt the user to select a keyboard layout. -->
+ <string name="select_keyboard_layout_notification_title">Select keyboard layout</string>
+ <!-- Message of the notification to prompt the user to select a keyboard layout. -->
+ <string name="select_keyboard_layout_notification_message">Touch to select a keyboard layout.</string>
+
<string name="fast_scroll_alphabet">\u0020ABCDEFGHIJKLMNOPQRSTUVWXYZ</string>
<string name="fast_scroll_numeric_alphabet">\u00200123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ</string>
@@ -252,6 +252,7 @@ key SPACE {
label: ' '
base: ' '
alt, meta: fallback SEARCH
+ ctrl: fallback LANGUAGE_SWITCH
}
key ENTER {
@@ -249,6 +249,7 @@ key SPACE {
label: ' '
base: ' '
alt, meta: fallback SEARCH
+ ctrl: fallback LANGUAGE_SWITCH
}
key ENTER {
@@ -326,6 +326,7 @@
RecentApplicationsDialog mRecentAppsDialog;
int mRecentAppsDialogHeldModifiers;
+ boolean mLanguageSwitchKeyPressed;
int mLidState = LID_ABSENT;
boolean mHaveBuiltInKeyboard;
@@ -1943,6 +1944,22 @@ public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int p
RECENT_APPS_BEHAVIOR_DISMISS_AND_SWITCH);
}
+ // Handle keyboard language switching.
+ if (down && repeatCount == 0
+ && (keyCode == KeyEvent.KEYCODE_LANGUAGE_SWITCH
+ || (keyCode == KeyEvent.KEYCODE_SPACE
+ && (metaState & KeyEvent.META_CTRL_MASK) != 0))) {
+ int direction = (metaState & KeyEvent.META_SHIFT_MASK) != 0 ? -1 : 1;
+ mWindowManagerFuncs.switchKeyboardLayout(event.getDeviceId(), direction);
+ return -1;
+ }
+ if (mLanguageSwitchKeyPressed && !down
+ && (keyCode == KeyEvent.KEYCODE_LANGUAGE_SWITCH
+ || keyCode == KeyEvent.KEYCODE_SPACE)) {
+ mLanguageSwitchKeyPressed = false;
+ return -1;
+ }
+
// Let the application handle the key.
return 0;
}
Oops, something went wrong.

0 comments on commit cf39bdf

Please sign in to comment.