Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b528dfdb authored by George Chan's avatar George Chan
Browse files

Refactor USB data protection unlock logic to use KeyguardLockedStateListener as well.

This change replaces the use of `ACTION_USER_PRESENT` broadcast with the `KeyguardLockedStateListener` to detect when the device is unlocked. The logic for enabling USB data after the first unlock is now handled within the `onKeyguardLockedStateChanged` callback. Additionally, USB data is now explicitly disabled when the keyguard becomes locked.

Bug: 34948618
Test: atest, manual testing
Flag: android.security.aapm_feature_usb_data_protection
Change-Id: Id08faf49d7dc05e322d68db7e6f7a0213bfd6c06
parent 8b903dd2
Loading
Loading
Loading
Loading
+20 −23
Original line number Diff line number Diff line
@@ -17,8 +17,6 @@
package com.android.server.security.advancedprotection.features;

import static android.app.Notification.EXTRA_SUBSTITUTE_APP_NAME;
import static android.content.Intent.ACTION_SCREEN_OFF;
import static android.content.Intent.ACTION_USER_PRESENT;
import static android.content.Intent.ACTION_LOCKED_BOOT_COMPLETED;
import static android.hardware.usb.UsbManager.ACTION_USB_PORT_CHANGED;
import static android.security.advancedprotection.AdvancedProtectionManager.FEATURE_ID_DISALLOW_USB;
@@ -317,15 +315,7 @@ public class UsbDataAdvancedProtectionHook extends AdvancedProtectionHook {
                    @Override
                    public void onReceive(Context context, Intent intent) {
                        try {
                            if (ACTION_USER_PRESENT.equals(intent.getAction())
                                    && !mKeyguardManager.isKeyguardLocked()) {
                                mDelayedDisableHandler.removeCallbacksAndMessages(null);
                                cleanUpNotificationHandlerTasks();
                                if (!currentUserIsGuest()) {
                                    mIsAfterFirstUnlock = true;
                                    setUsbDataSignalIfPossible(true);
                                }
                            } else if (ACTION_USB_PORT_CHANGED.equals(intent.getAction())) {
                            if (ACTION_USB_PORT_CHANGED.equals(intent.getAction())) {
                                UsbPortStatus portStatus =
                                        intent.getParcelableExtra(
                                                UsbManager.EXTRA_PORT_STATUS, UsbPortStatus.class);
@@ -394,12 +384,6 @@ public class UsbDataAdvancedProtectionHook extends AdvancedProtectionHook {
                        }
                    }

                    private boolean currentUserIsGuest() {
                        UserInfo currentUserInfo =
                                mUserManager.getUserInfo(ActivityManager.getCurrentUser());
                        return currentUserInfo != null && currentUserInfo.isGuest();
                    }

                    private void updateDelayedNotificationTask(long delayTimeMillis) {
                        if (!mDelayedNotificationHandler.hasMessagesOrCallbacks()
                                && delayTimeMillis > 0) {
@@ -462,10 +446,6 @@ public class UsbDataAdvancedProtectionHook extends AdvancedProtectionHook {
                        }
                    }

                    private void cleanUpNotificationHandlerTasks() {
                        mDelayedNotificationHandler.removeCallbacksAndMessages(null);
                    }

                    // TODO:(b/401540215) Remove this as part of pre-release cleanup
                    private void dumpUsbDevices(UsbPortStatus portStatus) {
                        Map<String, UsbDevice> portStatusMap = mUsbManager.getDeviceList();
@@ -493,6 +473,10 @@ public class UsbDataAdvancedProtectionHook extends AdvancedProtectionHook {
        }
    }

    private void cleanUpNotificationHandlerTasks() {
        mDelayedNotificationHandler.removeCallbacksAndMessages(null);
    }

    private void createAndSendNotificationIfDeviceIsLocked(
            UsbPortStatus portStatus, @NotificationType int notificationType) {
        if ((notificationType == NOTIFICATION_CHARGE
@@ -699,7 +683,6 @@ public class UsbDataAdvancedProtectionHook extends AdvancedProtectionHook {
    private void registerReceiver() {
        final IntentFilter filter = new IntentFilter();
        filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
        filter.addAction(ACTION_USER_PRESENT);
        filter.addAction(ACTION_LOCKED_BOOT_COMPLETED);
        filter.addAction(UsbManager.ACTION_USB_PORT_CHANGED);

@@ -723,7 +706,16 @@ public class UsbDataAdvancedProtectionHook extends AdvancedProtectionHook {
                    @Override
                    public void onKeyguardLockedStateChanged(boolean isKeyguardLocked) {
                        Slog.d(TAG, "onKeyguardLockedStateChanged: " + isKeyguardLocked);
                        setUsbDataSignalIfPossible(!isKeyguardLocked);
                        if (!isKeyguardLocked) {
                            mDelayedDisableHandler.removeCallbacksAndMessages(null);
                            cleanUpNotificationHandlerTasks();
                            if (!currentUserIsGuest()) {
                                setUsbDataSignalIfPossible(true);
                                mIsAfterFirstUnlock = true;
                            }
                        } else {
                            setUsbDataSignalIfPossible(false);
                        }
                    }
                };
        mKeyguardManager.addKeyguardLockedStateListener(
@@ -770,6 +762,11 @@ public class UsbDataAdvancedProtectionHook extends AdvancedProtectionHook {
        return null;
    }

    private boolean currentUserIsGuest() {
        UserInfo currentUserInfo = mUserManager.getUserInfo(ActivityManager.getCurrentUser());
        return currentUserInfo != null && currentUserInfo.isGuest();
    }

    private boolean canSetUsbDataSignal() {
        if (Build.IS_DEBUGGABLE) {
            Slog.i(TAG, "USB_HAL_VERSION: " + mUsbManager.getUsbHalVersion());
+4 −9
Original line number Diff line number Diff line
@@ -305,7 +305,7 @@ public class UsbDataAdvancedProtectionHookTest {
    @Test
    @EnableFlags(Flags.FLAG_AAPM_FEATURE_USB_DATA_PROTECTION)
    public void
            onAdvancedProtectionChanged_whenEnabledInUnlockedState_registersReceiverAndDisablesUsb()
            onAdvancedProtectionChanged_whenEnabledInUnlockedState_registersReceiverAndNotDisableUsb()
                    throws RemoteException {
        clearAllUsbConnections();
        when(mKeyguardManager.isKeyguardLocked()).thenReturn(false);
@@ -339,8 +339,7 @@ public class UsbDataAdvancedProtectionHookTest {
        IntentFilter mainFilter = mIntentFilterCaptor.getAllValues().get(0);
        assertEquals(UserHandle.ALL, mUserHandleCaptor.getAllValues().get(0));

        assertEquals(3, mainFilter.countActions());
        assertTrue(mainFilter.hasAction(Intent.ACTION_USER_PRESENT));
        assertEquals(2, mainFilter.countActions());
        assertTrue(mainFilter.hasAction(Intent.ACTION_LOCKED_BOOT_COMPLETED));
        assertTrue(mainFilter.hasAction(UsbManager.ACTION_USB_PORT_CHANGED));

@@ -371,10 +370,8 @@ public class UsbDataAdvancedProtectionHookTest {
        UserInfo mockUserInfo = mock(UserInfo.class);
        when(mockUserInfo.isGuest()).thenReturn(false);
        when(mUserManager.getUserInfo(anyInt())).thenReturn(mockUserInfo);
        when(mKeyguardManager.isKeyguardLocked()).thenReturn(false);
        BroadcastReceiver receiver = getAndCaptureReceiver();

        receiver.onReceive(mContext, new Intent(Intent.ACTION_USER_PRESENT));
        getKeyguardLockedStateListener().onKeyguardLockedStateChanged(false);

        verify(mDelayDisableHandler).removeCallbacksAndMessages(isNull());
        verify(mDelayedNotificationHandler).removeCallbacksAndMessages(isNull());
@@ -402,10 +399,8 @@ public class UsbDataAdvancedProtectionHookTest {
        UserInfo mockUserInfo = mock(UserInfo.class);
        when(mockUserInfo.isGuest()).thenReturn(true);
        when(mUserManager.getUserInfo(anyInt())).thenReturn(mockUserInfo);
        when(mKeyguardManager.isKeyguardLocked()).thenReturn(false);
        BroadcastReceiver receiver = getAndCaptureReceiver();

        receiver.onReceive(mContext, new Intent(Intent.ACTION_USER_PRESENT));
        getKeyguardLockedStateListener().onKeyguardLockedStateChanged(false);

        verify(mDelayDisableHandler).removeCallbacksAndMessages(isNull());
        verify(mDelayedNotificationHandler).removeCallbacksAndMessages(isNull());