Loading services/core/java/com/android/server/security/advancedprotection/features/UsbDataAdvancedProtectionHook.java +29 −75 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import static android.hardware.usb.InternalUsbDataSignalDisableReason.USB_DISABL import android.annotation.IntDef; import android.app.ActivityManager; import android.app.KeyguardManager; import android.app.KeyguardManager.KeyguardLockedStateListener; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationChannelGroup; Loading Loading @@ -63,7 +64,6 @@ import android.os.UserHandle; import android.os.UserManager; import android.os.SystemClock; import android.provider.Settings; import android.security.Flags; import android.util.Slog; import android.content.pm.PackageManager; Loading @@ -83,6 +83,8 @@ import java.net.URISyntaxException; import java.util.Map; import java.util.Objects; import java.util.concurrent.Executors; import java.util.concurrent.ExecutorService; import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.atomic.AtomicBoolean; Loading Loading @@ -117,18 +119,12 @@ public class UsbDataAdvancedProtectionHook extends AdvancedProtectionHook { private static final int NOTIFICATION_CHARGE_DATA = 1; private static final int NOTIFICATION_DATA = 2; // For connection recovery, in case of Android Auto or unreliable cables private static final int DELAY_DISABLE_MILLIS = 15000; private static final int USB_DATA_CHANGE_MAX_RETRY_ATTEMPTS = 3; private static final long USB_PORT_POWER_BRICK_CONNECTION_CHECK_TIMEOUT_DEFAULT_MILLIS = 3000; private static final long USB_PD_COMPLIANCE_CHECK_TIMEOUT_DEFAULT_MILLIS = 1000; // To partially avoid race conditions between SCREEN_OFF and Keyguard actions, we wait a bit // before updating the keyguard lock state. Ideally we should have a callback for keyguard // state changes, but none exist today. // TODO(b/436659963): Determine a reasonable delay time value private static final long KEYGUARD_LOCK_UPDATE_DELAY_MILLIS = 1000; private static final long LOCK_SCREEN_LOCK_AFTER_TIMEOUT_DEFAULT_MILLIS = 5000; @IntDef({NOTIFICATION_CHARGE, NOTIFICATION_CHARGE_DATA, NOTIFICATION_DATA}) private @interface NotificationType {} Loading Loading @@ -186,7 +182,8 @@ public class UsbDataAdvancedProtectionHook extends AdvancedProtectionHook { private NotificationManager mNotificationManager; private NotificationChannel mNotificationChannel; private AdvancedProtectionService mAdvancedProtectionService; private ExecutorService mUsbDataSignalUpdateExecutor = Executors.newSingleThreadExecutor(); private KeyguardLockedStateListener mKeyguardLockedStateListener; private UsbPortStatus mLastUsbPortStatus; // TODO(b/418846176): Move these to a system property Loading Loading @@ -285,6 +282,7 @@ public class UsbDataAdvancedProtectionHook extends AdvancedProtectionHook { } if (!mBroadcastReceiverIsRegistered) { registerReceiver(); registerKeyguardLockListener(); } if (mKeyguardManager.isKeyguardLocked()) { setUsbDataSignalIfPossible(false); Loading Loading @@ -327,14 +325,6 @@ public class UsbDataAdvancedProtectionHook extends AdvancedProtectionHook { mIsAfterFirstUnlock = true; setUsbDataSignalIfPossible(true); } } else if (ACTION_SCREEN_OFF.equals(intent.getAction())) { if (mKeyguardManager.isKeyguardLocked()) { setUsbDataSignalIfPossible(false); } else { // If a race condition occurs, or is a lockScreenTimeout, we // retry a check again after a set time setRetryAndLockScreenTimeoutDisableTask(); } } else if (ACTION_USB_PORT_CHANGED.equals(intent.getAction())) { UsbPortStatus portStatus = intent.getParcelableExtra( Loading Loading @@ -391,9 +381,12 @@ public class UsbDataAdvancedProtectionHook extends AdvancedProtectionHook { createAndSendNotificationIfDeviceIsLocked( portStatus, NOTIFICATION_DATA); } // Any earlier call to USBService during bootup have a risk of having } // Any earlier call to USBService during bootup have a risk of // having // request dropped due to USB stack not being ready. } else if (ACTION_LOCKED_BOOT_COMPLETED.equals(intent.getAction())) { else if (ACTION_LOCKED_BOOT_COMPLETED.equals(intent.getAction())) { setUsbDataSignalIfPossible(false); } } catch (Exception e) { Loading Loading @@ -442,61 +435,6 @@ public class UsbDataAdvancedProtectionHook extends AdvancedProtectionHook { } } // Used for fallback on race condition between keyguard and screen off event and // lockScreenTimeout private void setRetryAndLockScreenTimeoutDisableTask() { if (!mDelayedDisableHandler.hasMessagesOrCallbacks()) { long lockscreenTimeoutDelayMillis = Math.max( KEYGUARD_LOCK_UPDATE_DELAY_MILLIS, getLockAfterScreenTimeoutSetting()); boolean taskPosted = mDelayedDisableHandler.postDelayed( () -> { Slog.d(TAG, "Delayed Retry Task: Running"); if (mKeyguardManager.isKeyguardLocked()) { setUsbDataSignalIfPossible(false); } else { // If it fails, it's likely a // lockScreenTimeoutEvent, so we will recheck // after the set lock screen timeout // If lock screen timeout is turned off = 0, we // check again with retry delay for redundancy if (!mDelayedDisableHandler.postDelayed( () -> { Slog.d( TAG, "Delayed LockscreenTimeout" + " Task: Running"); if (mKeyguardManager .isKeyguardLocked()) { setUsbDataSignalIfPossible( false); } }, lockscreenTimeoutDelayMillis)) { Slog.w( TAG, "Delayed LockScreenTimeout Task:" + " Failed to post task"); } } }, KEYGUARD_LOCK_UPDATE_DELAY_MILLIS); if (!taskPosted) { Slog.w(TAG, "Delayed ScreenOff Retry Task: Failed to post task"); } } } private long getLockAfterScreenTimeoutSetting() { return Settings.Secure.getLongForUser( mContext.getContentResolver(), Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, LOCK_SCREEN_LOCK_AFTER_TIMEOUT_DEFAULT_MILLIS, ActivityManager.getCurrentUser()); } private void determineUsbChargeStateAndSendNotification( UsbPortStatus portStatus) { clearExistingNotification(); Loading Loading @@ -762,7 +700,6 @@ public class UsbDataAdvancedProtectionHook extends AdvancedProtectionHook { final IntentFilter filter = new IntentFilter(); filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); filter.addAction(ACTION_USER_PRESENT); filter.addAction(ACTION_SCREEN_OFF); filter.addAction(ACTION_LOCKED_BOOT_COMPLETED); filter.addAction(UsbManager.ACTION_USB_PORT_CHANGED); Loading @@ -780,6 +717,23 @@ public class UsbDataAdvancedProtectionHook extends AdvancedProtectionHook { mBroadcastReceiverIsRegistered = true; } private void registerKeyguardLockListener() { KeyguardLockedStateListener keyguardListener = new KeyguardLockedStateListener() { @Override public void onKeyguardLockedStateChanged(boolean isKeyguardLocked) { Slog.d(TAG, "onKeyguardLockedStateChanged: " + isKeyguardLocked); setUsbDataSignalIfPossible(!isKeyguardLocked); } }; mKeyguardManager.addKeyguardLockedStateListener( mUsbDataSignalUpdateExecutor, keyguardListener); } private void unregisterKeyguardLockListener() { mKeyguardManager.removeKeyguardLockedStateListener(mKeyguardLockedStateListener); } private void unregisterReceiver() { mContext.unregisterReceiver(mUsbProtectionBroadcastReceiver); mBroadcastReceiverIsRegistered = false; Loading services/tests/mockingservicestests/src/com/android/server/security/advancedprotection/features/UsbDataAdvancedProtectionHookTest.java +17 −63 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ import static org.mockito.Mockito.when; import android.annotation.SuppressLint; import android.app.ActivityManager; import android.app.KeyguardManager; import android.app.KeyguardManager.KeyguardLockedStateListener; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; Loading Loading @@ -99,6 +100,7 @@ import org.mockito.MockitoAnnotations; import org.mockito.Spy; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.ExecutorService; /** * Unit tests for {@link UsbDataAdvancedProtectionHook}. Loading Loading @@ -147,6 +149,7 @@ public class UsbDataAdvancedProtectionHookTest { @Captor private ArgumentCaptor<String> mNotificationTagCaptor; @Captor private ArgumentCaptor<UserHandle> mUserHandleCaptor; @Captor private ArgumentCaptor<IntentFilter> mIntentFilterCaptor; @Captor private ArgumentCaptor<KeyguardLockedStateListener> mKeyguardLockedStateListenerCaptor; private AtomicBoolean mApmRequestedUsbDataStatusBoolean = new AtomicBoolean(false); private UsbDataAdvancedProtectionHook mUsbDataHook; Loading Loading @@ -292,13 +295,17 @@ public class UsbDataAdvancedProtectionHookTest { setupAndEnableFeature(false, false, true); verifyAdvancedProtectionChanged_registersReceiverRegisterReceiverBehavior(); verify(mKeyguardManager) .addKeyguardLockedStateListener( any(ExecutorService.class), any(KeyguardLockedStateListener.class)); verify(mUsbManagerInternal).enableUsbDataSignal(eq(false), eq(USB_DISABLE_REASON_APM)); } // For enablement of Advanced Protection mode through Settings page. @Test @EnableFlags(Flags.FLAG_AAPM_FEATURE_USB_DATA_PROTECTION) public void onAdvancedProtectionChanged_whenEnabledInUnlockedState_registersReceiverAndDisablesUsb() public void onAdvancedProtectionChanged_whenEnabledInUnlockedState_registersReceiverAndDisablesUsb() throws RemoteException { clearAllUsbConnections(); when(mKeyguardManager.isKeyguardLocked()).thenReturn(false); Loading Loading @@ -332,9 +339,8 @@ public class UsbDataAdvancedProtectionHookTest { IntentFilter mainFilter = mIntentFilterCaptor.getAllValues().get(0); assertEquals(UserHandle.ALL, mUserHandleCaptor.getAllValues().get(0)); assertEquals(4, mainFilter.countActions()); assertEquals(3, mainFilter.countActions()); assertTrue(mainFilter.hasAction(Intent.ACTION_USER_PRESENT)); assertTrue(mainFilter.hasAction(Intent.ACTION_SCREEN_OFF)); assertTrue(mainFilter.hasAction(Intent.ACTION_LOCKED_BOOT_COMPLETED)); assertTrue(mainFilter.hasAction(UsbManager.ACTION_USB_PORT_CHANGED)); Loading Loading @@ -439,71 +445,19 @@ public class UsbDataAdvancedProtectionHookTest { @EnableFlags(Flags.FLAG_AAPM_FEATURE_USB_DATA_PROTECTION) public void screenOffAndLocked_withNoConnectedDevice_disablesUsb() throws RemoteException { setupAndEnableFeature(false, false, true); when(mKeyguardManager.isKeyguardLocked()).thenReturn(true); clearAllUsbConnections(); BroadcastReceiver receiver = getAndCaptureReceiver(); receiver.onReceive(mContext, new Intent(Intent.ACTION_SCREEN_OFF)); verify(mUsbManagerInternal, times(1)) .enableUsbDataSignal(eq(false), eq(USB_DISABLE_REASON_APM)); } @Test @EnableFlags(Flags.FLAG_AAPM_FEATURE_USB_DATA_PROTECTION) public void screenOffAndLocked_withNoConnectedDevice_butKeyguardIsSlow_retriesDelayedUsbDisable() throws RemoteException { setupAndEnableFeature(false, false, true); when(mKeyguardManager.isKeyguardLocked()).thenReturn(false).thenReturn(true); clearAllUsbConnections(); BroadcastReceiver receiver = getAndCaptureReceiver(); receiver.onReceive(mContext, new Intent(Intent.ACTION_SCREEN_OFF)); verify(mDelayDisableHandler).postDelayed(mRunnableCaptor.capture(), anyLong()); mRunnableCaptor.getValue().run(); getKeyguardLockedStateListener().onKeyguardLockedStateChanged(true); verify(mUsbManagerInternal, times(1)) .enableUsbDataSignal(eq(false), eq(USB_DISABLE_REASON_APM)); } @Test @EnableFlags(Flags.FLAG_AAPM_FEATURE_USB_DATA_PROTECTION) public void screenOffAndLocked_withNoConnectedDevice_butScreenTimeoutBeforeLock_retriesDelayedUsbDisable() throws RemoteException { setupAndEnableFeature(false, false, true); when(mKeyguardManager.isKeyguardLocked()) .thenReturn(false) .thenReturn(false) .thenReturn(true); // Reference of KEYGUARD_LOCK_UPDATE_DELAY_MILLIS long keyguardUpdateDelayMillis = 1000L; long lockScreenTimeoutMillis = 5000L; doReturn(lockScreenTimeoutMillis) .when( () -> Settings.Secure.getLongForUser( any(ContentResolver.class), eq(Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT), anyLong(), anyInt())); clearAllUsbConnections(); BroadcastReceiver receiver = getAndCaptureReceiver(); receiver.onReceive(mContext, new Intent(Intent.ACTION_SCREEN_OFF)); verify(mDelayDisableHandler) .postDelayed(mRunnableCaptor.capture(), eq(keyguardUpdateDelayMillis)); mRunnableCaptor.getValue().run(); verify(mDelayDisableHandler) .postDelayed(mRunnableCaptor.capture(), eq(lockScreenTimeoutMillis)); mRunnableCaptor.getValue().run(); assertEquals(2, mRunnableCaptor.getAllValues().size()); verify(mUsbManagerInternal, times(1)) .enableUsbDataSignal(eq(false), eq(USB_DISABLE_REASON_APM)); private KeyguardLockedStateListener getKeyguardLockedStateListener() { verify(mKeyguardManager) .addKeyguardLockedStateListener( any(ExecutorService.class), mKeyguardLockedStateListenerCaptor.capture()); return mKeyguardLockedStateListenerCaptor.getValue(); } @Test Loading @@ -515,7 +469,7 @@ public class UsbDataAdvancedProtectionHookTest { addUsbConnection( UsbPortStatus.POWER_ROLE_SINK, UsbPortStatus.POWER_BRICK_STATUS_DISCONNECTED); receiver.onReceive(mContext, new Intent(Intent.ACTION_SCREEN_OFF)); getKeyguardLockedStateListener().onKeyguardLockedStateChanged(true); verify(mUsbManagerInternal, never()).enableUsbDataSignal(anyBoolean(), anyInt()); } Loading Loading
services/core/java/com/android/server/security/advancedprotection/features/UsbDataAdvancedProtectionHook.java +29 −75 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import static android.hardware.usb.InternalUsbDataSignalDisableReason.USB_DISABL import android.annotation.IntDef; import android.app.ActivityManager; import android.app.KeyguardManager; import android.app.KeyguardManager.KeyguardLockedStateListener; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationChannelGroup; Loading Loading @@ -63,7 +64,6 @@ import android.os.UserHandle; import android.os.UserManager; import android.os.SystemClock; import android.provider.Settings; import android.security.Flags; import android.util.Slog; import android.content.pm.PackageManager; Loading @@ -83,6 +83,8 @@ import java.net.URISyntaxException; import java.util.Map; import java.util.Objects; import java.util.concurrent.Executors; import java.util.concurrent.ExecutorService; import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.atomic.AtomicBoolean; Loading Loading @@ -117,18 +119,12 @@ public class UsbDataAdvancedProtectionHook extends AdvancedProtectionHook { private static final int NOTIFICATION_CHARGE_DATA = 1; private static final int NOTIFICATION_DATA = 2; // For connection recovery, in case of Android Auto or unreliable cables private static final int DELAY_DISABLE_MILLIS = 15000; private static final int USB_DATA_CHANGE_MAX_RETRY_ATTEMPTS = 3; private static final long USB_PORT_POWER_BRICK_CONNECTION_CHECK_TIMEOUT_DEFAULT_MILLIS = 3000; private static final long USB_PD_COMPLIANCE_CHECK_TIMEOUT_DEFAULT_MILLIS = 1000; // To partially avoid race conditions between SCREEN_OFF and Keyguard actions, we wait a bit // before updating the keyguard lock state. Ideally we should have a callback for keyguard // state changes, but none exist today. // TODO(b/436659963): Determine a reasonable delay time value private static final long KEYGUARD_LOCK_UPDATE_DELAY_MILLIS = 1000; private static final long LOCK_SCREEN_LOCK_AFTER_TIMEOUT_DEFAULT_MILLIS = 5000; @IntDef({NOTIFICATION_CHARGE, NOTIFICATION_CHARGE_DATA, NOTIFICATION_DATA}) private @interface NotificationType {} Loading Loading @@ -186,7 +182,8 @@ public class UsbDataAdvancedProtectionHook extends AdvancedProtectionHook { private NotificationManager mNotificationManager; private NotificationChannel mNotificationChannel; private AdvancedProtectionService mAdvancedProtectionService; private ExecutorService mUsbDataSignalUpdateExecutor = Executors.newSingleThreadExecutor(); private KeyguardLockedStateListener mKeyguardLockedStateListener; private UsbPortStatus mLastUsbPortStatus; // TODO(b/418846176): Move these to a system property Loading Loading @@ -285,6 +282,7 @@ public class UsbDataAdvancedProtectionHook extends AdvancedProtectionHook { } if (!mBroadcastReceiverIsRegistered) { registerReceiver(); registerKeyguardLockListener(); } if (mKeyguardManager.isKeyguardLocked()) { setUsbDataSignalIfPossible(false); Loading Loading @@ -327,14 +325,6 @@ public class UsbDataAdvancedProtectionHook extends AdvancedProtectionHook { mIsAfterFirstUnlock = true; setUsbDataSignalIfPossible(true); } } else if (ACTION_SCREEN_OFF.equals(intent.getAction())) { if (mKeyguardManager.isKeyguardLocked()) { setUsbDataSignalIfPossible(false); } else { // If a race condition occurs, or is a lockScreenTimeout, we // retry a check again after a set time setRetryAndLockScreenTimeoutDisableTask(); } } else if (ACTION_USB_PORT_CHANGED.equals(intent.getAction())) { UsbPortStatus portStatus = intent.getParcelableExtra( Loading Loading @@ -391,9 +381,12 @@ public class UsbDataAdvancedProtectionHook extends AdvancedProtectionHook { createAndSendNotificationIfDeviceIsLocked( portStatus, NOTIFICATION_DATA); } // Any earlier call to USBService during bootup have a risk of having } // Any earlier call to USBService during bootup have a risk of // having // request dropped due to USB stack not being ready. } else if (ACTION_LOCKED_BOOT_COMPLETED.equals(intent.getAction())) { else if (ACTION_LOCKED_BOOT_COMPLETED.equals(intent.getAction())) { setUsbDataSignalIfPossible(false); } } catch (Exception e) { Loading Loading @@ -442,61 +435,6 @@ public class UsbDataAdvancedProtectionHook extends AdvancedProtectionHook { } } // Used for fallback on race condition between keyguard and screen off event and // lockScreenTimeout private void setRetryAndLockScreenTimeoutDisableTask() { if (!mDelayedDisableHandler.hasMessagesOrCallbacks()) { long lockscreenTimeoutDelayMillis = Math.max( KEYGUARD_LOCK_UPDATE_DELAY_MILLIS, getLockAfterScreenTimeoutSetting()); boolean taskPosted = mDelayedDisableHandler.postDelayed( () -> { Slog.d(TAG, "Delayed Retry Task: Running"); if (mKeyguardManager.isKeyguardLocked()) { setUsbDataSignalIfPossible(false); } else { // If it fails, it's likely a // lockScreenTimeoutEvent, so we will recheck // after the set lock screen timeout // If lock screen timeout is turned off = 0, we // check again with retry delay for redundancy if (!mDelayedDisableHandler.postDelayed( () -> { Slog.d( TAG, "Delayed LockscreenTimeout" + " Task: Running"); if (mKeyguardManager .isKeyguardLocked()) { setUsbDataSignalIfPossible( false); } }, lockscreenTimeoutDelayMillis)) { Slog.w( TAG, "Delayed LockScreenTimeout Task:" + " Failed to post task"); } } }, KEYGUARD_LOCK_UPDATE_DELAY_MILLIS); if (!taskPosted) { Slog.w(TAG, "Delayed ScreenOff Retry Task: Failed to post task"); } } } private long getLockAfterScreenTimeoutSetting() { return Settings.Secure.getLongForUser( mContext.getContentResolver(), Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, LOCK_SCREEN_LOCK_AFTER_TIMEOUT_DEFAULT_MILLIS, ActivityManager.getCurrentUser()); } private void determineUsbChargeStateAndSendNotification( UsbPortStatus portStatus) { clearExistingNotification(); Loading Loading @@ -762,7 +700,6 @@ public class UsbDataAdvancedProtectionHook extends AdvancedProtectionHook { final IntentFilter filter = new IntentFilter(); filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); filter.addAction(ACTION_USER_PRESENT); filter.addAction(ACTION_SCREEN_OFF); filter.addAction(ACTION_LOCKED_BOOT_COMPLETED); filter.addAction(UsbManager.ACTION_USB_PORT_CHANGED); Loading @@ -780,6 +717,23 @@ public class UsbDataAdvancedProtectionHook extends AdvancedProtectionHook { mBroadcastReceiverIsRegistered = true; } private void registerKeyguardLockListener() { KeyguardLockedStateListener keyguardListener = new KeyguardLockedStateListener() { @Override public void onKeyguardLockedStateChanged(boolean isKeyguardLocked) { Slog.d(TAG, "onKeyguardLockedStateChanged: " + isKeyguardLocked); setUsbDataSignalIfPossible(!isKeyguardLocked); } }; mKeyguardManager.addKeyguardLockedStateListener( mUsbDataSignalUpdateExecutor, keyguardListener); } private void unregisterKeyguardLockListener() { mKeyguardManager.removeKeyguardLockedStateListener(mKeyguardLockedStateListener); } private void unregisterReceiver() { mContext.unregisterReceiver(mUsbProtectionBroadcastReceiver); mBroadcastReceiverIsRegistered = false; Loading
services/tests/mockingservicestests/src/com/android/server/security/advancedprotection/features/UsbDataAdvancedProtectionHookTest.java +17 −63 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ import static org.mockito.Mockito.when; import android.annotation.SuppressLint; import android.app.ActivityManager; import android.app.KeyguardManager; import android.app.KeyguardManager.KeyguardLockedStateListener; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; Loading Loading @@ -99,6 +100,7 @@ import org.mockito.MockitoAnnotations; import org.mockito.Spy; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.ExecutorService; /** * Unit tests for {@link UsbDataAdvancedProtectionHook}. Loading Loading @@ -147,6 +149,7 @@ public class UsbDataAdvancedProtectionHookTest { @Captor private ArgumentCaptor<String> mNotificationTagCaptor; @Captor private ArgumentCaptor<UserHandle> mUserHandleCaptor; @Captor private ArgumentCaptor<IntentFilter> mIntentFilterCaptor; @Captor private ArgumentCaptor<KeyguardLockedStateListener> mKeyguardLockedStateListenerCaptor; private AtomicBoolean mApmRequestedUsbDataStatusBoolean = new AtomicBoolean(false); private UsbDataAdvancedProtectionHook mUsbDataHook; Loading Loading @@ -292,13 +295,17 @@ public class UsbDataAdvancedProtectionHookTest { setupAndEnableFeature(false, false, true); verifyAdvancedProtectionChanged_registersReceiverRegisterReceiverBehavior(); verify(mKeyguardManager) .addKeyguardLockedStateListener( any(ExecutorService.class), any(KeyguardLockedStateListener.class)); verify(mUsbManagerInternal).enableUsbDataSignal(eq(false), eq(USB_DISABLE_REASON_APM)); } // For enablement of Advanced Protection mode through Settings page. @Test @EnableFlags(Flags.FLAG_AAPM_FEATURE_USB_DATA_PROTECTION) public void onAdvancedProtectionChanged_whenEnabledInUnlockedState_registersReceiverAndDisablesUsb() public void onAdvancedProtectionChanged_whenEnabledInUnlockedState_registersReceiverAndDisablesUsb() throws RemoteException { clearAllUsbConnections(); when(mKeyguardManager.isKeyguardLocked()).thenReturn(false); Loading Loading @@ -332,9 +339,8 @@ public class UsbDataAdvancedProtectionHookTest { IntentFilter mainFilter = mIntentFilterCaptor.getAllValues().get(0); assertEquals(UserHandle.ALL, mUserHandleCaptor.getAllValues().get(0)); assertEquals(4, mainFilter.countActions()); assertEquals(3, mainFilter.countActions()); assertTrue(mainFilter.hasAction(Intent.ACTION_USER_PRESENT)); assertTrue(mainFilter.hasAction(Intent.ACTION_SCREEN_OFF)); assertTrue(mainFilter.hasAction(Intent.ACTION_LOCKED_BOOT_COMPLETED)); assertTrue(mainFilter.hasAction(UsbManager.ACTION_USB_PORT_CHANGED)); Loading Loading @@ -439,71 +445,19 @@ public class UsbDataAdvancedProtectionHookTest { @EnableFlags(Flags.FLAG_AAPM_FEATURE_USB_DATA_PROTECTION) public void screenOffAndLocked_withNoConnectedDevice_disablesUsb() throws RemoteException { setupAndEnableFeature(false, false, true); when(mKeyguardManager.isKeyguardLocked()).thenReturn(true); clearAllUsbConnections(); BroadcastReceiver receiver = getAndCaptureReceiver(); receiver.onReceive(mContext, new Intent(Intent.ACTION_SCREEN_OFF)); verify(mUsbManagerInternal, times(1)) .enableUsbDataSignal(eq(false), eq(USB_DISABLE_REASON_APM)); } @Test @EnableFlags(Flags.FLAG_AAPM_FEATURE_USB_DATA_PROTECTION) public void screenOffAndLocked_withNoConnectedDevice_butKeyguardIsSlow_retriesDelayedUsbDisable() throws RemoteException { setupAndEnableFeature(false, false, true); when(mKeyguardManager.isKeyguardLocked()).thenReturn(false).thenReturn(true); clearAllUsbConnections(); BroadcastReceiver receiver = getAndCaptureReceiver(); receiver.onReceive(mContext, new Intent(Intent.ACTION_SCREEN_OFF)); verify(mDelayDisableHandler).postDelayed(mRunnableCaptor.capture(), anyLong()); mRunnableCaptor.getValue().run(); getKeyguardLockedStateListener().onKeyguardLockedStateChanged(true); verify(mUsbManagerInternal, times(1)) .enableUsbDataSignal(eq(false), eq(USB_DISABLE_REASON_APM)); } @Test @EnableFlags(Flags.FLAG_AAPM_FEATURE_USB_DATA_PROTECTION) public void screenOffAndLocked_withNoConnectedDevice_butScreenTimeoutBeforeLock_retriesDelayedUsbDisable() throws RemoteException { setupAndEnableFeature(false, false, true); when(mKeyguardManager.isKeyguardLocked()) .thenReturn(false) .thenReturn(false) .thenReturn(true); // Reference of KEYGUARD_LOCK_UPDATE_DELAY_MILLIS long keyguardUpdateDelayMillis = 1000L; long lockScreenTimeoutMillis = 5000L; doReturn(lockScreenTimeoutMillis) .when( () -> Settings.Secure.getLongForUser( any(ContentResolver.class), eq(Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT), anyLong(), anyInt())); clearAllUsbConnections(); BroadcastReceiver receiver = getAndCaptureReceiver(); receiver.onReceive(mContext, new Intent(Intent.ACTION_SCREEN_OFF)); verify(mDelayDisableHandler) .postDelayed(mRunnableCaptor.capture(), eq(keyguardUpdateDelayMillis)); mRunnableCaptor.getValue().run(); verify(mDelayDisableHandler) .postDelayed(mRunnableCaptor.capture(), eq(lockScreenTimeoutMillis)); mRunnableCaptor.getValue().run(); assertEquals(2, mRunnableCaptor.getAllValues().size()); verify(mUsbManagerInternal, times(1)) .enableUsbDataSignal(eq(false), eq(USB_DISABLE_REASON_APM)); private KeyguardLockedStateListener getKeyguardLockedStateListener() { verify(mKeyguardManager) .addKeyguardLockedStateListener( any(ExecutorService.class), mKeyguardLockedStateListenerCaptor.capture()); return mKeyguardLockedStateListenerCaptor.getValue(); } @Test Loading @@ -515,7 +469,7 @@ public class UsbDataAdvancedProtectionHookTest { addUsbConnection( UsbPortStatus.POWER_ROLE_SINK, UsbPortStatus.POWER_BRICK_STATUS_DISCONNECTED); receiver.onReceive(mContext, new Intent(Intent.ACTION_SCREEN_OFF)); getKeyguardLockedStateListener().onKeyguardLockedStateChanged(true); verify(mUsbManagerInternal, never()).enableUsbDataSignal(anyBoolean(), anyInt()); } Loading