Merge "Enable credential suggestions without autofill provider" into main
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index c7df15c..bfe4e6f 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -1592,7 +1592,8 @@
                 // request comes in but PCC Detection hasn't been triggered. There is no benefit to
                 // trigger PCC Detection separately in those cases.
                 if (!isActiveLocked()) {
-                    final boolean clientAdded = tryAddServiceClientIfNeededLocked();
+                    final boolean clientAdded =
+                            tryAddServiceClientIfNeededLocked(isCredmanRequested);
                     if (clientAdded) {
                         startSessionLocked(/* id= */ AutofillId.NO_AUTOFILL_ID, /* bounds= */ null,
                             /* value= */ null, /* flags= */ FLAG_PCC_DETECTION);
@@ -1850,7 +1851,8 @@
             Rect bounds, AutofillValue value, int flags) {
         if (shouldIgnoreViewEnteredLocked(id, flags)) return null;
 
-        final boolean clientAdded = tryAddServiceClientIfNeededLocked();
+        boolean credmanRequested = isCredmanRequested(view);
+        final boolean clientAdded = tryAddServiceClientIfNeededLocked(credmanRequested);
         if (!clientAdded) {
             if (sVerbose) Log.v(TAG, "ignoring notifyViewEntered(" + id + "): no service client");
             return null;
@@ -2645,6 +2647,11 @@
      */
     @GuardedBy("mLock")
     private boolean tryAddServiceClientIfNeededLocked() {
+        return tryAddServiceClientIfNeededLocked(/*credmanRequested=*/ false);
+    }
+
+    @GuardedBy("mLock")
+    private boolean tryAddServiceClientIfNeededLocked(boolean credmanRequested) {
         final AutofillClient client = getClient();
         if (client == null) {
             return false;
@@ -2659,7 +2666,7 @@
                 final int userId = mContext.getUserId();
                 final SyncResultReceiver receiver = new SyncResultReceiver(SYNC_CALLS_TIMEOUT_MS);
                 mService.addClient(mServiceClient, client.autofillClientGetComponentName(),
-                        userId, receiver);
+                        userId, receiver, credmanRequested);
                 int flags = 0;
                 try {
                     flags = receiver.getIntResult();
diff --git a/core/java/android/view/autofill/IAutoFillManager.aidl b/core/java/android/view/autofill/IAutoFillManager.aidl
index cefd6dc..1a9322e 100644
--- a/core/java/android/view/autofill/IAutoFillManager.aidl
+++ b/core/java/android/view/autofill/IAutoFillManager.aidl
@@ -38,7 +38,7 @@
 oneway interface IAutoFillManager {
     // Returns flags: FLAG_ADD_CLIENT_ENABLED | FLAG_ADD_CLIENT_DEBUG | FLAG_ADD_CLIENT_VERBOSE
     void addClient(in IAutoFillManagerClient client, in ComponentName componentName, int userId,
-        in IResultReceiver result);
+        in IResultReceiver result, boolean credmanRequested);
     void removeClient(in IAutoFillManagerClient client, int userId);
     void startSession(IBinder activityToken, in IBinder appCallback, in AutofillId autoFillId,
         in Rect bounds, in AutofillValue value, int userId, boolean hasCallback, int flags,
diff --git a/packages/CredentialManager/res/xml/autofill_service_configuration.xml b/packages/CredentialManager/res/xml/autofill_service_configuration.xml
index 25cc094..0151add 100644
--- a/packages/CredentialManager/res/xml/autofill_service_configuration.xml
+++ b/packages/CredentialManager/res/xml/autofill_service_configuration.xml
@@ -5,6 +5,6 @@
    Note: This file is ignored for devices older that API 31
    See https://developer.android.com/about/versions/12/backup-restore
 -->
-<autofill-service-configuration
+<autofill-service
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:supportsInlineSuggestions="true"/>
\ No newline at end of file
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index 9701292..763879e 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -1625,13 +1625,13 @@
     final class AutoFillManagerServiceStub extends IAutoFillManager.Stub {
         @Override
         public void addClient(IAutoFillManagerClient client, ComponentName componentName,
-                int userId, IResultReceiver receiver) {
+                int userId, IResultReceiver receiver, boolean credmanRequested) {
             int flags = 0;
             try {
                 synchronized (mLock) {
                     final int enabledFlags =
                             getServiceForUserWithLocalBinderIdentityLocked(userId)
-                            .addClientLocked(client, componentName);
+                            .addClientLocked(client, componentName, credmanRequested);
                     if (enabledFlags != 0) {
                         flags |= enabledFlags;
                     }
@@ -1644,7 +1644,7 @@
                 }
             } catch (Exception ex) {
                 // Don't do anything, send back default flags
-                Log.wtf(TAG, "addClient(): failed " + ex.toString());
+                Log.wtf(TAG, "addClient(): failed " + ex.toString(), ex);
             } finally {
                 send(receiver, flags);
             }
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 6822229..92acce2 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -33,6 +33,7 @@
 import android.annotation.Nullable;
 import android.app.ActivityManagerInternal;
 import android.content.ComponentName;
+import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
@@ -96,6 +97,7 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 import java.util.Random;
 /**
  * Bridge between the {@code system_server}'s {@link AutofillManagerService} and the
@@ -293,19 +295,31 @@
      * @return {@code 0} if disabled, {@code FLAG_ADD_CLIENT_ENABLED} if enabled (it might be
      * OR'ed with {@code FLAG_AUGMENTED_AUTOFILL_REQUEST}).
      */
-    @GuardedBy("mLock")
-    int addClientLocked(IAutoFillManagerClient client, ComponentName componentName) {
-        if (mClients == null) {
-            mClients = new RemoteCallbackList<>();
-        }
-        mClients.register(client);
+    int addClientLocked(IAutoFillManagerClient client, ComponentName componentName,
+            boolean credmanRequested) {
+        synchronized (mLock) {
+            ComponentName credComponentName = getCredentialAutofillService(getContext());
 
-        if (isEnabledLocked()) return FLAG_ADD_CLIENT_ENABLED;
+            if (!credmanRequested
+                    && Objects.equals(credComponentName,
+                    mInfo == null ? null : mInfo.getServiceInfo().getComponentName())) {
+                // If the service component name corresponds to cred component name, then it means
+                // no autofill provider is selected by the user. Cred Autofill Service should only
+                // be active if there is a credman request.
+                return 0;
+            }
+            if (mClients == null) {
+                mClients = new RemoteCallbackList<>();
+            }
+            mClients.register(client);
 
-        // Check if it's enabled for augmented autofill
-        if (componentName != null && isAugmentedAutofillServiceAvailableLocked()
-                && isWhitelistedForAugmentedAutofillLocked(componentName)) {
-            return FLAG_ADD_CLIENT_ENABLED_FOR_AUGMENTED_AUTOFILL_ONLY;
+            if (isEnabledLocked()) return FLAG_ADD_CLIENT_ENABLED;
+
+            // Check if it's enabled for augmented autofill
+            if (componentName != null && isAugmentedAutofillServiceAvailableLocked()
+                    && isWhitelistedForAugmentedAutofillLocked(componentName)) {
+                return FLAG_ADD_CLIENT_ENABLED_FOR_AUGMENTED_AUTOFILL_ONLY;
+            }
         }
 
         // No flags / disabled
@@ -1486,6 +1500,22 @@
         return true;
     }
 
+    @Nullable
+    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;
+    }
+
     @GuardedBy("mLock")
     private int getAugmentedAutofillServiceUidLocked() {
         if (mRemoteAugmentedAutofillServiceInfo == null) {
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index ba6b067..519236d 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -1493,10 +1493,16 @@
 
         mCredentialAutofillService = getCredentialAutofillService(context);
 
-        ComponentName primaryServiceComponentName, secondaryServiceComponentName;
+        ComponentName primaryServiceComponentName, secondaryServiceComponentName = null;
         if (isPrimaryCredential) {
             primaryServiceComponentName = mCredentialAutofillService;
-            secondaryServiceComponentName = serviceComponentName;
+            if (serviceComponentName != null
+                    && !serviceComponentName.equals(mCredentialAutofillService)) {
+                // if service component name is credential autofill service, no need to initialize
+                // secondary provider. This happens if the user sets non-autofill provider as
+                // password provider.
+                secondaryServiceComponentName = serviceComponentName;
+            }
         } else {
             primaryServiceComponentName = serviceComponentName;
             secondaryServiceComponentName = mCredentialAutofillService;
diff --git a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
index 6ef1436..0c83e8e 100644
--- a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
+++ b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
@@ -66,6 +66,7 @@
 import android.util.Slog;
 import android.util.SparseArray;
 
+import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
 import com.android.server.credentials.metrics.ApiName;
 import com.android.server.credentials.metrics.ApiStatus;
@@ -1166,11 +1167,17 @@
                 settingsWrapper.getStringForUser(
                         Settings.Secure.AUTOFILL_SERVICE, UserHandle.myUserId());
 
-        // If there is an autofill provider and it is the placeholder indicating
+        // If there is an autofill provider and it is the credential autofill service indicating
         // that the currently selected primary provider does not support autofill
-        // then we should wipe the setting to keep it in sync.
-        if (autofillProvider != null && primaryProviders.isEmpty()) {
-            if (autofillProvider.equals(AUTOFILL_PLACEHOLDER_VALUE)) {
+        // then we should keep as is
+        String credentialAutofillService = settingsWrapper.mContext.getResources().getString(
+                R.string.config_defaultCredentialManagerAutofillService);
+        if (autofillProvider != null && primaryProviders.isEmpty() && !TextUtils.equals(
+                autofillProvider, credentialAutofillService)) {
+            // If the existing autofill provider is from the app being removed
+            // then erase the autofill service setting.
+            ComponentName cn = ComponentName.unflattenFromString(autofillProvider);
+            if (cn != null && cn.getPackageName().equals(packageName)) {
                 if (!settingsWrapper.putStringForUser(
                         Settings.Secure.AUTOFILL_SERVICE,
                         "",
@@ -1178,19 +1185,6 @@
                         /* overrideableByRestore= */ true)) {
                     Slog.e(TAG, "Failed to remove autofill package: " + packageName);
                 }
-            } else {
-                // If the existing autofill provider is from the app being removed
-                // then erase the autofill service setting.
-                ComponentName cn = ComponentName.unflattenFromString(autofillProvider);
-                if (cn != null && cn.getPackageName().equals(packageName)) {
-                    if (!settingsWrapper.putStringForUser(
-                            Settings.Secure.AUTOFILL_SERVICE,
-                            "",
-                            UserHandle.myUserId(),
-                            /* overrideableByRestore= */ true)) {
-                        Slog.e(TAG, "Failed to remove autofill package: " + packageName);
-                    }
-                }
             }
         }