Loading core/java/android/hardware/input/InputManager.java +7 −246 Original line number Diff line number Diff line Loading @@ -88,10 +88,6 @@ public final class InputManager { // 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 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; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) Loading @@ -112,12 +108,6 @@ public final class InputManager { @Nullable 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 private final Object mTabletModeLock = new Object(); @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) Loading Loading @@ -403,27 +393,7 @@ public final class InputManager { */ @Nullable public InputDevice getInputDevice(int id) { synchronized (mInputDevicesLock) { 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; } return mGlobal.getInputDevice(id); } /** Loading @@ -433,34 +403,7 @@ public final class InputManager { * @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) { throw ex.rethrowFromSystemServer(); } if (inputDevice == null) { continue; } mInputDevices.setValueAt(i, inputDevice); } if (descriptor.equals(inputDevice.getDescriptor())) { return inputDevice; } } return null; } return mGlobal.getInputDeviceByDescriptor(descriptor); } /** Loading @@ -468,16 +411,7 @@ public final class InputManager { * @return The input device ids. */ public int[] getInputDeviceIds() { synchronized (mInputDevicesLock) { 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; } return mGlobal.getInputDeviceIds(); } /** Loading Loading @@ -547,17 +481,7 @@ public final class InputManager { * @see #unregisterInputDeviceListener */ public void registerInputDeviceListener(InputDeviceListener listener, Handler handler) { if (listener == null) { throw new IllegalArgumentException("listener must not be null"); } synchronized (mInputDevicesLock) { populateInputDevicesLocked(); int index = findInputDeviceListenerLocked(listener); if (index < 0) { mInputDeviceListeners.add(new InputDeviceListenerDelegate(listener, handler)); } } mGlobal.registerInputDeviceListener(listener, handler); } /** Loading @@ -568,28 +492,7 @@ public final class InputManager { * @see #registerInputDeviceListener */ public void unregisterInputDeviceListener(InputDeviceListener listener) { if (listener == null) { 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; mGlobal.unregisterInputDeviceListener(listener); } /** Loading Loading @@ -1543,120 +1446,9 @@ public final class InputManager { */ @Nullable public 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 (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(); } } } return mGlobal.getHostUsiVersion(display); } // 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) { if (DEBUG) { Log.d(TAG, "Received tablet mode changed: " Loading Loading @@ -2149,7 +1941,7 @@ public final class InputManager { public interface InputDeviceListener { /** * 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. */ Loading @@ -2172,37 +1964,6 @@ public final class InputManager { 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 */ public interface OnTabletModeChangedListener { /** Loading core/java/android/hardware/input/InputManagerGlobal.java +306 −0 Original line number Diff line number Diff line Loading @@ -16,9 +16,25 @@ package android.hardware.input; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.hardware.input.InputManager.InputDeviceListener; import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.RemoteException; 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 Loading @@ -28,6 +44,20 @@ import android.os.ServiceManager; */ public final class 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; Loading Loading @@ -79,4 +109,280 @@ public final class InputManagerGlobal { 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(); } } } core/java/android/view/InputDevice.java +3 −2 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.hardware.SensorManager; import android.hardware.input.HostUsiVersion; import android.hardware.input.InputDeviceIdentifier; import android.hardware.input.InputManager; import android.hardware.input.InputManagerGlobal; import android.hardware.lights.LightsManager; import android.icu.util.ULocale; import android.os.Build; Loading Loading @@ -742,7 +743,7 @@ public final class InputDevice implements Parcelable { */ @Nullable public static InputDevice getDevice(int id) { return InputManager.getInstance().getInputDevice(id); return InputManagerGlobal.getInstance().getInputDevice(id); } /** Loading @@ -750,7 +751,7 @@ public final class InputDevice implements Parcelable { * @return The input device ids. */ public static int[] getDeviceIds() { return InputManager.getInstance().getInputDeviceIds(); return InputManagerGlobal.getInstance().getInputDeviceIds(); } /** Loading core/java/android/view/ViewConfiguration.java +2 −1 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Rect; import android.hardware.input.InputManager; import android.hardware.input.InputManagerGlobal; import android.os.Build; import android.os.Bundle; import android.os.RemoteException; Loading Loading @@ -1188,7 +1189,7 @@ public class ViewConfiguration { } 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; } Loading services/companion/java/com/android/server/companion/virtual/InputController.java +2 −1 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
core/java/android/hardware/input/InputManager.java +7 −246 Original line number Diff line number Diff line Loading @@ -88,10 +88,6 @@ public final class InputManager { // 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 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; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) Loading @@ -112,12 +108,6 @@ public final class InputManager { @Nullable 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 private final Object mTabletModeLock = new Object(); @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) Loading Loading @@ -403,27 +393,7 @@ public final class InputManager { */ @Nullable public InputDevice getInputDevice(int id) { synchronized (mInputDevicesLock) { 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; } return mGlobal.getInputDevice(id); } /** Loading @@ -433,34 +403,7 @@ public final class InputManager { * @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) { throw ex.rethrowFromSystemServer(); } if (inputDevice == null) { continue; } mInputDevices.setValueAt(i, inputDevice); } if (descriptor.equals(inputDevice.getDescriptor())) { return inputDevice; } } return null; } return mGlobal.getInputDeviceByDescriptor(descriptor); } /** Loading @@ -468,16 +411,7 @@ public final class InputManager { * @return The input device ids. */ public int[] getInputDeviceIds() { synchronized (mInputDevicesLock) { 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; } return mGlobal.getInputDeviceIds(); } /** Loading Loading @@ -547,17 +481,7 @@ public final class InputManager { * @see #unregisterInputDeviceListener */ public void registerInputDeviceListener(InputDeviceListener listener, Handler handler) { if (listener == null) { throw new IllegalArgumentException("listener must not be null"); } synchronized (mInputDevicesLock) { populateInputDevicesLocked(); int index = findInputDeviceListenerLocked(listener); if (index < 0) { mInputDeviceListeners.add(new InputDeviceListenerDelegate(listener, handler)); } } mGlobal.registerInputDeviceListener(listener, handler); } /** Loading @@ -568,28 +492,7 @@ public final class InputManager { * @see #registerInputDeviceListener */ public void unregisterInputDeviceListener(InputDeviceListener listener) { if (listener == null) { 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; mGlobal.unregisterInputDeviceListener(listener); } /** Loading Loading @@ -1543,120 +1446,9 @@ public final class InputManager { */ @Nullable public 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 (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(); } } } return mGlobal.getHostUsiVersion(display); } // 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) { if (DEBUG) { Log.d(TAG, "Received tablet mode changed: " Loading Loading @@ -2149,7 +1941,7 @@ public final class InputManager { public interface InputDeviceListener { /** * 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. */ Loading @@ -2172,37 +1964,6 @@ public final class InputManager { 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 */ public interface OnTabletModeChangedListener { /** Loading
core/java/android/hardware/input/InputManagerGlobal.java +306 −0 Original line number Diff line number Diff line Loading @@ -16,9 +16,25 @@ package android.hardware.input; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.hardware.input.InputManager.InputDeviceListener; import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.RemoteException; 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 Loading @@ -28,6 +44,20 @@ import android.os.ServiceManager; */ public final class 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; Loading Loading @@ -79,4 +109,280 @@ public final class InputManagerGlobal { 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(); } } }
core/java/android/view/InputDevice.java +3 −2 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.hardware.SensorManager; import android.hardware.input.HostUsiVersion; import android.hardware.input.InputDeviceIdentifier; import android.hardware.input.InputManager; import android.hardware.input.InputManagerGlobal; import android.hardware.lights.LightsManager; import android.icu.util.ULocale; import android.os.Build; Loading Loading @@ -742,7 +743,7 @@ public final class InputDevice implements Parcelable { */ @Nullable public static InputDevice getDevice(int id) { return InputManager.getInstance().getInputDevice(id); return InputManagerGlobal.getInstance().getInputDevice(id); } /** Loading @@ -750,7 +751,7 @@ public final class InputDevice implements Parcelable { * @return The input device ids. */ public static int[] getDeviceIds() { return InputManager.getInstance().getInputDeviceIds(); return InputManagerGlobal.getInstance().getInputDeviceIds(); } /** Loading
core/java/android/view/ViewConfiguration.java +2 −1 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Rect; import android.hardware.input.InputManager; import android.hardware.input.InputManagerGlobal; import android.os.Build; import android.os.Bundle; import android.os.RemoteException; Loading Loading @@ -1188,7 +1189,7 @@ public class ViewConfiguration { } 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; } Loading
services/companion/java/com/android/server/companion/virtual/InputController.java +2 −1 File changed.Preview size limit exceeded, changes collapsed. Show changes