Make IAutofillManager fully oneway.
The critical methods on this interface - like updateSession() - were already
void, so all we had to do were to "onewaywize" the other methods. We could
either refactor them to be truly async, or implement a blocking mechanism that
let them still be sync *and* oneway - because these methods are not in the
critical path, we opted for the latter, which is simpler and less risky.
Fixes: 73536867
Test: mmma -j ./frameworks/base/apct-tests/perftests/autofill/ && \
adb install -r $OUT/data/app/AutofillPerfTests/AutofillPerfTests.apk && \
adb shell am instrument -w -e class android.view.autofill.LoginTest \
com.android.perftests.autofill/android.support.test.runner.AndroidJUnitRunner
Test: CtsAutoFillServiceTestCases
Change-Id: I380430aa2a7805aed6f629afb360566fc5402abb
This commit is contained in:
@@ -57,6 +57,7 @@ import android.view.accessibility.AccessibilityWindowInfo;
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.internal.os.IResultReceiver;
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
@@ -72,6 +73,8 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
//TODO: use java.lang.ref.Cleaner once Android supports Java 9
|
||||
import sun.misc.Cleaner;
|
||||
@@ -572,10 +575,11 @@ public final class AutofillManager {
|
||||
|
||||
final AutofillClient client = getClient();
|
||||
if (client != null) {
|
||||
final SyncResultReceiver receiver = new SyncResultReceiver();
|
||||
try {
|
||||
final boolean sessionWasRestored = mService.restoreSession(mSessionId,
|
||||
client.autofillClientGetActivityToken(),
|
||||
mServiceClient.asBinder());
|
||||
mService.restoreSession(mSessionId, client.autofillClientGetActivityToken(),
|
||||
mServiceClient.asBinder(), receiver);
|
||||
final boolean sessionWasRestored = receiver.getIntResult() == 1;
|
||||
|
||||
if (!sessionWasRestored) {
|
||||
Log.w(TAG, "Session " + mSessionId + " could not be restored");
|
||||
@@ -691,7 +695,9 @@ public final class AutofillManager {
|
||||
*/
|
||||
@Nullable public FillEventHistory getFillEventHistory() {
|
||||
try {
|
||||
return mService.getFillEventHistory();
|
||||
final SyncResultReceiver receiver = new SyncResultReceiver();
|
||||
mService.getFillEventHistory(receiver);
|
||||
return receiver.getObjectResult(SyncResultReceiver.TYPE_PARCELABLE);
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowFromSystemServer();
|
||||
return null;
|
||||
@@ -1242,8 +1248,10 @@ public final class AutofillManager {
|
||||
public boolean hasEnabledAutofillServices() {
|
||||
if (mService == null) return false;
|
||||
|
||||
final SyncResultReceiver receiver = new SyncResultReceiver();
|
||||
try {
|
||||
return mService.isServiceEnabled(mContext.getUserId(), mContext.getPackageName());
|
||||
mService.isServiceEnabled(mContext.getUserId(), mContext.getPackageName(), receiver);
|
||||
return receiver.getIntResult() == 1;
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
@@ -1257,8 +1265,10 @@ public final class AutofillManager {
|
||||
public ComponentName getAutofillServiceComponentName() {
|
||||
if (mService == null) return null;
|
||||
|
||||
final SyncResultReceiver receiver = new SyncResultReceiver();
|
||||
try {
|
||||
return mService.getAutofillServiceComponentName();
|
||||
mService.getAutofillServiceComponentName(receiver);
|
||||
return receiver.getObjectResult(SyncResultReceiver.TYPE_PARCELABLE);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
@@ -1281,7 +1291,9 @@ public final class AutofillManager {
|
||||
*/
|
||||
@Nullable public String getUserDataId() {
|
||||
try {
|
||||
return mService.getUserDataId();
|
||||
final SyncResultReceiver receiver = new SyncResultReceiver();
|
||||
mService.getUserDataId(receiver);
|
||||
return receiver.getObjectResult(SyncResultReceiver.TYPE_STRING);
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowFromSystemServer();
|
||||
return null;
|
||||
@@ -1301,7 +1313,9 @@ public final class AutofillManager {
|
||||
*/
|
||||
@Nullable public UserData getUserData() {
|
||||
try {
|
||||
return mService.getUserData();
|
||||
final SyncResultReceiver receiver = new SyncResultReceiver();
|
||||
mService.getUserData(receiver);
|
||||
return receiver.getObjectResult(SyncResultReceiver.TYPE_PARCELABLE);
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowFromSystemServer();
|
||||
return null;
|
||||
@@ -1337,8 +1351,10 @@ public final class AutofillManager {
|
||||
* the user.
|
||||
*/
|
||||
public boolean isFieldClassificationEnabled() {
|
||||
final SyncResultReceiver receiver = new SyncResultReceiver();
|
||||
try {
|
||||
return mService.isFieldClassificationEnabled();
|
||||
mService.isFieldClassificationEnabled(receiver);
|
||||
return receiver.getIntResult() == 1;
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowFromSystemServer();
|
||||
return false;
|
||||
@@ -1358,8 +1374,10 @@ public final class AutofillManager {
|
||||
*/
|
||||
@Nullable
|
||||
public String getDefaultFieldClassificationAlgorithm() {
|
||||
final SyncResultReceiver receiver = new SyncResultReceiver();
|
||||
try {
|
||||
return mService.getDefaultFieldClassificationAlgorithm();
|
||||
mService.getDefaultFieldClassificationAlgorithm(receiver);
|
||||
return receiver.getObjectResult(SyncResultReceiver.TYPE_STRING);
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowFromSystemServer();
|
||||
return null;
|
||||
@@ -1376,9 +1394,10 @@ public final class AutofillManager {
|
||||
*/
|
||||
@NonNull
|
||||
public List<String> getAvailableFieldClassificationAlgorithms() {
|
||||
final String[] algorithms;
|
||||
final SyncResultReceiver receiver = new SyncResultReceiver();
|
||||
try {
|
||||
algorithms = mService.getAvailableFieldClassificationAlgorithms();
|
||||
mService.getAvailableFieldClassificationAlgorithms(receiver);
|
||||
final String[] algorithms = receiver.getObjectResult(SyncResultReceiver.TYPE_STRING);
|
||||
return algorithms != null ? Arrays.asList(algorithms) : Collections.emptyList();
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowFromSystemServer();
|
||||
@@ -1399,8 +1418,10 @@ public final class AutofillManager {
|
||||
public boolean isAutofillSupported() {
|
||||
if (mService == null) return false;
|
||||
|
||||
final SyncResultReceiver receiver = new SyncResultReceiver();
|
||||
try {
|
||||
return mService.isServiceSupported(mContext.getUserId());
|
||||
mService.isServiceSupported(mContext.getUserId(), receiver);
|
||||
return receiver.getIntResult() == 1;
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
@@ -1521,10 +1542,12 @@ public final class AutofillManager {
|
||||
final AutofillClient client = getClient();
|
||||
if (client == null) return; // NOTE: getClient() already logged it..
|
||||
|
||||
mSessionId = mService.startSession(client.autofillClientGetActivityToken(),
|
||||
final SyncResultReceiver receiver = new SyncResultReceiver();
|
||||
mService.startSession(client.autofillClientGetActivityToken(),
|
||||
mServiceClient.asBinder(), id, bounds, value, mContext.getUserId(),
|
||||
mCallback != null, flags, client.autofillClientGetComponentName(),
|
||||
isCompatibilityModeEnabledLocked());
|
||||
isCompatibilityModeEnabledLocked(), receiver);
|
||||
mSessionId = receiver.getIntResult();
|
||||
if (mSessionId != NO_SESSION) {
|
||||
mState = STATE_ACTIVE;
|
||||
}
|
||||
@@ -1602,7 +1625,9 @@ public final class AutofillManager {
|
||||
mServiceClient = new AutofillManagerClient(this);
|
||||
try {
|
||||
final int userId = mContext.getUserId();
|
||||
final int flags = mService.addClient(mServiceClient, userId);
|
||||
final SyncResultReceiver receiver = new SyncResultReceiver();
|
||||
mService.addClient(mServiceClient, userId, receiver);
|
||||
final int flags = receiver.getIntResult();
|
||||
mEnabled = (flags & FLAG_ADD_CLIENT_ENABLED) != 0;
|
||||
sDebug = (flags & FLAG_ADD_CLIENT_DEBUG) != 0;
|
||||
sVerbose = (flags & FLAG_ADD_CLIENT_VERBOSE) != 0;
|
||||
@@ -2818,4 +2843,104 @@ public final class AutofillManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public static final class SyncResultReceiver extends IResultReceiver.Stub {
|
||||
|
||||
private static final String EXTRA = "EXTRA";
|
||||
|
||||
/**
|
||||
* How long to block waiting for {@link IResultReceiver} callbacks when calling server.
|
||||
*/
|
||||
private static final long BINDER_TIMEOUT_MS = 5000;
|
||||
|
||||
private static final int TYPE_STRING = 0;
|
||||
private static final int TYPE_STRING_ARRAY = 1;
|
||||
private static final int TYPE_PARCELABLE = 2;
|
||||
|
||||
private final CountDownLatch mLatch = new CountDownLatch(1);
|
||||
private int mResult;
|
||||
private Bundle mBundle;
|
||||
|
||||
private void waitResult() {
|
||||
try {
|
||||
if (!mLatch.await(BINDER_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
|
||||
throw new IllegalStateException("Not called in " + BINDER_TIMEOUT_MS + "ms");
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the result from an operation that returns an {@code int}.
|
||||
*/
|
||||
int getIntResult() {
|
||||
waitResult();
|
||||
return mResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the result from an operation that returns an {@code Object}.
|
||||
*
|
||||
* @param type type of expected object.
|
||||
*/
|
||||
@Nullable
|
||||
@SuppressWarnings("unchecked")
|
||||
<T> T getObjectResult(int type) {
|
||||
waitResult();
|
||||
if (mBundle == null) {
|
||||
return null;
|
||||
}
|
||||
switch (type) {
|
||||
case TYPE_STRING:
|
||||
return (T) mBundle.getString(EXTRA);
|
||||
case TYPE_STRING_ARRAY:
|
||||
return (T) mBundle.getString(EXTRA);
|
||||
case TYPE_PARCELABLE:
|
||||
return (T) mBundle.getParcelable(EXTRA);
|
||||
default:
|
||||
throw new IllegalArgumentException("unsupported type: " + type);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(int resultCode, Bundle resultData) {
|
||||
mResult = resultCode;
|
||||
mBundle = resultData;
|
||||
mLatch.countDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a bundle for a {@code String} value.
|
||||
*/
|
||||
@NonNull
|
||||
public static Bundle bundleFor(@Nullable String value) {
|
||||
final Bundle bundle = new Bundle();
|
||||
bundle.putString(EXTRA, value);
|
||||
return bundle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a bundle for a {@code String[]} value.
|
||||
*/
|
||||
@NonNull
|
||||
public static Bundle bundleFor(@Nullable String[] value) {
|
||||
final Bundle bundle = new Bundle();
|
||||
bundle.putStringArray(EXTRA, value);
|
||||
return bundle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a bundle for a {@code Parcelable} value.
|
||||
*/
|
||||
@NonNull
|
||||
public static Bundle bundleFor(@Nullable Parcelable value) {
|
||||
final Bundle bundle = new Bundle();
|
||||
bundle.putParcelable(EXTRA, value);
|
||||
return bundle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,41 +28,39 @@ import android.service.autofill.UserData;
|
||||
import android.view.autofill.AutofillId;
|
||||
import android.view.autofill.AutofillValue;
|
||||
import android.view.autofill.IAutoFillManagerClient;
|
||||
import com.android.internal.os.IResultReceiver;
|
||||
|
||||
/**
|
||||
* Mediator between apps being auto-filled and auto-fill service implementations.
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
// TODO(b/73536867) STOPSHIP : this whole interface should be either oneway or not, and we're
|
||||
// gradually converting the methods (as some of them return a value form the server and must be
|
||||
// refactored).
|
||||
interface IAutoFillManager {
|
||||
oneway interface IAutoFillManager {
|
||||
// Returns flags: FLAG_ADD_CLIENT_ENABLED | FLAG_ADD_CLIENT_DEBUG | FLAG_ADD_CLIENT_VERBOSE
|
||||
int addClient(in IAutoFillManagerClient client, int userId);
|
||||
void addClient(in IAutoFillManagerClient client, int userId, in IResultReceiver result);
|
||||
void removeClient(in IAutoFillManagerClient client, int userId);
|
||||
int startSession(IBinder activityToken, in IBinder appCallback, in AutofillId autoFillId,
|
||||
in Rect bounds, in AutofillValue value, int userId, boolean hasCallback, int flags,
|
||||
in ComponentName componentName, boolean compatMode);
|
||||
FillEventHistory getFillEventHistory();
|
||||
boolean restoreSession(int sessionId, in IBinder activityToken, in IBinder appCallback);
|
||||
oneway void updateSession(int sessionId, in AutofillId id, in Rect bounds,
|
||||
in AutofillValue value, int action, int flags, int userId);
|
||||
oneway void setAutofillFailure(int sessionId, in List<AutofillId> ids, int userId);
|
||||
oneway void finishSession(int sessionId, int userId);
|
||||
oneway void cancelSession(int sessionId, int userId);
|
||||
oneway void setAuthenticationResult(in Bundle data, int sessionId, int authenticationId,
|
||||
int userId);
|
||||
oneway void setHasCallback(int sessionId, int userId, boolean hasIt);
|
||||
void startSession(IBinder activityToken, in IBinder appCallback, in AutofillId autoFillId,
|
||||
in Rect bounds, in AutofillValue value, int userId, boolean hasCallback, int flags,
|
||||
in ComponentName componentName, boolean compatMode, in IResultReceiver result);
|
||||
void getFillEventHistory(in IResultReceiver result);
|
||||
void restoreSession(int sessionId, in IBinder activityToken, in IBinder appCallback,
|
||||
in IResultReceiver result);
|
||||
void updateSession(int sessionId, in AutofillId id, in Rect bounds,
|
||||
in AutofillValue value, int action, int flags, int userId);
|
||||
void setAutofillFailure(int sessionId, in List<AutofillId> ids, int userId);
|
||||
void finishSession(int sessionId, int userId);
|
||||
void cancelSession(int sessionId, int userId);
|
||||
void setAuthenticationResult(in Bundle data, int sessionId, int authenticationId, int userId);
|
||||
void setHasCallback(int sessionId, int userId, boolean hasIt);
|
||||
void disableOwnedAutofillServices(int userId);
|
||||
boolean isServiceSupported(int userId);
|
||||
boolean isServiceEnabled(int userId, String packageName);
|
||||
void isServiceSupported(int userId, in IResultReceiver result);
|
||||
void isServiceEnabled(int userId, String packageName, in IResultReceiver result);
|
||||
void onPendingSaveUi(int operation, IBinder token);
|
||||
UserData getUserData();
|
||||
String getUserDataId();
|
||||
void getUserData(in IResultReceiver result);
|
||||
void getUserDataId(in IResultReceiver result);
|
||||
void setUserData(in UserData userData);
|
||||
boolean isFieldClassificationEnabled();
|
||||
ComponentName getAutofillServiceComponentName();
|
||||
String[] getAvailableFieldClassificationAlgorithms();
|
||||
String getDefaultFieldClassificationAlgorithm();
|
||||
void isFieldClassificationEnabled(in IResultReceiver result);
|
||||
void getAutofillServiceComponentName(in IResultReceiver result);
|
||||
void getAvailableFieldClassificationAlgorithms(in IResultReceiver result);
|
||||
void getDefaultFieldClassificationAlgorithm(in IResultReceiver result);
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Parcelable;
|
||||
import android.os.RemoteCallback;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ResultReceiver;
|
||||
@@ -622,6 +623,38 @@ public final class AutofillManagerService extends SystemService {
|
||||
return getWhitelistedCompatModePackages(getWhitelistedCompatModePackagesFromSettings());
|
||||
}
|
||||
|
||||
private void send(@NonNull IResultReceiver receiver, int value) {
|
||||
try {
|
||||
receiver.send(value, null);
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "Error async reporting result to client: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
private void send(@NonNull IResultReceiver receiver, @NonNull Bundle value) {
|
||||
try {
|
||||
receiver.send(0, value);
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "Error async reporting result to client: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
private void send(@NonNull IResultReceiver receiver, @Nullable String value) {
|
||||
send(receiver, AutofillManager.SyncResultReceiver.bundleFor(value));
|
||||
}
|
||||
|
||||
private void send(@NonNull IResultReceiver receiver, @Nullable String[] value) {
|
||||
send(receiver, AutofillManager.SyncResultReceiver.bundleFor(value));
|
||||
}
|
||||
|
||||
private void send(@NonNull IResultReceiver receiver, @Nullable Parcelable value) {
|
||||
send(receiver, AutofillManager.SyncResultReceiver.bundleFor(value));
|
||||
}
|
||||
|
||||
private void send(@NonNull IResultReceiver receiver, boolean value) {
|
||||
send(receiver, value ? 1 : 0);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@VisibleForTesting
|
||||
static Map<String, String[]> getWhitelistedCompatModePackages(String setting) {
|
||||
@@ -827,9 +860,10 @@ public final class AutofillManagerService extends SystemService {
|
||||
|
||||
final class AutoFillManagerServiceStub extends IAutoFillManager.Stub {
|
||||
@Override
|
||||
public int addClient(IAutoFillManagerClient client, int userId) {
|
||||
public void addClient(IAutoFillManagerClient client, int userId,
|
||||
@NonNull IResultReceiver receiver) {
|
||||
int flags = 0;
|
||||
synchronized (mLock) {
|
||||
int flags = 0;
|
||||
if (getServiceForUserLocked(userId).addClientLocked(client)) {
|
||||
flags |= AutofillManager.FLAG_ADD_CLIENT_ENABLED;
|
||||
}
|
||||
@@ -839,8 +873,8 @@ public final class AutofillManagerService extends SystemService {
|
||||
if (sVerbose) {
|
||||
flags |= AutofillManager.FLAG_ADD_CLIENT_VERBOSE;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
send(receiver, flags);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -874,9 +908,9 @@ public final class AutofillManagerService extends SystemService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int startSession(IBinder activityToken, IBinder appCallback, AutofillId autofillId,
|
||||
public void startSession(IBinder activityToken, IBinder appCallback, AutofillId autofillId,
|
||||
Rect bounds, AutofillValue value, int userId, boolean hasCallback, int flags,
|
||||
ComponentName componentName, boolean compatMode) {
|
||||
ComponentName componentName, boolean compatMode, IResultReceiver receiver) {
|
||||
|
||||
activityToken = Preconditions.checkNotNull(activityToken, "activityToken");
|
||||
appCallback = Preconditions.checkNotNull(appCallback, "appCallback");
|
||||
@@ -892,61 +926,63 @@ public final class AutofillManagerService extends SystemService {
|
||||
throw new IllegalArgumentException(packageName + " is not a valid package", e);
|
||||
}
|
||||
|
||||
final int sessionId;
|
||||
synchronized (mLock) {
|
||||
final AutofillManagerServiceImpl service = getServiceForUserLocked(userId);
|
||||
return service.startSessionLocked(activityToken, getCallingUid(), appCallback,
|
||||
sessionId = service.startSessionLocked(activityToken, getCallingUid(), appCallback,
|
||||
autofillId, bounds, value, hasCallback, componentName, compatMode,
|
||||
mAllowInstantService, flags);
|
||||
}
|
||||
send(receiver, sessionId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FillEventHistory getFillEventHistory() throws RemoteException {
|
||||
public void getFillEventHistory(@NonNull IResultReceiver receiver) throws RemoteException {
|
||||
final int userId = UserHandle.getCallingUserId();
|
||||
|
||||
FillEventHistory fillEventHistory = null;
|
||||
synchronized (mLock) {
|
||||
final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
|
||||
if (service != null) {
|
||||
return service.getFillEventHistory(getCallingUid());
|
||||
fillEventHistory = service.getFillEventHistory(getCallingUid());
|
||||
} else if (sVerbose) {
|
||||
Slog.v(TAG, "getFillEventHistory(): no service for " + userId);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
send(receiver, fillEventHistory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserData getUserData() throws RemoteException {
|
||||
public void getUserData(@NonNull IResultReceiver receiver) throws RemoteException {
|
||||
final int userId = UserHandle.getCallingUserId();
|
||||
|
||||
UserData userData = null;
|
||||
synchronized (mLock) {
|
||||
final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
|
||||
if (service != null) {
|
||||
return service.getUserData(getCallingUid());
|
||||
userData = service.getUserData(getCallingUid());
|
||||
} else if (sVerbose) {
|
||||
Slog.v(TAG, "getUserData(): no service for " + userId);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
send(receiver, userData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUserDataId() throws RemoteException {
|
||||
public void getUserDataId(@NonNull IResultReceiver receiver) throws RemoteException {
|
||||
final int userId = UserHandle.getCallingUserId();
|
||||
UserData userData = null;
|
||||
|
||||
synchronized (mLock) {
|
||||
final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
|
||||
if (service != null) {
|
||||
final UserData userData = service.getUserData(getCallingUid());
|
||||
return userData == null ? null : userData.getId();
|
||||
userData = service.getUserData(getCallingUid());
|
||||
} else if (sVerbose) {
|
||||
Slog.v(TAG, "getUserDataId(): no service for " + userId);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
final String userDataId = userData == null ? null : userData.getId();
|
||||
send(receiver, userDataId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -964,89 +1000,96 @@ public final class AutofillManagerService extends SystemService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFieldClassificationEnabled() throws RemoteException {
|
||||
public void isFieldClassificationEnabled(@NonNull IResultReceiver receiver)
|
||||
throws RemoteException {
|
||||
final int userId = UserHandle.getCallingUserId();
|
||||
boolean enabled = false;
|
||||
|
||||
synchronized (mLock) {
|
||||
final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
|
||||
if (service != null) {
|
||||
return service.isFieldClassificationEnabled(getCallingUid());
|
||||
enabled = service.isFieldClassificationEnabled(getCallingUid());
|
||||
} else if (sVerbose) {
|
||||
Slog.v(TAG, "isFieldClassificationEnabled(): no service for " + userId);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
send(receiver, enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDefaultFieldClassificationAlgorithm() throws RemoteException {
|
||||
public void getDefaultFieldClassificationAlgorithm(@NonNull IResultReceiver receiver)
|
||||
throws RemoteException {
|
||||
final int userId = UserHandle.getCallingUserId();
|
||||
String algorithm = null;
|
||||
|
||||
synchronized (mLock) {
|
||||
final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
|
||||
if (service != null) {
|
||||
return service.getDefaultFieldClassificationAlgorithm(getCallingUid());
|
||||
algorithm = service.getDefaultFieldClassificationAlgorithm(getCallingUid());
|
||||
} else {
|
||||
if (sVerbose) {
|
||||
Slog.v(TAG, "getDefaultFcAlgorithm(): no service for " + userId);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
send(receiver, algorithm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getAvailableFieldClassificationAlgorithms() throws RemoteException {
|
||||
public void getAvailableFieldClassificationAlgorithms(@NonNull IResultReceiver receiver)
|
||||
throws RemoteException {
|
||||
final int userId = UserHandle.getCallingUserId();
|
||||
String[] algorithms = null;
|
||||
|
||||
synchronized (mLock) {
|
||||
final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
|
||||
if (service != null) {
|
||||
return service.getAvailableFieldClassificationAlgorithms(getCallingUid());
|
||||
algorithms = service.getAvailableFieldClassificationAlgorithms(getCallingUid());
|
||||
} else {
|
||||
if (sVerbose) {
|
||||
Slog.v(TAG, "getAvailableFcAlgorithms(): no service for " + userId);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
send(receiver, algorithms);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ComponentName getAutofillServiceComponentName() throws RemoteException {
|
||||
public void getAutofillServiceComponentName(@NonNull IResultReceiver receiver)
|
||||
throws RemoteException {
|
||||
final int userId = UserHandle.getCallingUserId();
|
||||
|
||||
ComponentName componentName = null;
|
||||
synchronized (mLock) {
|
||||
final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
|
||||
if (service != null) {
|
||||
return service.getServiceComponentName();
|
||||
componentName = service.getServiceComponentName();
|
||||
} else if (sVerbose) {
|
||||
Slog.v(TAG, "getAutofillServiceComponentName(): no service for " + userId);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
send(receiver, componentName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean restoreSession(int sessionId, IBinder activityToken, IBinder appCallback)
|
||||
public void restoreSession(int sessionId, @NonNull IBinder activityToken,
|
||||
@NonNull IBinder appCallback, @NonNull IResultReceiver receiver)
|
||||
throws RemoteException {
|
||||
final int userId = UserHandle.getCallingUserId();
|
||||
activityToken = Preconditions.checkNotNull(activityToken, "activityToken");
|
||||
appCallback = Preconditions.checkNotNull(appCallback, "appCallback");
|
||||
|
||||
boolean restored = false;
|
||||
synchronized (mLock) {
|
||||
final AutofillManagerServiceImpl service = mServicesCache.get(userId);
|
||||
if (service != null) {
|
||||
return service.restoreSession(sessionId, getCallingUid(), activityToken,
|
||||
restored = service.restoreSession(sessionId, getCallingUid(), activityToken,
|
||||
appCallback);
|
||||
} else if (sVerbose) {
|
||||
Slog.v(TAG, "restoreSession(): no service for " + userId);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
send(receiver, restored);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1112,23 +1155,27 @@ public final class AutofillManagerService extends SystemService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isServiceSupported(int userId) {
|
||||
public void isServiceSupported(int userId, @NonNull IResultReceiver receiver) {
|
||||
boolean supported = false;
|
||||
synchronized (mLock) {
|
||||
return !mDisabledUsers.get(userId);
|
||||
supported = !mDisabledUsers.get(userId);
|
||||
}
|
||||
send(receiver, supported);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isServiceEnabled(int userId, String packageName) {
|
||||
public void isServiceEnabled(int userId, @NonNull String packageName,
|
||||
@NonNull IResultReceiver receiver) {
|
||||
boolean enabled = false;
|
||||
synchronized (mLock) {
|
||||
final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
|
||||
if (service != null) {
|
||||
return Objects.equals(packageName, service.getServicePackageName());
|
||||
enabled = Objects.equals(packageName, service.getServicePackageName());
|
||||
} else if (sVerbose) {
|
||||
Slog.v(TAG, "isServiceEnabled(): no service for " + userId);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
send(receiver, enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user