Added support to run autofill service from instant apps.
Bug: 79422318
Test: m -j CtsAutoFillServiceTestCases && \
cts-tradefed run commandAndExit cts-instant-dev \
-m CtsAutoFillServiceTestCases
Test: cts-tradefed run commandAndExit cts-dev -m CtsAutoFillServiceTestCases
Change-Id: I1e885fe7edcbc0ace3a0f60abacb9cea9b6c03e7
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index 51c0488..9b833f7 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -157,6 +157,9 @@
}
};
+ @GuardedBy("mLock")
+ private boolean mAllowInstantService;
+
public AutofillManagerService(Context context) {
super(context);
mContext = context;
@@ -518,6 +521,23 @@
sFullScreenMode = mode;
}
+ // Called by Shell command.
+ boolean getAllowInstantService() {
+ mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+ synchronized (mLock) {
+ return mAllowInstantService;
+ }
+ }
+
+ // Called by Shell command.
+ void setAllowInstantService(boolean mode) {
+ mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+ Slog.i(TAG, "setAllowInstantService(): " + mode);
+ synchronized (mLock) {
+ mAllowInstantService = mode;
+ }
+ }
+
private void setDebugLocked(boolean debug) {
com.android.server.autofill.Helper.sDebug = debug;
android.view.autofill.Helper.sDebug = debug;
@@ -866,7 +886,8 @@
synchronized (mLock) {
final AutofillManagerServiceImpl service = getServiceForUserLocked(userId);
return service.startSessionLocked(activityToken, getCallingUid(), appCallback,
- autofillId, bounds, value, hasCallback, flags, componentName, compatMode);
+ autofillId, bounds, value, hasCallback, componentName, compatMode,
+ mAllowInstantService, flags);
}
}
@@ -1202,6 +1223,7 @@
mAutofillCompatState.dump(prefix2, pw);
pw.print(prefix2); pw.print("from settings: ");
pw.println(getWhitelistedCompatModePackagesFromSettings());
+ pw.print("Allow instant service: "); pw.println(mAllowInstantService);
}
if (showHistory) {
pw.println(); pw.println("Requests history:"); pw.println();
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 4bd8063..d97253e 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -342,7 +342,8 @@
int startSessionLocked(@NonNull IBinder activityToken, int uid,
@NonNull IBinder appCallbackToken, @NonNull AutofillId autofillId,
@NonNull Rect virtualBounds, @Nullable AutofillValue value, boolean hasCallback,
- int flags, @NonNull ComponentName componentName, boolean compatMode) {
+ @NonNull ComponentName componentName, boolean compatMode,
+ boolean bindInstantServiceAllowed, int flags) {
if (!isEnabledLocked()) {
return 0;
}
@@ -372,7 +373,7 @@
pruneAbandonedSessionsLocked();
final Session newSession = createSessionByTokenLocked(activityToken, uid, appCallbackToken,
- hasCallback, componentName, compatMode, flags);
+ hasCallback, componentName, compatMode, bindInstantServiceAllowed, flags);
if (newSession == null) {
return NO_SESSION;
}
@@ -491,7 +492,8 @@
@GuardedBy("mLock")
private Session createSessionByTokenLocked(@NonNull IBinder activityToken, int uid,
@NonNull IBinder appCallbackToken, boolean hasCallback,
- @NonNull ComponentName componentName, boolean compatMode, int flags) {
+ @NonNull ComponentName componentName, boolean compatMode,
+ boolean bindInstantServiceAllowed, int flags) {
// use random ids so that one app cannot know that another app creates sessions
int sessionId;
int tries = 0;
@@ -510,7 +512,7 @@
final Session newSession = new Session(this, mUi, mContext, mHandler, mUserId, mLock,
sessionId, uid, activityToken, appCallbackToken, hasCallback, mUiLatencyHistory,
mWtfHistory, mInfo.getServiceInfo().getComponentName(), componentName, compatMode,
- flags);
+ bindInstantServiceAllowed, flags);
mSessions.put(newSession.id, newSession);
return newSession;
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java
index c76c8ac..f7b7ceb4 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java
@@ -86,6 +86,9 @@
pw.println(" get fc_score [--algorithm ALGORITHM] value1 value2");
pw.println(" Gets the field classification score for 2 fields.");
pw.println("");
+ pw.println(" get bind-instant-service-allowed");
+ pw.println(" Gets whether binding to services provided by instant apps is allowed");
+ pw.println("");
pw.println(" set log_level [off | debug | verbose]");
pw.println(" Sets the Autofill log level.");
pw.println("");
@@ -98,6 +101,9 @@
pw.println(" set full_screen_mode [true | false | default]");
pw.println(" Sets the Fill UI full screen mode");
pw.println("");
+ pw.println(" set bind-instant-service-allowed [true | false]");
+ pw.println(" Sets whether binding to services provided by instant apps is allowed");
+ pw.println("");
pw.println(" list sessions [--user USER_ID]");
pw.println(" Lists all pending sessions.");
pw.println("");
@@ -123,6 +129,8 @@
return getFieldClassificationScore(pw);
case "full_screen_mode":
return getFullScreenMode(pw);
+ case "bind-instant-service-allowed":
+ return getBindInstantService(pw);
default:
pw.println("Invalid set: " + what);
return -1;
@@ -141,6 +149,8 @@
return setMaxVisibileDatasets();
case "full_screen_mode":
return setFullScreenMode(pw);
+ case "bind-instant-service-allowed":
+ return setBindInstantService(pw);
default:
pw.println("Invalid set: " + what);
return -1;
@@ -259,6 +269,30 @@
}
}
+ private int getBindInstantService(PrintWriter pw) {
+ if (mService.getAllowInstantService()) {
+ pw.println("true");
+ } else {
+ pw.println("false");
+ }
+ return 0;
+ }
+
+ private int setBindInstantService(PrintWriter pw) {
+ final String mode = getNextArgRequired();
+ switch (mode.toLowerCase()) {
+ case "true":
+ mService.setAllowInstantService(true);
+ return 0;
+ case "false":
+ mService.setAllowInstantService(false);
+ return 0;
+ default:
+ pw.println("Invalid mode: " + mode);
+ return -1;
+ }
+ }
+
private int requestDestroy(PrintWriter pw) {
if (!isNextArgSessions(pw)) {
return -1;
diff --git a/services/autofill/java/com/android/server/autofill/FieldClassificationStrategy.java b/services/autofill/java/com/android/server/autofill/FieldClassificationStrategy.java
index 9bec856..ba544f1 100644
--- a/services/autofill/java/com/android/server/autofill/FieldClassificationStrategy.java
+++ b/services/autofill/java/com/android/server/autofill/FieldClassificationStrategy.java
@@ -15,8 +15,6 @@
*/
package com.android.server.autofill;
-import static android.view.autofill.AutofillManager.FC_SERVICE_TIMEOUT;
-
import static com.android.server.autofill.Helper.sDebug;
import static com.android.server.autofill.Helper.sVerbose;
import static android.service.autofill.AutofillFieldClassificationService.SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS;
@@ -52,8 +50,6 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
/**
* Strategy used to bridge the field classification algorithms provided by a service in an external
diff --git a/services/autofill/java/com/android/server/autofill/Helper.java b/services/autofill/java/com/android/server/autofill/Helper.java
index 5372d0c..f781013 100644
--- a/services/autofill/java/com/android/server/autofill/Helper.java
+++ b/services/autofill/java/com/android/server/autofill/Helper.java
@@ -68,6 +68,9 @@
/**
* When non-null, overrides whether the UI should be shown on full-screen mode.
+ *
+ * <p>Note: access to this variable is not synchronized because it's "final" on real usage -
+ * it's only set by Shell cmd, for development purposes.
*/
public static Boolean sFullScreenMode = null;
diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
index f7a4b73..4ded3fe 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
@@ -84,6 +84,8 @@
private final Handler mHandler;
+ private final boolean mBindInstantServiceAllowed;
+
private IAutoFillService mAutoFillService;
private boolean mBinding;
@@ -109,13 +111,14 @@
}
public RemoteFillService(Context context, ComponentName componentName,
- int userId, FillServiceCallbacks callbacks) {
+ int userId, FillServiceCallbacks callbacks, boolean bindInstantServiceAllowed) {
mContext = context;
mCallbacks = callbacks;
mComponentName = componentName;
mIntent = new Intent(AutofillService.SERVICE_INTERFACE).setComponent(mComponentName);
mUserId = userId;
mHandler = new Handler(FgThread.getHandler().getLooper());
+ mBindInstantServiceAllowed = bindInstantServiceAllowed;
}
public void destroy() {
@@ -207,6 +210,7 @@
.append(String.valueOf(isBound())).println();
pw.append(prefix).append(tab).append("hasPendingRequest=")
.append(String.valueOf(mPendingRequest != null)).println();
+ pw.append(prefix).append("mBindInstantServiceAllowed=").println(mBindInstantServiceAllowed);
pw.println();
}
@@ -258,12 +262,17 @@
if (sVerbose) Slog.v(LOG_TAG, "[user: " + mUserId + "] ensureBound()");
mBinding = true;
- boolean willBind = mContext.bindServiceAsUser(mIntent, mServiceConnection,
- Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
+ int flags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE;
+ if (mBindInstantServiceAllowed) {
+ flags |= Context.BIND_ALLOW_INSTANT;
+ }
+
+ final boolean willBind = mContext.bindServiceAsUser(mIntent, mServiceConnection, flags,
new UserHandle(mUserId));
if (!willBind) {
- if (sDebug) Slog.d(LOG_TAG, "[user: " + mUserId + "] could not bind to " + mIntent);
+ Slog.w(LOG_TAG, "[user: " + mUserId + "] could not bind to " + mIntent + " using flags "
+ + flags);
mBinding = false;
if (!mServiceDied) {
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 88a679b..73c7172 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -517,7 +517,7 @@
@NonNull IBinder client, boolean hasCallback, @NonNull LocalLog uiLatencyHistory,
@NonNull LocalLog wtfHistory,
@NonNull ComponentName serviceComponentName, @NonNull ComponentName componentName,
- boolean compatMode, int flags) {
+ boolean compatMode, boolean bindInstantServiceAllowed, int flags) {
id = sessionId;
mFlags = flags;
this.uid = uid;
@@ -526,7 +526,8 @@
mLock = lock;
mUi = ui;
mHandler = handler;
- mRemoteFillService = new RemoteFillService(context, serviceComponentName, userId, this);
+ mRemoteFillService = new RemoteFillService(context, serviceComponentName, userId, this,
+ bindInstantServiceAllowed);
mActivityToken = activityToken;
mHasCallback = hasCallback;
mUiLatencyHistory = uiLatencyHistory;
diff --git a/services/autofill/java/com/android/server/autofill/ViewState.java b/services/autofill/java/com/android/server/autofill/ViewState.java
index 2a76055..cff1a84 100644
--- a/services/autofill/java/com/android/server/autofill/ViewState.java
+++ b/services/autofill/java/com/android/server/autofill/ViewState.java
@@ -18,7 +18,6 @@
import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST;
import static com.android.server.autofill.Helper.sDebug;
-import static com.android.server.autofill.Helper.sVerbose;
import android.annotation.Nullable;
import android.graphics.Rect;