Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 48f10a2a authored by Svet Ganov's avatar Svet Ganov
Browse files

Handle package changes in autofill manager service

Autofill manager service was not observing package changes thus
we did not properly handle the cases of the service being updated,
added, and removed. Handling, additions is needed to properly
support restore from a backup. Fixed a few missing locks.

Test: all autofill CTS tests pass and manually tested update, add,
      and remove of autofill services.

bug:36638606
bug:36978445

Change-Id: Idd47891774ba2a4e562a1952cbb5a048211fd4e3
parent f9e53950
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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();
    }
+25 −12
Original line number Diff line number Diff line
@@ -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,16 +1036,17 @@ public final class AutofillManager {

        AutofillCallback callback = null;
        synchronized (mLock) {
            if (mSessionId == sessionId) {
            // 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;
                }
            }
        }
        }

        if (callback != null) {
            if (id.isVirtual()) {
@@ -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));
            }
        }

+1 −1
Original line number Diff line number Diff line
@@ -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.
+6 −3
Original line number Diff line number Diff line
@@ -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) {
+84 −0
Original line number Diff line number Diff line
@@ -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);
            }
        }
    }

Loading