Create a white list to allow while-in-use permission in FGS.

Add AttentionService, SystemCaptionService(for live caption) and assistant
(voice interaction service) into the white list.

Bug: 149203389, 136219221
Test: manual test.
Change-Id: Ibf677019d37c72d620fa6917e436eccc4807df65
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 97b5eaa..430a5b9 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -79,6 +79,7 @@
 import android.os.TransactionTooLargeException;
 import android.os.UserHandle;
 import android.provider.Settings;
+import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.EventLog;
@@ -187,6 +188,9 @@
 
     AppWidgetManagerInternal mAppWidgetManagerInternal;
 
+    // white listed packageName.
+    ArraySet<String> mWhiteListAllowWhileInUsePermissionInFgs = new ArraySet<>();
+
     final Runnable mLastAnrDumpClearer = new Runnable() {
         @Override public void run() {
             synchronized (mAm) {
@@ -389,6 +393,20 @@
         AppStateTracker ast = LocalServices.getService(AppStateTracker.class);
         ast.addListener(new ForcedStandbyListener());
         mAppWidgetManagerInternal = LocalServices.getService(AppWidgetManagerInternal.class);
+        setWhiteListAllowWhileInUsePermissionInFgs();
+    }
+
+    private void setWhiteListAllowWhileInUsePermissionInFgs() {
+        final String attentionServicePackageName =
+                mAm.mContext.getPackageManager().getAttentionServicePackageName();
+        if (!TextUtils.isEmpty(attentionServicePackageName)) {
+            mWhiteListAllowWhileInUsePermissionInFgs.add(attentionServicePackageName);
+        }
+        final String systemCaptionsServicePackageName =
+                mAm.mContext.getPackageManager().getSystemCaptionsServicePackageName();
+        if (!TextUtils.isEmpty(systemCaptionsServicePackageName)) {
+            mWhiteListAllowWhileInUsePermissionInFgs.add(systemCaptionsServicePackageName);
+        }
     }
 
     ServiceRecord getServiceByNameLocked(ComponentName name, int callingUser) {
@@ -4634,6 +4652,12 @@
             return true;
         }
 
+        final boolean isWhiteListedPackage =
+                mWhiteListAllowWhileInUsePermissionInFgs.contains(callingPackage);
+        if (isWhiteListedPackage) {
+            return true;
+        }
+
         r.mInfoDenyWhileInUsePermissionInFgs =
                 "Background FGS start while-in-use permission restriction [callingPackage: "
                 + callingPackage
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index fabe92db..8fbe923 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -19,12 +19,16 @@
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
 
 import android.app.ActivityThread;
+import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
+import android.content.pm.UserInfo;
 import android.database.ContentObserver;
 import android.net.Uri;
 import android.os.Build;
 import android.os.Handler;
+import android.os.UserHandle;
+import android.os.UserManager;
 import android.provider.DeviceConfig;
 import android.provider.DeviceConfig.OnPropertiesChangedListener;
 import android.provider.DeviceConfig.Properties;
@@ -33,6 +37,7 @@
 import android.util.ArraySet;
 import android.util.KeyValueListParser;
 import android.util.Slog;
+import android.util.SparseArray;
 
 import java.io.PrintWriter;
 import java.util.Arrays;
@@ -289,6 +294,12 @@
     // started, the restriction is on while-in-use permissions.)
     volatile boolean mFlagBackgroundFgsStartRestrictionEnabled = true;
 
+    /**
+     * UserId to Assistant ComponentName mapping.
+     * Per user Assistant ComponentName is from {@link android.provider.Settings.Secure#ASSISTANT}
+     */
+    SparseArray<ComponentName> mAssistants = new SparseArray<>();
+
     private final ActivityManagerService mService;
     private ContentResolver mResolver;
     private final KeyValueListParser mParser = new KeyValueListParser(',');
@@ -364,6 +375,8 @@
                 Settings.Global.getUriFor(
                         Settings.Global.FOREGROUND_SERVICE_STARTS_LOGGING_ENABLED);
 
+    private static final Uri ASSISTANT_URI = Settings.Secure.getUriFor(Settings.Secure.ASSISTANT);
+
     private static final Uri ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS_URI =
             Settings.Global.getUriFor(Settings.Global.ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS);
 
@@ -430,6 +443,8 @@
         mResolver.registerContentObserver(ACTIVITY_STARTS_LOGGING_ENABLED_URI, false, this);
         mResolver.registerContentObserver(FOREGROUND_SERVICE_STARTS_LOGGING_ENABLED_URI,
                 false, this);
+        mResolver.registerContentObserver(ASSISTANT_URI, false, this,
+                UserHandle.USER_ALL);
         if (mSystemServerAutomaticHeapDumpEnabled) {
             mResolver.registerContentObserver(ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS_URI,
                     false, this);
@@ -445,6 +460,7 @@
         // The following read from Settings.
         updateActivityStartsLoggingEnabled();
         updateForegroundServiceStartsLoggingEnabled();
+        updateAssistant();
     }
 
     private void loadDeviceConfigConstants() {
@@ -476,6 +492,8 @@
             updateForegroundServiceStartsLoggingEnabled();
         } else if (ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS_URI.equals(uri)) {
             updateEnableAutomaticSystemServerHeapDumps();
+        } else if (ASSISTANT_URI.equals(uri)) {
+            updateAssistant();
         }
     }
 
@@ -573,6 +591,31 @@
                 Settings.Global.FOREGROUND_SERVICE_STARTS_LOGGING_ENABLED, 1) == 1;
     }
 
+    private void updateAssistant() {
+        final List<UserInfo> users =
+                mService.mContext.getSystemService(UserManager.class).getUsers();
+        SparseArray<ComponentName> componentNames = new SparseArray<>();
+        for (int i = 0; i < users.size(); i++) {
+            final int userId = users.get(i).id;
+            final String str = Settings.Secure.getStringForUser(mResolver,
+                    Settings.Secure.ASSISTANT, userId);
+            if (!TextUtils.isEmpty(str)) {
+                componentNames.put(userId, ComponentName.unflattenFromString(str));
+            }
+        }
+        synchronized (mService) {
+            for (int i = 0; i < mAssistants.size(); i++) {
+                mService.mServices.mWhiteListAllowWhileInUsePermissionInFgs.remove(
+                        mAssistants.valueAt(i).getPackageName());
+            }
+            mAssistants = componentNames;
+            for (int i = 0; i < mAssistants.size(); i++) {
+                mService.mServices.mWhiteListAllowWhileInUsePermissionInFgs.add(
+                        mAssistants.valueAt(i).getPackageName());
+            }
+        }
+    }
+
     private void updateBackgroundFgsStartsRestriction() {
         mFlagBackgroundFgsStartRestrictionEnabled = DeviceConfig.getBoolean(
                 DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
@@ -581,9 +624,6 @@
     }
 
     private void updateOomAdjUpdatePolicy() {
-
-
-
         OOMADJ_UPDATE_QUICK = DeviceConfig.getInt(
                 DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
                 KEY_OOMADJ_UPDATE_POLICY,