Merge "UsbDeviceManager: Invoke accessoryAttached after ACTION_USER_UNLOCKED" into main
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 1294945..15c8b13 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -185,6 +185,7 @@
     private static final int MSG_INCREASE_SENDSTRING_COUNT = 21;
     private static final int MSG_UPDATE_USB_SPEED = 22;
     private static final int MSG_UPDATE_HAL_VERSION = 23;
+    private static final int MSG_USER_UNLOCKED_AFTER_BOOT = 24;
 
     // Delay for debouncing USB disconnects.
     // We often get rapid connect/disconnect events when enabling USB functions,
@@ -414,6 +415,17 @@
             }
         };
 
+        if (Flags.checkUserActionUnlocked()) {
+            BroadcastReceiver userUnlockedAfterBootReceiver = new BroadcastReceiver() {
+                @Override
+                public void onReceive(Context context, Intent intent) {
+                    mHandler.sendEmptyMessage(MSG_USER_UNLOCKED_AFTER_BOOT);
+                }
+            };
+            mContext.registerReceiver(userUnlockedAfterBootReceiver,
+                    new IntentFilter(Intent.ACTION_USER_UNLOCKED));
+        }
+
         mContext.registerReceiver(portReceiver,
                 new IntentFilter(UsbManager.ACTION_USB_PORT_CHANGED));
         mContext.registerReceiver(chargingReceiver,
@@ -474,6 +486,7 @@
         mHandler.sendEmptyMessage(MSG_SYSTEM_READY);
     }
 
+    // Same as ACTION_LOCKED_BOOT_COMPLETED.
     public void bootCompleted() {
         if (DEBUG) Slog.d(TAG, "boot completed");
         mHandler.sendEmptyMessage(MSG_BOOT_COMPLETED);
@@ -632,7 +645,7 @@
         protected int mUsbSpeed;
         protected int mCurrentGadgetHalVersion;
         protected boolean mPendingBootAccessoryHandshakeBroadcast;
-
+        protected boolean mUserUnlockedAfterBoot;
         /**
          * The persistent property which stores whether adb is enabled or not.
          * May also contain vendor-specific default functions for testing purposes.
@@ -837,6 +850,12 @@
             return !userManager.hasUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER);
         }
 
+        private void attachAccessory() {
+            mUsbDeviceManager.getCurrentSettings().accessoryAttached(mCurrentAccessory);
+            removeMessages(MSG_ACCESSORY_HANDSHAKE_TIMEOUT);
+            broadcastUsbAccessoryHandshake();
+        }
+
         private void updateCurrentAccessory() {
             // We are entering accessory mode if we have received a request from the host
             // and the request has not timed out yet.
@@ -863,10 +882,13 @@
 
                     Slog.d(TAG, "entering USB accessory mode: " + mCurrentAccessory);
                     // defer accessoryAttached if system is not ready
-                    if (mBootCompleted) {
-                        mUsbDeviceManager.getCurrentSettings().accessoryAttached(mCurrentAccessory);
-                        removeMessages(MSG_ACCESSORY_HANDSHAKE_TIMEOUT);
-                        broadcastUsbAccessoryHandshake();
+                    if (!Flags.checkUserActionUnlocked() && mBootCompleted) {
+                        attachAccessory();
+                    }
+                    // Defer accessoryAttached till user unlocks after boot.
+                    // When no pin pattern is set, ACTION_USER_UNLOCKED would fire anyways
+                    if (Flags.checkUserActionUnlocked() && mUserUnlockedAfterBoot) {
+                        attachAccessory();
                     } // else handle in boot completed
                 } else {
                     Slog.e(TAG, "nativeGetAccessoryStrings failed");
@@ -887,7 +909,10 @@
             setEnabledFunctions(UsbManager.FUNCTION_NONE, false, operationId);
 
             if (mCurrentAccessory != null) {
-                if (mBootCompleted) {
+                if (!Flags.checkUserActionUnlocked() && mBootCompleted) {
+                    mPermissionManager.usbAccessoryRemoved(mCurrentAccessory);
+                }
+                if (Flags.checkUserActionUnlocked() && mUserUnlockedAfterBoot) {
                     mPermissionManager.usbAccessoryRemoved(mCurrentAccessory);
                 }
                 mCurrentAccessory = null;
@@ -1377,6 +1402,7 @@
                 case MSG_BOOT_COMPLETED:
                     operationId = sUsbOperationCount.incrementAndGet();
                     mBootCompleted = true;
+                    if (DEBUG) Slog.d(TAG, "MSG_BOOT_COMPLETED");
                     finishBoot(operationId);
                     break;
                 case MSG_USER_SWITCHED: {
@@ -1423,14 +1449,38 @@
                 }
                 case MSG_INCREASE_SENDSTRING_COUNT: {
                     mSendStringCount = mSendStringCount + 1;
+                    break;
+                }
+                case MSG_USER_UNLOCKED_AFTER_BOOT: {
+                    if (DEBUG) Slog.d(TAG, "MSG_USER_UNLOCKED_AFTER_BOOT");
+                    if (mUserUnlockedAfterBoot) {
+                        break;
+                    }
+                    mUserUnlockedAfterBoot = true;
+                    if (mCurrentUsbFunctionsReceived && mUserUnlockedAfterBoot) {
+                        attachAccessoryAfterBoot();
+                    }
+                    break;
                 }
             }
         }
 
+        private void attachAccessoryAfterBoot() {
+            if (mCurrentAccessory != null) {
+                Slog.i(TAG, "AccessoryAttached");
+                mUsbDeviceManager.getCurrentSettings().accessoryAttached(mCurrentAccessory);
+                broadcastUsbAccessoryHandshake();
+            } else if (mPendingBootAccessoryHandshakeBroadcast) {
+                broadcastUsbAccessoryHandshake();
+            }
+            mPendingBootAccessoryHandshakeBroadcast = false;
+        }
+
         public abstract void handlerInitDone(int operationId);
 
         protected void finishBoot(int operationId) {
             if (mBootCompleted && mCurrentUsbFunctionsReceived && mSystemReady) {
+                if (DEBUG) Slog.d(TAG, "finishBoot all flags true");
                 if (mPendingBootBroadcast) {
                     updateUsbStateBroadcastIfNeeded(getAppliedFunctions(mCurrentFunctions));
                     mPendingBootBroadcast = false;
@@ -1441,14 +1491,12 @@
                 } else {
                     setEnabledFunctions(UsbManager.FUNCTION_NONE, false, operationId);
                 }
-                if (mCurrentAccessory != null) {
-                    mUsbDeviceManager.getCurrentSettings().accessoryAttached(mCurrentAccessory);
-                    broadcastUsbAccessoryHandshake();
-                } else if (mPendingBootAccessoryHandshakeBroadcast) {
-                    broadcastUsbAccessoryHandshake();
+                if (!Flags.checkUserActionUnlocked()) {
+                    attachAccessoryAfterBoot();
                 }
-
-                mPendingBootAccessoryHandshakeBroadcast = false;
+                if (Flags.checkUserActionUnlocked() && mUserUnlockedAfterBoot) {
+                    attachAccessoryAfterBoot();
+                }
                 updateUsbNotification(false);
                 updateAdbNotification(false);
                 updateUsbFunctions();
diff --git a/services/usb/java/com/android/server/usb/flags/usb_flags.aconfig b/services/usb/java/com/android/server/usb/flags/usb_flags.aconfig
index cd96d76..a2d0efd 100644
--- a/services/usb/java/com/android/server/usb/flags/usb_flags.aconfig
+++ b/services/usb/java/com/android/server/usb/flags/usb_flags.aconfig
@@ -14,3 +14,10 @@
     description: "This flag enables binding to MtpService when in mtp/ptp modes"
     bug: "332256525"
 }
+
+flag {
+    name: "check_user_action_unlocked"
+    namespace: "usb"
+    description: "This flag checks if phone is unlocked after boot"
+    bug: "73654179"
+}