Move API for disabling an autofill service to the manager
Test: the topic has a CTS test
bug:37170723
Change-Id: I2be18968ea8df0fd3fb070fe2efc3e811b0e5a76
diff --git a/Android.mk b/Android.mk
index 915f103..b8b85ba 100644
--- a/Android.mk
+++ b/Android.mk
@@ -273,7 +273,6 @@
core/java/android/security/IKeystoreService.aidl \
core/java/android/security/keymaster/IKeyAttestationApplicationIdProvider.aidl \
core/java/android/service/autofill/IAutoFillService.aidl \
- core/java/android/service/autofill/IAutoFillServiceConnection.aidl \
core/java/android/service/autofill/IFillCallback.aidl \
core/java/android/service/autofill/ISaveCallback.aidl \
core/java/android/service/carrier/ICarrierService.aidl \
diff --git a/api/current.txt b/api/current.txt
index 7c532d4..cfcdb7d 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -36986,7 +36986,6 @@
public abstract class AutofillService extends android.app.Service {
ctor public AutofillService();
- method public final void disableSelf();
method public final android.os.IBinder onBind(android.content.Intent);
method public void onConnected();
method public void onDisconnected();
@@ -47732,6 +47731,7 @@
public final class AutofillManager {
method public void cancel();
method public void commit();
+ method public void disableOwnedAutofillServices();
method public boolean isEnabled();
method public void notifyValueChanged(android.view.View);
method public void notifyValueChanged(android.view.View, int, android.view.autofill.AutofillValue);
diff --git a/api/system-current.txt b/api/system-current.txt
index 99a5793..df8d49a 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -40082,7 +40082,6 @@
public abstract class AutofillService extends android.app.Service {
ctor public AutofillService();
- method public final void disableSelf();
method public final android.os.IBinder onBind(android.content.Intent);
method public void onConnected();
method public void onDisconnected();
@@ -51284,6 +51283,7 @@
public final class AutofillManager {
method public void cancel();
method public void commit();
+ method public void disableOwnedAutofillServices();
method public boolean isEnabled();
method public void notifyValueChanged(android.view.View);
method public void notifyValueChanged(android.view.View, int, android.view.autofill.AutofillValue);
diff --git a/api/test-current.txt b/api/test-current.txt
index 570855f..a8060d8 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -37144,7 +37144,6 @@
public abstract class AutofillService extends android.app.Service {
ctor public AutofillService();
- method public final void disableSelf();
method public final android.os.IBinder onBind(android.content.Intent);
method public void onConnected();
method public void onDisconnected();
@@ -48114,6 +48113,7 @@
public final class AutofillManager {
method public void cancel();
method public void commit();
+ method public void disableOwnedAutofillServices();
method public boolean isEnabled();
method public void notifyValueChanged(android.view.View);
method public void notifyValueChanged(android.view.View, int, android.view.autofill.AutofillValue);
diff --git a/core/java/android/service/autofill/AutofillService.java b/core/java/android/service/autofill/AutofillService.java
index c82b9eb..d86dd5b 100644
--- a/core/java/android/service/autofill/AutofillService.java
+++ b/core/java/android/service/autofill/AutofillService.java
@@ -94,9 +94,9 @@
private final IAutoFillService mInterface = new IAutoFillService.Stub() {
@Override
- public void onInit(IAutoFillServiceConnection connection) {
- if (connection != null) {
- mHandlerCaller.obtainMessageO(MSG_CONNECT, connection).sendToTarget();
+ public void onConnectedStateChanged(boolean connected) {
+ if (connected) {
+ mHandlerCaller.obtainMessage(MSG_CONNECT).sendToTarget();
} else {
mHandlerCaller.obtainMessage(MSG_DISCONNECT).sendToTarget();
}
@@ -127,7 +127,6 @@
private final HandlerCaller.Callback mHandlerCallback = (msg) -> {
switch (msg.what) {
case MSG_CONNECT: {
- mConnection = (IAutoFillServiceConnection) msg.obj;
onConnected();
break;
} case MSG_ON_FILL_REQUEST: {
@@ -152,7 +151,6 @@
break;
} case MSG_DISCONNECT: {
onDisconnected();
- mConnection = null;
break;
} default: {
Log.w(TAG, "MyCallbacks received invalid message type: " + msg);
@@ -162,8 +160,6 @@
private HandlerCaller mHandlerCaller;
- private IAutoFillServiceConnection mConnection;
-
/**
* {@inheritDoc}
*
@@ -246,21 +242,9 @@
public void onDisconnected() {
}
- /**
- * Disables the service. After calling this method, the service will
- * be disabled and settings will show that it is turned off.
- *
- * <p>You should call this method only after a call to {@link #onConnected()}
- * and before the corresponding call to {@link #onDisconnected()}. In other words
- * you can disable your service only while the system is connected to it.</p>
- */
+ /** @hide */
public final void disableSelf() {
- if (mConnection != null) {
- try {
- mConnection.disableSelf();
- } catch (RemoteException re) {
- throw re.rethrowFromSystemServer();
- }
- }
+ // TODO(b/33197203): Remove when GCore has migrated off this API
+ getSystemService(AutofillManager.class).disableOwnedAutofillServices();
}
}
diff --git a/core/java/android/service/autofill/IAutoFillService.aidl b/core/java/android/service/autofill/IAutoFillService.aidl
index 9f296c6..a8d86ca 100644
--- a/core/java/android/service/autofill/IAutoFillService.aidl
+++ b/core/java/android/service/autofill/IAutoFillService.aidl
@@ -18,7 +18,6 @@
import android.app.assist.AssistStructure;
import android.os.Bundle;
-import android.service.autofill.IAutoFillServiceConnection;
import android.service.autofill.IFillCallback;
import android.service.autofill.ISaveCallback;
import com.android.internal.os.IResultReceiver;
@@ -29,7 +28,7 @@
* @hide
*/
oneway interface IAutoFillService {
- void onInit(in IAutoFillServiceConnection connection);
+ void onConnectedStateChanged(boolean connected);
void onFillRequest(in AssistStructure structure, in Bundle extras,
in IFillCallback callback, int flags);
void onSaveRequest(in AssistStructure structure, in Bundle extras,
diff --git a/core/java/android/service/autofill/IAutoFillServiceConnection.aidl b/core/java/android/service/autofill/IAutoFillServiceConnection.aidl
deleted file mode 100644
index cf73a10..0000000
--- a/core/java/android/service/autofill/IAutoFillServiceConnection.aidl
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.service.autofill;
-
-/**
- * Interface from an auto fill service to the system.
- *
- * @hide
- */
-interface IAutoFillServiceConnection {
- void disableSelf();
-}
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index d429d37..ba004b96 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -537,6 +537,18 @@
}
}
+ /**
+ * If the app calling this API has enabled autofill services they
+ * will be disabled.
+ */
+ public void disableOwnedAutofillServices() {
+ try {
+ mService.disableOwnedAutofillServices(mContext.getUserId());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
private AutofillClient getClientLocked() {
if (mContext instanceof AutofillClient) {
return (AutofillClient) mContext;
diff --git a/core/java/android/view/autofill/IAutoFillManager.aidl b/core/java/android/view/autofill/IAutoFillManager.aidl
index 20d09ae..68b3ccabc 100644
--- a/core/java/android/view/autofill/IAutoFillManager.aidl
+++ b/core/java/android/view/autofill/IAutoFillManager.aidl
@@ -35,10 +35,11 @@
boolean hasCallback, int flags, String packageName);
boolean restoreSession(int sessionId, in IBinder activityToken, in IBinder appCallback);
void setWindow(int sessionId, in IBinder windowToken);
- oneway void updateSession(int sessionId, in AutofillId id, in Rect bounds,
+ void updateSession(int sessionId, in AutofillId id, in Rect bounds,
in AutofillValue value, int flags, int userId);
void finishSession(int sessionId, int userId);
void cancelSession(int sessionId, int userId);
void setAuthenticationResult(in Bundle data, int sessionId, int userId);
- oneway void setHasCallback(int sessionId, int userId, boolean hasIt);
+ void setHasCallback(int sessionId, int userId, boolean hasIt);
+ void disableOwnedAutofillServices(int userId);
}
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index 89645f4..d6f5256 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -24,6 +24,8 @@
import static com.android.server.autofill.Helper.bundleToString;
import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
@@ -35,6 +37,7 @@
import android.database.ContentObserver;
import android.graphics.Rect;
import android.net.Uri;
+import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
@@ -194,15 +197,29 @@
*/
@NonNull
AutofillManagerServiceImpl getServiceForUserLocked(int userId) {
- AutofillManagerServiceImpl service = mServicesCache.get(userId);
+ final int resolvedUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
+ Binder.getCallingUid(), userId, false, false, null, null);
+ AutofillManagerServiceImpl service = mServicesCache.get(resolvedUserId);
if (service == null) {
- service = new AutofillManagerServiceImpl(mContext, mLock,
- mRequestsHistory, userId, mUi, mDisabledUsers.get(userId));
+ service = new AutofillManagerServiceImpl(mContext, mLock, mRequestsHistory,
+ resolvedUserId, mUi, mDisabledUsers.get(resolvedUserId));
mServicesCache.put(userId, service);
}
return service;
}
+ /**
+ * Peeks the service instance for a user.
+ *
+ * @return service instance or null if not already present
+ */
+ @Nullable
+ AutofillManagerServiceImpl peekServiceForUserLocked(int userId) {
+ final int resolvedUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
+ Binder.getCallingUid(), userId, false, false, null, null);
+ return mServicesCache.get(resolvedUserId);
+ }
+
// Called by Shell command.
void requestSaveForUser(int userId) {
Slog.i(TAG, "requestSaveForUser(): " + userId);
@@ -210,7 +227,7 @@
final IBinder activityToken = getTopActivityForUser();
if (activityToken != null) {
synchronized (mLock) {
- final AutofillManagerServiceImpl service = mServicesCache.get(userId);
+ final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
if (service == null) {
Log.w(TAG, "handleSaveForUser(): no cached service for userId " + userId);
return;
@@ -228,7 +245,10 @@
synchronized (mLock) {
if (userId != UserHandle.USER_ALL) {
- mServicesCache.get(userId).destroySessionsLocked();
+ AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
+ if (service != null) {
+ service.destroySessionsLocked();
+ }
} else {
final int size = mServicesCache.size();
for (int i = 0; i < size; i++) {
@@ -253,7 +273,10 @@
synchronized (mLock) {
if (userId != UserHandle.USER_ALL) {
- mServicesCache.get(userId).listSessionsLocked(sessions);
+ AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
+ if (service != null) {
+ service.listSessionsLocked(sessions);
+ }
} else {
final int size = mServicesCache.size();
for (int i = 0; i < size; i++) {
@@ -287,7 +310,7 @@
* Removes a cached service for a given user.
*/
private void removeCachedServiceLocked(int userId) {
- final AutofillManagerServiceImpl service = mServicesCache.get(userId);
+ final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
if (service != null) {
mServicesCache.delete(userId);
service.destroyLocked();
@@ -305,7 +328,7 @@
* Updates a cached service for a given user.
*/
private void updateCachedServiceLocked(int userId, boolean disabled) {
- AutofillManagerServiceImpl service = mServicesCache.get(userId);
+ AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
if (service != null) {
service.updateLocked(disabled);
}
@@ -409,8 +432,7 @@
public void updateSession(int sessionId, AutofillId id, Rect bounds,
AutofillValue value, int flags, int userId) {
synchronized (mLock) {
- final AutofillManagerServiceImpl service = mServicesCache.get(
- UserHandle.getCallingUserId());
+ final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
if (service != null) {
service.updateSessionLocked(sessionId, getCallingUid(), id, bounds, value,
flags);
@@ -421,8 +443,7 @@
@Override
public void finishSession(int sessionId, int userId) {
synchronized (mLock) {
- final AutofillManagerServiceImpl service = mServicesCache.get(
- UserHandle.getCallingUserId());
+ final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
if (service != null) {
service.finishSessionLocked(sessionId, getCallingUid());
}
@@ -432,8 +453,7 @@
@Override
public void cancelSession(int sessionId, int userId) {
synchronized (mLock) {
- final AutofillManagerServiceImpl service = mServicesCache.get(
- UserHandle.getCallingUserId());
+ final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
if (service != null) {
service.cancelSessionLocked(sessionId, getCallingUid());
}
@@ -441,6 +461,16 @@
}
@Override
+ public void disableOwnedAutofillServices(int userId) {
+ synchronized (mLock) {
+ final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
+ if (service != null) {
+ service.disableOwnedAutofillServicesLocked(Binder.getCallingUid());
+ }
+ }
+ }
+
+ @Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
synchronized (mLock) {
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 94d534a..63bf373 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -43,6 +43,7 @@
import android.os.Looper;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
+import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.service.autofill.AutofillService;
@@ -348,6 +349,25 @@
session.removeSelfLocked();
}
+ void disableOwnedAutofillServicesLocked(int uid) {
+ if (mInfo == null || mInfo.getServiceInfo().applicationInfo.uid
+ != UserHandle.getAppId(uid)) {
+ return;
+ }
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ final String autoFillService = getComponentNameFromSettings();
+ if (mInfo.getServiceInfo().getComponentName().equals(
+ ComponentName.unflattenFromString(autoFillService))) {
+ Settings.Secure.putStringForUser(mContext.getContentResolver(),
+ Settings.Secure.AUTOFILL_SERVICE, null, mUserId);
+ destroySessionsLocked();
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
private Session createSessionByTokenLocked(@NonNull IBinder activityToken, int uid,
@Nullable IBinder windowToken, @NonNull IBinder appCallbackToken, boolean hasCallback,
int flags, @NonNull String packageName) {
@@ -474,20 +494,6 @@
mSessions.clear();
}
- void disableSelf() {
- final long identity = Binder.clearCallingIdentity();
- try {
- final String autoFillService = getComponentNameFromSettings();
- if (mInfo.getServiceInfo().getComponentName().equals(
- ComponentName.unflattenFromString(autoFillService))) {
- Settings.Secure.putStringForUser(mContext.getContentResolver(),
- Settings.Secure.AUTOFILL_SERVICE, null, mUserId);
- }
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
-
CharSequence getServiceLabel() {
return mInfo.getServiceInfo().loadLabel(mContext.getPackageManager());
}
diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
index 003c8f1..dd520ac 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
@@ -35,7 +35,6 @@
import android.service.autofill.AutofillService;
import android.service.autofill.FillResponse;
import android.service.autofill.IAutoFillService;
-import android.service.autofill.IAutoFillServiceConnection;
import android.service.autofill.IFillCallback;
import android.service.autofill.ISaveCallback;
import android.text.format.DateUtils;
@@ -96,7 +95,6 @@
void onSaveRequestFailure(@Nullable CharSequence message,
@NonNull String servicePackageName);
void onServiceDied(RemoteFillService service);
- void onDisableSelf();
}
public RemoteFillService(Context context, ComponentName componentName,
@@ -203,10 +201,6 @@
}
}
- private void handleDisableSelf() {
- mCallbacks.onDisableSelf();
- }
-
private boolean isBound() {
return mAutoFillService != null;
}
@@ -246,7 +240,7 @@
mBinding = false;
if (isBound()) {
try {
- mAutoFillService.onInit(null);
+ mAutoFillService.onConnectedStateChanged(false);
} catch (Exception e) {
Slog.w(LOG_TAG, "Exception calling onDisconnected(): " + e);
}
@@ -322,12 +316,7 @@
return;
}
try {
- mAutoFillService.onInit(new IAutoFillServiceConnection.Stub() {
- @Override
- public void disableSelf() {
- mHandler.obtainMessage(MyHandler.MSG_ON_DISABLE_SELF).sendToTarget();
- }
- });
+ mAutoFillService.onConnectedStateChanged(true);
} catch (RemoteException e) {
Slog.w(LOG_TAG, "Exception calling onConnected(): " + e);
}
@@ -353,7 +342,6 @@
public static final int MSG_BINDER_DIED = 2;
public static final int MSG_UNBIND = 3;
public static final int MSG_ON_PENDING_REQUEST = 4;
- public static final int MSG_ON_DISABLE_SELF = 5;
public MyHandler(Context context) {
// Cannot use lambda - doesn't compile
@@ -381,10 +369,6 @@
case MSG_ON_PENDING_REQUEST: {
handlePendingRequest((PendingRequest) message.obj);
} break;
-
- case MSG_ON_DISABLE_SELF: {
- handleDisableSelf();
- } break;
}
}
}, false);
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 3ef9cd5..67c2314c 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -311,15 +311,6 @@
// FillServiceCallbacks
@Override
- public void onDisableSelf() {
- mService.disableSelf();
- synchronized (mLock) {
- removeSelfLocked();
- }
- }
-
- // FillServiceCallbacks
- @Override
public void onServiceDied(RemoteFillService service) {
// TODO(b/33197203): implement
}