Loading services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java +14 −1 Original line number Diff line number Diff line Loading @@ -105,6 +105,10 @@ class AccessibilityServiceConnection extends AbstractAccessibilityServiceConnect private final Handler mMainHandler; private UsbDeviceReceiver mUsbDeviceReceiverReceiver; // The serial number of the braille display which USB permission was last granted for. Needed to // automatically re-grant USB permission to this same braille display if unplugged and connected // again in the same accessibility service session. private String mConnectedBrailleDisplaySerialNumber = null; private static final class AccessibilityInputMethodSessionCallback extends IAccessibilityInputMethodSessionCallback.Stub { Loading Loading @@ -225,6 +229,7 @@ class AccessibilityServiceConnection extends AbstractAccessibilityServiceConnect resetLocked(); if (Flags.enableBrailleSuwImmediateConnections() && mUsbDeviceReceiverReceiver != null) { mContext.unregisterReceiver(mUsbDeviceReceiverReceiver); mConnectedBrailleDisplaySerialNumber = null; } } Loading Loading @@ -839,7 +844,8 @@ class AccessibilityServiceConnection extends AbstractAccessibilityServiceConnect return; } if (isInSetupWizard()) { if (isInSetupWizard() || (mConnectedBrailleDisplaySerialNumber != null && mConnectedBrailleDisplaySerialNumber.equals(device.getSerialNumber()))) { int clientUid = getClientUid(); if (clientUid == UID_UNKNOWN) { return; Loading @@ -847,6 +853,13 @@ class AccessibilityServiceConnection extends AbstractAccessibilityServiceConnect UsbManager usbManager = mContext.getSystemService(UsbManager.class); usbManager.grantPermission(device, /* uid of client's App */ clientUid); String usbSerialNumber = device.getSerialNumber(); if (!TextUtils.isEmpty(usbSerialNumber)) { // Store the serial number to re-grant USB permission to this braille display if it // is unplugged and reconnected. mConnectedBrailleDisplaySerialNumber = usbSerialNumber; } } } Loading services/tests/servicestests/src/com/android/server/accessibility/AccessibilityServiceConnectionTest.java +44 −0 Original line number Diff line number Diff line Loading @@ -598,4 +598,48 @@ public class AccessibilityServiceConnectionTest { usbDeviceReceiverCaptor.getValue().onReceive(mMockContext, intent); verify(usbManager, never()).grantPermission(any(), any()); } @Test @EnableFlags( com.android.server.accessibility.Flags.FLAG_ENABLE_BRAILLE_SUW_IMMEDIATE_CONNECTIONS) public void sendUsbAttachedIntentOutsideSuw_grantPermissionToSavedUsbDevice() { // Set USER_SETUP_COMPLETE = 0 to simulate running in SUW. Settings.Secure.putIntForUser(mContentResolver, Settings.Secure.USER_SETUP_COMPLETE, 0, mMockUserState.mUserId); mConnection.bindLocked(); ArgumentCaptor<BroadcastReceiver> usbDeviceReceiverCaptor = ArgumentCaptor.forClass( BroadcastReceiver.class); verify(mMockContext).registerReceiver(usbDeviceReceiverCaptor.capture(), any()); // Create USB device with a serial number for identification. UsbDevice usbDevice = Mockito.mock(UsbDevice.class); when(usbDevice.getSerialNumber()).thenReturn("UsbSerialNo"); // Setup USB device attach intent. Intent intent = new Intent(UsbManager.ACTION_USB_DEVICE_ATTACHED); intent.putExtra(UsbManager.EXTRA_DEVICE, usbDevice); // Send intent to simulate the USB device was unplugged and plugged in again and verify // permission is granted to the device because it was previously connected. UsbManager usbManager = Mockito.mock(UsbManager.class); when(mMockContext.getSystemService(Context.USB_SERVICE)).thenReturn(usbManager); when(mMockContext.getSystemServiceName(UsbManager.class)).thenReturn(Context.USB_SERVICE); usbDeviceReceiverCaptor.getValue().onReceive(mMockContext, intent); verify(usbManager, times(1)).grantPermission(usbDevice, 0); // After registering the USB device in the SUW, set USER_SETUP_COMPLETE = 1 to simulate // plugging in the USB device again outside of SUW. Settings.Secure.putIntForUser(mContentResolver, Settings.Secure.USER_SETUP_COMPLETE, 1, mMockUserState.mUserId); // Reset the USB manager mock for the next call. Mockito.clearInvocations(usbManager); // Send intent to simulate the USB device was unplugged and plugged in again and verify // permission is granted to the device because it was previously connected. usbDeviceReceiverCaptor.getValue().onReceive(mMockContext, intent); verify(usbManager, times(1)).grantPermission(usbDevice, 0); } } Loading
services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java +14 −1 Original line number Diff line number Diff line Loading @@ -105,6 +105,10 @@ class AccessibilityServiceConnection extends AbstractAccessibilityServiceConnect private final Handler mMainHandler; private UsbDeviceReceiver mUsbDeviceReceiverReceiver; // The serial number of the braille display which USB permission was last granted for. Needed to // automatically re-grant USB permission to this same braille display if unplugged and connected // again in the same accessibility service session. private String mConnectedBrailleDisplaySerialNumber = null; private static final class AccessibilityInputMethodSessionCallback extends IAccessibilityInputMethodSessionCallback.Stub { Loading Loading @@ -225,6 +229,7 @@ class AccessibilityServiceConnection extends AbstractAccessibilityServiceConnect resetLocked(); if (Flags.enableBrailleSuwImmediateConnections() && mUsbDeviceReceiverReceiver != null) { mContext.unregisterReceiver(mUsbDeviceReceiverReceiver); mConnectedBrailleDisplaySerialNumber = null; } } Loading Loading @@ -839,7 +844,8 @@ class AccessibilityServiceConnection extends AbstractAccessibilityServiceConnect return; } if (isInSetupWizard()) { if (isInSetupWizard() || (mConnectedBrailleDisplaySerialNumber != null && mConnectedBrailleDisplaySerialNumber.equals(device.getSerialNumber()))) { int clientUid = getClientUid(); if (clientUid == UID_UNKNOWN) { return; Loading @@ -847,6 +853,13 @@ class AccessibilityServiceConnection extends AbstractAccessibilityServiceConnect UsbManager usbManager = mContext.getSystemService(UsbManager.class); usbManager.grantPermission(device, /* uid of client's App */ clientUid); String usbSerialNumber = device.getSerialNumber(); if (!TextUtils.isEmpty(usbSerialNumber)) { // Store the serial number to re-grant USB permission to this braille display if it // is unplugged and reconnected. mConnectedBrailleDisplaySerialNumber = usbSerialNumber; } } } Loading
services/tests/servicestests/src/com/android/server/accessibility/AccessibilityServiceConnectionTest.java +44 −0 Original line number Diff line number Diff line Loading @@ -598,4 +598,48 @@ public class AccessibilityServiceConnectionTest { usbDeviceReceiverCaptor.getValue().onReceive(mMockContext, intent); verify(usbManager, never()).grantPermission(any(), any()); } @Test @EnableFlags( com.android.server.accessibility.Flags.FLAG_ENABLE_BRAILLE_SUW_IMMEDIATE_CONNECTIONS) public void sendUsbAttachedIntentOutsideSuw_grantPermissionToSavedUsbDevice() { // Set USER_SETUP_COMPLETE = 0 to simulate running in SUW. Settings.Secure.putIntForUser(mContentResolver, Settings.Secure.USER_SETUP_COMPLETE, 0, mMockUserState.mUserId); mConnection.bindLocked(); ArgumentCaptor<BroadcastReceiver> usbDeviceReceiverCaptor = ArgumentCaptor.forClass( BroadcastReceiver.class); verify(mMockContext).registerReceiver(usbDeviceReceiverCaptor.capture(), any()); // Create USB device with a serial number for identification. UsbDevice usbDevice = Mockito.mock(UsbDevice.class); when(usbDevice.getSerialNumber()).thenReturn("UsbSerialNo"); // Setup USB device attach intent. Intent intent = new Intent(UsbManager.ACTION_USB_DEVICE_ATTACHED); intent.putExtra(UsbManager.EXTRA_DEVICE, usbDevice); // Send intent to simulate the USB device was unplugged and plugged in again and verify // permission is granted to the device because it was previously connected. UsbManager usbManager = Mockito.mock(UsbManager.class); when(mMockContext.getSystemService(Context.USB_SERVICE)).thenReturn(usbManager); when(mMockContext.getSystemServiceName(UsbManager.class)).thenReturn(Context.USB_SERVICE); usbDeviceReceiverCaptor.getValue().onReceive(mMockContext, intent); verify(usbManager, times(1)).grantPermission(usbDevice, 0); // After registering the USB device in the SUW, set USER_SETUP_COMPLETE = 1 to simulate // plugging in the USB device again outside of SUW. Settings.Secure.putIntForUser(mContentResolver, Settings.Secure.USER_SETUP_COMPLETE, 1, mMockUserState.mUserId); // Reset the USB manager mock for the next call. Mockito.clearInvocations(usbManager); // Send intent to simulate the USB device was unplugged and plugged in again and verify // permission is granted to the device because it was previously connected. usbDeviceReceiverCaptor.getValue().onReceive(mMockContext, intent); verify(usbManager, times(1)).grantPermission(usbDevice, 0); } }