Merge "Handle package changes in autofill manager service" into oc-dev
am: 01d51288df
Change-Id: Idcc327443e903d7b5b09526babf62426e3b83291
This commit is contained in:
@@ -7642,7 +7642,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
||||
return mContext.getSystemService(AutofillManager.class);
|
||||
}
|
||||
|
||||
private boolean isAutofillable() {
|
||||
/** @hide */
|
||||
public boolean isAutofillable() {
|
||||
return getAutofillType() != AUTOFILL_TYPE_NONE && !isAutofillBlocked();
|
||||
}
|
||||
|
||||
|
||||
@@ -400,7 +400,6 @@ public final class AutofillManager {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called when a {@link View} that supports autofill is entered.
|
||||
*
|
||||
@@ -780,8 +779,12 @@ public final class AutofillManager {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
|
||||
mTrackedViews = null;
|
||||
resetSessionLocked();
|
||||
}
|
||||
|
||||
private void resetSessionLocked() {
|
||||
mSessionId = NO_SESSION;
|
||||
mTrackedViews = null;
|
||||
}
|
||||
|
||||
private void updateSessionLocked(AutofillId id, Rect bounds, AutofillValue value, int flags) {
|
||||
@@ -903,9 +906,17 @@ public final class AutofillManager {
|
||||
}
|
||||
}
|
||||
|
||||
private void setState(boolean enabled) {
|
||||
private void setState(boolean enabled, boolean resetSession, boolean resetClient) {
|
||||
synchronized (mLock) {
|
||||
mEnabled = enabled;
|
||||
if (!mEnabled || resetSession) {
|
||||
// Reset the session state
|
||||
resetSessionLocked();
|
||||
}
|
||||
if (resetClient) {
|
||||
// Reset connection to system
|
||||
mServiceClient = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1025,13 +1036,14 @@ public final class AutofillManager {
|
||||
|
||||
AutofillCallback callback = null;
|
||||
synchronized (mLock) {
|
||||
if (mSessionId == sessionId) {
|
||||
AutofillClient client = getClientLocked();
|
||||
|
||||
if (client != null) {
|
||||
if (client.autofillCallbackRequestHideFillUi() && mCallback != null) {
|
||||
callback = mCallback;
|
||||
}
|
||||
// We do not check the session id for two reasons:
|
||||
// 1. If local and remote session id are off sync the UI would be stuck shown
|
||||
// 2. There is a race between the user state being destroyed due the fill
|
||||
// service being uninstalled and the UI being dismissed.
|
||||
AutofillClient client = getClientLocked();
|
||||
if (client != null) {
|
||||
if (client.autofillCallbackRequestHideFillUi() && mCallback != null) {
|
||||
callback = mCallback;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1343,10 +1355,11 @@ public final class AutofillManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setState(boolean enabled) {
|
||||
public void setState(boolean enabled, boolean resetSession, boolean resetClient) {
|
||||
final AutofillManager afm = mAfm.get();
|
||||
if (afm != null) {
|
||||
afm.mContext.getMainThreadHandler().post(() -> afm.setState(enabled));
|
||||
afm.mContext.getMainThreadHandler().post(
|
||||
() -> afm.setState(enabled, resetSession, resetClient));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ oneway interface IAutoFillManagerClient {
|
||||
/**
|
||||
* Notifies the client when the autofill enabled state changed.
|
||||
*/
|
||||
void setState(boolean enabled);
|
||||
void setState(boolean enabled, boolean resetSession, boolean resetClient);
|
||||
|
||||
/**
|
||||
* Autofills the activity with the contents of a dataset.
|
||||
|
||||
@@ -5337,7 +5337,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
sendAfterTextChanged((Editable) text);
|
||||
} else {
|
||||
// Always notify AutoFillManager - it will return right away if autofill is disabled.
|
||||
notifyAutoFillManagerAfterTextChanged();
|
||||
notifyAutoFillManagerAfterTextChangedIfNeeded();
|
||||
}
|
||||
|
||||
// SelectionModifierCursorController depends on textCanBeSelected, which depends on text
|
||||
@@ -9280,12 +9280,15 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
}
|
||||
|
||||
// Always notify AutoFillManager - it will return right away if autofill is disabled.
|
||||
notifyAutoFillManagerAfterTextChanged();
|
||||
notifyAutoFillManagerAfterTextChangedIfNeeded();
|
||||
|
||||
hideErrorIfUnchanged();
|
||||
}
|
||||
|
||||
private void notifyAutoFillManagerAfterTextChanged() {
|
||||
private void notifyAutoFillManagerAfterTextChangedIfNeeded() {
|
||||
if (!isAutofillable()) {
|
||||
return;
|
||||
}
|
||||
final AutofillManager afm = mContext.getSystemService(AutofillManager.class);
|
||||
if (afm != null) {
|
||||
if (DEBUG_AUTOFILL) {
|
||||
|
||||
@@ -28,6 +28,7 @@ import android.annotation.Nullable;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.ActivityManagerInternal;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@@ -49,6 +50,7 @@ import android.os.UserManager;
|
||||
import android.os.UserManagerInternal;
|
||||
import android.provider.Settings;
|
||||
import android.service.autofill.FillEventHistory;
|
||||
import android.text.TextUtils;
|
||||
import android.util.LocalLog;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
@@ -60,6 +62,7 @@ import android.view.autofill.IAutoFillManager;
|
||||
import android.view.autofill.IAutoFillManagerClient;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.content.PackageMonitor;
|
||||
import com.android.internal.os.BackgroundThread;
|
||||
import com.android.internal.os.IResultReceiver;
|
||||
import com.android.internal.util.DumpUtils;
|
||||
@@ -161,6 +164,84 @@ public final class AutofillManagerService extends SystemService {
|
||||
updateCachedServiceLocked(userId, disabledNow);
|
||||
}
|
||||
});
|
||||
startTrackingPackageChanges();
|
||||
}
|
||||
|
||||
|
||||
private void startTrackingPackageChanges() {
|
||||
PackageMonitor monitor = new PackageMonitor() {
|
||||
@Override
|
||||
public void onSomePackagesChanged() {
|
||||
synchronized (mLock) {
|
||||
updateCachedServiceLocked(getChangingUserId());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPackageUpdateFinished(String packageName, int uid) {
|
||||
synchronized (mLock) {
|
||||
final String activePackageName = getActiveAutofillServicePackageName();
|
||||
if (packageName.equals(activePackageName)) {
|
||||
removeCachedServiceLocked(getChangingUserId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPackageRemoved(String packageName, int uid) {
|
||||
synchronized (mLock) {
|
||||
final int userId = getChangingUserId();
|
||||
final AutofillManagerServiceImpl userState = peekServiceForUserLocked(userId);
|
||||
if (userState != null) {
|
||||
final ComponentName componentName = userState.getServiceComponentName();
|
||||
if (componentName != null) {
|
||||
if (packageName.equals(componentName.getPackageName())) {
|
||||
handleActiveAutofillServiceRemoved(userId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onHandleForceStop(Intent intent, String[] packages,
|
||||
int uid, boolean doit) {
|
||||
synchronized (mLock) {
|
||||
final String activePackageName = getActiveAutofillServicePackageName();
|
||||
for (String pkg : packages) {
|
||||
if (pkg.equals(activePackageName)) {
|
||||
if (!doit) {
|
||||
return true;
|
||||
}
|
||||
handleActiveAutofillServiceRemoved(getChangingUserId());
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void handleActiveAutofillServiceRemoved(int userId) {
|
||||
removeCachedServiceLocked(userId);
|
||||
Settings.Secure.putStringForUser(mContext.getContentResolver(),
|
||||
Settings.Secure.AUTOFILL_SERVICE, null, userId);
|
||||
}
|
||||
|
||||
private String getActiveAutofillServicePackageName() {
|
||||
final int userId = getChangingUserId();
|
||||
final AutofillManagerServiceImpl userState = peekServiceForUserLocked(userId);
|
||||
if (userState == null) {
|
||||
return null;
|
||||
}
|
||||
final ComponentName serviceComponent = userState.getServiceComponentName();
|
||||
if (serviceComponent == null) {
|
||||
return null;
|
||||
}
|
||||
return serviceComponent.getPackageName();
|
||||
}
|
||||
};
|
||||
|
||||
// package changes
|
||||
monitor.register(mContext, null, UserHandle.ALL, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -312,6 +393,9 @@ public final class AutofillManagerService extends SystemService {
|
||||
AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
|
||||
if (service != null) {
|
||||
service.updateLocked(disabled);
|
||||
if (!service.isEnabled()) {
|
||||
removeCachedServiceLocked(userId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -53,6 +53,7 @@ import android.util.PrintWriterPrinter;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
import android.view.autofill.AutofillId;
|
||||
import android.view.autofill.AutofillManager;
|
||||
import android.view.autofill.AutofillValue;
|
||||
import android.view.autofill.IAutoFillManagerClient;
|
||||
|
||||
@@ -146,11 +147,20 @@ final class AutofillManagerServiceImpl {
|
||||
}
|
||||
|
||||
String getPackageName() {
|
||||
if (mInfo == null) {
|
||||
return null;
|
||||
final ComponentName serviceComponent = getServiceComponentName();
|
||||
if (serviceComponent != null) {
|
||||
return serviceComponent.getPackageName();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
ComponentName getServiceComponentName() {
|
||||
synchronized (mLock) {
|
||||
if (mInfo == null) {
|
||||
return null;
|
||||
}
|
||||
return mInfo.getServiceInfo().getComponentName();
|
||||
}
|
||||
final ComponentName serviceComponent = mInfo.getServiceInfo().getComponentName();
|
||||
return serviceComponent.getPackageName();
|
||||
}
|
||||
|
||||
private String getComponentNameFromSettings() {
|
||||
@@ -189,7 +199,7 @@ final class AutofillManagerServiceImpl {
|
||||
session.removeSelfLocked();
|
||||
}
|
||||
}
|
||||
sendStateToClients();
|
||||
sendStateToClients(false);
|
||||
}
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
Slog.e(TAG, "Bad autofill service name " + componentName + ": " + e);
|
||||
@@ -240,7 +250,9 @@ final class AutofillManagerServiceImpl {
|
||||
}
|
||||
final Session session = mSessions.get(sessionId);
|
||||
if (session != null && uid == session.uid) {
|
||||
session.setHasCallback(hasIt);
|
||||
synchronized (mLock) {
|
||||
session.setHasCallbackLocked(hasIt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,14 +271,14 @@ final class AutofillManagerServiceImpl {
|
||||
}
|
||||
|
||||
final String historyItem =
|
||||
"id=" + newSession.id + " uid=" + uid + " s=" + mInfo.getServiceInfo().packageName
|
||||
"id=" + newSession.getId() + " uid=" + uid + " s=" + mInfo.getServiceInfo().packageName
|
||||
+ " u=" + mUserId + " i=" + autofillId + " b=" + virtualBounds + " hc=" +
|
||||
hasCallback + " f=" + flags;
|
||||
mRequestsHistory.log(historyItem);
|
||||
|
||||
newSession.updateLocked(autofillId, virtualBounds, value, FLAG_START_SESSION);
|
||||
|
||||
return newSession.id;
|
||||
return newSession.getId();
|
||||
}
|
||||
|
||||
void finishSessionLocked(int sessionId, int uid) {
|
||||
@@ -285,7 +297,7 @@ final class AutofillManagerServiceImpl {
|
||||
Log.d(TAG, "finishSessionLocked(): session finished on save? " + finished);
|
||||
}
|
||||
if (finished) {
|
||||
session.removeSelf();
|
||||
session.removeSelfLocked();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -340,7 +352,7 @@ final class AutofillManagerServiceImpl {
|
||||
final Session newSession = new Session(this, mUi, mContext, mHandlerCaller, mUserId, mLock,
|
||||
sessionId, uid, activityToken, windowToken, appCallbackToken, hasCallback, flags,
|
||||
mInfo.getServiceInfo().getComponentName(), packageName);
|
||||
mSessions.put(newSession.id, newSession);
|
||||
mSessions.put(newSession.getId(), newSession);
|
||||
|
||||
return newSession;
|
||||
}
|
||||
@@ -423,6 +435,8 @@ final class AutofillManagerServiceImpl {
|
||||
mSessions.valueAt(i).destroyLocked();
|
||||
}
|
||||
mSessions.clear();
|
||||
|
||||
sendStateToClients(true);
|
||||
}
|
||||
|
||||
CharSequence getServiceLabel() {
|
||||
@@ -540,7 +554,7 @@ final class AutofillManagerServiceImpl {
|
||||
|
||||
void destroySessionsLocked() {
|
||||
while (mSessions.size() > 0) {
|
||||
mSessions.valueAt(0).removeSelf();
|
||||
mSessions.valueAt(0).removeSelfLocked();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -552,7 +566,7 @@ final class AutofillManagerServiceImpl {
|
||||
}
|
||||
}
|
||||
|
||||
private void sendStateToClients() {
|
||||
private void sendStateToClients(boolean resetClient) {
|
||||
final RemoteCallbackList<IAutoFillManagerClient> clients;
|
||||
final int userClientCount;
|
||||
synchronized (mLock) {
|
||||
@@ -566,7 +580,11 @@ final class AutofillManagerServiceImpl {
|
||||
for (int i = 0; i < userClientCount; i++) {
|
||||
final IAutoFillManagerClient client = clients.getBroadcastItem(i);
|
||||
try {
|
||||
client.setState(isEnabled());
|
||||
final boolean resetSession;
|
||||
synchronized (mLock) {
|
||||
resetSession = resetClient || isClientSessionDestroyedLocked(client);
|
||||
}
|
||||
client.setState(isEnabled(), resetSession, resetClient);
|
||||
} catch (RemoteException re) {
|
||||
/* ignore */
|
||||
}
|
||||
@@ -576,7 +594,18 @@ final class AutofillManagerServiceImpl {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isEnabled() {
|
||||
private boolean isClientSessionDestroyedLocked(IAutoFillManagerClient client) {
|
||||
final int sessionCount = mSessions.size();
|
||||
for (int i = 0; i < sessionCount; i++) {
|
||||
final Session session = mSessions.valueAt(i);
|
||||
if (session.getClient().equals(client)) {
|
||||
return session.isDestroyed();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean isEnabled() {
|
||||
return mInfo != null && !mDisabled;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package com.android.server.autofill;
|
||||
|
||||
import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST;
|
||||
@@ -109,7 +108,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
private static AtomicInteger sIdCounter = new AtomicInteger();
|
||||
|
||||
/** Id of the session */
|
||||
public final int id;
|
||||
private final int mId;
|
||||
|
||||
/** uid the session is for */
|
||||
public final int uid;
|
||||
@@ -171,6 +170,9 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
@GuardedBy("mLock")
|
||||
private Bundle mClientState;
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private boolean mDestroyed;
|
||||
|
||||
/**
|
||||
* Flags used to start the session.
|
||||
*/
|
||||
@@ -333,7 +335,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
@NonNull Object lock, int sessionId, int uid, @NonNull IBinder activityToken,
|
||||
@Nullable IBinder windowToken, @NonNull IBinder client, boolean hasCallback,
|
||||
int flags, @NonNull ComponentName componentName, @NonNull String packageName) {
|
||||
id = sessionId;
|
||||
mId = sessionId;
|
||||
this.uid = uid;
|
||||
mService = service;
|
||||
mLock = lock;
|
||||
@@ -355,7 +357,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
*
|
||||
* @return The activity token
|
||||
*/
|
||||
public IBinder getActivityTokenLocked() {
|
||||
IBinder getActivityTokenLocked() {
|
||||
return mActivityToken;
|
||||
}
|
||||
|
||||
@@ -367,6 +369,11 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
*/
|
||||
void switchWindow(@NonNull IBinder newWindow) {
|
||||
synchronized (mLock) {
|
||||
if (mDestroyed) {
|
||||
Slog.w(TAG, "Call to Session#switchWindow() rejected - session: "
|
||||
+ mId + " destroyed");
|
||||
return;
|
||||
}
|
||||
mWindowToken = newWindow;
|
||||
}
|
||||
}
|
||||
@@ -379,6 +386,11 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
*/
|
||||
void switchActivity(@NonNull IBinder newActivity, @NonNull IBinder newClient) {
|
||||
synchronized (mLock) {
|
||||
if (mDestroyed) {
|
||||
Slog.w(TAG, "Call to Session#switchActivity() rejected - session: "
|
||||
+ mId + " destroyed");
|
||||
return;
|
||||
}
|
||||
mActivityToken = newActivity;
|
||||
mClient = IAutoFillManagerClient.Stub.asInterface(newClient);
|
||||
|
||||
@@ -391,6 +403,13 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
@Override
|
||||
public void onFillRequestSuccess(@Nullable FillResponse response, int serviceUid,
|
||||
@NonNull String servicePackageName) {
|
||||
synchronized (mLock) {
|
||||
if (mDestroyed) {
|
||||
Slog.w(TAG, "Call to Session#onFillRequestSuccess() rejected - session: "
|
||||
+ mId + " destroyed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (response == null) {
|
||||
if ((mFlags & FLAG_MANUAL_REQUEST) != 0) {
|
||||
getUiForShowing().showError(R.string.autofill_error_cannot_autofill);
|
||||
@@ -430,6 +449,13 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
@Override
|
||||
public void onFillRequestFailure(@Nullable CharSequence message,
|
||||
@NonNull String servicePackageName) {
|
||||
synchronized (mLock) {
|
||||
if (mDestroyed) {
|
||||
Slog.w(TAG, "Call to Session#onFillRequestFailure() rejected - session: "
|
||||
+ mId + " destroyed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
LogMaker log = (new LogMaker(MetricsEvent.AUTOFILL_REQUEST))
|
||||
.setType(MetricsEvent.TYPE_FAILURE)
|
||||
.setPackageName(mPackageName)
|
||||
@@ -443,6 +469,13 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
// FillServiceCallbacks
|
||||
@Override
|
||||
public void onSaveRequestSuccess(@NonNull String servicePackageName) {
|
||||
synchronized (mLock) {
|
||||
if (mDestroyed) {
|
||||
Slog.w(TAG, "Call to Session#onSaveRequestSuccess() rejected - session: "
|
||||
+ mId + " destroyed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
LogMaker log = (new LogMaker(
|
||||
MetricsEvent.AUTOFILL_DATA_SAVE_REQUEST))
|
||||
.setType(MetricsEvent.TYPE_SUCCESS)
|
||||
@@ -458,6 +491,13 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
@Override
|
||||
public void onSaveRequestFailure(@Nullable CharSequence message,
|
||||
@NonNull String servicePackageName) {
|
||||
synchronized (mLock) {
|
||||
if (mDestroyed) {
|
||||
Slog.w(TAG, "Call to Session#onSaveRequestFailure() rejected - session: "
|
||||
+ mId + " destroyed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
LogMaker log = (new LogMaker(
|
||||
MetricsEvent.AUTOFILL_DATA_SAVE_REQUEST))
|
||||
.setType(MetricsEvent.TYPE_FAILURE)
|
||||
@@ -498,6 +538,13 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
public void authenticate(int requestId, IntentSender intent, Bundle extras) {
|
||||
final Intent fillInIntent;
|
||||
synchronized (mLock) {
|
||||
synchronized (mLock) {
|
||||
if (mDestroyed) {
|
||||
Slog.w(TAG, "Call to Session#authenticate() rejected - session: "
|
||||
+ mId + " destroyed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
fillInIntent = createAuthFillInIntent(
|
||||
getFillContextByRequestIdLocked(requestId).getStructure(), extras);
|
||||
}
|
||||
@@ -517,19 +564,41 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
@Override
|
||||
public void fill(int requestId, Dataset dataset) {
|
||||
mHandlerCaller.getHandler().post(() -> autoFill(requestId, dataset));
|
||||
synchronized (mLock) {
|
||||
if (mDestroyed) {
|
||||
Slog.w(TAG, "Call to Session#fill() rejected - session: "
|
||||
+ mId + " destroyed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
mHandlerCaller.getHandler().post(() -> autoFill(requestId, dataset));
|
||||
}
|
||||
|
||||
// AutoFillUiCallback
|
||||
@Override
|
||||
public void save() {
|
||||
synchronized (mLock) {
|
||||
if (mDestroyed) {
|
||||
Slog.w(TAG, "Call to Session#save() rejected - session: "
|
||||
+ mId + " destroyed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
mHandlerCaller.getHandler()
|
||||
.obtainMessage(AutofillManagerServiceImpl.MSG_SERVICE_SAVE, id, 0)
|
||||
.obtainMessage(AutofillManagerServiceImpl.MSG_SERVICE_SAVE, mId, 0)
|
||||
.sendToTarget();
|
||||
}
|
||||
|
||||
// AutoFillUiCallback
|
||||
@Override
|
||||
public void cancelSave() {
|
||||
synchronized (mLock) {
|
||||
if (mDestroyed) {
|
||||
Slog.w(TAG, "Call to Session#cancelSave() rejected - session: "
|
||||
+ mId + " destroyed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
mHandlerCaller.getHandler().post(() -> removeSelf());
|
||||
}
|
||||
|
||||
@@ -538,10 +607,15 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
public void requestShowFillUi(AutofillId id, int width, int height,
|
||||
IAutofillWindowPresenter presenter) {
|
||||
synchronized (mLock) {
|
||||
if (mDestroyed) {
|
||||
Slog.w(TAG, "Call to Session#requestShowFillUi() rejected - session: "
|
||||
+ mId + " destroyed");
|
||||
return;
|
||||
}
|
||||
if (id.equals(mCurrentViewId)) {
|
||||
try {
|
||||
final ViewState view = mViewStates.get(id);
|
||||
mClient.requestShowFillUi(this.id, mWindowToken, id, width, height,
|
||||
mClient.requestShowFillUi(mId, mWindowToken, id, width, height,
|
||||
view.getVirtualBounds(), presenter);
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Error requesting to show fill UI", e);
|
||||
@@ -559,8 +633,10 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
@Override
|
||||
public void requestHideFillUi(AutofillId id) {
|
||||
synchronized (mLock) {
|
||||
// NOTE: We allow this call in a destroyed state as the UI is
|
||||
// asked to go away after we get destroyed, so let it do that.
|
||||
try {
|
||||
mClient.requestHideFillUi(this.id, mWindowToken, id);
|
||||
mClient.requestHideFillUi(mId, mWindowToken, id);
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Error requesting to hide fill UI", e);
|
||||
}
|
||||
@@ -571,6 +647,11 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
@Override
|
||||
public void startIntentSender(IntentSender intentSender) {
|
||||
synchronized (mLock) {
|
||||
if (mDestroyed) {
|
||||
Slog.w(TAG, "Call to Session#startIntentSender() rejected - session: "
|
||||
+ mId + " destroyed");
|
||||
return;
|
||||
}
|
||||
removeSelfLocked();
|
||||
}
|
||||
mHandlerCaller.getHandler().post(() -> {
|
||||
@@ -584,7 +665,12 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
});
|
||||
}
|
||||
|
||||
public void setAuthenticationResultLocked(Bundle data) {
|
||||
void setAuthenticationResultLocked(Bundle data) {
|
||||
if (mDestroyed) {
|
||||
Slog.w(TAG, "Call to Session#setAuthenticationResultLocked() rejected - session: "
|
||||
+ mId + " destroyed");
|
||||
return;
|
||||
}
|
||||
if ((mResponseWaitingAuth == null && mDatasetWaitingAuth == null) || data == null) {
|
||||
removeSelf();
|
||||
} else {
|
||||
@@ -619,7 +705,12 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
}
|
||||
}
|
||||
|
||||
public void setHasCallback(boolean hasIt) {
|
||||
void setHasCallbackLocked(boolean hasIt) {
|
||||
if (mDestroyed) {
|
||||
Slog.w(TAG, "Call to Session#setHasCallbackLocked() rejected - session: "
|
||||
+ mId + " destroyed");
|
||||
return;
|
||||
}
|
||||
mHasCallback = hasIt;
|
||||
}
|
||||
|
||||
@@ -629,6 +720,11 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
* @return {@code true} if session is done, or {@code false} if it's pending user action.
|
||||
*/
|
||||
public boolean showSaveLocked() {
|
||||
if (mDestroyed) {
|
||||
Slog.w(TAG, "Call to Session#showSaveLocked() rejected - session: "
|
||||
+ mId + " destroyed");
|
||||
return false;
|
||||
}
|
||||
if (mContexts == null) {
|
||||
Slog.d(TAG, "showSaveLocked(): no contexts");
|
||||
return true;
|
||||
@@ -748,6 +844,12 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
* Calls service when user requested save.
|
||||
*/
|
||||
void callSaveLocked() {
|
||||
if (mDestroyed) {
|
||||
Slog.w(TAG, "Call to Session#callSaveLocked() rejected - session: "
|
||||
+ mId + " destroyed");
|
||||
return;
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "callSaveLocked(): mViewStates=" + mViewStates);
|
||||
}
|
||||
@@ -844,6 +946,11 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
}
|
||||
|
||||
void updateLocked(AutofillId id, Rect virtualBounds, AutofillValue value, int flags) {
|
||||
if (mDestroyed) {
|
||||
Slog.w(TAG, "Call to Session#updateLocked() rejected - session: "
|
||||
+ mId + " destroyed");
|
||||
return;
|
||||
}
|
||||
ViewState viewState = mViewStates.get(id);
|
||||
|
||||
if (viewState == null) {
|
||||
@@ -933,6 +1040,14 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
@Override
|
||||
public void onFillReady(FillResponse response, AutofillId filledId,
|
||||
@Nullable AutofillValue value) {
|
||||
synchronized (mLock) {
|
||||
if (mDestroyed) {
|
||||
Slog.w(TAG, "Call to Session#onFillReady() rejected - session: "
|
||||
+ mId + " destroyed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
String filterText = null;
|
||||
if (value != null && value.isText()) {
|
||||
filterText = value.getTextValue().toString();
|
||||
@@ -941,15 +1056,31 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
getUiForShowing().showFillUi(filledId, response, filterText, mPackageName);
|
||||
}
|
||||
|
||||
String getFlagAsString(int flag) {
|
||||
static String getFlagAsString(int flag) {
|
||||
return DebugUtils.flagsToString(AutofillManager.class, "FLAG_", flag);
|
||||
}
|
||||
|
||||
int getId() {
|
||||
return mId;
|
||||
}
|
||||
|
||||
boolean isDestroyed() {
|
||||
synchronized (mLock) {
|
||||
return mDestroyed;
|
||||
}
|
||||
}
|
||||
|
||||
IAutoFillManagerClient getClient() {
|
||||
synchronized (mLock) {
|
||||
return mClient;
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyUnavailableToClient() {
|
||||
synchronized (mLock) {
|
||||
if (!mHasCallback) return;
|
||||
try {
|
||||
mClient.notifyNoFillUi(id, mWindowToken, mCurrentViewId);
|
||||
mClient.notifyNoFillUi(mId, mWindowToken, mCurrentViewId);
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Error notifying client no fill UI: windowToken=" + mWindowToken
|
||||
+ " id=" + mCurrentViewId, e);
|
||||
@@ -984,7 +1115,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
}
|
||||
|
||||
try {
|
||||
mClient.setTrackedViews(id, trackedViews, saveOnAllViewsInvisible);
|
||||
mClient.setTrackedViews(mId, trackedViews, saveOnAllViewsInvisible);
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "Cannot set tracked ids", e);
|
||||
}
|
||||
@@ -1102,6 +1233,11 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
|
||||
void autoFill(int requestId, Dataset dataset) {
|
||||
synchronized (mLock) {
|
||||
if (mDestroyed) {
|
||||
Slog.w(TAG, "Call to Session#autoFill() rejected - session: "
|
||||
+ mId + " destroyed");
|
||||
return;
|
||||
}
|
||||
// Autofill it directly...
|
||||
if (dataset.getAuthentication() == null) {
|
||||
mService.setDatasetSelected(dataset.getId());
|
||||
@@ -1122,11 +1258,15 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
}
|
||||
|
||||
CharSequence getServiceName() {
|
||||
return mService.getServiceName();
|
||||
synchronized (mLock) {
|
||||
return mService.getServiceName();
|
||||
}
|
||||
}
|
||||
|
||||
FillResponse getResponseWaitingAuth() {
|
||||
return mResponseWaitingAuth;
|
||||
synchronized (mLock) {
|
||||
return mResponseWaitingAuth;
|
||||
}
|
||||
}
|
||||
|
||||
private Intent createAuthFillInIntent(AssistStructure structure, Bundle extras) {
|
||||
@@ -1141,7 +1281,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
private void startAuthentication(IntentSender intent, Intent fillInIntent) {
|
||||
try {
|
||||
synchronized (mLock) {
|
||||
mClient.authenticate(id, intent, fillInIntent);
|
||||
mClient.authenticate(mId, intent, fillInIntent);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Error launching auth intent", e);
|
||||
@@ -1149,7 +1289,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
}
|
||||
|
||||
void dumpLocked(String prefix, PrintWriter pw) {
|
||||
pw.print(prefix); pw.print("id: "); pw.println(id);
|
||||
pw.print(prefix); pw.print("id: "); pw.println(mId);
|
||||
pw.print(prefix); pw.print("uid: "); pw.println(uid);
|
||||
pw.print(prefix); pw.print("mActivityToken: "); pw.println(mActivityToken);
|
||||
pw.print(prefix); pw.print("mFlags: "); pw.println(mFlags);
|
||||
@@ -1158,6 +1298,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
pw.print(prefix); pw.print("mDatasetWaitingAuth: "); pw.println(mDatasetWaitingAuth);
|
||||
pw.print(prefix); pw.print("mCurrentViewId: "); pw.println(mCurrentViewId);
|
||||
pw.print(prefix); pw.print("mViewStates size: "); pw.println(mViewStates.size());
|
||||
pw.print(prefix); pw.print("mDestroyed: "); pw.println(mDestroyed);
|
||||
final String prefix2 = prefix + " ";
|
||||
for (Map.Entry<AutofillId, ViewState> entry : mViewStates.entrySet()) {
|
||||
pw.print(prefix); pw.print("State for id "); pw.println(entry.getKey());
|
||||
@@ -1190,11 +1331,17 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
|
||||
void autoFillApp(Dataset dataset) {
|
||||
synchronized (mLock) {
|
||||
if (mDestroyed) {
|
||||
Slog.w(TAG, "Call to Session#autoFillApp() rejected - session: "
|
||||
+ mId + " destroyed");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "autoFillApp(): the buck is on the app: " + dataset);
|
||||
}
|
||||
mClient.autofill(id, mWindowToken, dataset.getFieldIds(), dataset.getFieldValues());
|
||||
mClient.autofill(mId, mWindowToken, dataset.getFieldIds(),
|
||||
dataset.getFieldValues());
|
||||
setViewStatesLocked(null, dataset, ViewState.STATE_AUTOFILLED);
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "Error autofilling activity: " + e);
|
||||
@@ -1210,12 +1357,17 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
}
|
||||
|
||||
void destroyLocked() {
|
||||
if (mDestroyed) {
|
||||
return;
|
||||
}
|
||||
mRemoteFillService.destroy();
|
||||
mUi.hideAll();
|
||||
mUi.setCallback(null);
|
||||
mDestroyed = true;
|
||||
mMetricsLogger.action(MetricsEvent.AUTOFILL_SESSION_FINISHED, mPackageName);
|
||||
}
|
||||
|
||||
void removeSelf() {
|
||||
private void removeSelf() {
|
||||
synchronized (mLock) {
|
||||
removeSelfLocked();
|
||||
}
|
||||
@@ -1225,8 +1377,13 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
if (VERBOSE) {
|
||||
Slog.v(TAG, "removeSelfLocked()");
|
||||
}
|
||||
if (mDestroyed) {
|
||||
Slog.w(TAG, "Call to Session#removeSelfLocked() rejected - session: "
|
||||
+ mId + " destroyed");
|
||||
return;
|
||||
}
|
||||
destroyLocked();
|
||||
mService.removeSessionLocked(id);
|
||||
mService.removeSessionLocked(mId);
|
||||
}
|
||||
|
||||
private int getLastResponseIndex() {
|
||||
|
||||
Reference in New Issue
Block a user