Revert "Support mouse pointer on external displays (2/3)"
This reverts commit 84cdf9cc3b849679e6b4f6d3ccb66270f0abad2f.
Reason for revert: b/120864177
Test: Presubmit
Bug: b/120864177
Change-Id: Ia65e704169527b54cf1d1d470445f96a65fa0294
diff --git a/libs/input/PointerController.cpp b/libs/input/PointerController.cpp
index 80d8e72..0a90f85 100644
--- a/libs/input/PointerController.cpp
+++ b/libs/input/PointerController.cpp
@@ -89,6 +89,10 @@
mLocked.animationPending = false;
+ mLocked.displayWidth = -1;
+ mLocked.displayHeight = -1;
+ mLocked.displayOrientation = DISPLAY_ORIENTATION_0;
+
mLocked.presentation = PRESENTATION_POINTER;
mLocked.presentationChanged = false;
@@ -106,6 +110,15 @@
mLocked.lastFrameUpdatedTime = 0;
mLocked.buttonState = 0;
+
+ mPolicy->loadPointerIcon(&mLocked.pointerIcon);
+
+ loadResources();
+
+ if (mLocked.pointerIcon.isValid()) {
+ mLocked.pointerIconChanged = true;
+ updatePointerLocked();
+ }
}
PointerController::~PointerController() {
@@ -131,15 +144,23 @@
bool PointerController::getBoundsLocked(float* outMinX, float* outMinY,
float* outMaxX, float* outMaxY) const {
-
- if (!mLocked.viewport.isValid()) {
+ if (mLocked.displayWidth <= 0 || mLocked.displayHeight <= 0) {
return false;
}
- *outMinX = mLocked.viewport.logicalLeft;
- *outMinY = mLocked.viewport.logicalTop;
- *outMaxX = mLocked.viewport.logicalRight - 1;
- *outMaxY = mLocked.viewport.logicalBottom - 1;
+ *outMinX = 0;
+ *outMinY = 0;
+ switch (mLocked.displayOrientation) {
+ case DISPLAY_ORIENTATION_90:
+ case DISPLAY_ORIENTATION_270:
+ *outMaxX = mLocked.displayHeight - 1;
+ *outMaxY = mLocked.displayWidth - 1;
+ break;
+ default:
+ *outMaxX = mLocked.displayWidth - 1;
+ *outMaxY = mLocked.displayHeight - 1;
+ break;
+ }
return true;
}
@@ -210,12 +231,6 @@
*outY = mLocked.pointerY;
}
-int32_t PointerController::getDisplayId() const {
- AutoMutex _l(mLock);
-
- return mLocked.viewport.displayId;
-}
-
void PointerController::fade(Transition transition) {
AutoMutex _l(mLock);
@@ -340,57 +355,48 @@
void PointerController::reloadPointerResources() {
AutoMutex _l(mLock);
- loadResourcesLocked();
+ loadResources();
+
+ if (mLocked.presentation == PRESENTATION_POINTER) {
+ mLocked.additionalMouseResources.clear();
+ mLocked.animationResources.clear();
+ mPolicy->loadPointerIcon(&mLocked.pointerIcon);
+ mPolicy->loadAdditionalMouseResources(&mLocked.additionalMouseResources,
+ &mLocked.animationResources);
+ }
+
+ mLocked.presentationChanged = true;
updatePointerLocked();
}
-/**
- * The viewport values for deviceHeight and deviceWidth have already been adjusted for rotation,
- * so here we are getting the dimensions in the original, unrotated orientation (orientation 0).
- */
-static void getNonRotatedSize(const DisplayViewport& viewport, int32_t& width, int32_t& height) {
- if (viewport.orientation == DISPLAY_ORIENTATION_90
- || viewport.orientation == DISPLAY_ORIENTATION_270) {
- width = viewport.deviceHeight;
- height = viewport.deviceWidth;
- } else {
- width = viewport.deviceWidth;
- height = viewport.deviceHeight;
- }
-}
-
-void PointerController::setDisplayViewport(const DisplayViewport& viewport) {
+void PointerController::setDisplayViewport(int32_t width, int32_t height, int32_t orientation) {
AutoMutex _l(mLock);
- if (viewport == mLocked.viewport) {
- return;
+
+ // Adjust to use the display's unrotated coordinate frame.
+ if (orientation == DISPLAY_ORIENTATION_90
+ || orientation == DISPLAY_ORIENTATION_270) {
+ int32_t temp = height;
+ height = width;
+ width = temp;
}
- const DisplayViewport oldViewport = mLocked.viewport;
- mLocked.viewport = viewport;
-
- int32_t oldDisplayWidth, oldDisplayHeight;
- getNonRotatedSize(oldViewport, oldDisplayWidth, oldDisplayHeight);
- int32_t newDisplayWidth, newDisplayHeight;
- getNonRotatedSize(viewport, newDisplayWidth, newDisplayHeight);
-
- // Reset cursor position to center if size or display changed.
- if (oldViewport.displayId != viewport.displayId
- || oldDisplayWidth != newDisplayWidth
- || oldDisplayHeight != newDisplayHeight) {
+ if (mLocked.displayWidth != width || mLocked.displayHeight != height) {
+ mLocked.displayWidth = width;
+ mLocked.displayHeight = height;
float minX, minY, maxX, maxY;
if (getBoundsLocked(&minX, &minY, &maxX, &maxY)) {
mLocked.pointerX = (minX + maxX) * 0.5f;
mLocked.pointerY = (minY + maxY) * 0.5f;
- // Reload icon resources for density may be changed.
- loadResourcesLocked();
} else {
mLocked.pointerX = 0;
mLocked.pointerY = 0;
}
fadeOutAndReleaseAllSpotsLocked();
- } else if (oldViewport.orientation != viewport.orientation) {
+ }
+
+ if (mLocked.displayOrientation != orientation) {
// Apply offsets to convert from the pixel top-left corner position to the pixel center.
// This creates an invariant frame of reference that we can easily rotate when
// taking into account that the pointer may be located at fractional pixel offsets.
@@ -399,37 +405,37 @@
float temp;
// Undo the previous rotation.
- switch (oldViewport.orientation) {
+ switch (mLocked.displayOrientation) {
case DISPLAY_ORIENTATION_90:
temp = x;
- x = oldViewport.deviceHeight - y;
+ x = mLocked.displayWidth - y;
y = temp;
break;
case DISPLAY_ORIENTATION_180:
- x = oldViewport.deviceWidth - x;
- y = oldViewport.deviceHeight - y;
+ x = mLocked.displayWidth - x;
+ y = mLocked.displayHeight - y;
break;
case DISPLAY_ORIENTATION_270:
temp = x;
x = y;
- y = oldViewport.deviceWidth - temp;
+ y = mLocked.displayHeight - temp;
break;
}
// Perform the new rotation.
- switch (viewport.orientation) {
+ switch (orientation) {
case DISPLAY_ORIENTATION_90:
temp = x;
x = y;
- y = viewport.deviceHeight - temp;
+ y = mLocked.displayWidth - temp;
break;
case DISPLAY_ORIENTATION_180:
- x = viewport.deviceWidth - x;
- y = viewport.deviceHeight - y;
+ x = mLocked.displayWidth - x;
+ y = mLocked.displayHeight - y;
break;
case DISPLAY_ORIENTATION_270:
temp = x;
- x = viewport.deviceWidth - y;
+ x = mLocked.displayHeight - y;
y = temp;
break;
}
@@ -438,6 +444,7 @@
// and save the results.
mLocked.pointerX = x - 0.5f;
mLocked.pointerY = y - 0.5f;
+ mLocked.displayOrientation = orientation;
}
updatePointerLocked();
@@ -607,16 +614,11 @@
mLooper->removeMessages(mHandler, MSG_INACTIVITY_TIMEOUT);
}
-void PointerController::updatePointerLocked() REQUIRES(mLock) {
- if (!mLocked.viewport.isValid()) {
- return;
- }
-
+void PointerController::updatePointerLocked() {
mSpriteController->openTransaction();
mLocked.pointerSprite->setLayer(Sprite::BASE_LAYER_POINTER);
mLocked.pointerSprite->setPosition(mLocked.pointerX, mLocked.pointerY);
- mLocked.pointerSprite->setDisplayId(mLocked.viewport.displayId);
if (mLocked.pointerAlpha > 0) {
mLocked.pointerSprite->setAlpha(mLocked.pointerAlpha);
@@ -727,18 +729,8 @@
}
}
-void PointerController::loadResourcesLocked() REQUIRES(mLock) {
+void PointerController::loadResources() {
mPolicy->loadPointerResources(&mResources);
-
- if (mLocked.presentation == PRESENTATION_POINTER) {
- mLocked.additionalMouseResources.clear();
- mLocked.animationResources.clear();
- mPolicy->loadPointerIcon(&mLocked.pointerIcon);
- mPolicy->loadAdditionalMouseResources(&mLocked.additionalMouseResources,
- &mLocked.animationResources);
- }
-
- mLocked.pointerIconChanged = true;
}
diff --git a/libs/input/PointerController.h b/libs/input/PointerController.h
index a32cc42..7f4e5a5 100644
--- a/libs/input/PointerController.h
+++ b/libs/input/PointerController.h
@@ -23,7 +23,6 @@
#include <vector>
#include <ui/DisplayInfo.h>
-#include <input/DisplayViewport.h>
#include <input/Input.h>
#include <PointerControllerInterface.h>
#include <utils/BitSet.h>
@@ -97,7 +96,6 @@
virtual int32_t getButtonState() const;
virtual void setPosition(float x, float y);
virtual void getPosition(float* outX, float* outY) const;
- virtual int32_t getDisplayId() const;
virtual void fade(Transition transition);
virtual void unfade(Transition transition);
@@ -108,7 +106,7 @@
void updatePointerIcon(int32_t iconId);
void setCustomPointerIcon(const SpriteIcon& icon);
- void setDisplayViewport(const DisplayViewport& viewport);
+ void setDisplayViewport(int32_t width, int32_t height, int32_t orientation);
void setInactivityTimeout(InactivityTimeout inactivityTimeout);
void reloadPointerResources();
@@ -158,7 +156,9 @@
size_t animationFrameIndex;
nsecs_t lastFrameUpdatedTime;
- DisplayViewport viewport;
+ int32_t displayWidth;
+ int32_t displayHeight;
+ int32_t displayOrientation;
InactivityTimeout inactivityTimeout;
@@ -182,7 +182,7 @@
Vector<Spot*> spots;
Vector<sp<Sprite> > recycledSprites;
- } mLocked GUARDED_BY(mLock);
+ } mLocked;
bool getBoundsLocked(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const;
void setPositionLocked(float x, float y);
@@ -207,7 +207,7 @@
void fadeOutAndReleaseSpotLocked(Spot* spot);
void fadeOutAndReleaseAllSpotsLocked();
- void loadResourcesLocked();
+ void loadResources();
};
} // namespace android
diff --git a/libs/input/SpriteController.cpp b/libs/input/SpriteController.cpp
index c1868d3..eb2bc98 100644
--- a/libs/input/SpriteController.cpp
+++ b/libs/input/SpriteController.cpp
@@ -144,16 +144,13 @@
}
}
- // Resize and/or reparent sprites if needed.
+ // Resize sprites if needed.
SurfaceComposerClient::Transaction t;
bool needApplyTransaction = false;
for (size_t i = 0; i < numSprites; i++) {
SpriteUpdate& update = updates.editItemAt(i);
- if (update.state.surfaceControl == nullptr) {
- continue;
- }
- if (update.state.wantSurfaceVisible()) {
+ if (update.state.surfaceControl != NULL && update.state.wantSurfaceVisible()) {
int32_t desiredWidth = update.state.icon.bitmap.width();
int32_t desiredHeight = update.state.icon.bitmap.height();
if (update.state.surfaceWidth < desiredWidth
@@ -173,12 +170,6 @@
}
}
}
-
- // If surface is a new one, we have to set right layer stack.
- if (update.surfaceChanged || update.state.dirty & DIRTY_DISPLAY_ID) {
- t.setLayerStack(update.state.surfaceControl, update.state.displayId);
- needApplyTransaction = true;
- }
}
if (needApplyTransaction) {
t.apply();
@@ -245,7 +236,7 @@
if (update.state.surfaceControl != NULL && (becomingVisible || becomingHidden
|| (wantSurfaceVisibleAndDrawn && (update.state.dirty & (DIRTY_ALPHA
| DIRTY_POSITION | DIRTY_TRANSFORMATION_MATRIX | DIRTY_LAYER
- | DIRTY_VISIBILITY | DIRTY_HOTSPOT | DIRTY_DISPLAY_ID))))) {
+ | DIRTY_VISIBILITY | DIRTY_HOTSPOT))))) {
needApplyTransaction = true;
if (wantSurfaceVisibleAndDrawn
@@ -454,15 +445,6 @@
}
}
-void SpriteController::SpriteImpl::setDisplayId(int32_t displayId) {
- AutoMutex _l(mController->mLock);
-
- if (mLocked.state.displayId != displayId) {
- mLocked.state.displayId = displayId;
- invalidateLocked(DIRTY_DISPLAY_ID);
- }
-}
-
void SpriteController::SpriteImpl::invalidateLocked(uint32_t dirty) {
bool wasDirty = mLocked.state.dirty;
mLocked.state.dirty |= dirty;
diff --git a/libs/input/SpriteController.h b/libs/input/SpriteController.h
index 5b216f5..31e43e9 100644
--- a/libs/input/SpriteController.h
+++ b/libs/input/SpriteController.h
@@ -125,9 +125,6 @@
/* Sets the sprite transformation matrix. */
virtual void setTransformationMatrix(const SpriteTransformationMatrix& matrix) = 0;
-
- /* Sets the id of the display where the sprite should be shown. */
- virtual void setDisplayId(int32_t displayId) = 0;
};
/*
@@ -173,7 +170,6 @@
DIRTY_LAYER = 1 << 4,
DIRTY_VISIBILITY = 1 << 5,
DIRTY_HOTSPOT = 1 << 6,
- DIRTY_DISPLAY_ID = 1 << 7,
};
/* Describes the state of a sprite.
@@ -184,7 +180,7 @@
struct SpriteState {
inline SpriteState() :
dirty(0), visible(false),
- positionX(0), positionY(0), layer(0), alpha(1.0f), displayId(ADISPLAY_ID_DEFAULT),
+ positionX(0), positionY(0), layer(0), alpha(1.0f),
surfaceWidth(0), surfaceHeight(0), surfaceDrawn(false), surfaceVisible(false) {
}
@@ -197,7 +193,6 @@
int32_t layer;
float alpha;
SpriteTransformationMatrix transformationMatrix;
- int32_t displayId;
sp<SurfaceControl> surfaceControl;
int32_t surfaceWidth;
@@ -230,7 +225,6 @@
virtual void setLayer(int32_t layer);
virtual void setAlpha(float alpha);
virtual void setTransformationMatrix(const SpriteTransformationMatrix& matrix);
- virtual void setDisplayId(int32_t displayId);
inline const SpriteState& getStateLocked() const {
return mLocked.state;
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index e7c3c7b..d96b6cb 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -1951,11 +1951,6 @@
}
// Native callback.
- private int getPointerDisplayId() {
- return mWindowManagerCallbacks.getPointerDisplayId();
- }
-
- // Native callback.
private String[] getKeyboardLayoutOverlay(InputDeviceIdentifier identifier) {
if (!mSystemReady) {
return null;
@@ -2022,8 +2017,6 @@
KeyEvent event, int policyFlags);
public int getPointerLayer();
-
- public int getPointerDisplayId();
}
/**
diff --git a/services/core/java/com/android/server/wm/InputManagerCallback.java b/services/core/java/com/android/server/wm/InputManagerCallback.java
index f9c9d33..639ed02 100644
--- a/services/core/java/com/android/server/wm/InputManagerCallback.java
+++ b/services/core/java/com/android/server/wm/InputManagerCallback.java
@@ -1,6 +1,5 @@
package com.android.server.wm;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
@@ -10,6 +9,7 @@
import android.os.Debug;
import android.os.IBinder;
import android.util.Slog;
+import android.view.InputApplicationHandle;
import android.view.KeyEvent;
import android.view.WindowManager;
@@ -204,37 +204,6 @@
+ WindowManagerService.TYPE_LAYER_OFFSET;
}
- /** Callback to get pointer display id. */
- @Override
- public int getPointerDisplayId() {
- synchronized (mService.mGlobalLock) {
- // If desktop mode is not enabled, show on the default display.
- if (!mService.mForceDesktopModeOnExternalDisplays) {
- return DEFAULT_DISPLAY;
- }
-
- // Look for the topmost freeform display.
- int firstExternalDisplayId = DEFAULT_DISPLAY;
- for (int i = mService.mRoot.mChildren.size() - 1; i >= 0; --i) {
- final DisplayContent displayContent = mService.mRoot.mChildren.get(i);
- // Heuristic solution here. Currently when "Freeform windows" developer option is
- // enabled we automatically put secondary displays in freeform mode and emulating
- // "desktop mode". It also makes sense to show the pointer on the same display.
- if (displayContent.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
- return displayContent.getDisplayId();
- }
-
- if (firstExternalDisplayId == DEFAULT_DISPLAY
- && displayContent.getDisplayId() != DEFAULT_DISPLAY) {
- firstExternalDisplayId = displayContent.getDisplayId();
- }
- }
-
- // Look for the topmost non-default display
- return firstExternalDisplayId;
- }
- }
-
/** Waits until the built-in input devices have been configured. */
public boolean waitForInputDevicesReady(long timeoutMillis) {
synchronized (mInputDevicesReadyMonitor) {
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index bf83ca9..43d2dcf 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -107,7 +107,6 @@
jmethodID getLongPressTimeout;
jmethodID getPointerLayer;
jmethodID getPointerIcon;
- jmethodID getPointerDisplayId;
jmethodID getKeyboardLayoutOverlay;
jmethodID getDeviceAlias;
jmethodID getTouchCalibrationForInputDevice;
@@ -175,6 +174,15 @@
loadSystemIconAsSpriteWithPointerIcon(env, contextObj, style, &pointerIcon, outSpriteIcon);
}
+static void updatePointerControllerFromViewport(
+ sp<PointerController> controller, const DisplayViewport* const viewport) {
+ if (controller != nullptr && viewport != nullptr) {
+ const int32_t width = viewport->logicalRight - viewport->logicalLeft;
+ const int32_t height = viewport->logicalBottom - viewport->logicalTop;
+ controller->setDisplayViewport(width, height, viewport->orientation);
+ }
+}
+
enum {
WM_ACTION_PASS_TO_USER = 1,
};
@@ -234,7 +242,6 @@
jfloatArray matrixArr);
virtual TouchAffineTransformation getTouchAffineTransformation(
const std::string& inputDeviceDescriptor, int32_t surfaceRotation);
- virtual void updatePointerDisplay();
/* --- InputDispatcherPolicyInterface implementation --- */
@@ -307,11 +314,10 @@
std::atomic<bool> mInteractive;
- void updateInactivityTimeoutLocked();
+ void updateInactivityTimeoutLocked(const sp<PointerController>& controller);
void handleInterceptActions(jint wmActions, nsecs_t when, uint32_t& policyFlags);
void ensureSpriteControllerLocked();
- const DisplayViewport* findDisplayViewportLocked(int32_t displayId);
- int32_t getPointerDisplayId();
+
static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
static inline JNIEnv* jniEnv() {
@@ -385,10 +391,9 @@
return false;
}
-const DisplayViewport* NativeInputManager::findDisplayViewportLocked(int32_t displayId)
- REQUIRES(mLock) {
- for (const DisplayViewport& v : mLocked.viewports) {
- if (v.displayId == displayId) {
+static const DisplayViewport* findInternalViewport(const std::vector<DisplayViewport>& viewports) {
+ for (const DisplayViewport& v : viewports) {
+ if (v.type == ViewportType::VIEWPORT_INTERNAL) {
return &v;
}
}
@@ -415,10 +420,20 @@
}
}
- { // acquire lock
+ const DisplayViewport* newInternalViewport = findInternalViewport(viewports);
+ {
AutoMutex _l(mLock);
+ const DisplayViewport* oldInternalViewport = findInternalViewport(mLocked.viewports);
+ // Internal viewport has changed if there wasn't one earlier, and there is one now, or,
+ // if they are different.
+ const bool internalViewportChanged = (newInternalViewport != nullptr) &&
+ (oldInternalViewport == nullptr || (*oldInternalViewport != *newInternalViewport));
+ if (internalViewportChanged) {
+ sp<PointerController> controller = mLocked.pointerController.promote();
+ updatePointerControllerFromViewport(controller, newInternalViewport);
+ }
mLocked.viewports = viewports;
- } // release lock
+ }
mInputManager->getReader()->requestRefreshConfiguration(
InputReaderConfiguration::CHANGE_DISPLAY_INFO);
@@ -541,43 +556,15 @@
controller = new PointerController(this, mLooper, mLocked.spriteController);
mLocked.pointerController = controller;
- updateInactivityTimeoutLocked();
- }
+ const DisplayViewport* internalViewport = findInternalViewport(mLocked.viewports);
+ updatePointerControllerFromViewport(controller, internalViewport);
+
+ updateInactivityTimeoutLocked(controller);
+ }
return controller;
}
-int32_t NativeInputManager::getPointerDisplayId() {
- JNIEnv* env = jniEnv();
- jint pointerDisplayId = env->CallIntMethod(mServiceObj,
- gServiceClassInfo.getPointerDisplayId);
- if (checkAndClearExceptionFromCallback(env, "getPointerDisplayId")) {
- pointerDisplayId = ADISPLAY_ID_DEFAULT;
- }
-
- return pointerDisplayId;
-}
-
-void NativeInputManager::updatePointerDisplay() {
- ATRACE_CALL();
-
- jint pointerDisplayId = getPointerDisplayId();
-
- AutoMutex _l(mLock);
- sp<PointerController> controller = mLocked.pointerController.promote();
- if (controller != nullptr) {
- const DisplayViewport* viewport = findDisplayViewportLocked(pointerDisplayId);
- if (viewport == nullptr) {
- ALOGW("Can't find pointer display viewport, fallback to default display.");
- viewport = findDisplayViewportLocked(ADISPLAY_ID_DEFAULT);
- }
-
- if (viewport != nullptr) {
- controller->setDisplayViewport(*viewport);
- }
- }
-}
-
void NativeInputManager::ensureSpriteControllerLocked() REQUIRES(mLock) {
if (mLocked.spriteController == nullptr) {
JNIEnv* env = jniEnv();
@@ -834,16 +821,16 @@
if (mLocked.systemUiVisibility != visibility) {
mLocked.systemUiVisibility = visibility;
- updateInactivityTimeoutLocked();
+
+ sp<PointerController> controller = mLocked.pointerController.promote();
+ if (controller != nullptr) {
+ updateInactivityTimeoutLocked(controller);
+ }
}
}
-void NativeInputManager::updateInactivityTimeoutLocked() REQUIRES(mLock) {
- sp<PointerController> controller = mLocked.pointerController.promote();
- if (controller == nullptr) {
- return;
- }
-
+void NativeInputManager::updateInactivityTimeoutLocked(const sp<PointerController>& controller)
+ REQUIRES(mLock) {
bool lightsOut = mLocked.systemUiVisibility & ASYSTEM_UI_VISIBILITY_STATUS_BAR_HIDDEN;
controller->setInactivityTimeout(lightsOut
? PointerController::INACTIVITY_TIMEOUT_SHORT
@@ -1837,9 +1824,6 @@
GET_METHOD_ID(gServiceClassInfo.getPointerIcon, clazz,
"getPointerIcon", "()Landroid/view/PointerIcon;");
- GET_METHOD_ID(gServiceClassInfo.getPointerDisplayId, clazz,
- "getPointerDisplayId", "()I");
-
GET_METHOD_ID(gServiceClassInfo.getKeyboardLayoutOverlay, clazz,
"getKeyboardLayoutOverlay",
"(Landroid/hardware/input/InputDeviceIdentifier;)[Ljava/lang/String;");