summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Daniel <danieljkim@google.com> 2024-04-15 22:32:04 +0000
committer Daniel <danieljkim@google.com> 2024-05-02 22:03:43 +0000
commit1db5e5d1806aef3ef2fca89491b4a1883e7a1fa5 (patch)
tree92fdc76aafdc47fec5b016959968e47438373d74
parent82612236d4373f801f78b8be1dc42ec0b23365f3 (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
-rw-r--r--core/java/android/view/autofill/AutofillManager.java13
-rw-r--r--core/java/android/view/autofill/IAutoFillManager.aidl2
-rw-r--r--packages/CredentialManager/res/xml/autofill_service_configuration.xml2
-rw-r--r--services/autofill/java/com/android/server/autofill/AutofillManagerService.java6
-rw-r--r--services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java52
-rw-r--r--services/autofill/java/com/android/server/autofill/Session.java10
-rw-r--r--services/credentials/java/com/android/server/credentials/CredentialManagerService.java28
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);
- }
- }
}
}