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

Commit 02aca105 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Initial implementation of AutofillManager.setAugmentedAutofillWhitelist()"

parents 788f3a09 80e7bf11
Loading
Loading
Loading
Loading
+36 −2
Original line number Diff line number Diff line
@@ -369,6 +369,11 @@ public final class AutofillManager {
    public static final String DEVICE_CONFIG_AUTOFILL_SMART_SUGGESTION_SUPPORTED_MODES =
            "smart_suggestion_supported_modes";

    /** @hide */
    public static final int RESULT_OK = 0;
    /** @hide */
    public static final int RESULT_CODE_NOT_SERVICE = -1;

    /**
     * Makes an authentication id from a request id and a dataset id.
     *
@@ -1789,7 +1794,11 @@ public final class AutofillManager {
    @Deprecated
    public void setAugmentedAutofillWhitelist(@Nullable List<String> packages,
            @Nullable List<ComponentName> activities) {
        // TODO(b/123100824): implement
        setAugmentedAutofillWhitelist(toSet(packages), toSet(activities));
    }

    private <T> ArraySet<T> toSet(@Nullable List<T> set) {
        return set == null ? null : new ArraySet<T>(set);
    }

    /**
@@ -1814,7 +1823,32 @@ public final class AutofillManager {
    @TestApi
    public void setAugmentedAutofillWhitelist(@Nullable Set<String> packages,
            @Nullable Set<ComponentName> activities) {
        // TODO(b/123100824): implement
        if (!hasAutofillFeature()) {
            return;
        }

        final SyncResultReceiver resultReceiver = new SyncResultReceiver(SYNC_CALLS_TIMEOUT_MS);
        final int resultCode;
        try {
            mService.setAugmentedAutofillWhitelist(toList(packages), toList(activities),
                    resultReceiver);
            resultCode = resultReceiver.getIntResult();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
        switch (resultCode) {
            case RESULT_OK:
                return;
            case RESULT_CODE_NOT_SERVICE:
                throw new SecurityException("caller is not user's Augmented Autofill Service");
            default:
                Log.wtf(TAG, "setAugmentedAutofillWhitelist(): received invalid result: "
                        + resultCode);
        }
    }

    private <T> ArrayList<T> toList(@Nullable Set<T> set) {
        return set == null ? null : new ArrayList<T>(set);
    }

    private void requestShowFillUi(int sessionId, AutofillId id, int width, int height,
+2 −0
Original line number Diff line number Diff line
@@ -63,4 +63,6 @@ oneway interface IAutoFillManager {
    void getAutofillServiceComponentName(in IResultReceiver result);
    void getAvailableFieldClassificationAlgorithms(in IResultReceiver result);
    void getDefaultFieldClassificationAlgorithm(in IResultReceiver result);
    void setAugmentedAutofillWhitelist(in List<String> packages, in List<ComponentName> activities,
        in IResultReceiver result);
}
+23 −0
Original line number Diff line number Diff line
@@ -1025,6 +1025,29 @@ public final class AutofillManagerService
            send(receiver, algorithm);
        }

        @Override
        public void setAugmentedAutofillWhitelist(@Nullable List<String> packages,
                @Nullable List<ComponentName> activities, @NonNull IResultReceiver receiver)
                throws RemoteException {
            final int userId = UserHandle.getCallingUserId();

            boolean ok;
            synchronized (mLock) {
                final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
                if (service != null) {
                    ok = service.setAugmentedAutofillWhitelistLocked(packages, activities,
                            getCallingUid());
                } else {
                    if (sVerbose) {
                        Slog.v(TAG, "setAugmentedAutofillWhitelist(): no service for " + userId);
                    }
                    ok = false;
                }
            }
            send(receiver,
                    ok ? AutofillManager.RESULT_OK : AutofillManager.RESULT_CODE_NOT_SERVICE);
        }

        @Override
        public void getAvailableFieldClassificationAlgorithms(@NonNull IResultReceiver receiver)
                throws RemoteException {
+117 −9
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Process;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.SystemClock;
@@ -58,6 +59,7 @@ import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.DebugUtils;
import android.util.LocalLog;
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
import android.util.TimeUtils;
@@ -165,6 +167,16 @@ final class AutofillManagerServiceImpl
    @Nullable
    private RemoteAugmentedAutofillService mRemoteAugmentedAutofillService;

    @GuardedBy("mLock")
    @Nullable
    private ServiceInfo mRemoteAugmentedAutofillServiceInfo;

    /**
     * List of packages that are whitelisted to be trigger augmented autofill.
     */
    @GuardedBy("mLock")
    private final ArraySet<String> mWhitelistedAugmentAutofillPackages = new ArraySet<>();

    AutofillManagerServiceImpl(AutofillManagerService master, Object lock,
            LocalLog uiLatencyHistory, LocalLog wtfHistory, int userId, AutoFillUI ui,
            AutofillCompatState autofillCompatState,
@@ -844,10 +856,11 @@ final class AutofillManagerServiceImpl
    }

    @GuardedBy("mLock")
    private boolean isCalledByServiceLocked(String methodName, int callingUid) {
        if (getServiceUidLocked() != callingUid) {
    private boolean isCalledByServiceLocked(@NonNull String methodName, int callingUid) {
        final int serviceUid = getServiceUidLocked();
        if (serviceUid != callingUid) {
            Slog.w(TAG, methodName + "() called by UID " + callingUid
                    + ", but service UID is " + getServiceUidLocked());
                    + ", but service UID is " + serviceUid);
            return false;
        }
        return true;
@@ -886,6 +899,19 @@ final class AutofillManagerServiceImpl
            pw.print(prefix); pw.println("RemoteAugmentedAutofillService: ");
            mRemoteAugmentedAutofillService.dump(prefix2, pw);
        }
        if (mRemoteAugmentedAutofillServiceInfo != null) {
            pw.print(prefix); pw.print("RemoteAugmentedAutofillServiceInfo: ");
            pw.println(mRemoteAugmentedAutofillServiceInfo);
        }

        final int whitelistSize = mWhitelistedAugmentAutofillPackages.size();
        pw.print(prefix); pw.print("Packages whitelisted for augmented autofill: ");
        pw.println(whitelistSize);
        for (int i = 0; i < whitelistSize; i++) {
            final String whitelistedPkg = mWhitelistedAugmentAutofillPackages.valueAt(i);
            pw.print(prefix2); pw.print(i + 1); pw.print(": "); pw.println(whitelistedPkg);
        }

        pw.print(prefix); pw.print("Field classification enabled: ");
            pw.println(isFieldClassificationEnabledLocked());
        pw.print(prefix); pw.print("Compat pkgs: ");
@@ -1037,9 +1063,13 @@ final class AutofillManagerServiceImpl
                }
                return null;
            }
            final ComponentName componentName = RemoteAugmentedAutofillService.getComponentName(
            final Pair<ServiceInfo, ComponentName> pair = RemoteAugmentedAutofillService
                    .getComponentName(
                            serviceName, mUserId, mAugmentedAutofillResolver.isTemporary(mUserId));
            if (componentName == null) return null;
            if (pair == null) return null;

            mRemoteAugmentedAutofillServiceInfo = pair.first;
            final ComponentName componentName = pair.second;
            if (sVerbose) {
                Slog.v(TAG, "getRemoteAugmentedAutofillServiceLocked(): " + componentName);
            }
@@ -1067,12 +1097,90 @@ final class AutofillManagerServiceImpl
    private void updateRemoteAugmentedAutofillService(@Nullable String serviceName) {
        if (serviceName == null) {
            if (sVerbose) Slog.v(TAG, "updateRemoteAugmentedAutofillService(): time's up!");
            synchronized (mLock) {
                if (mRemoteAugmentedAutofillService != null) {
                    mRemoteAugmentedAutofillService.destroy();
                    mRemoteAugmentedAutofillService = null;
                }
            }
        }
    }

    /**
     * Sets which packages and activities can trigger augmented autofill.
     *
     * @return whether caller UID is the augmented autofill service for the user
     */
    boolean setAugmentedAutofillWhitelistLocked(List<String> packages,
            List<ComponentName> activities, int callingUid) {

        if (!isCalledByAugmentedAutofillServiceLocked("setAugmentedAutofillWhitelistLocked",
                callingUid)) {
            return false;
        }
        if (mMaster.verbose) {
            Slog.v(TAG, "setAugmentedAutofillWhitelistLocked(packages=" + packages + ", activities="
                    + activities + ")");
        }
        whitelistForAugmentedAutofillPackages(packages);

        // TODO(b/123100824): whitelist activities as well
        // TODO(b/122858578): log metrics
        return true;
    }

    @GuardedBy("mLock")
    private boolean isCalledByAugmentedAutofillServiceLocked(@NonNull String methodName,
            int callingUid) {
        // Lazy load service first
        final RemoteAugmentedAutofillService service = getRemoteAugmentedAutofillServiceLocked();
        if (service == null) {
            Slog.w(TAG, methodName + "() called by UID " + callingUid
                    + ", but there is no augmented autofill service defined for user "
                    + getUserId());
            return false;
        }

        if (getAugmentedAutofillServiceUidLocked() != callingUid) {
            Slog.w(TAG, methodName + "() called by UID " + callingUid
                    + ", but service UID is " + getAugmentedAutofillServiceUidLocked()
                    + " for user " + getUserId());
            return false;
        }
        return true;
    }

    @GuardedBy("mLock")
    private int getAugmentedAutofillServiceUidLocked() {
        if (mRemoteAugmentedAutofillServiceInfo == null) {
            if (mMaster.verbose) {
                Slog.v(TAG, "getAugmentedAutofillServiceUid(): "
                        + "no mRemoteAugmentedAutofillServiceInfo");
            }
            return Process.INVALID_UID;
        }
        return mRemoteAugmentedAutofillServiceInfo.applicationInfo.uid;
    }

    @GuardedBy("mLock")
    boolean isWhitelistedForAugmentedAutofillLocked(@NonNull ComponentName componentName) {
        // TODO(b/122595322): need to check whitelisted activities as well.
        final String packageName = componentName.getPackageName();
        return mWhitelistedAugmentAutofillPackages.contains(packageName);
    }

    private void whitelistForAugmentedAutofillPackages(@NonNull List<String> packages) {
        // TODO(b/123100824): add CTS test for when it's null
        synchronized (mLock) {
            if (packages == null) {
                if (mMaster.verbose) Slog.v(TAG, "clearing all whitelisted augmented packages");
                mWhitelistedAugmentAutofillPackages.clear();
            } else {
                if (mMaster.verbose) Slog.v(TAG, "whitelisting augmented packages: " + packages);
                mWhitelistedAugmentAutofillPackages.addAll(packages);
            }
        }
    }

    private void sendStateToClients(boolean resetClient) {
        final RemoteCallbackList<IAutoFillManagerClient> clients;
+3 −2
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import android.service.autofill.augmented.AugmentedAutofillService;
import android.service.autofill.augmented.IAugmentedAutofillService;
import android.service.autofill.augmented.IFillCallback;
import android.text.format.DateUtils;
import android.util.Pair;
import android.util.Slog;
import android.view.autofill.AutofillId;
import android.view.autofill.AutofillManager;
@@ -57,7 +58,7 @@ final class RemoteAugmentedAutofillService
    }

    @Nullable
    public static ComponentName getComponentName(@NonNull String componentName,
    static Pair<ServiceInfo, ComponentName> getComponentName(@NonNull String componentName,
            @UserIdInt int userId, boolean isTemporary) {
        int flags = PackageManager.GET_META_DATA;
        if (!isTemporary) {
@@ -78,7 +79,7 @@ final class RemoteAugmentedAutofillService
            Slog.e(TAG, "Error getting service info for '" + componentName + "': " + e);
            return null;
        }
        return serviceComponent;
        return new Pair<>(serviceInfo, serviceComponent);
    }

    @Override // from AbstractRemoteService
Loading