Merge "Check virtual displays for ime dispatch" into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
8327ce6b24
@@ -117,6 +117,11 @@ interface IInputManager {
|
||||
// static association for the cleared input port will be restored.
|
||||
void removePortAssociation(in String inputPort);
|
||||
|
||||
// Add a runtime association between the input device and display.
|
||||
void addUniqueIdAssociation(in String inputDeviceName, in String displayUniqueId);
|
||||
// Remove the runtime association between the input device and display.
|
||||
void removeUniqueIdAssociation(in String inputDeviceName);
|
||||
|
||||
InputSensorInfo[] getSensorList(int deviceId);
|
||||
|
||||
boolean registerSensorListener(IInputSensorEventListener listener);
|
||||
|
||||
@@ -1293,7 +1293,7 @@ public final class InputManager {
|
||||
* @param inputPort The port of the input device.
|
||||
* @param displayPort The physical port of the associated display.
|
||||
* <p>
|
||||
* Requires {@link android.Manifest.permissions.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY_BY_PORT}.
|
||||
* Requires {@link android.Manifest.permissions.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY}.
|
||||
* </p>
|
||||
* @hide
|
||||
*/
|
||||
@@ -1310,7 +1310,7 @@ public final class InputManager {
|
||||
* static association for the cleared input port will be restored.
|
||||
* @param inputPort The port of the input device to be cleared.
|
||||
* <p>
|
||||
* Requires {@link android.Manifest.permissions.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY_BY_PORT}.
|
||||
* Requires {@link android.Manifest.permissions.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY}.
|
||||
* </p>
|
||||
* @hide
|
||||
*/
|
||||
@@ -1322,6 +1322,41 @@ public final class InputManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a runtime association between the input device name and display, by unique id. Input
|
||||
* device names are expected to be unique.
|
||||
* @param inputDeviceName The name of the input device.
|
||||
* @param displayUniqueId The unique id of the associated display.
|
||||
* <p>
|
||||
* Requires {@link android.Manifest.permissions.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY}.
|
||||
* </p>
|
||||
* @hide
|
||||
*/
|
||||
public void addUniqueIdAssociation(@NonNull String inputDeviceName,
|
||||
@NonNull String displayUniqueId) {
|
||||
try {
|
||||
mIm.addUniqueIdAssociation(inputDeviceName, displayUniqueId);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a runtime association between the input device and display.
|
||||
* @param inputDeviceName The name of the input device.
|
||||
* <p>
|
||||
* Requires {@link android.Manifest.permissions.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY}.
|
||||
* </p>
|
||||
* @hide
|
||||
*/
|
||||
public void removeUniqueIdAssociation(@NonNull String inputDeviceName) {
|
||||
try {
|
||||
mIm.removeUniqueIdAssociation(inputDeviceName);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
private void populateInputDevicesLocked() {
|
||||
if (mInputDevicesChangedListener == null) {
|
||||
final InputDevicesChangedListener listener = new InputDevicesChangedListener();
|
||||
|
||||
@@ -5638,7 +5638,7 @@
|
||||
android:protectionLevel="signature|recents" />
|
||||
<!-- Allows the caller to change the associations between input devices and displays.
|
||||
Very dangerous! @hide -->
|
||||
<permission android:name="android.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY_BY_PORT"
|
||||
<permission android:name="android.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY"
|
||||
android:protectionLevel="signature" />
|
||||
|
||||
<!-- Allows query of any normal app on the device, regardless of manifest declarations.
|
||||
|
||||
@@ -270,6 +270,8 @@ public class InputManagerService extends IInputManager.Stub
|
||||
private final Object mAssociationsLock = new Object();
|
||||
@GuardedBy("mAssociationLock")
|
||||
private final Map<String, Integer> mRuntimeAssociations = new ArrayMap<String, Integer>();
|
||||
@GuardedBy("mAssociationLock")
|
||||
private final Map<String, String> mUniqueIdAssociations = new ArrayMap<>();
|
||||
|
||||
private static native long nativeInit(InputManagerService service,
|
||||
Context context, MessageQueue messageQueue);
|
||||
@@ -340,6 +342,7 @@ public class InputManagerService extends IInputManager.Stub
|
||||
boolean enabled);
|
||||
private static native boolean nativeCanDispatchToDisplay(long ptr, int deviceId, int displayId);
|
||||
private static native void nativeNotifyPortAssociationsChanged(long ptr);
|
||||
private static native void nativeChangeUniqueIdAssociation(long ptr);
|
||||
private static native void nativeSetMotionClassifierEnabled(long ptr, boolean enabled);
|
||||
private static native InputSensorInfo[] nativeGetSensorList(long ptr, int deviceId);
|
||||
private static native boolean nativeFlushSensor(long ptr, int deviceId, int sensorType);
|
||||
@@ -2222,10 +2225,10 @@ public class InputManagerService extends IInputManager.Stub
|
||||
@Override // Binder call
|
||||
public void addPortAssociation(@NonNull String inputPort, int displayPort) {
|
||||
if (!checkCallingPermission(
|
||||
android.Manifest.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY_BY_PORT,
|
||||
android.Manifest.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY,
|
||||
"addPortAssociation()")) {
|
||||
throw new SecurityException(
|
||||
"Requires ASSOCIATE_INPUT_DEVICE_TO_DISPLAY_BY_PORT permission");
|
||||
"Requires ASSOCIATE_INPUT_DEVICE_TO_DISPLAY permission");
|
||||
}
|
||||
|
||||
Objects.requireNonNull(inputPort);
|
||||
@@ -2243,10 +2246,10 @@ public class InputManagerService extends IInputManager.Stub
|
||||
@Override // Binder call
|
||||
public void removePortAssociation(@NonNull String inputPort) {
|
||||
if (!checkCallingPermission(
|
||||
android.Manifest.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY_BY_PORT,
|
||||
android.Manifest.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY,
|
||||
"clearPortAssociations()")) {
|
||||
throw new SecurityException(
|
||||
"Requires ASSOCIATE_INPUT_DEVICE_TO_DISPLAY_BY_PORT permission");
|
||||
"Requires ASSOCIATE_INPUT_DEVICE_TO_DISPLAY permission");
|
||||
}
|
||||
|
||||
Objects.requireNonNull(inputPort);
|
||||
@@ -2256,6 +2259,49 @@ public class InputManagerService extends IInputManager.Stub
|
||||
nativeNotifyPortAssociationsChanged(mPtr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a runtime association between the input device name and the display unique id.
|
||||
* @param inputDeviceName The name of the input device.
|
||||
* @param displayUniqueId The unique id of the associated display.
|
||||
*/
|
||||
@Override // Binder call
|
||||
public void addUniqueIdAssociation(@NonNull String inputDeviceName,
|
||||
@NonNull String displayUniqueId) {
|
||||
if (!checkCallingPermission(
|
||||
android.Manifest.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY,
|
||||
"addNameAssociation()")) {
|
||||
throw new SecurityException(
|
||||
"Requires ASSOCIATE_INPUT_DEVICE_TO_DISPLAY permission");
|
||||
}
|
||||
|
||||
Objects.requireNonNull(inputDeviceName);
|
||||
Objects.requireNonNull(displayUniqueId);
|
||||
synchronized (mAssociationsLock) {
|
||||
mUniqueIdAssociations.put(inputDeviceName, displayUniqueId);
|
||||
}
|
||||
nativeChangeUniqueIdAssociation(mPtr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the runtime association between the input device and the display.
|
||||
* @param inputDeviceName The port of the input device to be cleared.
|
||||
*/
|
||||
@Override // Binder call
|
||||
public void removeUniqueIdAssociation(@NonNull String inputDeviceName) {
|
||||
if (!checkCallingPermission(
|
||||
android.Manifest.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY,
|
||||
"removeUniqueIdAssociation()")) {
|
||||
throw new SecurityException(
|
||||
"Requires ASSOCIATE_INPUT_DEVICE_TO_DISPLAY permission");
|
||||
}
|
||||
|
||||
Objects.requireNonNull(inputDeviceName);
|
||||
synchronized (mAssociationsLock) {
|
||||
mUniqueIdAssociations.remove(inputDeviceName);
|
||||
}
|
||||
nativeChangeUniqueIdAssociation(mPtr);
|
||||
}
|
||||
|
||||
@Override // Binder call
|
||||
public InputSensorInfo[] getSensorList(int deviceId) {
|
||||
return nativeGetSensorList(mPtr, deviceId);
|
||||
@@ -2790,13 +2836,13 @@ public class InputManagerService extends IInputManager.Stub
|
||||
* key.
|
||||
* @return Flattened list
|
||||
*/
|
||||
private static List<String> flatten(@NonNull Map<String, Integer> map) {
|
||||
private static <T> String[] flatten(@NonNull Map<String, T> map) {
|
||||
final List<String> list = new ArrayList<>(map.size() * 2);
|
||||
map.forEach((k, v)-> {
|
||||
list.add(k);
|
||||
list.add(v.toString());
|
||||
});
|
||||
return list;
|
||||
return list.toArray(new String[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2828,8 +2874,17 @@ public class InputManagerService extends IInputManager.Stub
|
||||
associations.putAll(mRuntimeAssociations);
|
||||
}
|
||||
|
||||
final List<String> associationList = flatten(associations);
|
||||
return associationList.toArray(new String[0]);
|
||||
return flatten(associations);
|
||||
}
|
||||
|
||||
// Native callback
|
||||
private String[] getInputUniqueIdAssociations() {
|
||||
final Map<String, String> associations;
|
||||
synchronized (mAssociationsLock) {
|
||||
associations = new HashMap<>(mUniqueIdAssociations);
|
||||
}
|
||||
|
||||
return flatten(associations);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -118,6 +118,7 @@ static struct {
|
||||
jmethodID getVirtualKeyQuietTimeMillis;
|
||||
jmethodID getExcludedDeviceNames;
|
||||
jmethodID getInputPortAssociations;
|
||||
jmethodID getInputUniqueIdAssociations;
|
||||
jmethodID getKeyRepeatTimeout;
|
||||
jmethodID getKeyRepeatDelay;
|
||||
jmethodID getHoverTapTimeout;
|
||||
@@ -579,6 +580,21 @@ void NativeInputManager::getReaderConfiguration(InputReaderConfiguration* outCon
|
||||
}
|
||||
env->DeleteLocalRef(portAssociations);
|
||||
}
|
||||
outConfig->uniqueIdAssociations.clear();
|
||||
jobjectArray uniqueIdAssociations = jobjectArray(
|
||||
env->CallObjectMethod(mServiceObj, gServiceClassInfo.getInputUniqueIdAssociations));
|
||||
if (!checkAndClearExceptionFromCallback(env, "getInputUniqueIdAssociations") &&
|
||||
uniqueIdAssociations) {
|
||||
jsize length = env->GetArrayLength(uniqueIdAssociations);
|
||||
for (jsize i = 0; i < length / 2; i++) {
|
||||
std::string inputDeviceUniqueId =
|
||||
getStringElementFromJavaArray(env, uniqueIdAssociations, 2 * i);
|
||||
std::string displayUniqueId =
|
||||
getStringElementFromJavaArray(env, uniqueIdAssociations, 2 * i + 1);
|
||||
outConfig->uniqueIdAssociations.insert({inputDeviceUniqueId, displayUniqueId});
|
||||
}
|
||||
env->DeleteLocalRef(uniqueIdAssociations);
|
||||
}
|
||||
|
||||
jint hoverTapTimeout = env->CallIntMethod(mServiceObj,
|
||||
gServiceClassInfo.getHoverTapTimeout);
|
||||
@@ -2134,6 +2150,12 @@ static void nativeNotifyPortAssociationsChanged(JNIEnv* env, jclass /* clazz */,
|
||||
InputReaderConfiguration::CHANGE_DISPLAY_INFO);
|
||||
}
|
||||
|
||||
static void nativeChangeUniqueIdAssociation(JNIEnv* env, jclass /* clazz */, jlong ptr) {
|
||||
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
|
||||
im->getInputManager()->getReader()->requestRefreshConfiguration(
|
||||
InputReaderConfiguration::CHANGE_DISPLAY_INFO);
|
||||
}
|
||||
|
||||
static void nativeSetMotionClassifierEnabled(JNIEnv* /* env */, jclass /* clazz */, jlong ptr,
|
||||
jboolean enabled) {
|
||||
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
|
||||
@@ -2316,6 +2338,7 @@ static const JNINativeMethod gInputManagerMethods[] = {
|
||||
(void*)nativeSetCustomPointerIcon},
|
||||
{"nativeCanDispatchToDisplay", "(JII)Z", (void*)nativeCanDispatchToDisplay},
|
||||
{"nativeNotifyPortAssociationsChanged", "(J)V", (void*)nativeNotifyPortAssociationsChanged},
|
||||
{"nativeChangeUniqueIdAssociation", "(J)V", (void*)nativeChangeUniqueIdAssociation},
|
||||
{"nativeSetMotionClassifierEnabled", "(JZ)V", (void*)nativeSetMotionClassifierEnabled},
|
||||
{"nativeGetSensorList", "(JI)[Landroid/hardware/input/InputSensorInfo;",
|
||||
(void*)nativeGetSensorList},
|
||||
@@ -2425,6 +2448,9 @@ int register_android_server_InputManager(JNIEnv* env) {
|
||||
GET_METHOD_ID(gServiceClassInfo.getInputPortAssociations, clazz,
|
||||
"getInputPortAssociations", "()[Ljava/lang/String;");
|
||||
|
||||
GET_METHOD_ID(gServiceClassInfo.getInputUniqueIdAssociations, clazz,
|
||||
"getInputUniqueIdAssociations", "()[Ljava/lang/String;");
|
||||
|
||||
GET_METHOD_ID(gServiceClassInfo.getKeyRepeatTimeout, clazz,
|
||||
"getKeyRepeatTimeout", "()I");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user