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

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

Made a few improvements to the Advanced Protection USB Data Protection Feature:

- Added a edge case mitigation for devices that may need a replug upon device unlock (notification text change)
- Added a edge case mitigation for devices that may have reduced charging capabilities when locked (notification text change)
- Fixed issue where BFU state does not disable USB
- Extended USB reconnect grace window from 1 second to 3 seconds (for Android Auto)

Test: manual testing
Bug: 405402033
Flag: android.security.aapm_feature_usb_data_protection
Change-Id: Ifcda84e3a704faca7a3440c4d17952c15abf77d5
parent 8b7bfe3c
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -6866,7 +6866,9 @@ ul.</string>
    <!--  AdvancedProtectionService USB notifications -->
    <string name="usb_apm_usb_plugged_in_when_locked_notification_title">USB device plugged in when locked</string>
    <string name="usb_apm_usb_plugged_in_when_locked_notification_text">USB device is plugged in when Android is locked. To use device, please unlock Android first and then reinsert USB device to use it.</string>
    <string name="usb_apm_usb_plugged_in_when_locked_notification_text">USB device is plugged in when Android is locked. To use device, please unlock Android first.</string>
    <string name="usb_apm_usb_plugged_in_when_locked_no_replug_notification_text">USB device is plugged in when Android is locked. To use device, please unlock Android first and then reinsert USB device to use it.</string>
    <string name="usb_apm_usb_plugged_in_when_locked_low_power_charge_notification_text">Charging capability may be reduced or unavailable when locked.</string>
    <string name="usb_apm_usb_suspicious_activity_notification_title">Suspicious USB activity</string>
    <string name="usb_apm_usb_suspicious_activity_notification_text">USB data signal has been disabled.</string>
+2 −0
Original line number Diff line number Diff line
@@ -5992,6 +5992,8 @@
  <!-- Advanced Protection Service USB feature -->
  <java-symbol type="string" name="usb_apm_usb_plugged_in_when_locked_notification_title" />
  <java-symbol type="string" name="usb_apm_usb_plugged_in_when_locked_notification_text" />
<java-symbol type="string" name="usb_apm_usb_plugged_in_when_locked_no_replug_notification_text" />
  <java-symbol type="string" name="usb_apm_usb_plugged_in_when_locked_low_power_charge_notification_text" />
  <java-symbol type="string" name="usb_apm_usb_suspicious_activity_notification_title" />
  <java-symbol type="string" name="usb_apm_usb_suspicious_activity_notification_text" />

+61 −22
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.security.Flags;
import android.util.Slog;
@@ -70,8 +71,15 @@ public class UsbDataAdvancedProtectionHook extends AdvancedProtectionHook {

    private static final String APM_USB_FEATURE_NOTIF_CHANNEL = "APM_USB_SERVICE_NOTIF_CHANNEL";
    private static final String CHANNEL_NAME = "BackgroundInstallUiNotificationChannel";
    private static final String USB_DATA_PROTECTION_DISABLE_SYSTEM_PROPERTY =
            "ro.usb.data_protection.apm.disabled";
    private static final String USB_DATA_PROTECTION_REPLUG_REQUIRED_UPON_ENABLE_SYSTEM_PROPERTY =
            "ro.usb.data_protection.apm.replug_required_upon_enable";
    private static final String
            USB_DATA_PROTECTION_DATA_REQUIRED_FOR_HIGH_POWER_CHARGE_SYSTEM_PROPERTY =
                    "ro.usb.data_protection.apm.data_required_for_high_power_charge";
    private static final int APM_USB_FEATURE_CHANNEL_ID = 1;
    private static final int DELAY_DISABLE_MS = 1000;
    private static final int DELAY_DISABLE_MS = 3000;
    private static final int OS_USB_DISABLE_REASON_LOCKDOWN_MODE = 1;

    private final Context mContext;
@@ -85,20 +93,21 @@ public class UsbDataAdvancedProtectionHook extends AdvancedProtectionHook {
    private NotificationChannel mNotificationChannel;

    private boolean mCanSetUsbDataSignal = false;
    private AdvancedProtectionFeature mFeature
        = new AdvancedProtectionFeature(FEATURE_ID_DISALLOW_USB);
    private AdvancedProtectionFeature mFeature =
            new AdvancedProtectionFeature(FEATURE_ID_DISALLOW_USB);

    private boolean mBroadcastReceiverIsRegistered = false;
    private boolean mInitialPlugInNotificationSent = false;
    private boolean mDevicedIsNotInBfuState = false;

    public UsbDataAdvancedProtectionHook(Context context, boolean enabled) {
        super(context, enabled);
        mContext = context;
        mUsbManager = mContext.getSystemService(UsbManager.class);
        mUsbManagerInternal = Objects.requireNonNull(
            LocalServices.getService(IUsbManagerInternal.class));
        onAdvancedProtectionChanged(enabled);
        mUsbManagerInternal =
                Objects.requireNonNull(LocalServices.getService(IUsbManagerInternal.class));
        mCanSetUsbDataSignal = canSetUsbDataSignal();
        onAdvancedProtectionChanged(enabled);
    }

    @Override
@@ -108,7 +117,14 @@ public class UsbDataAdvancedProtectionHook extends AdvancedProtectionHook {

    @Override
    public boolean isAvailable() {
        return Flags.aapmFeatureUsbDataProtection() && mCanSetUsbDataSignal;
        boolean usbDataProtectionDisabled =
                SystemProperties.getBoolean(USB_DATA_PROTECTION_DISABLE_SYSTEM_PROPERTY, false);
        if (usbDataProtectionDisabled) {
            Slog.d(TAG, "USB data protection is disabled through system property");
        }
        return Flags.aapmFeatureUsbDataProtection()
                && mCanSetUsbDataSignal
                && !usbDataProtectionDisabled;
    }

    @Override
@@ -144,6 +160,7 @@ public class UsbDataAdvancedProtectionHook extends AdvancedProtectionHook {
                        try {
                            if (ACTION_USER_PRESENT.equals(intent.getAction())
                                    && !mKeyguardManager.isKeyguardLocked()) {
                                mDevicedIsNotInBfuState = true;
                                mDelayedDisableHandler.removeCallbacksAndMessages(null);
                                setUsbDataSignalIfPossible(true);

@@ -159,7 +176,6 @@ public class UsbDataAdvancedProtectionHook extends AdvancedProtectionHook {
                                    updateDelayedDisableTask(intent);
                                }
                                sendNotificationIfDeviceLocked(intent);

                            }
                        } catch (Exception e) {
                            Slog.e(TAG, "USB Data protection failed with: " + e.getMessage());
@@ -171,11 +187,13 @@ public class UsbDataAdvancedProtectionHook extends AdvancedProtectionHook {
                        if (usbPortIsConnectedAndDataEnabled(intent)) {
                            mDelayedDisableHandler.removeCallbacksAndMessages(null);
                        } else if (!mDelayedDisableHandler.hasMessagesOrCallbacks()) {
                            mDelayedDisableHandler.postDelayed(() -> {
                            mDelayedDisableHandler.postDelayed(
                                    () -> {
                                        if (mKeyguardManager.isKeyguardLocked()) {
                                            setUsbDataSignalIfPossible(false);
                                        }
                            }, DELAY_DISABLE_MS);
                                    },
                                    DELAY_DISABLE_MS);
                        }
                    }

@@ -235,11 +253,31 @@ public class UsbDataAdvancedProtectionHook extends AdvancedProtectionHook {
                    intent.getParcelableExtra(UsbManager.EXTRA_PORT_STATUS, UsbPortStatus.class);
            if (mKeyguardManager.isKeyguardLocked()
                    && usbPortIsConnectedWithDataDisabled(portStatus)) {

                String notificationBody =
                        mContext.getString(
                                R.string.usb_apm_usb_plugged_in_when_locked_notification_text);
                if (SystemProperties.getBoolean(
                        USB_DATA_PROTECTION_REPLUG_REQUIRED_UPON_ENABLE_SYSTEM_PROPERTY, false)) {
                    notificationBody =
                            mContext.getString(
                                    R.string
                                            .usb_apm_usb_plugged_in_when_locked_no_replug_notification_text);
                }

                if (SystemProperties.getBoolean(
                        USB_DATA_PROTECTION_DATA_REQUIRED_FOR_HIGH_POWER_CHARGE_SYSTEM_PROPERTY,
                        false)) {
                    notificationBody +=
                            " "
                                    + mContext.getString(R.string
                                    .usb_apm_usb_plugged_in_when_locked_low_power_charge_notification_text);
                }

                sendNotification(
                        mContext.getString(
                                R.string.usb_apm_usb_plugged_in_when_locked_notification_title),
                        mContext.getString(
                                R.string.usb_apm_usb_plugged_in_when_locked_notification_text));
                        notificationBody);
                mInitialPlugInNotificationSent = true;
            }
        }
@@ -252,12 +290,13 @@ public class UsbDataAdvancedProtectionHook extends AdvancedProtectionHook {
    }

    private void setUsbDataSignalIfPossible(boolean status) {
        if (!status && deviceHaveUsbDataConnection()) {
        // We disable USB in BFU state regardless of USB connection upon reboot.
        if (!status && (deviceHaveUsbDataConnection() && mDevicedIsNotInBfuState)) {
            return;
        }
        try {
            if (!mUsbManagerInternal.enableUsbDataSignal(status,
                    OS_USB_DISABLE_REASON_LOCKDOWN_MODE)) {
            if (!mUsbManagerInternal.enableUsbDataSignal(
                    status, OS_USB_DISABLE_REASON_LOCKDOWN_MODE)) {
                Slog.e(TAG, "USB Data protection toggle failed");
            }
        } catch (RemoteException e) {