Merge "Add config for cedman-autofill service" into main
diff --git a/core/java/android/service/autofill/AutofillServiceInfo.java b/core/java/android/service/autofill/AutofillServiceInfo.java
index 83f9662..0e67477 100644
--- a/core/java/android/service/autofill/AutofillServiceInfo.java
+++ b/core/java/android/service/autofill/AutofillServiceInfo.java
@@ -312,6 +312,7 @@
             final ServiceInfo serviceInfo = resolveInfo.serviceInfo;
             try {
                 if (serviceInfo != null && isCredentialManagerAutofillService(
+                        context,
                         serviceInfo.getComponentName())) {
                     // Skip this service as it is for internal use only
                     continue;
@@ -325,11 +326,23 @@
         return services;
     }
 
-    private static boolean isCredentialManagerAutofillService(ComponentName componentName) {
+    private static boolean isCredentialManagerAutofillService(Context context,
+            ComponentName componentName) {
         if (componentName == null) {
             return false;
         }
-        return componentName.equals(CREDMAN_SERVICE_COMPONENT_NAME);
+        ComponentName credAutofillService = null;
+        String credentialManagerAutofillCompName = context.getResources().getString(
+                R.string.config_defaultCredentialManagerAutofillService);
+        if (credentialManagerAutofillCompName != null && !credentialManagerAutofillCompName
+                .isEmpty()) {
+            credAutofillService = ComponentName.unflattenFromString(
+                    credentialManagerAutofillCompName);
+        } else {
+            Log.w(TAG, "Invalid CredentialAutofillService");
+        }
+
+        return componentName.equals(credAutofillService);
     }
 
     @Override
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index d2f74b2..806ba48 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -4807,6 +4807,18 @@
      See android.credentials.CredentialManager
     -->
     <string name="config_defaultCredentialManagerHybridService" translatable="false"></string>
+    
+    <!-- The component name, flattened to a string, for the system's credential manager
+      autofill service. This service allows interceding autofill requests and routing
+      them to credential manager.
+
+     This service must be trusted, as it can be activated without explicit consent of the user.
+     If no service with the specified name exists on the device, autofill will still
+     work with the user configured autofill service
+
+     See android.credentials.CredentialManager
+    -->
+    <string name="config_defaultCredentialManagerAutofillService" translatable="false"></string>
 
     <!-- The component name(s), flattened to a string, for the system's credential manager
       provider services. These services allow retrieving and storing credentials.
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 08f377b..a19c9d0 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3905,6 +3905,7 @@
   <java-symbol type="string" name="config_defaultAppPredictionService" />
   <java-symbol type="string" name="config_defaultContentSuggestionsService" />
   <java-symbol type="string" name="config_defaultCredentialManagerHybridService" />
+  <java-symbol type="string" name="config_defaultCredentialManagerAutofillService" />
   <java-symbol type="array" name="config_enabledCredentialProviderService" />
   <java-symbol type="array" name="config_primaryCredentialProviderService" />
   <java-symbol type="string" name="config_defaultSearchUiService" />
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index fef3216..9701292 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -79,6 +79,7 @@
 import android.view.autofill.IAutoFillManager;
 import android.view.autofill.IAutoFillManagerClient;
 
+import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.infra.AbstractRemoteService;
@@ -159,6 +160,7 @@
     final FrameworkResourcesServiceNameResolver mFieldClassificationResolver;
 
     private final AutoFillUI mUi;
+    final ComponentName mCredentialAutofillService;
 
     private final LocalLog mRequestsHistory = new LocalLog(20);
     private final LocalLog mUiLatencyHistory = new LocalLog(20);
@@ -288,6 +290,16 @@
                         mAugmentedAutofillResolver.isTemporary(userId));
             }
         }
+        String credentialManagerAutofillCompName = context.getResources().getString(
+                R.string.config_defaultCredentialManagerAutofillService);
+        if (credentialManagerAutofillCompName != null
+                && !credentialManagerAutofillCompName.isEmpty()) {
+            mCredentialAutofillService = ComponentName.unflattenFromString(
+                    credentialManagerAutofillCompName);
+        } else {
+            mCredentialAutofillService = null;
+            Slog.w(TAG, "Invalid CredentialAutofillService");
+        }
     }
 
     @Override // from AbstractMasterSystemService
@@ -417,7 +429,6 @@
         } finally {
             Binder.restoreCallingIdentity(token);
         }
-
         return managerService;
     }
 
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 272d63d..6822229 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -1291,7 +1291,8 @@
         RemoteFillService remoteService =
                 new RemoteFillService(
                         getContext(), mInfo.getServiceInfo().getComponentName(), mUserId,
-                        /* callbacks= */ null, mMaster.isInstantServiceAllowed());
+                        /* callbacks= */ null, mMaster.isInstantServiceAllowed(),
+                        mMaster.mCredentialAutofillService);
         remoteService.onSavedPasswordCountRequest(receiver);
     }
 
diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
index f914ed5..c96688c 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
@@ -62,10 +62,6 @@
     private static final long TIMEOUT_IDLE_BIND_MILLIS = 5 * DateUtils.SECOND_IN_MILLIS;
     private static final long TIMEOUT_REMOTE_REQUEST_MILLIS = 5 * DateUtils.SECOND_IN_MILLIS;
 
-    private static final ComponentName CREDMAN_SERVICE_COMPONENT_NAME =
-            new ComponentName("com.android.credentialmanager",
-                    "com.android.credentialmanager.autofill.CredentialAutofillService");
-
     private final FillServiceCallbacks mCallbacks;
     private final Object mLock = new Object();
     private CompletableFuture<FillResponse> mPendingFillRequest;
@@ -102,14 +98,15 @@
     }
 
     RemoteFillService(Context context, ComponentName componentName, int userId,
-            FillServiceCallbacks callbacks, boolean bindInstantServiceAllowed) {
+            FillServiceCallbacks callbacks, boolean bindInstantServiceAllowed,
+            @Nullable ComponentName credentialAutofillService) {
         super(context, new Intent(AutofillService.SERVICE_INTERFACE).setComponent(componentName),
                 Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS
                         | (bindInstantServiceAllowed ? Context.BIND_ALLOW_INSTANT : 0),
                 userId, IAutoFillService.Stub::asInterface);
         mCallbacks = callbacks;
         mComponentName = componentName;
-        mIsCredentialAutofillService = mComponentName.equals(CREDMAN_SERVICE_COMPONENT_NAME);
+        mIsCredentialAutofillService = mComponentName.equals(credentialAutofillService);
     }
 
     @Override // from ServiceConnector.Impl
diff --git a/services/autofill/java/com/android/server/autofill/SecondaryProviderHandler.java b/services/autofill/java/com/android/server/autofill/SecondaryProviderHandler.java
index 0af703e..4506779 100644
--- a/services/autofill/java/com/android/server/autofill/SecondaryProviderHandler.java
+++ b/services/autofill/java/com/android/server/autofill/SecondaryProviderHandler.java
@@ -59,9 +59,10 @@
 
     SecondaryProviderHandler(
             @NonNull Context context, int userId, boolean bindInstantServiceAllowed,
-            SecondaryProviderCallback callback, ComponentName componentName) {
+            SecondaryProviderCallback callback, ComponentName componentName,
+            @Nullable ComponentName credentialAutofillService) {
         mRemoteFillService = new RemoteFillService(context, componentName, userId, this,
-                bindInstantServiceAllowed);
+                bindInstantServiceAllowed, credentialAutofillService);
         mCallback = callback;
         Slog.v(TAG, "Creating a secondary provider handler with component name, " + componentName);
     }
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index b8a18c0..0b68f5f 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -244,10 +244,6 @@
     private static final int DEFAULT__FILL_REQUEST_ID_SNAPSHOT = -2;
     private static final int DEFAULT__FIELD_CLASSIFICATION_REQUEST_ID_SNAPSHOT = -2;
 
-    private static final ComponentName CREDMAN_SERVICE_COMPONENT_NAME =
-            new ComponentName("com.android.credentialmanager",
-                    "com.android.credentialmanager.autofill.CredentialAutofillService");
-
     static final String SESSION_ID_KEY = "autofill_session_id";
     static final String REQUEST_ID_KEY = "autofill_request_id";
 
@@ -524,6 +520,9 @@
 
     private final ClassificationState mClassificationState = new ClassificationState();
 
+    @Nullable
+    private final ComponentName mCredentialAutofillService;
+
     // TODO(b/216576510): Share one BroadcastReceiver between all Sessions instead of creating a
     // new one per Session.
     private final BroadcastReceiver mDelayedFillBroadcastReceiver =
@@ -1481,23 +1480,26 @@
         mUi = ui;
         mHandler = handler;
 
+        mCredentialAutofillService = getCredentialAutofillService(context);
+
         ComponentName primaryServiceComponentName, secondaryServiceComponentName;
         if (isPrimaryCredential) {
-            primaryServiceComponentName = CREDMAN_SERVICE_COMPONENT_NAME;
+            primaryServiceComponentName = mCredentialAutofillService;
             secondaryServiceComponentName = serviceComponentName;
         } else {
             primaryServiceComponentName = serviceComponentName;
-            secondaryServiceComponentName = CREDMAN_SERVICE_COMPONENT_NAME;
+            secondaryServiceComponentName = mCredentialAutofillService;
         }
         Slog.v(TAG, "Primary service component name: " + primaryServiceComponentName
                 + ", secondary service component name: " + secondaryServiceComponentName);
 
         mRemoteFillService = primaryServiceComponentName == null ? null
                 : new RemoteFillService(context, primaryServiceComponentName, userId, this,
-                        bindInstantServiceAllowed);
+                        bindInstantServiceAllowed, mCredentialAutofillService);
         mSecondaryProviderHandler = secondaryServiceComponentName == null ? null
                 : new SecondaryProviderHandler(context, userId, bindInstantServiceAllowed,
-                this::onSecondaryFillResponse, secondaryServiceComponentName);
+                this::onSecondaryFillResponse, secondaryServiceComponentName,
+                        mCredentialAutofillService);
         mActivityToken = activityToken;
         mHasCallback = hasCallback;
         mUiLatencyHistory = uiLatencyHistory;
@@ -1556,6 +1558,21 @@
         mLogViewEntered = false;
     }
 
+    private ComponentName getCredentialAutofillService(Context context) {
+        ComponentName componentName = null;
+        String credentialManagerAutofillCompName = context.getResources().getString(
+                R.string.config_defaultCredentialManagerAutofillService);
+        if (credentialManagerAutofillCompName != null
+                && !credentialManagerAutofillCompName.isEmpty()) {
+            componentName = ComponentName.unflattenFromString(
+                    credentialManagerAutofillCompName);
+        }
+        if (componentName == null) {
+            Slog.w(TAG, "Invalid CredentialAutofillService");
+        }
+        return componentName;
+    }
+
     /**
      * Gets the currently registered activity token
      *