Merge "Added a whitelist for factory trust agents."
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 85ecaff..30625d0 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2812,6 +2812,11 @@
     <!-- TODO(b/35230407) complete the link field -->
     <bool name="config_allowEscrowTokenForTrustAgent">false</bool>
 
+    <!-- A flattened ComponentName which corresponds to the only trust agent that should be enabled
+         by default. If the default value is used, or set to an empty string, the restriction will
+         not be applied. -->
+    <string name="config_defaultTrustAgent" translatable="false"></string>
+
     <!-- Colon separated list of package names that should be granted Notification Listener access -->
     <string name="config_defaultListenerAccessPackages" translatable="false"></string>
 
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index ae05a69..9ebbe29 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2890,6 +2890,7 @@
 
   <!-- android.service.trust -->
   <java-symbol type="bool" name="config_allowEscrowTokenForTrustAgent"/>
+  <java-symbol type="string" name="config_defaultTrustAgent" />
 
   <!-- Time picker -->
   <java-symbol type="id" name="toggle_mode"/>
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index f4f7e24..cc4c23d 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -49,6 +49,7 @@
 import android.os.storage.StorageManager;
 import android.provider.Settings;
 import android.service.trust.TrustAgentService;
+import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -580,16 +581,24 @@
         }
         PackageManager pm = mContext.getPackageManager();
         List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userId);
+        ComponentName defaultAgent = getDefaultFactoryTrustAgent(mContext);
+        boolean shouldUseDefaultAgent = defaultAgent != null;
         ArraySet<ComponentName> discoveredAgents = new ArraySet<>();
-        for (ResolveInfo resolveInfo : resolveInfos) {
-            ComponentName componentName = getComponentName(resolveInfo);
-            int applicationInfoFlags = resolveInfo.serviceInfo.applicationInfo.flags;
-            if ((applicationInfoFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
-                Log.i(TAG, "Leaving agent " + componentName + " disabled because package "
-                        + "is not a system package.");
-                continue;
+
+        if (shouldUseDefaultAgent) {
+            discoveredAgents.add(defaultAgent);
+            Log.i(TAG, "Enabling " + defaultAgent + " because it is a default agent.");
+        } else { // A default agent is not set; perform regular trust agent discovery
+            for (ResolveInfo resolveInfo : resolveInfos) {
+                ComponentName componentName = getComponentName(resolveInfo);
+                int applicationInfoFlags = resolveInfo.serviceInfo.applicationInfo.flags;
+                if ((applicationInfoFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
+                    Log.i(TAG, "Leaving agent " + componentName + " disabled because package "
+                            + "is not a system package.");
+                    continue;
+                }
+                discoveredAgents.add(componentName);
             }
-            discoveredAgents.add(componentName);
         }
 
         List<ComponentName> previouslyEnabledAgents = utils.getEnabledTrustAgents(userId);
@@ -601,6 +610,19 @@
                 Settings.Secure.TRUST_AGENTS_INITIALIZED, 1, userId);
     }
 
+    /**
+     * Returns the {@link ComponentName} for the default trust agent, or {@code null} if there
+     * is no trust agent set.
+     */
+    private static ComponentName getDefaultFactoryTrustAgent(Context context) {
+        String defaultTrustAgent = context.getResources()
+            .getString(com.android.internal.R.string.config_defaultTrustAgent);
+        if (TextUtils.isEmpty(defaultTrustAgent)) {
+            return null;
+        }
+        return ComponentName.unflattenFromString(defaultTrustAgent);
+    }
+
     private List<ResolveInfo> resolveAllowedTrustAgents(PackageManager pm, int userId) {
         List<ResolveInfo> resolveInfos = pm.queryIntentServicesAsUser(TRUST_AGENT_INTENT,
                 PackageManager.GET_META_DATA |