diff options
author | 2024-04-15 22:32:04 +0000 | |
---|---|---|
committer | 2024-05-02 22:03:43 +0000 | |
commit | 1db5e5d1806aef3ef2fca89491b4a1883e7a1fa5 (patch) | |
tree | 92fdc76aafdc47fec5b016959968e47438373d74 | |
parent | 82612236d4373f801f78b8be1dc42ec0b23365f3 (diff) |
Enable credential suggestions without autofill provider
When the user does not select an autofill provider as the main password
provider, the autofill feature gets disabled. However, for views that
have credman requests, we still want to support providing credman
suggestions. To enable this, credential autofill service will be the
default autofill provider if there is no valid autofill provider. The
autofill session, in this case, will only be activated when the views
have credman requests.
Bug: 330177328
Test: cts
Change-Id: I9a7c8c6763d2814ed5a46790442f0133f0bd7537
7 files changed, 75 insertions, 38 deletions
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java index c7df15c7d5fa..bfe4e6f3cc9b 100644 --- a/core/java/android/view/autofill/AutofillManager.java +++ b/core/java/android/view/autofill/AutofillManager.java @@ -1592,7 +1592,8 @@ public final class AutofillManager { // 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 @@ public final class AutofillManager { 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 @@ public final class AutofillManager { */ @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 @@ public final class AutofillManager { 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 cefd6dc13005..1a9322e6f2b8 100644 --- a/core/java/android/view/autofill/IAutoFillManager.aidl +++ b/core/java/android/view/autofill/IAutoFillManager.aidl @@ -38,7 +38,7 @@ import com.android.internal.os.IResultReceiver; 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 25cc094fa44e..0151add1c8e8 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 970129231f03..763879e5379a 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 @@ public final class AutofillManagerService 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 @@ public final class AutofillManagerService } } 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 68222298b94c..92acce24e64e 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.NonNull; 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 com.android.server.wm.ActivityTaskManagerInternal; 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 @@ final class AutofillManagerServiceImpl * @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 (!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); - if (isEnabledLocked()) return FLAG_ADD_CLIENT_ENABLED; + 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; + // 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 @@ final class AutofillManagerServiceImpl 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 3a384065217e..7d23ca57eaa7 100644 --- a/services/autofill/java/com/android/server/autofill/Session.java +++ b/services/autofill/java/com/android/server/autofill/Session.java @@ -1492,10 +1492,16 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState 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 6ef14366b9e7..0c83e8e468d9 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.Pair; 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 @@ public final class CredentialManagerService 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 @@ public final class CredentialManagerService /* 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); - } - } } } |