Merge "Move InputDevicesChangedListener & other functions to InputManagerGlobal" into udc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
ea947c426d
@@ -88,10 +88,6 @@ public final class InputManager {
|
|||||||
// To enable these logs, run: 'adb shell setprop log.tag.InputManager DEBUG' (requires restart)
|
// To enable these logs, run: 'adb shell setprop log.tag.InputManager DEBUG' (requires restart)
|
||||||
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
||||||
|
|
||||||
private static final int MSG_DEVICE_ADDED = 1;
|
|
||||||
private static final int MSG_DEVICE_REMOVED = 2;
|
|
||||||
private static final int MSG_DEVICE_CHANGED = 3;
|
|
||||||
|
|
||||||
private static InputManager sInstance;
|
private static InputManager sInstance;
|
||||||
|
|
||||||
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
|
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
|
||||||
@@ -112,12 +108,6 @@ public final class InputManager {
|
|||||||
@Nullable
|
@Nullable
|
||||||
private Boolean mIsStylusPointerIconEnabled = null;
|
private Boolean mIsStylusPointerIconEnabled = null;
|
||||||
|
|
||||||
// Guarded by mInputDevicesLock
|
|
||||||
private final Object mInputDevicesLock = new Object();
|
|
||||||
private SparseArray<InputDevice> mInputDevices;
|
|
||||||
private InputDevicesChangedListener mInputDevicesChangedListener;
|
|
||||||
private final ArrayList<InputDeviceListenerDelegate> mInputDeviceListeners = new ArrayList<>();
|
|
||||||
|
|
||||||
// Guarded by mTabletModeLock
|
// Guarded by mTabletModeLock
|
||||||
private final Object mTabletModeLock = new Object();
|
private final Object mTabletModeLock = new Object();
|
||||||
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
|
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
|
||||||
@@ -403,27 +393,7 @@ public final class InputManager {
|
|||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public InputDevice getInputDevice(int id) {
|
public InputDevice getInputDevice(int id) {
|
||||||
synchronized (mInputDevicesLock) {
|
return mGlobal.getInputDevice(id);
|
||||||
populateInputDevicesLocked();
|
|
||||||
|
|
||||||
int index = mInputDevices.indexOfKey(id);
|
|
||||||
if (index < 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
InputDevice inputDevice = mInputDevices.valueAt(index);
|
|
||||||
if (inputDevice == null) {
|
|
||||||
try {
|
|
||||||
inputDevice = mIm.getInputDevice(id);
|
|
||||||
} catch (RemoteException ex) {
|
|
||||||
throw ex.rethrowFromSystemServer();
|
|
||||||
}
|
|
||||||
if (inputDevice != null) {
|
|
||||||
mInputDevices.setValueAt(index, inputDevice);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return inputDevice;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -433,34 +403,7 @@ public final class InputManager {
|
|||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public InputDevice getInputDeviceByDescriptor(String descriptor) {
|
public InputDevice getInputDeviceByDescriptor(String descriptor) {
|
||||||
if (descriptor == null) {
|
return mGlobal.getInputDeviceByDescriptor(descriptor);
|
||||||
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) {
|
|
||||||
throw ex.rethrowFromSystemServer();
|
|
||||||
}
|
|
||||||
if (inputDevice == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
mInputDevices.setValueAt(i, inputDevice);
|
|
||||||
}
|
|
||||||
if (descriptor.equals(inputDevice.getDescriptor())) {
|
|
||||||
return inputDevice;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -468,16 +411,7 @@ public final class InputManager {
|
|||||||
* @return The input device ids.
|
* @return The input device ids.
|
||||||
*/
|
*/
|
||||||
public int[] getInputDeviceIds() {
|
public int[] getInputDeviceIds() {
|
||||||
synchronized (mInputDevicesLock) {
|
return mGlobal.getInputDeviceIds();
|
||||||
populateInputDevicesLocked();
|
|
||||||
|
|
||||||
final int count = mInputDevices.size();
|
|
||||||
final int[] ids = new int[count];
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
ids[i] = mInputDevices.keyAt(i);
|
|
||||||
}
|
|
||||||
return ids;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -547,17 +481,7 @@ public final class InputManager {
|
|||||||
* @see #unregisterInputDeviceListener
|
* @see #unregisterInputDeviceListener
|
||||||
*/
|
*/
|
||||||
public void registerInputDeviceListener(InputDeviceListener listener, Handler handler) {
|
public void registerInputDeviceListener(InputDeviceListener listener, Handler handler) {
|
||||||
if (listener == null) {
|
mGlobal.registerInputDeviceListener(listener, handler);
|
||||||
throw new IllegalArgumentException("listener must not be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized (mInputDevicesLock) {
|
|
||||||
populateInputDevicesLocked();
|
|
||||||
int index = findInputDeviceListenerLocked(listener);
|
|
||||||
if (index < 0) {
|
|
||||||
mInputDeviceListeners.add(new InputDeviceListenerDelegate(listener, handler));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -568,28 +492,7 @@ public final class InputManager {
|
|||||||
* @see #registerInputDeviceListener
|
* @see #registerInputDeviceListener
|
||||||
*/
|
*/
|
||||||
public void unregisterInputDeviceListener(InputDeviceListener listener) {
|
public void unregisterInputDeviceListener(InputDeviceListener listener) {
|
||||||
if (listener == null) {
|
mGlobal.unregisterInputDeviceListener(listener);
|
||||||
throw new IllegalArgumentException("listener must not be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized (mInputDevicesLock) {
|
|
||||||
int index = findInputDeviceListenerLocked(listener);
|
|
||||||
if (index >= 0) {
|
|
||||||
InputDeviceListenerDelegate d = mInputDeviceListeners.get(index);
|
|
||||||
d.removeCallbacksAndMessages(null);
|
|
||||||
mInputDeviceListeners.remove(index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int findInputDeviceListenerLocked(InputDeviceListener listener) {
|
|
||||||
final int numListeners = mInputDeviceListeners.size();
|
|
||||||
for (int i = 0; i < numListeners; i++) {
|
|
||||||
if (mInputDeviceListeners.get(i).mListener == listener) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1543,119 +1446,8 @@ public final class InputManager {
|
|||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public HostUsiVersion getHostUsiVersion(@NonNull Display display) {
|
public HostUsiVersion getHostUsiVersion(@NonNull Display display) {
|
||||||
Objects.requireNonNull(display, "display should not be null");
|
return mGlobal.getHostUsiVersion(display);
|
||||||
|
|
||||||
// Return the first valid USI version reported by any input device associated with
|
|
||||||
// the display.
|
|
||||||
synchronized (mInputDevicesLock) {
|
|
||||||
populateInputDevicesLocked();
|
|
||||||
|
|
||||||
for (int i = 0; i < mInputDevices.size(); i++) {
|
|
||||||
final InputDevice device = getInputDevice(mInputDevices.keyAt(i));
|
|
||||||
if (device != null && device.getAssociatedDisplayId() == display.getDisplayId()) {
|
|
||||||
if (device.getHostUsiVersion() != null) {
|
|
||||||
return device.getHostUsiVersion();
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If there are no input devices that report a valid USI version, see if there is a config
|
|
||||||
// that specifies the USI version for the display. This is to handle cases where the USI
|
|
||||||
// input device is not registered by the kernel/driver all the time.
|
|
||||||
try {
|
|
||||||
return mIm.getHostUsiVersionFromDisplayConfig(display.getDisplayId());
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
throw e.rethrowFromSystemServer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void populateInputDevicesLocked() {
|
|
||||||
if (mInputDevicesChangedListener == null) {
|
|
||||||
final InputDevicesChangedListener listener = new InputDevicesChangedListener();
|
|
||||||
try {
|
|
||||||
mIm.registerInputDevicesChangedListener(listener);
|
|
||||||
} catch (RemoteException ex) {
|
|
||||||
throw ex.rethrowFromSystemServer();
|
|
||||||
}
|
|
||||||
mInputDevicesChangedListener = listener;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mInputDevices == null) {
|
|
||||||
final int[] ids;
|
|
||||||
try {
|
|
||||||
ids = mIm.getInputDeviceIds();
|
|
||||||
} catch (RemoteException ex) {
|
|
||||||
throw ex.rethrowFromSystemServer();
|
|
||||||
}
|
|
||||||
|
|
||||||
mInputDevices = new SparseArray<>();
|
|
||||||
for (int id : ids) {
|
|
||||||
mInputDevices.put(id, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onInputDevicesChanged(int[] deviceIdAndGeneration) {
|
|
||||||
if (DEBUG) {
|
|
||||||
Log.d(TAG, "Received input devices changed.");
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized (mInputDevicesLock) {
|
|
||||||
for (int i = mInputDevices.size(); --i > 0; ) {
|
|
||||||
final int deviceId = mInputDevices.keyAt(i);
|
|
||||||
if (!containsDeviceId(deviceIdAndGeneration, deviceId)) {
|
|
||||||
if (DEBUG) {
|
|
||||||
Log.d(TAG, "Device removed: " + deviceId);
|
|
||||||
}
|
|
||||||
mInputDevices.removeAt(i);
|
|
||||||
sendMessageToInputDeviceListenersLocked(MSG_DEVICE_REMOVED, deviceId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < deviceIdAndGeneration.length; i += 2) {
|
|
||||||
final int deviceId = deviceIdAndGeneration[i];
|
|
||||||
int index = mInputDevices.indexOfKey(deviceId);
|
|
||||||
if (index >= 0) {
|
|
||||||
final InputDevice device = mInputDevices.valueAt(index);
|
|
||||||
if (device != null) {
|
|
||||||
final int generation = deviceIdAndGeneration[i + 1];
|
|
||||||
if (device.getGeneration() != generation) {
|
|
||||||
if (DEBUG) {
|
|
||||||
Log.d(TAG, "Device changed: " + deviceId);
|
|
||||||
}
|
|
||||||
mInputDevices.setValueAt(index, null);
|
|
||||||
sendMessageToInputDeviceListenersLocked(MSG_DEVICE_CHANGED, deviceId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (DEBUG) {
|
|
||||||
Log.d(TAG, "Device added: " + deviceId);
|
|
||||||
}
|
|
||||||
mInputDevices.put(deviceId, null);
|
|
||||||
sendMessageToInputDeviceListenersLocked(MSG_DEVICE_ADDED, deviceId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sendMessageToInputDeviceListenersLocked(int what, int deviceId) {
|
|
||||||
final int numListeners = mInputDeviceListeners.size();
|
|
||||||
for (int i = 0; i < numListeners; i++) {
|
|
||||||
InputDeviceListenerDelegate listener = mInputDeviceListeners.get(i);
|
|
||||||
listener.sendMessage(listener.obtainMessage(what, deviceId, 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean containsDeviceId(int[] deviceIdAndGeneration, int deviceId) {
|
|
||||||
for (int i = 0; i < deviceIdAndGeneration.length; i += 2) {
|
|
||||||
if (deviceIdAndGeneration[i] == deviceId) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void onTabletModeChanged(long whenNanos, boolean inTabletMode) {
|
private void onTabletModeChanged(long whenNanos, boolean inTabletMode) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
@@ -2149,7 +1941,7 @@ public final class InputManager {
|
|||||||
public interface InputDeviceListener {
|
public interface InputDeviceListener {
|
||||||
/**
|
/**
|
||||||
* Called whenever an input device has been added to the system.
|
* Called whenever an input device has been added to the system.
|
||||||
* Use {@link InputManager#getInputDevice} to get more information about the device.
|
* Use {@link InputManagerGlobal#getInputDevice} to get more information about the device.
|
||||||
*
|
*
|
||||||
* @param deviceId The id of the input device that was added.
|
* @param deviceId The id of the input device that was added.
|
||||||
*/
|
*/
|
||||||
@@ -2172,37 +1964,6 @@ public final class InputManager {
|
|||||||
void onInputDeviceChanged(int deviceId);
|
void onInputDeviceChanged(int deviceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class InputDevicesChangedListener extends IInputDevicesChangedListener.Stub {
|
|
||||||
@Override
|
|
||||||
public void onInputDevicesChanged(int[] deviceIdAndGeneration) throws RemoteException {
|
|
||||||
InputManager.this.onInputDevicesChanged(deviceIdAndGeneration);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final class InputDeviceListenerDelegate extends Handler {
|
|
||||||
public final InputDeviceListener mListener;
|
|
||||||
|
|
||||||
public InputDeviceListenerDelegate(InputDeviceListener listener, Handler handler) {
|
|
||||||
super(handler != null ? handler.getLooper() : Looper.myLooper());
|
|
||||||
mListener = listener;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleMessage(Message msg) {
|
|
||||||
switch (msg.what) {
|
|
||||||
case MSG_DEVICE_ADDED:
|
|
||||||
mListener.onInputDeviceAdded(msg.arg1);
|
|
||||||
break;
|
|
||||||
case MSG_DEVICE_REMOVED:
|
|
||||||
mListener.onInputDeviceRemoved(msg.arg1);
|
|
||||||
break;
|
|
||||||
case MSG_DEVICE_CHANGED:
|
|
||||||
mListener.onInputDeviceChanged(msg.arg1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
public interface OnTabletModeChangedListener {
|
public interface OnTabletModeChangedListener {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -16,9 +16,25 @@
|
|||||||
|
|
||||||
package android.hardware.input;
|
package android.hardware.input;
|
||||||
|
|
||||||
|
import android.annotation.NonNull;
|
||||||
|
import android.annotation.Nullable;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.hardware.input.InputManager.InputDeviceListener;
|
||||||
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.os.Message;
|
||||||
|
import android.os.RemoteException;
|
||||||
import android.os.ServiceManager;
|
import android.os.ServiceManager;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.util.SparseArray;
|
||||||
|
import android.view.Display;
|
||||||
|
import android.view.InputDevice;
|
||||||
|
|
||||||
|
import com.android.internal.annotations.GuardedBy;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages communication with the input manager service on behalf of
|
* Manages communication with the input manager service on behalf of
|
||||||
@@ -28,6 +44,20 @@ import android.os.ServiceManager;
|
|||||||
*/
|
*/
|
||||||
public final class InputManagerGlobal {
|
public final class InputManagerGlobal {
|
||||||
private static final String TAG = "InputManagerGlobal";
|
private static final String TAG = "InputManagerGlobal";
|
||||||
|
// To enable these logs, run: 'adb shell setprop log.tag.InputManagerGlobal DEBUG'
|
||||||
|
// (requires restart)
|
||||||
|
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
||||||
|
|
||||||
|
private static final int MSG_DEVICE_ADDED = 1;
|
||||||
|
private static final int MSG_DEVICE_REMOVED = 2;
|
||||||
|
private static final int MSG_DEVICE_CHANGED = 3;
|
||||||
|
|
||||||
|
@GuardedBy("mInputDeviceListeners")
|
||||||
|
@Nullable private SparseArray<InputDevice> mInputDevices;
|
||||||
|
@GuardedBy("mInputDeviceListeners")
|
||||||
|
@Nullable private InputDevicesChangedListener mInputDevicesChangedListener;
|
||||||
|
@GuardedBy("mInputDeviceListeners")
|
||||||
|
private final ArrayList<InputDeviceListenerDelegate> mInputDeviceListeners = new ArrayList<>();
|
||||||
|
|
||||||
private static InputManagerGlobal sInstance;
|
private static InputManagerGlobal sInstance;
|
||||||
|
|
||||||
@@ -79,4 +109,280 @@ public final class InputManagerGlobal {
|
|||||||
sInstance = null;
|
sInstance = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see InputManager#getInputDevice(int)
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public InputDevice getInputDevice(int id) {
|
||||||
|
synchronized (mInputDeviceListeners) {
|
||||||
|
populateInputDevicesLocked();
|
||||||
|
|
||||||
|
int index = mInputDevices.indexOfKey(id);
|
||||||
|
if (index < 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
InputDevice inputDevice = mInputDevices.valueAt(index);
|
||||||
|
if (inputDevice == null) {
|
||||||
|
try {
|
||||||
|
inputDevice = mIm.getInputDevice(id);
|
||||||
|
} catch (RemoteException ex) {
|
||||||
|
throw ex.rethrowFromSystemServer();
|
||||||
|
}
|
||||||
|
if (inputDevice != null) {
|
||||||
|
mInputDevices.setValueAt(index, inputDevice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return inputDevice;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GuardedBy("mInputDeviceListeners")
|
||||||
|
private void populateInputDevicesLocked() {
|
||||||
|
if (mInputDevicesChangedListener == null) {
|
||||||
|
final InputDevicesChangedListener
|
||||||
|
listener = new InputDevicesChangedListener();
|
||||||
|
try {
|
||||||
|
mIm.registerInputDevicesChangedListener(listener);
|
||||||
|
} catch (RemoteException ex) {
|
||||||
|
throw ex.rethrowFromSystemServer();
|
||||||
|
}
|
||||||
|
mInputDevicesChangedListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mInputDevices == null) {
|
||||||
|
final int[] ids;
|
||||||
|
try {
|
||||||
|
ids = mIm.getInputDeviceIds();
|
||||||
|
} catch (RemoteException ex) {
|
||||||
|
throw ex.rethrowFromSystemServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
mInputDevices = new SparseArray<>();
|
||||||
|
for (int id : ids) {
|
||||||
|
mInputDevices.put(id, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final class InputDevicesChangedListener extends IInputDevicesChangedListener.Stub {
|
||||||
|
@Override
|
||||||
|
public void onInputDevicesChanged(int[] deviceIdAndGeneration) throws RemoteException {
|
||||||
|
InputManagerGlobal.this.onInputDevicesChanged(deviceIdAndGeneration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onInputDevicesChanged(int[] deviceIdAndGeneration) {
|
||||||
|
if (DEBUG) {
|
||||||
|
Log.d(TAG, "Received input devices changed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized (mInputDeviceListeners) {
|
||||||
|
for (int i = mInputDevices.size(); --i > 0; ) {
|
||||||
|
final int deviceId = mInputDevices.keyAt(i);
|
||||||
|
if (!containsDeviceId(deviceIdAndGeneration, deviceId)) {
|
||||||
|
if (DEBUG) {
|
||||||
|
Log.d(TAG, "Device removed: " + deviceId);
|
||||||
|
}
|
||||||
|
mInputDevices.removeAt(i);
|
||||||
|
sendMessageToInputDeviceListenersLocked(MSG_DEVICE_REMOVED, deviceId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < deviceIdAndGeneration.length; i += 2) {
|
||||||
|
final int deviceId = deviceIdAndGeneration[i];
|
||||||
|
int index = mInputDevices.indexOfKey(deviceId);
|
||||||
|
if (index >= 0) {
|
||||||
|
final InputDevice device = mInputDevices.valueAt(index);
|
||||||
|
if (device != null) {
|
||||||
|
final int generation = deviceIdAndGeneration[i + 1];
|
||||||
|
if (device.getGeneration() != generation) {
|
||||||
|
if (DEBUG) {
|
||||||
|
Log.d(TAG, "Device changed: " + deviceId);
|
||||||
|
}
|
||||||
|
mInputDevices.setValueAt(index, null);
|
||||||
|
sendMessageToInputDeviceListenersLocked(MSG_DEVICE_CHANGED, deviceId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (DEBUG) {
|
||||||
|
Log.d(TAG, "Device added: " + deviceId);
|
||||||
|
}
|
||||||
|
mInputDevices.put(deviceId, null);
|
||||||
|
sendMessageToInputDeviceListenersLocked(MSG_DEVICE_ADDED, deviceId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class InputDeviceListenerDelegate extends Handler {
|
||||||
|
public final InputDeviceListener mListener;
|
||||||
|
|
||||||
|
InputDeviceListenerDelegate(InputDeviceListener listener, Handler handler) {
|
||||||
|
super(handler != null ? handler.getLooper() : Looper.myLooper());
|
||||||
|
mListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleMessage(Message msg) {
|
||||||
|
switch (msg.what) {
|
||||||
|
case MSG_DEVICE_ADDED:
|
||||||
|
mListener.onInputDeviceAdded(msg.arg1);
|
||||||
|
break;
|
||||||
|
case MSG_DEVICE_REMOVED:
|
||||||
|
mListener.onInputDeviceRemoved(msg.arg1);
|
||||||
|
break;
|
||||||
|
case MSG_DEVICE_CHANGED:
|
||||||
|
mListener.onInputDeviceChanged(msg.arg1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean containsDeviceId(int[] deviceIdAndGeneration, int deviceId) {
|
||||||
|
for (int i = 0; i < deviceIdAndGeneration.length; i += 2) {
|
||||||
|
if (deviceIdAndGeneration[i] == deviceId) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GuardedBy("mInputDeviceListeners")
|
||||||
|
private void sendMessageToInputDeviceListenersLocked(int what, int deviceId) {
|
||||||
|
final int numListeners = mInputDeviceListeners.size();
|
||||||
|
for (int i = 0; i < numListeners; i++) {
|
||||||
|
InputDeviceListenerDelegate listener = mInputDeviceListeners.get(i);
|
||||||
|
listener.sendMessage(listener.obtainMessage(what, deviceId, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see InputManager#registerInputDeviceListener
|
||||||
|
*/
|
||||||
|
public void registerInputDeviceListener(InputDeviceListener listener, Handler handler) {
|
||||||
|
if (listener == null) {
|
||||||
|
throw new IllegalArgumentException("listener must not be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized (mInputDeviceListeners) {
|
||||||
|
populateInputDevicesLocked();
|
||||||
|
int index = findInputDeviceListenerLocked(listener);
|
||||||
|
if (index < 0) {
|
||||||
|
mInputDeviceListeners.add(new InputDeviceListenerDelegate(listener, handler));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see InputManager#unregisterInputDeviceListener
|
||||||
|
*/
|
||||||
|
public void unregisterInputDeviceListener(InputDeviceListener listener) {
|
||||||
|
if (listener == null) {
|
||||||
|
throw new IllegalArgumentException("listener must not be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized (mInputDeviceListeners) {
|
||||||
|
int index = findInputDeviceListenerLocked(listener);
|
||||||
|
if (index >= 0) {
|
||||||
|
InputDeviceListenerDelegate d = mInputDeviceListeners.get(index);
|
||||||
|
d.removeCallbacksAndMessages(null);
|
||||||
|
mInputDeviceListeners.remove(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GuardedBy("mInputDeviceListeners")
|
||||||
|
private int findInputDeviceListenerLocked(InputDeviceListener listener) {
|
||||||
|
final int numListeners = mInputDeviceListeners.size();
|
||||||
|
for (int i = 0; i < numListeners; i++) {
|
||||||
|
if (mInputDeviceListeners.get(i).mListener == listener) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see InputManager#getInputDeviceIds
|
||||||
|
*/
|
||||||
|
public int[] getInputDeviceIds() {
|
||||||
|
synchronized (mInputDeviceListeners) {
|
||||||
|
populateInputDevicesLocked();
|
||||||
|
|
||||||
|
final int count = mInputDevices.size();
|
||||||
|
final int[] ids = new int[count];
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
ids[i] = mInputDevices.keyAt(i);
|
||||||
|
}
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see InputManager#getInputDeviceByDescriptor
|
||||||
|
*/
|
||||||
|
InputDevice getInputDeviceByDescriptor(String descriptor) {
|
||||||
|
if (descriptor == null) {
|
||||||
|
throw new IllegalArgumentException("descriptor must not be null.");
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized (mInputDeviceListeners) {
|
||||||
|
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) {
|
||||||
|
throw ex.rethrowFromSystemServer();
|
||||||
|
}
|
||||||
|
if (inputDevice == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
mInputDevices.setValueAt(i, inputDevice);
|
||||||
|
}
|
||||||
|
if (descriptor.equals(inputDevice.getDescriptor())) {
|
||||||
|
return inputDevice;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see InputManager#getHostUsiVersion
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
HostUsiVersion getHostUsiVersion(@NonNull Display display) {
|
||||||
|
Objects.requireNonNull(display, "display should not be null");
|
||||||
|
|
||||||
|
// Return the first valid USI version reported by any input device associated with
|
||||||
|
// the display.
|
||||||
|
synchronized (mInputDeviceListeners) {
|
||||||
|
populateInputDevicesLocked();
|
||||||
|
|
||||||
|
for (int i = 0; i < mInputDevices.size(); i++) {
|
||||||
|
final InputDevice device = getInputDevice(mInputDevices.keyAt(i));
|
||||||
|
if (device != null && device.getAssociatedDisplayId() == display.getDisplayId()) {
|
||||||
|
if (device.getHostUsiVersion() != null) {
|
||||||
|
return device.getHostUsiVersion();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there are no input devices that report a valid USI version, see if there is a config
|
||||||
|
// that specifies the USI version for the display. This is to handle cases where the USI
|
||||||
|
// input device is not registered by the kernel/driver all the time.
|
||||||
|
try {
|
||||||
|
return mIm.getHostUsiVersionFromDisplayConfig(display.getDisplayId());
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
throw e.rethrowFromSystemServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import android.hardware.SensorManager;
|
|||||||
import android.hardware.input.HostUsiVersion;
|
import android.hardware.input.HostUsiVersion;
|
||||||
import android.hardware.input.InputDeviceIdentifier;
|
import android.hardware.input.InputDeviceIdentifier;
|
||||||
import android.hardware.input.InputManager;
|
import android.hardware.input.InputManager;
|
||||||
|
import android.hardware.input.InputManagerGlobal;
|
||||||
import android.hardware.lights.LightsManager;
|
import android.hardware.lights.LightsManager;
|
||||||
import android.icu.util.ULocale;
|
import android.icu.util.ULocale;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
@@ -742,7 +743,7 @@ public final class InputDevice implements Parcelable {
|
|||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public static InputDevice getDevice(int id) {
|
public static InputDevice getDevice(int id) {
|
||||||
return InputManager.getInstance().getInputDevice(id);
|
return InputManagerGlobal.getInstance().getInputDevice(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -750,7 +751,7 @@ public final class InputDevice implements Parcelable {
|
|||||||
* @return The input device ids.
|
* @return The input device ids.
|
||||||
*/
|
*/
|
||||||
public static int[] getDeviceIds() {
|
public static int[] getDeviceIds() {
|
||||||
return InputManager.getInstance().getInputDeviceIds();
|
return InputManagerGlobal.getInstance().getInputDeviceIds();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import android.content.res.Configuration;
|
|||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.hardware.input.InputManager;
|
import android.hardware.input.InputManager;
|
||||||
|
import android.hardware.input.InputManagerGlobal;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
@@ -1188,7 +1189,7 @@ public class ViewConfiguration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isInputDeviceInfoValid(int id, int axis, int source) {
|
private static boolean isInputDeviceInfoValid(int id, int axis, int source) {
|
||||||
InputDevice device = InputManager.getInstance().getInputDevice(id);
|
InputDevice device = InputManagerGlobal.getInstance().getInputDevice(id);
|
||||||
return device != null && device.getMotionRange(axis, source) != null;
|
return device != null && device.getMotionRange(axis, source) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import android.graphics.PointF;
|
|||||||
import android.hardware.display.DisplayManagerInternal;
|
import android.hardware.display.DisplayManagerInternal;
|
||||||
import android.hardware.input.InputDeviceIdentifier;
|
import android.hardware.input.InputDeviceIdentifier;
|
||||||
import android.hardware.input.InputManager;
|
import android.hardware.input.InputManager;
|
||||||
|
import android.hardware.input.InputManagerGlobal;
|
||||||
import android.hardware.input.VirtualKeyEvent;
|
import android.hardware.input.VirtualKeyEvent;
|
||||||
import android.hardware.input.VirtualMouseButtonEvent;
|
import android.hardware.input.VirtualMouseButtonEvent;
|
||||||
import android.hardware.input.VirtualMouseRelativeEvent;
|
import android.hardware.input.VirtualMouseRelativeEvent;
|
||||||
@@ -686,7 +687,7 @@ class InputController {
|
|||||||
mListener = new InputManager.InputDeviceListener() {
|
mListener = new InputManager.InputDeviceListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onInputDeviceAdded(int deviceId) {
|
public void onInputDeviceAdded(int deviceId) {
|
||||||
final InputDevice device = InputManager.getInstance().getInputDevice(
|
final InputDevice device = InputManagerGlobal.getInstance().getInputDevice(
|
||||||
deviceId);
|
deviceId);
|
||||||
Objects.requireNonNull(device, "Newly added input device was null.");
|
Objects.requireNonNull(device, "Newly added input device was null.");
|
||||||
if (!device.getName().equals(deviceName)) {
|
if (!device.getName().equals(deviceName)) {
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import static org.mockito.Mockito.verify;
|
|||||||
|
|
||||||
import android.hardware.display.DisplayManagerInternal;
|
import android.hardware.display.DisplayManagerInternal;
|
||||||
import android.hardware.input.IInputManager;
|
import android.hardware.input.IInputManager;
|
||||||
import android.hardware.input.InputManager;
|
import android.hardware.input.InputManagerGlobal;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
@@ -109,7 +109,7 @@ public class InputControllerTest {
|
|||||||
device1Id).isNotEqualTo(device2Id);
|
device1Id).isNotEqualTo(device2Id);
|
||||||
|
|
||||||
|
|
||||||
int[] deviceIds = InputManager.getInstance().getInputDeviceIds();
|
int[] deviceIds = InputManagerGlobal.getInstance().getInputDeviceIds();
|
||||||
assertWithMessage("InputManager's deviceIds list should contain id of device 1").that(
|
assertWithMessage("InputManager's deviceIds list should contain id of device 1").that(
|
||||||
deviceIds).asList().contains(device1Id);
|
deviceIds).asList().contains(device1Id);
|
||||||
assertWithMessage("InputManager's deviceIds list should contain id of device 2").that(
|
assertWithMessage("InputManager's deviceIds list should contain id of device 2").that(
|
||||||
@@ -153,7 +153,7 @@ public class InputControllerTest {
|
|||||||
deviceToken, /* displayId= */ 1, /* touchpadHeight= */ 50, /* touchpadWidth= */ 50);
|
deviceToken, /* displayId= */ 1, /* touchpadHeight= */ 50, /* touchpadWidth= */ 50);
|
||||||
|
|
||||||
int deviceId = mInputController.getInputDeviceId(deviceToken);
|
int deviceId = mInputController.getInputDeviceId(deviceToken);
|
||||||
int[] deviceIds = InputManager.getInstance().getInputDeviceIds();
|
int[] deviceIds = InputManagerGlobal.getInstance().getInputDeviceIds();
|
||||||
|
|
||||||
assertWithMessage("InputManager's deviceIds list should contain id of the device").that(
|
assertWithMessage("InputManager's deviceIds list should contain id of the device").that(
|
||||||
deviceIds).asList().contains(deviceId);
|
deviceIds).asList().contains(deviceId);
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import android.content.ContextWrapper;
|
|||||||
import android.hardware.input.IInputDevicesChangedListener;
|
import android.hardware.input.IInputDevicesChangedListener;
|
||||||
import android.hardware.input.IInputManager;
|
import android.hardware.input.IInputManager;
|
||||||
import android.hardware.input.InputManager;
|
import android.hardware.input.InputManager;
|
||||||
|
import android.hardware.input.InputManagerGlobal;
|
||||||
import android.os.CombinedVibration;
|
import android.os.CombinedVibration;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
@@ -82,8 +83,8 @@ public class InputDeviceDelegateTest {
|
|||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
mTestLooper = new TestLooper();
|
mTestLooper = new TestLooper();
|
||||||
mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getContext()));
|
|
||||||
InputManager inputManager = InputManager.resetInstance(mIInputManagerMock);
|
InputManager inputManager = InputManager.resetInstance(mIInputManagerMock);
|
||||||
|
mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getContext()));
|
||||||
|
|
||||||
when(mContextSpy.getSystemService(eq(Context.INPUT_SERVICE))).thenReturn(inputManager);
|
when(mContextSpy.getSystemService(eq(Context.INPUT_SERVICE))).thenReturn(inputManager);
|
||||||
doAnswer(invocation -> mIInputDevicesChangedListener = invocation.getArgument(0))
|
doAnswer(invocation -> mIInputDevicesChangedListener = invocation.getArgument(0))
|
||||||
@@ -314,7 +315,7 @@ public class InputDeviceDelegateTest {
|
|||||||
deviceIdsAndGenerations[i + 1] = 2; // update by increasing it's generation to 2.
|
deviceIdsAndGenerations[i + 1] = 2; // update by increasing it's generation to 2.
|
||||||
}
|
}
|
||||||
// Force initialization of mIInputDevicesChangedListener, if it still haven't
|
// Force initialization of mIInputDevicesChangedListener, if it still haven't
|
||||||
InputManager.getInstance().getInputDeviceIds();
|
InputManagerGlobal.getInstance().getInputDeviceIds();
|
||||||
mIInputDevicesChangedListener.onInputDevicesChanged(deviceIdsAndGenerations);
|
mIInputDevicesChangedListener.onInputDevicesChanged(deviceIdsAndGenerations);
|
||||||
// Makes sure all callbacks from InputDeviceDelegate are executed.
|
// Makes sure all callbacks from InputDeviceDelegate are executed.
|
||||||
mTestLooper.dispatchAll();
|
mTestLooper.dispatchAll();
|
||||||
|
|||||||
Reference in New Issue
Block a user