1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.autofill;
18 
19 import static android.Manifest.permission.MANAGE_AUTO_FILL;
20 import static android.content.Context.AUTOFILL_MANAGER_SERVICE;
21 import static android.view.autofill.AutofillManager.MAX_TEMP_AUGMENTED_SERVICE_DURATION_MS;
22 import static android.view.autofill.AutofillManager.getSmartSuggestionModeToString;
23 
24 import static com.android.server.autofill.Helper.sDebug;
25 import static com.android.server.autofill.Helper.sFullScreenMode;
26 import static com.android.server.autofill.Helper.sVerbose;
27 
28 import android.annotation.NonNull;
29 import android.annotation.Nullable;
30 import android.annotation.UserIdInt;
31 import android.app.ActivityManagerInternal;
32 import android.app.ActivityThread;
33 import android.content.AutofillOptions;
34 import android.content.BroadcastReceiver;
35 import android.content.ComponentName;
36 import android.content.ContentResolver;
37 import android.content.Context;
38 import android.content.Intent;
39 import android.content.IntentFilter;
40 import android.content.pm.PackageManager;
41 import android.content.pm.UserInfo;
42 import android.database.ContentObserver;
43 import android.graphics.Rect;
44 import android.os.Binder;
45 import android.os.Build;
46 import android.os.Bundle;
47 import android.os.IBinder;
48 import android.os.Parcelable;
49 import android.os.RemoteCallback;
50 import android.os.RemoteException;
51 import android.os.ResultReceiver;
52 import android.os.ShellCallback;
53 import android.os.UserHandle;
54 import android.os.UserManager;
55 import android.provider.DeviceConfig;
56 import android.provider.Settings;
57 import android.service.autofill.FillEventHistory;
58 import android.service.autofill.UserData;
59 import android.text.TextUtils;
60 import android.text.TextUtils.SimpleStringSplitter;
61 import android.util.ArrayMap;
62 import android.util.LocalLog;
63 import android.util.Slog;
64 import android.util.SparseArray;
65 import android.util.SparseBooleanArray;
66 import android.view.autofill.AutofillId;
67 import android.view.autofill.AutofillManager;
68 import android.view.autofill.AutofillManager.SmartSuggestionMode;
69 import android.view.autofill.AutofillManagerInternal;
70 import android.view.autofill.AutofillValue;
71 import android.view.autofill.IAutoFillManager;
72 import android.view.autofill.IAutoFillManagerClient;
73 
74 import com.android.internal.annotations.GuardedBy;
75 import com.android.internal.annotations.VisibleForTesting;
76 import com.android.internal.infra.AbstractRemoteService;
77 import com.android.internal.infra.GlobalWhitelistState;
78 import com.android.internal.infra.WhitelistHelper;
79 import com.android.internal.os.IResultReceiver;
80 import com.android.internal.util.DumpUtils;
81 import com.android.internal.util.Preconditions;
82 import com.android.internal.util.SyncResultReceiver;
83 import com.android.server.FgThread;
84 import com.android.server.LocalServices;
85 import com.android.server.autofill.ui.AutoFillUI;
86 import com.android.server.infra.AbstractMasterSystemService;
87 import com.android.server.infra.FrameworkResourcesServiceNameResolver;
88 import com.android.server.infra.SecureSettingsServiceNameResolver;
89 
90 import java.io.FileDescriptor;
91 import java.io.PrintWriter;
92 import java.util.ArrayList;
93 import java.util.Arrays;
94 import java.util.List;
95 import java.util.Map;
96 import java.util.Objects;
97 import java.util.Set;
98 
99 /**
100  * Entry point service for autofill management.
101  *
102  * <p>This service provides the {@link IAutoFillManager} implementation and keeps a list of
103  * {@link AutofillManagerServiceImpl} per user; the real work is done by
104  * {@link AutofillManagerServiceImpl} itself.
105  */
106 public final class AutofillManagerService
107         extends AbstractMasterSystemService<AutofillManagerService, AutofillManagerServiceImpl> {
108 
109     private static final String TAG = "AutofillManagerService";
110 
111     private static final Object sLock = AutofillManagerService.class;
112 
113     static final String RECEIVER_BUNDLE_EXTRA_SESSIONS = "sessions";
114 
115     private static final char COMPAT_PACKAGE_DELIMITER = ':';
116     private static final char COMPAT_PACKAGE_URL_IDS_DELIMITER = ',';
117     private static final char COMPAT_PACKAGE_URL_IDS_BLOCK_BEGIN = '[';
118     private static final char COMPAT_PACKAGE_URL_IDS_BLOCK_END = ']';
119 
120     private static final int DEFAULT_AUGMENTED_AUTOFILL_REQUEST_TIMEOUT_MILLIS = 5_000;
121 
122     /**
123      * Maximum number of partitions that can be allowed in a session.
124      *
125      * <p>Can be modified using {@code cmd autofill set max_partitions} or through
126      * {@link android.provider.Settings.Global#AUTOFILL_MAX_PARTITIONS_SIZE}.
127      */
128     @GuardedBy("sLock")
129     private static int sPartitionMaxCount = AutofillManager.DEFAULT_MAX_PARTITIONS_SIZE;
130 
131     /**
132      * Maximum number of visible datasets in the dataset picker UI, or {@code 0} to use default
133      * value from resources.
134      *
135      * <p>Can be modified using {@code cmd autofill set max_visible_datasets} or through
136      * {@link android.provider.Settings.Global#AUTOFILL_MAX_VISIBLE_DATASETS}.
137      */
138     @GuardedBy("sLock")
139     private static int sVisibleDatasetsMaxCount = 0;
140 
141     /**
142      * Object used to set the name of the augmented autofill service.
143      */
144     @NonNull
145     final FrameworkResourcesServiceNameResolver mAugmentedAutofillResolver;
146 
147     private final AutoFillUI mUi;
148 
149     private final LocalLog mRequestsHistory = new LocalLog(20);
150     private final LocalLog mUiLatencyHistory = new LocalLog(20);
151     private final LocalLog mWtfHistory = new LocalLog(50);
152 
153     private final AutofillCompatState mAutofillCompatState = new AutofillCompatState();
154 
155     private final LocalService mLocalService = new LocalService();
156     private final ActivityManagerInternal mAm;
157 
158     private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
159         @Override
160         public void onReceive(Context context, Intent intent) {
161             if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction())) {
162                 if (sDebug) Slog.d(TAG, "Close system dialogs");
163 
164                 // TODO(b/64940307): we need to destroy all sessions that are finished but showing
165                 // Save UI because there is no way to show the Save UI back when the activity
166                 // beneath it is brought back to top. Ideally, we should just hide the UI and
167                 // bring it back when the activity resumes.
168                 synchronized (mLock) {
169                     visitServicesLocked((s) -> s.destroyFinishedSessionsLocked());
170                 }
171                 mUi.hideAll(null);
172             }
173         }
174     };
175 
176     /**
177      * Supported modes for Augmented Autofill Smart Suggestions.
178      */
179     @GuardedBy("mLock")
180     private int mSupportedSmartSuggestionModes;
181 
182     @GuardedBy("mLock")
183     int mAugmentedServiceIdleUnbindTimeoutMs;
184     @GuardedBy("mLock")
185     int mAugmentedServiceRequestTimeoutMs;
186 
187     final AugmentedAutofillState mAugmentedAutofillState = new AugmentedAutofillState();
188 
AutofillManagerService(Context context)189     public AutofillManagerService(Context context) {
190         super(context,
191                 new SecureSettingsServiceNameResolver(context, Settings.Secure.AUTOFILL_SERVICE),
192                 UserManager.DISALLOW_AUTOFILL);
193         mUi = new AutoFillUI(ActivityThread.currentActivityThread().getSystemUiContext());
194         mAm = LocalServices.getService(ActivityManagerInternal.class);
195 
196         DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_AUTOFILL,
197                 ActivityThread.currentApplication().getMainExecutor(),
198                 (properties) -> onDeviceConfigChange(properties.getKeyset()));
199 
200         setLogLevelFromSettings();
201         setMaxPartitionsFromSettings();
202         setMaxVisibleDatasetsFromSettings();
203         setDeviceConfigProperties();
204 
205         final IntentFilter filter = new IntentFilter();
206         filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
207         context.registerReceiver(mBroadcastReceiver, filter, null, FgThread.getHandler());
208 
209         mAugmentedAutofillResolver = new FrameworkResourcesServiceNameResolver(getContext(),
210                 com.android.internal.R.string.config_defaultAugmentedAutofillService);
211         mAugmentedAutofillResolver.setOnTemporaryServiceNameChangedCallback(
212                 (u, s, t) -> onAugmentedServiceNameChanged(u, s, t));
213 
214         if (mSupportedSmartSuggestionModes != AutofillManager.FLAG_SMART_SUGGESTION_OFF) {
215             final UserManager um = getContext().getSystemService(UserManager.class);
216             final List<UserInfo> users = um.getUsers();
217             for (int i = 0; i < users.size(); i++) {
218                 final int userId = users.get(i).id;
219                 // Must eager load the services so they bind to the augmented autofill service
220                 getServiceForUserLocked(userId);
221 
222                 // And also set the global state
223                 mAugmentedAutofillState.setServiceInfo(userId,
224                         mAugmentedAutofillResolver.getServiceName(userId),
225                         mAugmentedAutofillResolver.isTemporary(userId));
226             }
227         }
228     }
229 
230     @Override // from AbstractMasterSystemService
getServiceSettingsProperty()231     protected String getServiceSettingsProperty() {
232         return Settings.Secure.AUTOFILL_SERVICE;
233     }
234 
235     @Override // from AbstractMasterSystemService
registerForExtraSettingsChanges(@onNull ContentResolver resolver, @NonNull ContentObserver observer)236     protected void registerForExtraSettingsChanges(@NonNull ContentResolver resolver,
237             @NonNull ContentObserver observer) {
238         resolver.registerContentObserver(Settings.Global.getUriFor(
239                 Settings.Global.AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES), false, observer,
240                 UserHandle.USER_ALL);
241         resolver.registerContentObserver(Settings.Global.getUriFor(
242                 Settings.Global.AUTOFILL_LOGGING_LEVEL), false, observer,
243                 UserHandle.USER_ALL);
244         resolver.registerContentObserver(Settings.Global.getUriFor(
245                 Settings.Global.AUTOFILL_MAX_PARTITIONS_SIZE), false, observer,
246                 UserHandle.USER_ALL);
247         resolver.registerContentObserver(Settings.Global.getUriFor(
248                 Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS), false, observer,
249                 UserHandle.USER_ALL);
250     }
251 
252     @Override // from AbstractMasterSystemService
onSettingsChanged(int userId, @NonNull String property)253     protected void onSettingsChanged(int userId, @NonNull String property) {
254         switch (property) {
255             case Settings.Global.AUTOFILL_LOGGING_LEVEL:
256                 setLogLevelFromSettings();
257                 break;
258             case Settings.Global.AUTOFILL_MAX_PARTITIONS_SIZE:
259                 setMaxPartitionsFromSettings();
260                 break;
261             case Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS:
262                 setMaxVisibleDatasetsFromSettings();
263                 break;
264             default:
265                 Slog.w(TAG, "Unexpected property (" + property + "); updating cache instead");
266                 // fall through
267             case Settings.Global.AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES:
268                 synchronized (mLock) {
269                     updateCachedServiceLocked(userId);
270                 }
271         }
272     }
273 
onDeviceConfigChange(@onNull Set<String> keys)274     private void onDeviceConfigChange(@NonNull Set<String> keys) {
275         for (String key : keys) {
276             switch (key) {
277                 case AutofillManager.DEVICE_CONFIG_AUTOFILL_SMART_SUGGESTION_SUPPORTED_MODES:
278                 case AutofillManager.DEVICE_CONFIG_AUGMENTED_SERVICE_IDLE_UNBIND_TIMEOUT:
279                 case AutofillManager.DEVICE_CONFIG_AUGMENTED_SERVICE_REQUEST_TIMEOUT:
280                     setDeviceConfigProperties();
281                     break;
282                 default:
283                     Slog.i(mTag, "Ignoring change on " + key);
284             }
285         }
286     }
287 
onAugmentedServiceNameChanged(@serIdInt int userId, @Nullable String serviceName, boolean isTemporary)288     private void onAugmentedServiceNameChanged(@UserIdInt int userId, @Nullable String serviceName,
289             boolean isTemporary) {
290         mAugmentedAutofillState.setServiceInfo(userId, serviceName, isTemporary);
291         synchronized (mLock) {
292             getServiceForUserLocked(userId).updateRemoteAugmentedAutofillService();
293         }
294     }
295 
296     @Override // from AbstractMasterSystemService
newServiceLocked(@serIdInt int resolvedUserId, boolean disabled)297     protected AutofillManagerServiceImpl newServiceLocked(@UserIdInt int resolvedUserId,
298             boolean disabled) {
299         return new AutofillManagerServiceImpl(this, mLock, mUiLatencyHistory,
300                 mWtfHistory, resolvedUserId, mUi, mAutofillCompatState, disabled);
301     }
302 
303     @Override // AbstractMasterSystemService
onServiceRemoved(@onNull AutofillManagerServiceImpl service, @UserIdInt int userId)304     protected void onServiceRemoved(@NonNull AutofillManagerServiceImpl service,
305             @UserIdInt int userId) {
306         service.destroyLocked();
307         mAutofillCompatState.removeCompatibilityModeRequests(userId);
308     }
309 
310     @Override // from AbstractMasterSystemService
onServiceEnabledLocked(@onNull AutofillManagerServiceImpl service, @UserIdInt int userId)311     protected void onServiceEnabledLocked(@NonNull AutofillManagerServiceImpl service,
312             @UserIdInt int userId) {
313         addCompatibilityModeRequestsLocked(service, userId);
314     }
315 
316     @Override // from AbstractMasterSystemService
enforceCallingPermissionForManagement()317     protected void enforceCallingPermissionForManagement() {
318         getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
319     }
320 
321     @Override // from SystemService
onStart()322     public void onStart() {
323         publishBinderService(AUTOFILL_MANAGER_SERVICE, new AutoFillManagerServiceStub());
324         publishLocalService(AutofillManagerInternal.class, mLocalService);
325     }
326 
327     @Override // from SystemService
onSwitchUser(int userHandle)328     public void onSwitchUser(int userHandle) {
329         if (sDebug) Slog.d(TAG, "Hiding UI when user switched");
330         mUi.hideAll(null);
331     }
332 
getSupportedSmartSuggestionModesLocked()333     @SmartSuggestionMode int getSupportedSmartSuggestionModesLocked() {
334         return mSupportedSmartSuggestionModes;
335     }
336 
337     /**
338      * Logs a request so it's dumped later...
339      */
logRequestLocked(@onNull String historyItem)340     void logRequestLocked(@NonNull String historyItem) {
341         mRequestsHistory.log(historyItem);
342     }
343 
344     // Called by AutofillManagerServiceImpl, doesn't need to check permission
isInstantServiceAllowed()345     boolean isInstantServiceAllowed() {
346         return mAllowInstantService;
347     }
348 
349     // Called by Shell command.
destroySessions(@serIdInt int userId, IResultReceiver receiver)350     void destroySessions(@UserIdInt int userId, IResultReceiver receiver) {
351         Slog.i(TAG, "destroySessions() for userId " + userId);
352         enforceCallingPermissionForManagement();
353 
354         synchronized (mLock) {
355             if (userId != UserHandle.USER_ALL) {
356                 AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
357                 if (service != null) {
358                     service.destroySessionsLocked();
359                 }
360             } else {
361                 visitServicesLocked((s) -> s.destroySessionsLocked());
362             }
363         }
364 
365         try {
366             receiver.send(0, new Bundle());
367         } catch (RemoteException e) {
368             // Just ignore it...
369         }
370     }
371 
372     // Called by Shell command.
listSessions(int userId, IResultReceiver receiver)373     void listSessions(int userId, IResultReceiver receiver) {
374         Slog.i(TAG, "listSessions() for userId " + userId);
375         enforceCallingPermissionForManagement();
376 
377         final Bundle resultData = new Bundle();
378         final ArrayList<String> sessions = new ArrayList<>();
379 
380         synchronized (mLock) {
381             if (userId != UserHandle.USER_ALL) {
382                 AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
383                 if (service != null) {
384                     service.listSessionsLocked(sessions);
385                 }
386             } else {
387                 visitServicesLocked((s) -> s.listSessionsLocked(sessions));
388             }
389         }
390 
391         resultData.putStringArrayList(RECEIVER_BUNDLE_EXTRA_SESSIONS, sessions);
392         try {
393             receiver.send(0, resultData);
394         } catch (RemoteException e) {
395             // Just ignore it...
396         }
397     }
398 
399     // Called by Shell command.
reset()400     void reset() {
401         Slog.i(TAG, "reset()");
402         enforceCallingPermissionForManagement();
403 
404         synchronized (mLock) {
405             visitServicesLocked((s) -> s.destroyLocked());
406             clearCacheLocked();
407         }
408     }
409 
410     // Called by Shell command.
setLogLevel(int level)411     void setLogLevel(int level) {
412         Slog.i(TAG, "setLogLevel(): " + level);
413         enforceCallingPermissionForManagement();
414 
415         final long token = Binder.clearCallingIdentity();
416         try {
417             Settings.Global.putInt(getContext().getContentResolver(),
418                     Settings.Global.AUTOFILL_LOGGING_LEVEL, level);
419         } finally {
420             Binder.restoreCallingIdentity(token);
421         }
422     }
423 
setLogLevelFromSettings()424     private void setLogLevelFromSettings() {
425         final int level = Settings.Global.getInt(
426                 getContext().getContentResolver(),
427                 Settings.Global.AUTOFILL_LOGGING_LEVEL, AutofillManager.DEFAULT_LOGGING_LEVEL);
428         boolean debug = false;
429         boolean verbose = false;
430         if (level != AutofillManager.NO_LOGGING) {
431             if (level == AutofillManager.FLAG_ADD_CLIENT_VERBOSE) {
432                 debug = verbose = true;
433             } else if (level == AutofillManager.FLAG_ADD_CLIENT_DEBUG) {
434                 debug = true;
435             } else {
436                 Slog.w(TAG,  "setLogLevelFromSettings(): invalid level: " + level);
437             }
438         }
439         if (debug || sDebug) {
440             Slog.d(TAG, "setLogLevelFromSettings(): level=" + level + ", debug=" + debug
441                     + ", verbose=" + verbose);
442         }
443         synchronized (mLock) {
444             setLoggingLevelsLocked(debug, verbose);
445         }
446     }
447 
448     // Called by Shell command.
getLogLevel()449     int getLogLevel() {
450         enforceCallingPermissionForManagement();
451 
452         synchronized (mLock) {
453             if (sVerbose) return AutofillManager.FLAG_ADD_CLIENT_VERBOSE;
454             if (sDebug) return AutofillManager.FLAG_ADD_CLIENT_DEBUG;
455             return 0;
456         }
457     }
458 
459     // Called by Shell command.
getMaxPartitions()460     int getMaxPartitions() {
461         enforceCallingPermissionForManagement();
462 
463         synchronized (mLock) {
464             return sPartitionMaxCount;
465         }
466     }
467 
468     // Called by Shell command.
setMaxPartitions(int max)469     void setMaxPartitions(int max) {
470         Slog.i(TAG, "setMaxPartitions(): " + max);
471         enforceCallingPermissionForManagement();
472 
473         final long token = Binder.clearCallingIdentity();
474         try {
475             Settings.Global.putInt(getContext().getContentResolver(),
476                     Settings.Global.AUTOFILL_MAX_PARTITIONS_SIZE, max);
477         } finally {
478             Binder.restoreCallingIdentity(token);
479         }
480     }
481 
setMaxPartitionsFromSettings()482     private void setMaxPartitionsFromSettings() {
483         final int max = Settings.Global.getInt(getContext().getContentResolver(),
484                 Settings.Global.AUTOFILL_MAX_PARTITIONS_SIZE,
485                 AutofillManager.DEFAULT_MAX_PARTITIONS_SIZE);
486         if (sDebug) Slog.d(TAG, "setMaxPartitionsFromSettings(): " + max);
487 
488         synchronized (sLock) {
489             sPartitionMaxCount = max;
490         }
491     }
492 
493     // Called by Shell command.
getMaxVisibleDatasets()494     int getMaxVisibleDatasets() {
495         enforceCallingPermissionForManagement();
496 
497         synchronized (sLock) {
498             return sVisibleDatasetsMaxCount;
499         }
500     }
501 
502     // Called by Shell command.
setMaxVisibleDatasets(int max)503     void setMaxVisibleDatasets(int max) {
504         Slog.i(TAG, "setMaxVisibleDatasets(): " + max);
505         enforceCallingPermissionForManagement();
506 
507         final long token = Binder.clearCallingIdentity();
508         try {
509             Settings.Global.putInt(getContext().getContentResolver(),
510                     Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS, max);
511         } finally {
512             Binder.restoreCallingIdentity(token);
513         }
514     }
515 
setMaxVisibleDatasetsFromSettings()516     private void setMaxVisibleDatasetsFromSettings() {
517         final int max = Settings.Global.getInt(getContext().getContentResolver(),
518                 Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS, 0);
519 
520         if (sDebug) Slog.d(TAG, "setMaxVisibleDatasetsFromSettings(): " + max);
521         synchronized (sLock) {
522             sVisibleDatasetsMaxCount = max;
523         }
524     }
525 
setDeviceConfigProperties()526     private void setDeviceConfigProperties() {
527         synchronized (mLock) {
528             mAugmentedServiceIdleUnbindTimeoutMs = DeviceConfig.getInt(
529                     DeviceConfig.NAMESPACE_AUTOFILL,
530                     AutofillManager.DEVICE_CONFIG_AUGMENTED_SERVICE_IDLE_UNBIND_TIMEOUT,
531                     (int) AbstractRemoteService.PERMANENT_BOUND_TIMEOUT_MS);
532             mAugmentedServiceRequestTimeoutMs = DeviceConfig.getInt(
533                     DeviceConfig.NAMESPACE_AUTOFILL,
534                     AutofillManager.DEVICE_CONFIG_AUGMENTED_SERVICE_REQUEST_TIMEOUT,
535                     DEFAULT_AUGMENTED_AUTOFILL_REQUEST_TIMEOUT_MILLIS);
536             mSupportedSmartSuggestionModes = DeviceConfig.getInt(
537                     DeviceConfig.NAMESPACE_AUTOFILL,
538                     AutofillManager.DEVICE_CONFIG_AUTOFILL_SMART_SUGGESTION_SUPPORTED_MODES,
539                     AutofillManager.FLAG_SMART_SUGGESTION_SYSTEM);
540             if (verbose) {
541                 Slog.v(mTag, "setDeviceConfigProperties(): "
542                         + "augmentedIdleTimeout=" + mAugmentedServiceIdleUnbindTimeoutMs
543                         + ", augmentedRequestTimeout=" + mAugmentedServiceRequestTimeoutMs
544                         + ", smartSuggestionMode="
545                         + getSmartSuggestionModeToString(mSupportedSmartSuggestionModes));
546             }
547         }
548     }
549 
550     // Called by Shell command.
calculateScore(@ullable String algorithmName, @NonNull String value1, @NonNull String value2, @NonNull RemoteCallback callback)551     void calculateScore(@Nullable String algorithmName, @NonNull String value1,
552             @NonNull String value2, @NonNull RemoteCallback callback) {
553         enforceCallingPermissionForManagement();
554 
555         final FieldClassificationStrategy strategy =
556                 new FieldClassificationStrategy(getContext(), UserHandle.USER_CURRENT);
557 
558         strategy.calculateScores(callback, Arrays.asList(AutofillValue.forText(value1)),
559                 new String[] { value2 }, new String[] { null }, algorithmName, null, null, null);
560     }
561 
562     // Called by Shell command.
getFullScreenMode()563     Boolean getFullScreenMode() {
564         enforceCallingPermissionForManagement();
565         return sFullScreenMode;
566     }
567 
568     // Called by Shell command.
setFullScreenMode(@ullable Boolean mode)569     void setFullScreenMode(@Nullable Boolean mode) {
570         enforceCallingPermissionForManagement();
571         sFullScreenMode = mode;
572     }
573 
574     // Called by Shell command.
setTemporaryAugmentedAutofillService(@serIdInt int userId, @NonNull String serviceName, int durationMs)575     void setTemporaryAugmentedAutofillService(@UserIdInt int userId, @NonNull String serviceName,
576             int durationMs) {
577         Slog.i(mTag, "setTemporaryAugmentedAutofillService(" + userId + ") to " + serviceName
578                 + " for " + durationMs + "ms");
579         enforceCallingPermissionForManagement();
580 
581         Preconditions.checkNotNull(serviceName);
582         if (durationMs > MAX_TEMP_AUGMENTED_SERVICE_DURATION_MS) {
583             throw new IllegalArgumentException("Max duration is "
584                     + MAX_TEMP_AUGMENTED_SERVICE_DURATION_MS + " (called with " + durationMs + ")");
585         }
586 
587         mAugmentedAutofillResolver.setTemporaryService(userId, serviceName, durationMs);
588     }
589 
590     // Called by Shell command
resetTemporaryAugmentedAutofillService(@serIdInt int userId)591     void resetTemporaryAugmentedAutofillService(@UserIdInt int userId) {
592         enforceCallingPermissionForManagement();
593         mAugmentedAutofillResolver.resetTemporaryService(userId);
594     }
595 
596     // Called by Shell command
isDefaultAugmentedServiceEnabled(@serIdInt int userId)597     boolean isDefaultAugmentedServiceEnabled(@UserIdInt int userId) {
598         enforceCallingPermissionForManagement();
599         return mAugmentedAutofillResolver.isDefaultServiceEnabled(userId);
600     }
601 
602     // Called by Shell command
setDefaultAugmentedServiceEnabled(@serIdInt int userId, boolean enabled)603     boolean setDefaultAugmentedServiceEnabled(@UserIdInt int userId, boolean enabled) {
604         Slog.i(mTag, "setDefaultAugmentedServiceEnabled() for userId " + userId + ": " + enabled);
605         enforceCallingPermissionForManagement();
606 
607         synchronized (mLock) {
608             final AutofillManagerServiceImpl service = getServiceForUserLocked(userId);
609             if (service != null) {
610                 final boolean changed = mAugmentedAutofillResolver
611                         .setDefaultServiceEnabled(userId, enabled);
612                 if (changed) {
613                     service.updateRemoteAugmentedAutofillService();
614                     return true;
615                 } else {
616                     if (debug) {
617                         Slog.d(TAG, "setDefaultAugmentedServiceEnabled(): already " + enabled);
618                     }
619                 }
620             }
621         }
622         return false;
623     }
624 
setLoggingLevelsLocked(boolean debug, boolean verbose)625     private void setLoggingLevelsLocked(boolean debug, boolean verbose) {
626         com.android.server.autofill.Helper.sDebug = debug;
627         android.view.autofill.Helper.sDebug = debug;
628         this.debug = debug;
629 
630         com.android.server.autofill.Helper.sVerbose = verbose;
631         android.view.autofill.Helper.sVerbose = verbose;
632         this.verbose = verbose;
633     }
634 
addCompatibilityModeRequestsLocked(@onNull AutofillManagerServiceImpl service , int userId)635     private void addCompatibilityModeRequestsLocked(@NonNull AutofillManagerServiceImpl service
636             , int userId) {
637         mAutofillCompatState.reset(userId);
638         final ArrayMap<String, Long> compatPackages =
639                 service.getCompatibilityPackagesLocked();
640         if (compatPackages == null || compatPackages.isEmpty()) {
641             return;
642         }
643 
644         final Map<String, String[]> whiteListedPackages = getWhitelistedCompatModePackages();
645         final int compatPackageCount = compatPackages.size();
646         for (int i = 0; i < compatPackageCount; i++) {
647             final String packageName = compatPackages.keyAt(i);
648             if (whiteListedPackages == null || !whiteListedPackages.containsKey(packageName)) {
649                 Slog.w(TAG, "Ignoring not whitelisted compat package " + packageName);
650                 continue;
651             }
652             final Long maxVersionCode = compatPackages.valueAt(i);
653             if (maxVersionCode != null) {
654                 mAutofillCompatState.addCompatibilityModeRequest(packageName,
655                         maxVersionCode, whiteListedPackages.get(packageName), userId);
656             }
657         }
658     }
659 
getWhitelistedCompatModePackagesFromSettings()660     private String getWhitelistedCompatModePackagesFromSettings() {
661         return Settings.Global.getString(
662                 getContext().getContentResolver(),
663                 Settings.Global.AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES);
664     }
665 
666     @Nullable
getWhitelistedCompatModePackages()667     private Map<String, String[]> getWhitelistedCompatModePackages() {
668         return getWhitelistedCompatModePackages(getWhitelistedCompatModePackagesFromSettings());
669     }
670 
send(@onNull IResultReceiver receiver, int value)671     private void send(@NonNull IResultReceiver receiver, int value) {
672         try {
673             receiver.send(value, null);
674         } catch (RemoteException e) {
675             Slog.w(TAG, "Error async reporting result to client: " + e);
676         }
677     }
678 
send(@onNull IResultReceiver receiver, @NonNull Bundle value)679     private void send(@NonNull IResultReceiver receiver, @NonNull Bundle value) {
680         try {
681             receiver.send(0, value);
682         } catch (RemoteException e) {
683             Slog.w(TAG, "Error async reporting result to client: " + e);
684         }
685     }
686 
send(@onNull IResultReceiver receiver, @Nullable String value)687     private void send(@NonNull IResultReceiver receiver, @Nullable String value) {
688         send(receiver, SyncResultReceiver.bundleFor(value));
689     }
690 
send(@onNull IResultReceiver receiver, @Nullable String[] value)691     private void send(@NonNull IResultReceiver receiver, @Nullable String[] value) {
692         send(receiver, SyncResultReceiver.bundleFor(value));
693     }
694 
send(@onNull IResultReceiver receiver, @Nullable Parcelable value)695     private void send(@NonNull IResultReceiver receiver, @Nullable Parcelable value) {
696         send(receiver, SyncResultReceiver.bundleFor(value));
697     }
698 
send(@onNull IResultReceiver receiver, boolean value)699     private void send(@NonNull IResultReceiver receiver, boolean value) {
700         send(receiver, value ? 1 : 0);
701     }
702 
send(@onNull IResultReceiver receiver, int value1, int value2)703     private void send(@NonNull IResultReceiver receiver, int value1, int value2) {
704         try {
705             receiver.send(value1, SyncResultReceiver.bundleFor(value2));
706         } catch (RemoteException e) {
707             Slog.w(TAG, "Error async reporting result to client: " + e);
708         }
709     }
710 
711     @Nullable
712     @VisibleForTesting
getWhitelistedCompatModePackages(String setting)713     static Map<String, String[]> getWhitelistedCompatModePackages(String setting) {
714         if (TextUtils.isEmpty(setting)) {
715             return null;
716         }
717 
718         final ArrayMap<String, String[]> compatPackages = new ArrayMap<>();
719         final SimpleStringSplitter splitter = new SimpleStringSplitter(COMPAT_PACKAGE_DELIMITER);
720         splitter.setString(setting);
721         while (splitter.hasNext()) {
722             final String packageBlock = splitter.next();
723             final int urlBlockIndex = packageBlock.indexOf(COMPAT_PACKAGE_URL_IDS_BLOCK_BEGIN);
724             final String packageName;
725             final List<String> urlBarIds;
726             if (urlBlockIndex == -1) {
727                 packageName = packageBlock;
728                 urlBarIds = null;
729             } else {
730                 if (packageBlock.charAt(packageBlock.length() - 1)
731                         != COMPAT_PACKAGE_URL_IDS_BLOCK_END) {
732                     Slog.w(TAG, "Ignoring entry '" + packageBlock + "' on '" + setting
733                             + "'because it does not end on '" + COMPAT_PACKAGE_URL_IDS_BLOCK_END +
734                             "'");
735                     continue;
736                 }
737                 packageName = packageBlock.substring(0, urlBlockIndex);
738                 urlBarIds = new ArrayList<>();
739                 final String urlBarIdsBlock =
740                         packageBlock.substring(urlBlockIndex + 1, packageBlock.length() - 1);
741                 if (sVerbose) {
742                     Slog.v(TAG, "pkg:" + packageName + ": block:" + packageBlock + ": urls:"
743                             + urlBarIds + ": block:" + urlBarIdsBlock + ":");
744                 }
745                 final SimpleStringSplitter splitter2 =
746                         new SimpleStringSplitter(COMPAT_PACKAGE_URL_IDS_DELIMITER);
747                 splitter2.setString(urlBarIdsBlock);
748                 while (splitter2.hasNext()) {
749                     final String urlBarId = splitter2.next();
750                     urlBarIds.add(urlBarId);
751                 }
752             }
753             if (urlBarIds == null) {
754                 compatPackages.put(packageName, null);
755             } else {
756                 final String[] urlBarIdsArray = new String[urlBarIds.size()];
757                 urlBarIds.toArray(urlBarIdsArray);
758                 compatPackages.put(packageName, urlBarIdsArray);
759             }
760         }
761         return compatPackages;
762     }
763 
764     /**
765      * Gets the maximum number of partitions / fill requests.
766      */
getPartitionMaxCount()767     public static int getPartitionMaxCount() {
768         synchronized (sLock) {
769             return sPartitionMaxCount;
770         }
771     }
772 
773     /**
774      * Gets the maxium number of datasets visible in the UI.
775      */
getVisibleDatasetsMaxCount()776     public static int getVisibleDatasetsMaxCount() {
777         synchronized (sLock) {
778             return sVisibleDatasetsMaxCount;
779         }
780     }
781 
782     private final class LocalService extends AutofillManagerInternal {
783         @Override
onBackKeyPressed()784         public void onBackKeyPressed() {
785             if (sDebug) Slog.d(TAG, "onBackKeyPressed()");
786             mUi.hideAll(null);
787             synchronized (mLock) {
788                 final AutofillManagerServiceImpl service =
789                         getServiceForUserLocked(UserHandle.getCallingUserId());
790                 service.onBackKeyPressed();
791             }
792         }
793 
794         @Override
getAutofillOptions(@onNull String packageName, long versionCode, @UserIdInt int userId)795         public AutofillOptions getAutofillOptions(@NonNull String packageName,
796                 long versionCode, @UserIdInt int userId) {
797             final int loggingLevel;
798             if (verbose) {
799                 loggingLevel = AutofillManager.FLAG_ADD_CLIENT_VERBOSE
800                         | AutofillManager.FLAG_ADD_CLIENT_DEBUG;
801             } else if (debug) {
802                 loggingLevel = AutofillManager.FLAG_ADD_CLIENT_DEBUG;
803             } else {
804                 loggingLevel = AutofillManager.NO_LOGGING;
805             }
806             final boolean compatModeEnabled = mAutofillCompatState.isCompatibilityModeRequested(
807                     packageName, versionCode, userId);
808             final AutofillOptions options = new AutofillOptions(loggingLevel, compatModeEnabled);
809             mAugmentedAutofillState.injectAugmentedAutofillInfo(options, userId, packageName);
810             return options;
811         }
812 
813         @Override
isAugmentedAutofillServiceForUser(int callingUid, int userId)814         public boolean isAugmentedAutofillServiceForUser(int callingUid, int userId) {
815             synchronized (mLock) {
816                 final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
817                 if (service != null) {
818                     return service.isAugmentedAutofillServiceForUserLocked(callingUid);
819                 }
820             }
821             return false;
822         }
823     }
824 
825     /**
826      * Compatibility mode metadata per package.
827      */
828     static final class PackageCompatState {
829         private final long maxVersionCode;
830         private final String[] urlBarResourceIds;
831 
PackageCompatState(long maxVersionCode, String[] urlBarResourceIds)832         PackageCompatState(long maxVersionCode, String[] urlBarResourceIds) {
833             this.maxVersionCode = maxVersionCode;
834             this.urlBarResourceIds = urlBarResourceIds;
835         }
836 
837         @Override
toString()838         public String toString() {
839             return "maxVersionCode=" + maxVersionCode
840                     + ", urlBarResourceIds=" + Arrays.toString(urlBarResourceIds);
841         }
842     }
843 
844     /**
845      * Compatibility mode metadata associated with all services.
846      *
847      * <p>This object is defined here instead of on each {@link AutofillManagerServiceImpl} because
848      * it cannot hold a lock on the main lock when
849      * {@link AutofillCompatState#isCompatibilityModeRequested(String, long, int)} is called by
850      * external services.
851      */
852     static final class AutofillCompatState {
853         private final Object mLock = new Object();
854 
855         /**
856          * Map of app->compat_state per user.
857          */
858         @GuardedBy("mLock")
859         private SparseArray<ArrayMap<String, PackageCompatState>> mUserSpecs;
860 
isCompatibilityModeRequested(@onNull String packageName, long versionCode, @UserIdInt int userId)861         boolean isCompatibilityModeRequested(@NonNull String packageName,
862                 long versionCode, @UserIdInt int userId) {
863             synchronized (mLock) {
864                 if (mUserSpecs == null) {
865                     return false;
866                 }
867                 final ArrayMap<String, PackageCompatState> userSpec = mUserSpecs.get(userId);
868                 if (userSpec == null) {
869                     return false;
870                 }
871                 final PackageCompatState metadata = userSpec.get(packageName);
872                 if (metadata == null) {
873                     return false;
874                 }
875                 return versionCode <= metadata.maxVersionCode;
876             }
877         }
878 
879         @Nullable
getUrlBarResourceIds(@onNull String packageName, @UserIdInt int userId)880         String[] getUrlBarResourceIds(@NonNull String packageName, @UserIdInt int userId) {
881             synchronized (mLock) {
882                 if (mUserSpecs == null) {
883                     return null;
884                 }
885                 final ArrayMap<String, PackageCompatState> userSpec = mUserSpecs.get(userId);
886                 if (userSpec == null) {
887                     return null;
888                 }
889                 final PackageCompatState metadata = userSpec.get(packageName);
890                 if (metadata == null) {
891                     return null;
892                 }
893                 return metadata.urlBarResourceIds;
894             }
895         }
896 
addCompatibilityModeRequest(@onNull String packageName, long versionCode, @Nullable String[] urlBarResourceIds, @UserIdInt int userId)897         void addCompatibilityModeRequest(@NonNull String packageName,
898                 long versionCode, @Nullable String[] urlBarResourceIds, @UserIdInt int userId) {
899             synchronized (mLock) {
900                 if (mUserSpecs == null) {
901                     mUserSpecs = new SparseArray<>();
902                 }
903                 ArrayMap<String, PackageCompatState> userSpec = mUserSpecs.get(userId);
904                 if (userSpec == null) {
905                     userSpec = new ArrayMap<>();
906                     mUserSpecs.put(userId, userSpec);
907                 }
908                 userSpec.put(packageName,
909                         new PackageCompatState(versionCode, urlBarResourceIds));
910             }
911         }
912 
removeCompatibilityModeRequests(@serIdInt int userId)913         void removeCompatibilityModeRequests(@UserIdInt int userId) {
914             synchronized (mLock) {
915                 if (mUserSpecs != null) {
916                     mUserSpecs.remove(userId);
917                     if (mUserSpecs.size() <= 0) {
918                         mUserSpecs = null;
919                     }
920                 }
921             }
922         }
923 
reset(int userId)924         void reset(int userId) {
925             synchronized (mLock) {
926                 if (mUserSpecs != null) {
927                     mUserSpecs.delete(userId);
928                     final int newSize = mUserSpecs.size();
929                     if (newSize == 0) {
930                         if (sVerbose) Slog.v(TAG, "reseting mUserSpecs");
931                         mUserSpecs = null;
932                     } else {
933                         if (sVerbose) Slog.v(TAG, "mUserSpecs down to " + newSize);
934                     }
935                 }
936             }
937         }
938 
dump(String prefix, PrintWriter pw)939         private void dump(String prefix, PrintWriter pw) {
940             synchronized (mLock) {
941                 if (mUserSpecs == null) {
942                     pw.println("N/A");
943                     return;
944                 }
945                 pw.println();
946                 final String prefix2 = prefix + "  ";
947                 for (int i = 0; i < mUserSpecs.size(); i++) {
948                     final int user = mUserSpecs.keyAt(i);
949                     pw.print(prefix);
950                     pw.print("User: ");
951                     pw.println(user);
952                     final ArrayMap<String, PackageCompatState> perUser = mUserSpecs.valueAt(i);
953                     for (int j = 0; j < perUser.size(); j++) {
954                         final String packageName = perUser.keyAt(j);
955                         final PackageCompatState state = perUser.valueAt(j);
956                         pw.print(prefix2); pw.print(packageName); pw.print(": "); pw.println(state);
957                     }
958                 }
959             }
960         }
961     }
962 
963     /**
964      * Augmented autofill metadata associated with all services.
965      *
966      * <p>This object is defined here instead of on each {@link AutofillManagerServiceImpl} because
967      * it cannot hold a lock on the main lock when
968      * {@link AugmentedAutofillState#injectAugmentedAutofillInfo(AutofillOptions, int, String)}
969      * is called by external services.
970      */
971     static final class AugmentedAutofillState extends GlobalWhitelistState {
972 
973         @GuardedBy("mGlobalWhitelistStateLock")
974         private final SparseArray<String> mServicePackages = new SparseArray<>();
975         @GuardedBy("mGlobalWhitelistStateLock")
976         private final SparseBooleanArray mTemporaryServices = new SparseBooleanArray();
977 
setServiceInfo(@serIdInt int userId, @Nullable String serviceName, boolean isTemporary)978         private void setServiceInfo(@UserIdInt int userId, @Nullable String serviceName,
979                 boolean isTemporary) {
980             synchronized (mGlobalWhitelistStateLock) {
981                 if (isTemporary) {
982                     mTemporaryServices.put(userId, true);
983                 } else {
984                     mTemporaryServices.delete(userId);
985                 }
986                 if (serviceName != null) {
987                     final ComponentName componentName =
988                             ComponentName.unflattenFromString(serviceName);
989                     if (componentName == null) {
990                         Slog.w(TAG, "setServiceInfo(): invalid name: " + serviceName);
991                         mServicePackages.remove(userId);
992                     } else {
993                         mServicePackages.put(userId, componentName.getPackageName());
994                     }
995                 } else {
996                     mServicePackages.remove(userId);
997                 }
998             }
999         }
1000 
injectAugmentedAutofillInfo(@onNull AutofillOptions options, @UserIdInt int userId, @NonNull String packageName)1001         public void injectAugmentedAutofillInfo(@NonNull AutofillOptions options,
1002                 @UserIdInt int userId, @NonNull String packageName) {
1003             synchronized (mGlobalWhitelistStateLock) {
1004                 if (mWhitelisterHelpers == null) return;
1005                 final WhitelistHelper helper = mWhitelisterHelpers.get(userId);
1006                 if (helper != null) {
1007                     options.augmentedAutofillEnabled = helper.isWhitelisted(packageName);
1008                     options.whitelistedActivitiesForAugmentedAutofill = helper
1009                             .getWhitelistedComponents(packageName);
1010                 }
1011             }
1012         }
1013 
1014         @Override
isWhitelisted(@serIdInt int userId, @NonNull ComponentName componentName)1015         public boolean isWhitelisted(@UserIdInt int userId, @NonNull ComponentName componentName) {
1016             synchronized (mGlobalWhitelistStateLock) {
1017                 if (!super.isWhitelisted(userId, componentName)) return false;
1018 
1019                 if (Build.IS_USER && mTemporaryServices.get(userId)) {
1020                     final String packageName = componentName.getPackageName();
1021                     if (!packageName.equals(mServicePackages.get(userId))) {
1022                         Slog.w(TAG, "Ignoring package " + packageName + " for augmented autofill "
1023                                 + "while using temporary service " + mServicePackages.get(userId));
1024                         return false;
1025                     }
1026                 }
1027             }
1028             return true;
1029         }
1030 
1031         @Override
dump(@onNull String prefix, @NonNull PrintWriter pw)1032         public void dump(@NonNull String prefix, @NonNull PrintWriter pw) {
1033             super.dump(prefix, pw);
1034 
1035             synchronized (mGlobalWhitelistStateLock) {
1036                 if (mServicePackages.size() > 0) {
1037                     pw.print(prefix); pw.print("Service packages: "); pw.println(mServicePackages);
1038                 }
1039                 if (mTemporaryServices.size() > 0) {
1040                     pw.print(prefix); pw.print("Temp services: "); pw.println(mTemporaryServices);
1041                 }
1042             }
1043         }
1044     }
1045 
1046     final class AutoFillManagerServiceStub extends IAutoFillManager.Stub {
1047         @Override
addClient(IAutoFillManagerClient client, ComponentName componentName, int userId, IResultReceiver receiver)1048         public void addClient(IAutoFillManagerClient client, ComponentName componentName,
1049                 int userId, IResultReceiver receiver) {
1050             int flags = 0;
1051             synchronized (mLock) {
1052                 final int enabledFlags = getServiceForUserLocked(userId).addClientLocked(client,
1053                         componentName);
1054                 if (enabledFlags != 0) {
1055                     flags |= enabledFlags;
1056                 }
1057                 if (sDebug) {
1058                     flags |= AutofillManager.FLAG_ADD_CLIENT_DEBUG;
1059                 }
1060                 if (sVerbose) {
1061                     flags |= AutofillManager.FLAG_ADD_CLIENT_VERBOSE;
1062                 }
1063             }
1064             send(receiver, flags);
1065         }
1066 
1067         @Override
removeClient(IAutoFillManagerClient client, int userId)1068         public void removeClient(IAutoFillManagerClient client, int userId) {
1069             synchronized (mLock) {
1070                 final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
1071                 if (service != null) {
1072                     service.removeClientLocked(client);
1073                 } else if (sVerbose) {
1074                     Slog.v(TAG, "removeClient(): no service for " + userId);
1075                 }
1076             }
1077         }
1078 
1079         @Override
setAuthenticationResult(Bundle data, int sessionId, int authenticationId, int userId)1080         public void setAuthenticationResult(Bundle data, int sessionId, int authenticationId,
1081                 int userId) {
1082             synchronized (mLock) {
1083                 final AutofillManagerServiceImpl service = getServiceForUserLocked(userId);
1084                 service.setAuthenticationResultLocked(data, sessionId, authenticationId,
1085                         getCallingUid());
1086             }
1087         }
1088 
1089         @Override
setHasCallback(int sessionId, int userId, boolean hasIt)1090         public void setHasCallback(int sessionId, int userId, boolean hasIt) {
1091             synchronized (mLock) {
1092                 final AutofillManagerServiceImpl service = getServiceForUserLocked(userId);
1093                 service.setHasCallback(sessionId, getCallingUid(), hasIt);
1094             }
1095         }
1096 
1097         @Override
startSession(IBinder activityToken, IBinder appCallback, AutofillId autofillId, Rect bounds, AutofillValue value, int userId, boolean hasCallback, int flags, ComponentName componentName, boolean compatMode, IResultReceiver receiver)1098         public void startSession(IBinder activityToken, IBinder appCallback, AutofillId autofillId,
1099                 Rect bounds, AutofillValue value, int userId, boolean hasCallback, int flags,
1100                 ComponentName componentName, boolean compatMode, IResultReceiver receiver) {
1101 
1102             activityToken = Preconditions.checkNotNull(activityToken, "activityToken");
1103             appCallback = Preconditions.checkNotNull(appCallback, "appCallback");
1104             autofillId = Preconditions.checkNotNull(autofillId, "autoFillId");
1105             componentName = Preconditions.checkNotNull(componentName, "componentName");
1106             final String packageName = Preconditions.checkNotNull(componentName.getPackageName());
1107 
1108             Preconditions.checkArgument(userId == UserHandle.getUserId(getCallingUid()), "userId");
1109 
1110             try {
1111                 getContext().getPackageManager().getPackageInfoAsUser(packageName, 0, userId);
1112             } catch (PackageManager.NameNotFoundException e) {
1113                 throw new IllegalArgumentException(packageName + " is not a valid package", e);
1114             }
1115 
1116             // TODO(b/113281366): add a callback method on AM to be notified when a task is finished
1117             // so we can clean up sessions kept alive
1118             final int taskId = mAm.getTaskIdForActivity(activityToken, false);
1119             final long result;
1120             synchronized (mLock) {
1121                 final AutofillManagerServiceImpl service = getServiceForUserLocked(userId);
1122                 result = service.startSessionLocked(activityToken, taskId, getCallingUid(),
1123                         appCallback, autofillId, bounds, value, hasCallback, componentName,
1124                         compatMode, mAllowInstantService, flags);
1125             }
1126             final int sessionId = (int) result;
1127             final int resultFlags = (int) (result >> 32);
1128             if (resultFlags != 0) {
1129                 send(receiver, sessionId, resultFlags);
1130             } else {
1131                 send(receiver, sessionId);
1132             }
1133         }
1134 
1135         @Override
getFillEventHistory(@onNull IResultReceiver receiver)1136         public void getFillEventHistory(@NonNull IResultReceiver receiver) throws RemoteException {
1137             final int userId = UserHandle.getCallingUserId();
1138 
1139             FillEventHistory fillEventHistory = null;
1140             synchronized (mLock) {
1141                 final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
1142                 if (service != null) {
1143                     fillEventHistory = service.getFillEventHistory(getCallingUid());
1144                 } else if (sVerbose) {
1145                     Slog.v(TAG, "getFillEventHistory(): no service for " + userId);
1146                 }
1147             }
1148             send(receiver, fillEventHistory);
1149         }
1150 
1151         @Override
getUserData(@onNull IResultReceiver receiver)1152         public void getUserData(@NonNull IResultReceiver receiver) throws RemoteException {
1153             final int userId = UserHandle.getCallingUserId();
1154 
1155             UserData userData = null;
1156             synchronized (mLock) {
1157                 final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
1158                 if (service != null) {
1159                     userData = service.getUserData(getCallingUid());
1160                 } else if (sVerbose) {
1161                     Slog.v(TAG, "getUserData(): no service for " + userId);
1162                 }
1163             }
1164             send(receiver, userData);
1165         }
1166 
1167         @Override
getUserDataId(@onNull IResultReceiver receiver)1168         public void getUserDataId(@NonNull IResultReceiver receiver) throws RemoteException {
1169             final int userId = UserHandle.getCallingUserId();
1170             UserData userData = null;
1171 
1172             synchronized (mLock) {
1173                 final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
1174                 if (service != null) {
1175                     userData = service.getUserData(getCallingUid());
1176                 } else if (sVerbose) {
1177                     Slog.v(TAG, "getUserDataId(): no service for " + userId);
1178                 }
1179             }
1180             final String userDataId = userData == null ? null : userData.getId();
1181             send(receiver, userDataId);
1182         }
1183 
1184         @Override
setUserData(UserData userData)1185         public void setUserData(UserData userData) throws RemoteException {
1186             final int userId = UserHandle.getCallingUserId();
1187 
1188             synchronized (mLock) {
1189                 final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
1190                 if (service != null) {
1191                     service.setUserData(getCallingUid(), userData);
1192                 } else if (sVerbose) {
1193                     Slog.v(TAG, "setUserData(): no service for " + userId);
1194                 }
1195             }
1196         }
1197 
1198         @Override
isFieldClassificationEnabled(@onNull IResultReceiver receiver)1199         public void isFieldClassificationEnabled(@NonNull IResultReceiver receiver)
1200                 throws RemoteException {
1201             final int userId = UserHandle.getCallingUserId();
1202             boolean enabled = false;
1203 
1204             synchronized (mLock) {
1205                 final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
1206                 if (service != null) {
1207                     enabled = service.isFieldClassificationEnabled(getCallingUid());
1208                 } else if (sVerbose) {
1209                     Slog.v(TAG, "isFieldClassificationEnabled(): no service for " + userId);
1210                 }
1211             }
1212             send(receiver, enabled);
1213         }
1214 
1215         @Override
getDefaultFieldClassificationAlgorithm(@onNull IResultReceiver receiver)1216         public void getDefaultFieldClassificationAlgorithm(@NonNull IResultReceiver receiver)
1217                 throws RemoteException {
1218             final int userId = UserHandle.getCallingUserId();
1219             String algorithm = null;
1220 
1221             synchronized (mLock) {
1222                 final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
1223                 if (service != null) {
1224                     algorithm = service.getDefaultFieldClassificationAlgorithm(getCallingUid());
1225                 } else {
1226                     if (sVerbose) {
1227                         Slog.v(TAG, "getDefaultFcAlgorithm(): no service for " + userId);
1228                     }
1229                }
1230             }
1231             send(receiver, algorithm);
1232         }
1233 
1234         @Override
setAugmentedAutofillWhitelist(@ullable List<String> packages, @Nullable List<ComponentName> activities, @NonNull IResultReceiver receiver)1235         public void setAugmentedAutofillWhitelist(@Nullable List<String> packages,
1236                 @Nullable List<ComponentName> activities, @NonNull IResultReceiver receiver)
1237                 throws RemoteException {
1238             final int userId = UserHandle.getCallingUserId();
1239 
1240             boolean ok;
1241             synchronized (mLock) {
1242                 final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
1243                 if (service != null) {
1244                     ok = service.setAugmentedAutofillWhitelistLocked(packages, activities,
1245                             getCallingUid());
1246                 } else {
1247                     if (sVerbose) {
1248                         Slog.v(TAG, "setAugmentedAutofillWhitelist(): no service for " + userId);
1249                     }
1250                     ok = false;
1251                 }
1252             }
1253             send(receiver,
1254                     ok ? AutofillManager.RESULT_OK : AutofillManager.RESULT_CODE_NOT_SERVICE);
1255         }
1256 
1257         @Override
getAvailableFieldClassificationAlgorithms(@onNull IResultReceiver receiver)1258         public void getAvailableFieldClassificationAlgorithms(@NonNull IResultReceiver receiver)
1259                 throws RemoteException {
1260             final int userId = UserHandle.getCallingUserId();
1261             String[] algorithms = null;
1262 
1263             synchronized (mLock) {
1264                 final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
1265                 if (service != null) {
1266                     algorithms = service.getAvailableFieldClassificationAlgorithms(getCallingUid());
1267                 } else {
1268                     if (sVerbose) {
1269                         Slog.v(TAG, "getAvailableFcAlgorithms(): no service for " + userId);
1270                     }
1271                 }
1272             }
1273             send(receiver, algorithms);
1274         }
1275 
1276         @Override
getAutofillServiceComponentName(@onNull IResultReceiver receiver)1277         public void getAutofillServiceComponentName(@NonNull IResultReceiver receiver)
1278                 throws RemoteException {
1279             final int userId = UserHandle.getCallingUserId();
1280 
1281             ComponentName componentName = null;
1282             synchronized (mLock) {
1283                 final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
1284                 if (service != null) {
1285                     componentName = service.getServiceComponentName();
1286                 } else if (sVerbose) {
1287                     Slog.v(TAG, "getAutofillServiceComponentName(): no service for " + userId);
1288                 }
1289             }
1290             send(receiver, componentName);
1291         }
1292 
1293         @Override
restoreSession(int sessionId, @NonNull IBinder activityToken, @NonNull IBinder appCallback, @NonNull IResultReceiver receiver)1294         public void restoreSession(int sessionId, @NonNull IBinder activityToken,
1295                 @NonNull IBinder appCallback, @NonNull IResultReceiver receiver)
1296                 throws RemoteException {
1297             final int userId = UserHandle.getCallingUserId();
1298             activityToken = Preconditions.checkNotNull(activityToken, "activityToken");
1299             appCallback = Preconditions.checkNotNull(appCallback, "appCallback");
1300 
1301             boolean restored = false;
1302             synchronized (mLock) {
1303                 final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
1304                 if (service != null) {
1305                     restored = service.restoreSession(sessionId, getCallingUid(), activityToken,
1306                             appCallback);
1307                 } else if (sVerbose) {
1308                     Slog.v(TAG, "restoreSession(): no service for " + userId);
1309                 }
1310             }
1311             send(receiver, restored);
1312         }
1313 
1314         @Override
updateSession(int sessionId, AutofillId autoFillId, Rect bounds, AutofillValue value, int action, int flags, int userId)1315         public void updateSession(int sessionId, AutofillId autoFillId, Rect bounds,
1316                 AutofillValue value, int action, int flags, int userId) {
1317             synchronized (mLock) {
1318                 final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
1319                 if (service != null) {
1320                     service.updateSessionLocked(sessionId, getCallingUid(), autoFillId, bounds,
1321                             value, action, flags);
1322                 } else if (sVerbose) {
1323                     Slog.v(TAG, "updateSession(): no service for " + userId);
1324                 }
1325             }
1326         }
1327 
1328         @Override
setAutofillFailure(int sessionId, @NonNull List<AutofillId> ids, int userId)1329         public void setAutofillFailure(int sessionId, @NonNull List<AutofillId> ids, int userId) {
1330             synchronized (mLock) {
1331                 final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
1332                 if (service != null) {
1333                     service.setAutofillFailureLocked(sessionId, getCallingUid(), ids);
1334                 } else if (sVerbose) {
1335                     Slog.v(TAG, "setAutofillFailure(): no service for " + userId);
1336                 }
1337             }
1338         }
1339 
1340         @Override
finishSession(int sessionId, int userId)1341         public void finishSession(int sessionId, int userId) {
1342             synchronized (mLock) {
1343                 final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
1344                 if (service != null) {
1345                     service.finishSessionLocked(sessionId, getCallingUid());
1346                 } else if (sVerbose) {
1347                     Slog.v(TAG, "finishSession(): no service for " + userId);
1348                 }
1349             }
1350         }
1351 
1352         @Override
cancelSession(int sessionId, int userId)1353         public void cancelSession(int sessionId, int userId) {
1354             synchronized (mLock) {
1355                 final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
1356                 if (service != null) {
1357                     service.cancelSessionLocked(sessionId, getCallingUid());
1358                 } else if (sVerbose) {
1359                     Slog.v(TAG, "cancelSession(): no service for " + userId);
1360                 }
1361             }
1362         }
1363 
1364         @Override
disableOwnedAutofillServices(int userId)1365         public void disableOwnedAutofillServices(int userId) {
1366             synchronized (mLock) {
1367                 final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
1368                 if (service != null) {
1369                     service.disableOwnedAutofillServicesLocked(Binder.getCallingUid());
1370                 } else if (sVerbose) {
1371                     Slog.v(TAG, "cancelSession(): no service for " + userId);
1372                 }
1373             }
1374         }
1375 
1376         @Override
isServiceSupported(int userId, @NonNull IResultReceiver receiver)1377         public void isServiceSupported(int userId, @NonNull IResultReceiver receiver) {
1378             boolean supported = false;
1379             synchronized (mLock) {
1380                 supported = !isDisabledLocked(userId);
1381             }
1382             send(receiver, supported);
1383         }
1384 
1385         @Override
isServiceEnabled(int userId, @NonNull String packageName, @NonNull IResultReceiver receiver)1386         public void isServiceEnabled(int userId, @NonNull String packageName,
1387                 @NonNull IResultReceiver receiver) {
1388             boolean enabled = false;
1389             synchronized (mLock) {
1390                 final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
1391                 if (service != null) {
1392                     enabled = Objects.equals(packageName, service.getServicePackageName());
1393                 } else if (sVerbose) {
1394                     Slog.v(TAG, "isServiceEnabled(): no service for " + userId);
1395                 }
1396             }
1397             send(receiver, enabled);
1398         }
1399 
1400         @Override
onPendingSaveUi(int operation, IBinder token)1401         public void onPendingSaveUi(int operation, IBinder token) {
1402             Preconditions.checkNotNull(token, "token");
1403             Preconditions.checkArgument(operation == AutofillManager.PENDING_UI_OPERATION_CANCEL
1404                     || operation == AutofillManager.PENDING_UI_OPERATION_RESTORE,
1405                     "invalid operation: %d", operation);
1406             synchronized (mLock) {
1407                 final AutofillManagerServiceImpl service = peekServiceForUserLocked(
1408                         UserHandle.getCallingUserId());
1409                 if (service != null) {
1410                     service.onPendingSaveUi(operation, token);
1411                 }
1412             }
1413         }
1414 
1415         @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)1416         public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1417             if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) return;
1418 
1419             boolean showHistory = true;
1420             boolean uiOnly = false;
1421             if (args != null) {
1422                 for (String arg : args) {
1423                     switch(arg) {
1424                         case "--no-history":
1425                             showHistory = false;
1426                             break;
1427                         case "--ui-only":
1428                             uiOnly = true;
1429                             break;
1430                         case "--help":
1431                             pw.println("Usage: dumpsys autofill [--ui-only|--no-history]");
1432                             return;
1433                         default:
1434                             Slog.w(TAG, "Ignoring invalid dump arg: " + arg);
1435                     }
1436                 }
1437             }
1438 
1439             if (uiOnly) {
1440                 mUi.dump(pw);
1441                 return;
1442             }
1443 
1444             final String prefix = "  ";
1445             boolean realDebug = sDebug;
1446             boolean realVerbose = sVerbose;
1447             try {
1448                 sDebug = sVerbose = true;
1449                 synchronized (mLock) {
1450                     pw.print("sDebug: "); pw.print(realDebug);
1451                     pw.print(" sVerbose: "); pw.println(realVerbose);
1452                     // Dump per-user services
1453                     dumpLocked("", pw);
1454                     mAugmentedAutofillResolver.dumpShort(pw); pw.println();
1455                     pw.print("Max partitions per session: "); pw.println(sPartitionMaxCount);
1456                     pw.print("Max visible datasets: "); pw.println(sVisibleDatasetsMaxCount);
1457                     if (sFullScreenMode != null) {
1458                         pw.print("Overridden full-screen mode: "); pw.println(sFullScreenMode);
1459                     }
1460                     pw.println("User data constraints: "); UserData.dumpConstraints(prefix, pw);
1461                     mUi.dump(pw);
1462                     pw.print("Autofill Compat State: ");
1463                     mAutofillCompatState.dump(prefix, pw);
1464                     pw.print("from settings: ");
1465                     pw.println(getWhitelistedCompatModePackagesFromSettings());
1466                     if (mSupportedSmartSuggestionModes != 0) {
1467                         pw.print("Smart Suggestion modes: ");
1468                         pw.println(getSmartSuggestionModeToString(mSupportedSmartSuggestionModes));
1469                     }
1470                     pw.print("Augmented Service Idle Unbind Timeout: ");
1471                     pw.println(mAugmentedServiceIdleUnbindTimeoutMs);
1472                     pw.print("Augmented Service Request Timeout: ");
1473                     pw.println(mAugmentedServiceRequestTimeoutMs);
1474                     if (showHistory) {
1475                         pw.println(); pw.println("Requests history:"); pw.println();
1476                         mRequestsHistory.reverseDump(fd, pw, args);
1477                         pw.println(); pw.println("UI latency history:"); pw.println();
1478                         mUiLatencyHistory.reverseDump(fd, pw, args);
1479                         pw.println(); pw.println("WTF history:"); pw.println();
1480                         mWtfHistory.reverseDump(fd, pw, args);
1481                     }
1482                     pw.println("Augmented Autofill State: ");
1483                     mAugmentedAutofillState.dump(prefix, pw);
1484                 }
1485             } finally {
1486                 sDebug = realDebug;
1487                 sVerbose = realVerbose;
1488             }
1489         }
1490 
1491         @Override
onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver)1492         public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
1493                 String[] args, ShellCallback callback, ResultReceiver resultReceiver) {
1494             new AutofillManagerServiceShellCommand(AutofillManagerService.this).exec(
1495                     this, in, out, err, args, callback, resultReceiver);
1496         }
1497     }
1498 }
1499