Loading core/java/android/view/autofill/AutofillManager.java +36 −2 Original line number Diff line number Diff line Loading @@ -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. * Loading Loading @@ -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); } /** Loading @@ -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, Loading core/java/android/view/autofill/IAutoFillManager.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -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); } services/autofill/java/com/android/server/autofill/AutofillManagerService.java +23 −0 Original line number Diff line number Diff line Loading @@ -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 { Loading services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java +117 −9 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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, Loading Loading @@ -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; Loading Loading @@ -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: "); Loading Loading @@ -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); } Loading Loading @@ -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; Loading services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java +3 −2 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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) { Loading @@ -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 Loading
core/java/android/view/autofill/AutofillManager.java +36 −2 Original line number Diff line number Diff line Loading @@ -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. * Loading Loading @@ -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); } /** Loading @@ -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, Loading
core/java/android/view/autofill/IAutoFillManager.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -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); }
services/autofill/java/com/android/server/autofill/AutofillManagerService.java +23 −0 Original line number Diff line number Diff line Loading @@ -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 { Loading
services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java +117 −9 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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, Loading Loading @@ -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; Loading Loading @@ -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: "); Loading Loading @@ -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); } Loading Loading @@ -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; Loading
services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java +3 −2 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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) { Loading @@ -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