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 static java.util.Objects.requireNonNull; 29 30 import android.annotation.NonNull; 31 import android.annotation.Nullable; 32 import android.annotation.UserIdInt; 33 import android.app.ActivityManagerInternal; 34 import android.app.ActivityThread; 35 import android.content.AutofillOptions; 36 import android.content.BroadcastReceiver; 37 import android.content.ComponentName; 38 import android.content.ContentResolver; 39 import android.content.Context; 40 import android.content.Intent; 41 import android.content.IntentFilter; 42 import android.content.pm.PackageManager; 43 import android.content.pm.UserInfo; 44 import android.database.ContentObserver; 45 import android.graphics.Rect; 46 import android.os.Binder; 47 import android.os.Build; 48 import android.os.Bundle; 49 import android.os.IBinder; 50 import android.os.Parcelable; 51 import android.os.RemoteCallback; 52 import android.os.RemoteException; 53 import android.os.ResultReceiver; 54 import android.os.ShellCallback; 55 import android.os.SystemClock; 56 import android.os.UserHandle; 57 import android.os.UserManager; 58 import android.provider.DeviceConfig; 59 import android.provider.Settings; 60 import android.service.autofill.FillEventHistory; 61 import android.service.autofill.UserData; 62 import android.text.TextUtils; 63 import android.text.TextUtils.SimpleStringSplitter; 64 import android.util.ArrayMap; 65 import android.util.LocalLog; 66 import android.util.Log; 67 import android.util.Slog; 68 import android.util.SparseArray; 69 import android.util.SparseBooleanArray; 70 import android.util.TimeUtils; 71 import android.view.autofill.AutofillFeatureFlags; 72 import android.view.autofill.AutofillId; 73 import android.view.autofill.AutofillManager; 74 import android.view.autofill.AutofillManager.AutofillCommitReason; 75 import android.view.autofill.AutofillManager.SmartSuggestionMode; 76 import android.view.autofill.AutofillManagerInternal; 77 import android.view.autofill.AutofillValue; 78 import android.view.autofill.IAutoFillManager; 79 import android.view.autofill.IAutoFillManagerClient; 80 81 import com.android.internal.annotations.GuardedBy; 82 import com.android.internal.annotations.VisibleForTesting; 83 import com.android.internal.infra.AbstractRemoteService; 84 import com.android.internal.infra.GlobalWhitelistState; 85 import com.android.internal.infra.WhitelistHelper; 86 import com.android.internal.os.IResultReceiver; 87 import com.android.internal.util.DumpUtils; 88 import com.android.internal.util.Preconditions; 89 import com.android.internal.util.SyncResultReceiver; 90 import com.android.server.FgThread; 91 import com.android.server.LocalServices; 92 import com.android.server.autofill.ui.AutoFillUI; 93 import com.android.server.infra.AbstractMasterSystemService; 94 import com.android.server.infra.FrameworkResourcesServiceNameResolver; 95 import com.android.server.infra.SecureSettingsServiceNameResolver; 96 97 import java.io.FileDescriptor; 98 import java.io.PrintWriter; 99 import java.util.ArrayList; 100 import java.util.Arrays; 101 import java.util.List; 102 import java.util.Map; 103 import java.util.Objects; 104 import java.util.Set; 105 106 /** 107 * Entry point service for autofill management. 108 * 109 * <p>This service provides the {@link IAutoFillManager} implementation and keeps a list of 110 * {@link AutofillManagerServiceImpl} per user; the real work is done by 111 * {@link AutofillManagerServiceImpl} itself. 112 */ 113 public final class AutofillManagerService 114 extends AbstractMasterSystemService<AutofillManagerService, AutofillManagerServiceImpl> { 115 116 private static final String TAG = "AutofillManagerService"; 117 118 private static final Object sLock = AutofillManagerService.class; 119 120 static final String RECEIVER_BUNDLE_EXTRA_SESSIONS = "sessions"; 121 122 private static final char COMPAT_PACKAGE_DELIMITER = ':'; 123 private static final char COMPAT_PACKAGE_URL_IDS_DELIMITER = ','; 124 private static final char COMPAT_PACKAGE_URL_IDS_BLOCK_BEGIN = '['; 125 private static final char COMPAT_PACKAGE_URL_IDS_BLOCK_END = ']'; 126 127 private static final int DEFAULT_AUGMENTED_AUTOFILL_REQUEST_TIMEOUT_MILLIS = 5_000; 128 129 /** 130 * Maximum number of partitions that can be allowed in a session. 131 * 132 * <p>Can be modified using {@code cmd autofill set max_partitions} or through 133 * {@link android.provider.Settings.Global#AUTOFILL_MAX_PARTITIONS_SIZE}. 134 */ 135 @GuardedBy("sLock") 136 private static int sPartitionMaxCount = AutofillManager.DEFAULT_MAX_PARTITIONS_SIZE; 137 138 /** 139 * Maximum number of visible datasets in the dataset picker UI, or {@code 0} to use default 140 * value from resources. 141 * 142 * <p>Can be modified using {@code cmd autofill set max_visible_datasets} or through 143 * {@link android.provider.Settings.Global#AUTOFILL_MAX_VISIBLE_DATASETS}. 144 */ 145 @GuardedBy("sLock") 146 private static int sVisibleDatasetsMaxCount = 0; 147 148 /** 149 * Object used to set the name of the augmented autofill service. 150 */ 151 @NonNull 152 final FrameworkResourcesServiceNameResolver mAugmentedAutofillResolver; 153 154 /** 155 * Object used to set the name of the field classification service. 156 */ 157 @NonNull 158 final FrameworkResourcesServiceNameResolver mFieldClassificationResolver; 159 160 private final AutoFillUI mUi; 161 162 private final LocalLog mRequestsHistory = new LocalLog(20); 163 private final LocalLog mUiLatencyHistory = new LocalLog(20); 164 private final LocalLog mWtfHistory = new LocalLog(50); 165 166 private final AutofillCompatState mAutofillCompatState = new AutofillCompatState(); 167 private final DisabledInfoCache mDisabledInfoCache = new DisabledInfoCache(); 168 169 private final LocalService mLocalService = new LocalService(); 170 private final ActivityManagerInternal mAm; 171 172 private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 173 @Override 174 public void onReceive(Context context, Intent intent) { 175 if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction())) { 176 if (sDebug) Slog.d(TAG, "Close system dialogs"); 177 178 // TODO(b/64940307): we need to destroy all sessions that are finished but showing 179 // Save UI because there is no way to show the Save UI back when the activity 180 // beneath it is brought back to top. Ideally, we should just hide the UI and 181 // bring it back when the activity resumes. 182 synchronized (mLock) { 183 visitServicesLocked((s) -> s.forceRemoveFinishedSessionsLocked()); 184 } 185 mUi.hideAll(null); 186 } 187 } 188 }; 189 190 /** 191 * Supported modes for Augmented Autofill Smart Suggestions. 192 */ 193 @GuardedBy("mLock") 194 private int mSupportedSmartSuggestionModes; 195 196 @GuardedBy("mLock") 197 int mAugmentedServiceIdleUnbindTimeoutMs; 198 @GuardedBy("mLock") 199 int mAugmentedServiceRequestTimeoutMs; 200 201 final AugmentedAutofillState mAugmentedAutofillState = new AugmentedAutofillState(); 202 203 /** 204 * Lock used to synchronize access to the flags. 205 * DO NOT USE ANY OTHER LOCK while holding this lock. 206 * NOTE: This lock should only be used for accessing flags. It should never call into other 207 * methods holding another lock. It can lead to potential deadlock if it calls into a method 208 * holding mLock. 209 */ 210 private final Object mFlagLock = new Object(); 211 212 // Flag holders for Autofill PCC classification 213 214 @GuardedBy("mFlagLock") 215 private boolean mPccClassificationEnabled; 216 217 @GuardedBy("mFlagLock") 218 private boolean mPccPreferProviderOverPcc; 219 220 @GuardedBy("mFlagLock") 221 private boolean mPccUseFallbackDetection; 222 223 @GuardedBy("mFlagLock") 224 private String mPccProviderHints; 225 226 // Default flag values for Autofill PCC 227 228 private static final String DEFAULT_PCC_FEATURE_PROVIDER_HINTS = ""; 229 private static final boolean DEFAULT_PREFER_PROVIDER_OVER_PCC = true; 230 231 private static final boolean DEFAULT_PCC_USE_FALLBACK = true; 232 AutofillManagerService(Context context)233 public AutofillManagerService(Context context) { 234 super(context, 235 new SecureSettingsServiceNameResolver(context, Settings.Secure.AUTOFILL_SERVICE), 236 UserManager.DISALLOW_AUTOFILL, PACKAGE_UPDATE_POLICY_REFRESH_EAGER); 237 mUi = new AutoFillUI(ActivityThread.currentActivityThread().getSystemUiContext()); 238 mAm = LocalServices.getService(ActivityManagerInternal.class); 239 240 DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_AUTOFILL, 241 ActivityThread.currentApplication().getMainExecutor(), 242 (properties) -> onDeviceConfigChange(properties.getKeyset())); 243 244 setLogLevelFromSettings(); 245 setMaxPartitionsFromSettings(); 246 setMaxVisibleDatasetsFromSettings(); 247 setDeviceConfigProperties(); 248 249 final IntentFilter filter = new IntentFilter(); 250 filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 251 context.registerReceiver(mBroadcastReceiver, filter, null, FgThread.getHandler(), 252 Context.RECEIVER_EXPORTED); 253 254 mAugmentedAutofillResolver = new FrameworkResourcesServiceNameResolver(getContext(), 255 com.android.internal.R.string.config_defaultAugmentedAutofillService); 256 mAugmentedAutofillResolver.setOnTemporaryServiceNameChangedCallback( 257 (u, s, t) -> onAugmentedServiceNameChanged(u, s, t)); 258 259 mFieldClassificationResolver = new FrameworkResourcesServiceNameResolver(getContext(), 260 com.android.internal.R.string.config_defaultFieldClassificationService); 261 if (sVerbose) { 262 Slog.v(TAG, "Resolving FieldClassificationService to serviceName: " 263 + mFieldClassificationResolver.readServiceName(0)); 264 } 265 mFieldClassificationResolver.setOnTemporaryServiceNameChangedCallback( 266 (u, s, t) -> onFieldClassificationServiceNameChanged(u, s, t)); 267 268 if (mSupportedSmartSuggestionModes != AutofillManager.FLAG_SMART_SUGGESTION_OFF) { 269 final List<UserInfo> users = getSupportedUsers(); 270 for (int i = 0; i < users.size(); i++) { 271 final int userId = users.get(i).id; 272 // Must eager load the services so they bind to the augmented autofill service 273 getServiceForUserLocked(userId); 274 275 // And also set the global state 276 mAugmentedAutofillState.setServiceInfo(userId, 277 mAugmentedAutofillResolver.getServiceName(userId), 278 mAugmentedAutofillResolver.isTemporary(userId)); 279 } 280 } 281 } 282 283 @Override // from AbstractMasterSystemService getServiceSettingsProperty()284 protected String getServiceSettingsProperty() { 285 return Settings.Secure.AUTOFILL_SERVICE; 286 } 287 288 @Override // from AbstractMasterSystemService registerForExtraSettingsChanges(@onNull ContentResolver resolver, @NonNull ContentObserver observer)289 protected void registerForExtraSettingsChanges(@NonNull ContentResolver resolver, 290 @NonNull ContentObserver observer) { 291 resolver.registerContentObserver(Settings.Global.getUriFor( 292 Settings.Global.AUTOFILL_LOGGING_LEVEL), false, observer, 293 UserHandle.USER_ALL); 294 resolver.registerContentObserver(Settings.Global.getUriFor( 295 Settings.Global.AUTOFILL_MAX_PARTITIONS_SIZE), false, observer, 296 UserHandle.USER_ALL); 297 resolver.registerContentObserver(Settings.Global.getUriFor( 298 Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS), false, observer, 299 UserHandle.USER_ALL); 300 resolver.registerContentObserver(Settings.Secure.getUriFor( 301 Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE), false, observer, 302 UserHandle.USER_ALL); 303 } 304 305 @Override // from AbstractMasterSystemService onSettingsChanged(int userId, @NonNull String property)306 protected void onSettingsChanged(int userId, @NonNull String property) { 307 switch (property) { 308 case Settings.Global.AUTOFILL_LOGGING_LEVEL: 309 setLogLevelFromSettings(); 310 break; 311 case Settings.Global.AUTOFILL_MAX_PARTITIONS_SIZE: 312 setMaxPartitionsFromSettings(); 313 break; 314 case Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS: 315 setMaxVisibleDatasetsFromSettings(); 316 break; 317 case Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE: 318 handleInputMethodSwitch(userId); 319 break; 320 default: 321 Slog.w(TAG, "Unexpected property (" + property + "); updating cache instead"); 322 synchronized (mLock) { 323 updateCachedServiceLocked(userId); 324 } 325 } 326 } 327 handleInputMethodSwitch(@serIdInt int userId)328 private void handleInputMethodSwitch(@UserIdInt int userId) { 329 // TODO(b/156903336): Used the SettingsObserver with a background thread maybe slow to 330 // respond to the IME switch in certain situations. 331 // See: services/core/java/com/android/server/FgThread.java 332 // In particular, the shared background thread could be doing relatively long-running 333 // operations like saving state to disk (in addition to simply being a background priority), 334 // which can cause operations scheduled on it to be delayed for a user-noticeable amount 335 // of time. 336 337 synchronized (mLock) { 338 final AutofillManagerServiceImpl service = 339 peekServiceForUserWithLocalBinderIdentityLocked(userId); 340 if (service != null) { 341 service.onSwitchInputMethod(); 342 } 343 } 344 } 345 onDeviceConfigChange(@onNull Set<String> keys)346 private void onDeviceConfigChange(@NonNull Set<String> keys) { 347 for (String key : keys) { 348 switch (key) { 349 case AutofillFeatureFlags.DEVICE_CONFIG_AUTOFILL_SMART_SUGGESTION_SUPPORTED_MODES: 350 case AutofillFeatureFlags.DEVICE_CONFIG_AUGMENTED_SERVICE_IDLE_UNBIND_TIMEOUT: 351 case AutofillFeatureFlags.DEVICE_CONFIG_AUGMENTED_SERVICE_REQUEST_TIMEOUT: 352 case AutofillFeatureFlags.DEVICE_CONFIG_AUTOFILL_PCC_CLASSIFICATION_ENABLED: 353 case AutofillFeatureFlags.DEVICE_CONFIG_AUTOFILL_PCC_FEATURE_PROVIDER_HINTS: 354 case AutofillFeatureFlags.DEVICE_CONFIG_PREFER_PROVIDER_OVER_PCC: 355 case AutofillFeatureFlags.DEVICE_CONFIG_PCC_USE_FALLBACK: 356 setDeviceConfigProperties(); 357 break; 358 case AutofillFeatureFlags.DEVICE_CONFIG_AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES: 359 updateCachedServices(); 360 break; 361 default: 362 Slog.i(mTag, "Ignoring change on " + key); 363 } 364 } 365 } 366 onAugmentedServiceNameChanged(@serIdInt int userId, @Nullable String serviceName, boolean isTemporary)367 private void onAugmentedServiceNameChanged(@UserIdInt int userId, @Nullable String serviceName, 368 boolean isTemporary) { 369 mAugmentedAutofillState.setServiceInfo(userId, serviceName, isTemporary); 370 synchronized (mLock) { 371 final AutofillManagerServiceImpl service = 372 peekServiceForUserWithLocalBinderIdentityLocked(userId); 373 if (service == null) { 374 // If we cannot get the service from the services cache, it will call 375 // updateRemoteAugmentedAutofillService() finally. Skip call this update again. 376 getServiceForUserWithLocalBinderIdentityLocked(userId); 377 } else { 378 service.updateRemoteAugmentedAutofillService(); 379 } 380 } 381 } 382 onFieldClassificationServiceNameChanged( @serIdInt int userId, @Nullable String serviceName, boolean isTemporary)383 private void onFieldClassificationServiceNameChanged( 384 @UserIdInt int userId, @Nullable String serviceName, boolean isTemporary) { 385 synchronized (mLock) { 386 final AutofillManagerServiceImpl service = 387 peekServiceForUserWithLocalBinderIdentityLocked(userId); 388 if (service == null) { 389 // If we cannot get the service from the services cache, it will call 390 // updateRemoteFieldClassificationService() finally. Skip call this update again. 391 getServiceForUserWithLocalBinderIdentityLocked(userId); 392 } else { 393 service.updateRemoteFieldClassificationService(); 394 } 395 } 396 } 397 398 @GuardedBy("mLock") 399 @Nullable getServiceForUserWithLocalBinderIdentityLocked(int userId)400 private AutofillManagerServiceImpl getServiceForUserWithLocalBinderIdentityLocked(int userId) { 401 final long token = Binder.clearCallingIdentity(); 402 AutofillManagerServiceImpl managerService = null; 403 try { 404 managerService = getServiceForUserLocked(userId); 405 } finally { 406 Binder.restoreCallingIdentity(token); 407 } 408 409 return managerService; 410 } 411 412 @GuardedBy("mLock") 413 @Nullable peekServiceForUserWithLocalBinderIdentityLocked(int userId)414 private AutofillManagerServiceImpl peekServiceForUserWithLocalBinderIdentityLocked(int userId) { 415 final long token = Binder.clearCallingIdentity(); 416 AutofillManagerServiceImpl managerService = null; 417 try { 418 managerService = peekServiceForUserLocked(userId); 419 } finally { 420 Binder.restoreCallingIdentity(token); 421 } 422 423 return managerService; 424 } 425 426 @Override // from AbstractMasterSystemService newServiceLocked(@serIdInt int resolvedUserId, boolean disabled)427 protected AutofillManagerServiceImpl newServiceLocked(@UserIdInt int resolvedUserId, 428 boolean disabled) { 429 return new AutofillManagerServiceImpl(this, mLock, mUiLatencyHistory, mWtfHistory, 430 resolvedUserId, mUi, mAutofillCompatState, disabled, mDisabledInfoCache); 431 } 432 433 @Override // AbstractMasterSystemService onServiceRemoved(@onNull AutofillManagerServiceImpl service, @UserIdInt int userId)434 protected void onServiceRemoved(@NonNull AutofillManagerServiceImpl service, 435 @UserIdInt int userId) { 436 service.destroyLocked(); 437 mDisabledInfoCache.remove(userId); 438 mAutofillCompatState.removeCompatibilityModeRequests(userId); 439 } 440 441 @Override // from AbstractMasterSystemService onServiceEnabledLocked(@onNull AutofillManagerServiceImpl service, @UserIdInt int userId)442 protected void onServiceEnabledLocked(@NonNull AutofillManagerServiceImpl service, 443 @UserIdInt int userId) { 444 addCompatibilityModeRequestsLocked(service, userId); 445 } 446 447 @Override // from AbstractMasterSystemService enforceCallingPermissionForManagement()448 protected void enforceCallingPermissionForManagement() { 449 getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG); 450 } 451 452 @Override // from SystemService onStart()453 public void onStart() { 454 publishBinderService(AUTOFILL_MANAGER_SERVICE, new AutoFillManagerServiceStub()); 455 publishLocalService(AutofillManagerInternal.class, mLocalService); 456 } 457 458 @Override // from SystemService isUserSupported(TargetUser user)459 public boolean isUserSupported(TargetUser user) { 460 return user.isFull() || user.isProfile(); 461 } 462 463 @Override // from SystemService onUserSwitching(@ullable TargetUser from, @NonNull TargetUser to)464 public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) { 465 if (sDebug) Slog.d(TAG, "Hiding UI when user switched"); 466 mUi.hideAll(null); 467 } 468 getSupportedSmartSuggestionModesLocked()469 @SmartSuggestionMode int getSupportedSmartSuggestionModesLocked() { 470 return mSupportedSmartSuggestionModes; 471 } 472 473 /** 474 * Logs a request so it's dumped later... 475 */ logRequestLocked(@onNull String historyItem)476 void logRequestLocked(@NonNull String historyItem) { 477 mRequestsHistory.log(historyItem); 478 } 479 480 // Called by AutofillManagerServiceImpl, doesn't need to check permission isInstantServiceAllowed()481 boolean isInstantServiceAllowed() { 482 return mAllowInstantService; 483 } 484 485 // Called by Shell command. removeAllSessions(@serIdInt int userId, IResultReceiver receiver)486 void removeAllSessions(@UserIdInt int userId, IResultReceiver receiver) { 487 Slog.i(TAG, "removeAllSessions() for userId " + userId); 488 enforceCallingPermissionForManagement(); 489 490 synchronized (mLock) { 491 if (userId != UserHandle.USER_ALL) { 492 AutofillManagerServiceImpl service = peekServiceForUserLocked(userId); 493 if (service != null) { 494 service.forceRemoveAllSessionsLocked(); 495 } 496 } else { 497 visitServicesLocked((s) -> s.forceRemoveAllSessionsLocked()); 498 } 499 } 500 501 try { 502 receiver.send(0, new Bundle()); 503 } catch (RemoteException e) { 504 // Just ignore it... 505 } 506 } 507 508 // Called by Shell command. listSessions(int userId, IResultReceiver receiver)509 void listSessions(int userId, IResultReceiver receiver) { 510 Slog.i(TAG, "listSessions() for userId " + userId); 511 enforceCallingPermissionForManagement(); 512 513 final Bundle resultData = new Bundle(); 514 final ArrayList<String> sessions = new ArrayList<>(); 515 516 synchronized (mLock) { 517 if (userId != UserHandle.USER_ALL) { 518 AutofillManagerServiceImpl service = peekServiceForUserLocked(userId); 519 if (service != null) { 520 service.listSessionsLocked(sessions); 521 } 522 } else { 523 visitServicesLocked((s) -> s.listSessionsLocked(sessions)); 524 } 525 } 526 527 resultData.putStringArrayList(RECEIVER_BUNDLE_EXTRA_SESSIONS, sessions); 528 try { 529 receiver.send(0, resultData); 530 } catch (RemoteException e) { 531 // Just ignore it... 532 } 533 } 534 535 // Called by Shell command. reset()536 void reset() { 537 Slog.i(TAG, "reset()"); 538 enforceCallingPermissionForManagement(); 539 540 synchronized (mLock) { 541 visitServicesLocked((s) -> s.destroyLocked()); 542 clearCacheLocked(); 543 } 544 } 545 546 // Called by Shell command. setLogLevel(int level)547 void setLogLevel(int level) { 548 Slog.i(TAG, "setLogLevel(): " + level); 549 enforceCallingPermissionForManagement(); 550 551 final long token = Binder.clearCallingIdentity(); 552 try { 553 Settings.Global.putInt(getContext().getContentResolver(), 554 Settings.Global.AUTOFILL_LOGGING_LEVEL, level); 555 } finally { 556 Binder.restoreCallingIdentity(token); 557 } 558 } 559 setLogLevelFromSettings()560 private void setLogLevelFromSettings() { 561 final int level = Settings.Global.getInt( 562 getContext().getContentResolver(), 563 Settings.Global.AUTOFILL_LOGGING_LEVEL, AutofillManager.DEFAULT_LOGGING_LEVEL); 564 boolean debug = false; 565 boolean verbose = false; 566 if (level != AutofillManager.NO_LOGGING) { 567 if (level == AutofillManager.FLAG_ADD_CLIENT_VERBOSE) { 568 debug = verbose = true; 569 } else if (level == AutofillManager.FLAG_ADD_CLIENT_DEBUG) { 570 debug = true; 571 } else { 572 Slog.w(TAG, "setLogLevelFromSettings(): invalid level: " + level); 573 } 574 } 575 if (debug || sDebug) { 576 Slog.d(TAG, "setLogLevelFromSettings(): level=" + level + ", debug=" + debug 577 + ", verbose=" + verbose); 578 } 579 synchronized (mLock) { 580 setLoggingLevelsLocked(debug, verbose); 581 } 582 } 583 584 // Called by Shell command. getLogLevel()585 int getLogLevel() { 586 enforceCallingPermissionForManagement(); 587 588 synchronized (mLock) { 589 if (sVerbose) return AutofillManager.FLAG_ADD_CLIENT_VERBOSE; 590 if (sDebug) return AutofillManager.FLAG_ADD_CLIENT_DEBUG; 591 return 0; 592 } 593 } 594 595 // Called by Shell command. getMaxPartitions()596 int getMaxPartitions() { 597 enforceCallingPermissionForManagement(); 598 599 synchronized (mLock) { 600 return sPartitionMaxCount; 601 } 602 } 603 604 // Called by Shell command. setMaxPartitions(int max)605 void setMaxPartitions(int max) { 606 Slog.i(TAG, "setMaxPartitions(): " + max); 607 enforceCallingPermissionForManagement(); 608 609 final long token = Binder.clearCallingIdentity(); 610 try { 611 Settings.Global.putInt(getContext().getContentResolver(), 612 Settings.Global.AUTOFILL_MAX_PARTITIONS_SIZE, max); 613 } finally { 614 Binder.restoreCallingIdentity(token); 615 } 616 } 617 setMaxPartitionsFromSettings()618 private void setMaxPartitionsFromSettings() { 619 final int max = Settings.Global.getInt(getContext().getContentResolver(), 620 Settings.Global.AUTOFILL_MAX_PARTITIONS_SIZE, 621 AutofillManager.DEFAULT_MAX_PARTITIONS_SIZE); 622 if (sDebug) Slog.d(TAG, "setMaxPartitionsFromSettings(): " + max); 623 624 synchronized (sLock) { 625 sPartitionMaxCount = max; 626 } 627 } 628 629 // Called by Shell command. getMaxVisibleDatasets()630 int getMaxVisibleDatasets() { 631 enforceCallingPermissionForManagement(); 632 633 synchronized (sLock) { 634 return sVisibleDatasetsMaxCount; 635 } 636 } 637 638 // Called by Shell command. setMaxVisibleDatasets(int max)639 void setMaxVisibleDatasets(int max) { 640 Slog.i(TAG, "setMaxVisibleDatasets(): " + max); 641 enforceCallingPermissionForManagement(); 642 643 final long token = Binder.clearCallingIdentity(); 644 try { 645 Settings.Global.putInt(getContext().getContentResolver(), 646 Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS, max); 647 } finally { 648 Binder.restoreCallingIdentity(token); 649 } 650 } 651 setMaxVisibleDatasetsFromSettings()652 private void setMaxVisibleDatasetsFromSettings() { 653 final int max = Settings.Global.getInt(getContext().getContentResolver(), 654 Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS, 0); 655 656 if (sDebug) Slog.d(TAG, "setMaxVisibleDatasetsFromSettings(): " + max); 657 synchronized (sLock) { 658 sVisibleDatasetsMaxCount = max; 659 } 660 } 661 setDeviceConfigProperties()662 private void setDeviceConfigProperties() { 663 synchronized (mLock) { 664 mAugmentedServiceIdleUnbindTimeoutMs = DeviceConfig.getInt( 665 DeviceConfig.NAMESPACE_AUTOFILL, 666 AutofillFeatureFlags.DEVICE_CONFIG_AUGMENTED_SERVICE_IDLE_UNBIND_TIMEOUT, 667 (int) AbstractRemoteService.PERMANENT_BOUND_TIMEOUT_MS); 668 mAugmentedServiceRequestTimeoutMs = DeviceConfig.getInt( 669 DeviceConfig.NAMESPACE_AUTOFILL, 670 AutofillFeatureFlags.DEVICE_CONFIG_AUGMENTED_SERVICE_REQUEST_TIMEOUT, 671 DEFAULT_AUGMENTED_AUTOFILL_REQUEST_TIMEOUT_MILLIS); 672 mSupportedSmartSuggestionModes = DeviceConfig.getInt( 673 DeviceConfig.NAMESPACE_AUTOFILL, 674 AutofillFeatureFlags.DEVICE_CONFIG_AUTOFILL_SMART_SUGGESTION_SUPPORTED_MODES, 675 AutofillManager.FLAG_SMART_SUGGESTION_SYSTEM); 676 if (verbose) { 677 Slog.v(mTag, "setDeviceConfigProperties() for AugmentedAutofill: " 678 + "augmentedIdleTimeout=" + mAugmentedServiceIdleUnbindTimeoutMs 679 + ", augmentedRequestTimeout=" + mAugmentedServiceRequestTimeoutMs 680 + ", smartSuggestionMode=" 681 + getSmartSuggestionModeToString(mSupportedSmartSuggestionModes)); 682 } 683 } 684 synchronized (mFlagLock) { 685 mPccClassificationEnabled = DeviceConfig.getBoolean( 686 DeviceConfig.NAMESPACE_AUTOFILL, 687 AutofillFeatureFlags.DEVICE_CONFIG_AUTOFILL_PCC_CLASSIFICATION_ENABLED, 688 AutofillFeatureFlags.DEFAULT_AUTOFILL_PCC_CLASSIFICATION_ENABLED); 689 mPccPreferProviderOverPcc = DeviceConfig.getBoolean( 690 DeviceConfig.NAMESPACE_AUTOFILL, 691 AutofillFeatureFlags.DEVICE_CONFIG_PREFER_PROVIDER_OVER_PCC, 692 DEFAULT_PREFER_PROVIDER_OVER_PCC); 693 mPccUseFallbackDetection = DeviceConfig.getBoolean( 694 DeviceConfig.NAMESPACE_AUTOFILL, 695 AutofillFeatureFlags.DEVICE_CONFIG_PCC_USE_FALLBACK, 696 DEFAULT_PCC_USE_FALLBACK); 697 mPccProviderHints = DeviceConfig.getString( 698 DeviceConfig.NAMESPACE_AUTOFILL, 699 AutofillFeatureFlags.DEVICE_CONFIG_AUTOFILL_PCC_FEATURE_PROVIDER_HINTS, 700 DEFAULT_PCC_FEATURE_PROVIDER_HINTS); 701 if (verbose) { 702 Slog.v(mTag, "setDeviceConfigProperties() for PCC: " 703 + "mPccClassificationEnabled=" + mPccClassificationEnabled 704 + ", mPccPreferProviderOverPcc=" + mPccPreferProviderOverPcc 705 + ", mPccUseFallbackDetection=" + mPccUseFallbackDetection 706 + ", mPccProviderHints=" + mPccProviderHints); 707 } 708 } 709 } 710 updateCachedServices()711 private void updateCachedServices() { 712 List<UserInfo> supportedUsers = getSupportedUsers(); 713 for (UserInfo userInfo : supportedUsers) { 714 synchronized (mLock) { 715 updateCachedServiceLocked(userInfo.id); 716 } 717 } 718 } 719 720 // Called by Shell command. calculateScore(@ullable String algorithmName, @NonNull String value1, @NonNull String value2, @NonNull RemoteCallback callback)721 void calculateScore(@Nullable String algorithmName, @NonNull String value1, 722 @NonNull String value2, @NonNull RemoteCallback callback) { 723 enforceCallingPermissionForManagement(); 724 725 final FieldClassificationStrategy strategy = 726 new FieldClassificationStrategy(getContext(), UserHandle.USER_CURRENT); 727 728 strategy.calculateScores(callback, Arrays.asList(AutofillValue.forText(value1)), 729 new String[] { value2 }, new String[] { null }, algorithmName, null, null, null); 730 } 731 732 // Called by Shell command. getFullScreenMode()733 Boolean getFullScreenMode() { 734 enforceCallingPermissionForManagement(); 735 return sFullScreenMode; 736 } 737 738 // Called by Shell command. setFullScreenMode(@ullable Boolean mode)739 void setFullScreenMode(@Nullable Boolean mode) { 740 enforceCallingPermissionForManagement(); 741 sFullScreenMode = mode; 742 } 743 744 // Called by Shell command. setTemporaryAugmentedAutofillService(@serIdInt int userId, @NonNull String serviceName, int durationMs)745 void setTemporaryAugmentedAutofillService(@UserIdInt int userId, @NonNull String serviceName, 746 int durationMs) { 747 Slog.i(mTag, "setTemporaryAugmentedAutofillService(" + userId + ") to " + serviceName 748 + " for " + durationMs + "ms"); 749 enforceCallingPermissionForManagement(); 750 751 Objects.requireNonNull(serviceName); 752 if (durationMs > MAX_TEMP_AUGMENTED_SERVICE_DURATION_MS) { 753 throw new IllegalArgumentException("Max duration is " 754 + MAX_TEMP_AUGMENTED_SERVICE_DURATION_MS + " (called with " + durationMs + ")"); 755 } 756 757 mAugmentedAutofillResolver.setTemporaryService(userId, serviceName, durationMs); 758 } 759 760 // Called by Shell command resetTemporaryAugmentedAutofillService(@serIdInt int userId)761 void resetTemporaryAugmentedAutofillService(@UserIdInt int userId) { 762 enforceCallingPermissionForManagement(); 763 mAugmentedAutofillResolver.resetTemporaryService(userId); 764 } 765 766 // Called by Shell command isDefaultAugmentedServiceEnabled(@serIdInt int userId)767 boolean isDefaultAugmentedServiceEnabled(@UserIdInt int userId) { 768 enforceCallingPermissionForManagement(); 769 return mAugmentedAutofillResolver.isDefaultServiceEnabled(userId); 770 } 771 772 // Called by Shell command setDefaultAugmentedServiceEnabled(@serIdInt int userId, boolean enabled)773 boolean setDefaultAugmentedServiceEnabled(@UserIdInt int userId, boolean enabled) { 774 Slog.i(mTag, "setDefaultAugmentedServiceEnabled() for userId " + userId + ": " + enabled); 775 enforceCallingPermissionForManagement(); 776 777 synchronized (mLock) { 778 final AutofillManagerServiceImpl service = getServiceForUserLocked(userId); 779 if (service != null) { 780 final boolean changed = mAugmentedAutofillResolver 781 .setDefaultServiceEnabled(userId, enabled); 782 if (changed) { 783 service.updateRemoteAugmentedAutofillService(); 784 return true; 785 } else { 786 if (debug) { 787 Slog.d(TAG, "setDefaultAugmentedServiceEnabled(): already " + enabled); 788 } 789 } 790 } 791 } 792 return false; 793 } 794 795 // Called by Shell command isFieldDetectionServiceEnabledForUser(@serIdInt int userId)796 boolean isFieldDetectionServiceEnabledForUser(@UserIdInt int userId) { 797 enforceCallingPermissionForManagement(); 798 synchronized (mLock) { 799 final AutofillManagerServiceImpl service = getServiceForUserLocked(userId); 800 if (service != null) { 801 return service.isPccClassificationEnabled(); 802 } 803 } 804 return false; 805 } 806 807 // Called by Shell command getFieldDetectionServiceName(@serIdInt int userId)808 String getFieldDetectionServiceName(@UserIdInt int userId) { 809 enforceCallingPermissionForManagement(); 810 return mFieldClassificationResolver.readServiceName(userId); 811 } 812 813 // Called by Shell command setTemporaryDetectionService(@serIdInt int userId, @NonNull String serviceName, int durationMs)814 boolean setTemporaryDetectionService(@UserIdInt int userId, @NonNull String serviceName, 815 int durationMs) { 816 Slog.i(mTag, "setTemporaryDetectionService(" + userId + ") to " + serviceName 817 + " for " + durationMs + "ms"); 818 enforceCallingPermissionForManagement(); 819 820 Objects.requireNonNull(serviceName); 821 if (durationMs > 100000) { 822 // limit duration 823 } 824 825 mFieldClassificationResolver.setTemporaryService(userId, serviceName, durationMs); 826 827 return false; 828 } 829 830 // Called by Shell command resetTemporaryDetectionService(@serIdInt int userId)831 void resetTemporaryDetectionService(@UserIdInt int userId) { 832 enforceCallingPermissionForManagement(); 833 mFieldClassificationResolver.resetTemporaryService(userId); 834 } 835 836 /** 837 * Requests a count of saved passwords from the current service. 838 * 839 * @return {@code true} if the request succeeded 840 */ 841 // Called by Shell command requestSavedPasswordCount(@serIdInt int userId, @NonNull IResultReceiver receiver)842 boolean requestSavedPasswordCount(@UserIdInt int userId, @NonNull IResultReceiver receiver) { 843 enforceCallingPermissionForManagement(); 844 synchronized (mLock) { 845 final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId); 846 if (service != null) { 847 service.requestSavedPasswordCount(receiver); 848 return true; 849 } else if (sVerbose) { 850 Slog.v(TAG, "requestSavedPasswordCount(): no service for " + userId); 851 } 852 } 853 return false; 854 } 855 setLoggingLevelsLocked(boolean debug, boolean verbose)856 private void setLoggingLevelsLocked(boolean debug, boolean verbose) { 857 com.android.server.autofill.Helper.sDebug = debug; 858 android.view.autofill.Helper.sDebug = debug; 859 this.debug = debug; 860 861 com.android.server.autofill.Helper.sVerbose = verbose; 862 android.view.autofill.Helper.sVerbose = verbose; 863 this.verbose = verbose; 864 } 865 addCompatibilityModeRequestsLocked(@onNull AutofillManagerServiceImpl service , int userId)866 private void addCompatibilityModeRequestsLocked(@NonNull AutofillManagerServiceImpl service 867 , int userId) { 868 mAutofillCompatState.reset(userId); 869 final ArrayMap<String, Long> compatPackages = 870 service.getCompatibilityPackagesLocked(); 871 if (compatPackages == null || compatPackages.isEmpty()) { 872 return; 873 } 874 875 final Map<String, String[]> allowedPackages = getAllowedCompatModePackages(); 876 final int compatPackageCount = compatPackages.size(); 877 for (int i = 0; i < compatPackageCount; i++) { 878 final String packageName = compatPackages.keyAt(i); 879 if (allowedPackages == null || !allowedPackages.containsKey(packageName)) { 880 Slog.w(TAG, "Ignoring not allowed compat package " + packageName); 881 continue; 882 } 883 final Long maxVersionCode = compatPackages.valueAt(i); 884 if (maxVersionCode != null) { 885 mAutofillCompatState.addCompatibilityModeRequest(packageName, 886 maxVersionCode, allowedPackages.get(packageName), userId); 887 } 888 } 889 } 890 getAllowedCompatModePackagesFromDeviceConfig()891 private String getAllowedCompatModePackagesFromDeviceConfig() { 892 String config = DeviceConfig.getString( 893 DeviceConfig.NAMESPACE_AUTOFILL, 894 AutofillFeatureFlags.DEVICE_CONFIG_AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES, 895 /* defaultValue */ null); 896 if (!TextUtils.isEmpty(config)) { 897 return config; 898 } 899 // Fallback to Settings.Global.AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES if 900 // the device config is null. 901 return getAllowedCompatModePackagesFromSettings(); 902 } 903 getAllowedCompatModePackagesFromSettings()904 private String getAllowedCompatModePackagesFromSettings() { 905 return Settings.Global.getString( 906 getContext().getContentResolver(), 907 Settings.Global.AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES); 908 } 909 910 @Nullable getAllowedCompatModePackages()911 private Map<String, String[]> getAllowedCompatModePackages() { 912 return getAllowedCompatModePackages(getAllowedCompatModePackagesFromDeviceConfig()); 913 } 914 send(@onNull IResultReceiver receiver, int value)915 private void send(@NonNull IResultReceiver receiver, int value) { 916 try { 917 receiver.send(value, null); 918 } catch (RemoteException e) { 919 Slog.w(TAG, "Error async reporting result to client: " + e); 920 } 921 } 922 send(@onNull IResultReceiver receiver, @NonNull Bundle value)923 private void send(@NonNull IResultReceiver receiver, @NonNull Bundle value) { 924 try { 925 receiver.send(0, value); 926 } catch (RemoteException e) { 927 Slog.w(TAG, "Error async reporting result to client: " + e); 928 } 929 } 930 send(@onNull IResultReceiver receiver, @Nullable String value)931 private void send(@NonNull IResultReceiver receiver, @Nullable String value) { 932 send(receiver, SyncResultReceiver.bundleFor(value)); 933 } 934 send(@onNull IResultReceiver receiver, @Nullable String[] value)935 private void send(@NonNull IResultReceiver receiver, @Nullable String[] value) { 936 send(receiver, SyncResultReceiver.bundleFor(value)); 937 } 938 send(@onNull IResultReceiver receiver, @Nullable Parcelable value)939 private void send(@NonNull IResultReceiver receiver, @Nullable Parcelable value) { 940 send(receiver, SyncResultReceiver.bundleFor(value)); 941 } 942 send(@onNull IResultReceiver receiver, boolean value)943 private void send(@NonNull IResultReceiver receiver, boolean value) { 944 send(receiver, value ? 1 : 0); 945 } 946 send(@onNull IResultReceiver receiver, int value1, int value2)947 private void send(@NonNull IResultReceiver receiver, int value1, int value2) { 948 try { 949 receiver.send(value1, SyncResultReceiver.bundleFor(value2)); 950 } catch (RemoteException e) { 951 Slog.w(TAG, "Error async reporting result to client: " + e); 952 } 953 } 954 955 /** 956 * Whether the Autofill PCC Classification feature flag is enabled. 957 */ isPccClassificationFlagEnabled()958 public boolean isPccClassificationFlagEnabled() { 959 synchronized (mFlagLock) { 960 return mPccClassificationEnabled; 961 } 962 } 963 964 /** 965 * Whether the Autofill Provider shouldbe preferred over PCC results for selecting datasets. 966 */ preferProviderOverPcc()967 public boolean preferProviderOverPcc() { 968 synchronized (mFlagLock) { 969 return mPccPreferProviderOverPcc; 970 } 971 } 972 973 /** 974 * Whether to use the fallback for detection. 975 * If true, use data from secondary source if primary not present . 976 * For eg: if we prefer PCC over provider, and PCC detection didn't classify a field, however, 977 * autofill provider did, this flag would decide whether we use that result, and show some 978 * presentation for that particular field. 979 */ shouldUsePccFallback()980 public boolean shouldUsePccFallback() { 981 synchronized (mFlagLock) { 982 return mPccUseFallbackDetection; 983 } 984 } 985 986 /** 987 * Provides Autofill Hints that would be requested by the service from the Autofill Provider. 988 */ getPccProviderHints()989 public String getPccProviderHints() { 990 synchronized (mFlagLock) { 991 return mPccProviderHints; 992 } 993 } 994 995 @Nullable 996 @VisibleForTesting getAllowedCompatModePackages(String setting)997 static Map<String, String[]> getAllowedCompatModePackages(String setting) { 998 if (TextUtils.isEmpty(setting)) { 999 return null; 1000 } 1001 1002 final ArrayMap<String, String[]> compatPackages = new ArrayMap<>(); 1003 final SimpleStringSplitter splitter = new SimpleStringSplitter(COMPAT_PACKAGE_DELIMITER); 1004 splitter.setString(setting); 1005 while (splitter.hasNext()) { 1006 final String packageBlock = splitter.next(); 1007 final int urlBlockIndex = packageBlock.indexOf(COMPAT_PACKAGE_URL_IDS_BLOCK_BEGIN); 1008 final String packageName; 1009 final List<String> urlBarIds; 1010 if (urlBlockIndex == -1) { 1011 packageName = packageBlock; 1012 urlBarIds = null; 1013 } else { 1014 if (packageBlock.charAt(packageBlock.length() - 1) 1015 != COMPAT_PACKAGE_URL_IDS_BLOCK_END) { 1016 Slog.w(TAG, "Ignoring entry '" + packageBlock + "' on '" + setting 1017 + "'because it does not end on '" + COMPAT_PACKAGE_URL_IDS_BLOCK_END + 1018 "'"); 1019 continue; 1020 } 1021 packageName = packageBlock.substring(0, urlBlockIndex); 1022 urlBarIds = new ArrayList<>(); 1023 final String urlBarIdsBlock = 1024 packageBlock.substring(urlBlockIndex + 1, packageBlock.length() - 1); 1025 if (sVerbose) { 1026 Slog.v(TAG, "pkg:" + packageName + ": block:" + packageBlock + ": urls:" 1027 + urlBarIds + ": block:" + urlBarIdsBlock + ":"); 1028 } 1029 final SimpleStringSplitter splitter2 = 1030 new SimpleStringSplitter(COMPAT_PACKAGE_URL_IDS_DELIMITER); 1031 splitter2.setString(urlBarIdsBlock); 1032 while (splitter2.hasNext()) { 1033 final String urlBarId = splitter2.next(); 1034 urlBarIds.add(urlBarId); 1035 } 1036 } 1037 if (urlBarIds == null) { 1038 compatPackages.put(packageName, null); 1039 } else { 1040 final String[] urlBarIdsArray = new String[urlBarIds.size()]; 1041 urlBarIds.toArray(urlBarIdsArray); 1042 compatPackages.put(packageName, urlBarIdsArray); 1043 } 1044 } 1045 return compatPackages; 1046 } 1047 1048 /** 1049 * Gets the maximum number of partitions / fill requests. 1050 */ getPartitionMaxCount()1051 public static int getPartitionMaxCount() { 1052 synchronized (sLock) { 1053 return sPartitionMaxCount; 1054 } 1055 } 1056 1057 /** 1058 * Gets the maxium number of datasets visible in the UI. 1059 */ getVisibleDatasetsMaxCount()1060 public static int getVisibleDatasetsMaxCount() { 1061 synchronized (sLock) { 1062 return sVisibleDatasetsMaxCount; 1063 } 1064 } 1065 1066 private final class LocalService extends AutofillManagerInternal { 1067 @Override onBackKeyPressed()1068 public void onBackKeyPressed() { 1069 if (sDebug) Slog.d(TAG, "onBackKeyPressed()"); 1070 mUi.hideAll(null); 1071 synchronized (mLock) { 1072 final AutofillManagerServiceImpl service = 1073 getServiceForUserWithLocalBinderIdentityLocked( 1074 UserHandle.getCallingUserId()); 1075 service.onBackKeyPressed(); 1076 } 1077 } 1078 1079 @Override getAutofillOptions(@onNull String packageName, long versionCode, @UserIdInt int userId)1080 public AutofillOptions getAutofillOptions(@NonNull String packageName, 1081 long versionCode, @UserIdInt int userId) { 1082 final int loggingLevel; 1083 if (verbose) { 1084 loggingLevel = AutofillManager.FLAG_ADD_CLIENT_VERBOSE 1085 | AutofillManager.FLAG_ADD_CLIENT_DEBUG; 1086 } else if (debug) { 1087 loggingLevel = AutofillManager.FLAG_ADD_CLIENT_DEBUG; 1088 } else { 1089 loggingLevel = AutofillManager.NO_LOGGING; 1090 } 1091 final boolean compatModeEnabled = mAutofillCompatState.isCompatibilityModeRequested( 1092 packageName, versionCode, userId); 1093 final AutofillOptions options = new AutofillOptions(loggingLevel, compatModeEnabled); 1094 mAugmentedAutofillState.injectAugmentedAutofillInfo(options, userId, packageName); 1095 injectDisableAppInfo(options, userId, packageName); 1096 return options; 1097 } 1098 1099 @Override isAugmentedAutofillServiceForUser(int callingUid, int userId)1100 public boolean isAugmentedAutofillServiceForUser(int callingUid, int userId) { 1101 synchronized (mLock) { 1102 final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId); 1103 if (service != null) { 1104 return service.isAugmentedAutofillServiceForUserLocked(callingUid); 1105 } 1106 } 1107 return false; 1108 } 1109 injectDisableAppInfo(@onNull AutofillOptions options, int userId, String packageName)1110 private void injectDisableAppInfo(@NonNull AutofillOptions options, int userId, 1111 String packageName) { 1112 options.appDisabledExpiration = 1113 mDisabledInfoCache.getAppDisabledExpiration(userId, packageName); 1114 options.disabledActivities = 1115 mDisabledInfoCache.getAppDisabledActivities(userId, packageName); 1116 } 1117 } 1118 1119 /** 1120 * Compatibility mode metadata per package. 1121 */ 1122 static final class PackageCompatState { 1123 private final long maxVersionCode; 1124 private final String[] urlBarResourceIds; 1125 PackageCompatState(long maxVersionCode, String[] urlBarResourceIds)1126 PackageCompatState(long maxVersionCode, String[] urlBarResourceIds) { 1127 this.maxVersionCode = maxVersionCode; 1128 this.urlBarResourceIds = urlBarResourceIds; 1129 } 1130 1131 @Override toString()1132 public String toString() { 1133 return "maxVersionCode=" + maxVersionCode 1134 + ", urlBarResourceIds=" + Arrays.toString(urlBarResourceIds); 1135 } 1136 } 1137 1138 /** 1139 * Stores autofill disable information, i.e. {@link AutofillDisabledInfo}, keyed by user id. 1140 * The information is cleaned up when the service is removed. 1141 */ 1142 static final class DisabledInfoCache { 1143 1144 private final Object mLock = new Object(); 1145 1146 @GuardedBy("mLock") 1147 private final SparseArray<AutofillDisabledInfo> mCache = new SparseArray<>(); 1148 remove(@serIdInt int userId)1149 void remove(@UserIdInt int userId) { 1150 synchronized (mLock) { 1151 mCache.remove(userId); 1152 } 1153 } 1154 addDisabledAppLocked(@serIdInt int userId, @NonNull String packageName, long expiration)1155 void addDisabledAppLocked(@UserIdInt int userId, @NonNull String packageName, 1156 long expiration) { 1157 Objects.requireNonNull(packageName); 1158 synchronized (mLock) { 1159 AutofillDisabledInfo info = 1160 getOrCreateAutofillDisabledInfoByUserIdLocked(userId); 1161 info.putDisableAppsLocked(packageName, expiration); 1162 } 1163 } 1164 addDisabledActivityLocked(@serIdInt int userId, @NonNull ComponentName componentName, long expiration)1165 void addDisabledActivityLocked(@UserIdInt int userId, @NonNull ComponentName componentName, 1166 long expiration) { 1167 Objects.requireNonNull(componentName); 1168 synchronized (mLock) { 1169 AutofillDisabledInfo info = 1170 getOrCreateAutofillDisabledInfoByUserIdLocked(userId); 1171 info.putDisableActivityLocked(componentName, expiration); 1172 } 1173 } 1174 isAutofillDisabledLocked(@serIdInt int userId, @NonNull ComponentName componentName)1175 boolean isAutofillDisabledLocked(@UserIdInt int userId, 1176 @NonNull ComponentName componentName) { 1177 Objects.requireNonNull(componentName); 1178 final boolean disabled; 1179 synchronized (mLock) { 1180 final AutofillDisabledInfo info = mCache.get(userId); 1181 disabled = info != null ? info.isAutofillDisabledLocked(componentName) : false; 1182 } 1183 return disabled; 1184 } 1185 getAppDisabledExpiration(@serIdInt int userId, @NonNull String packageName)1186 long getAppDisabledExpiration(@UserIdInt int userId, @NonNull String packageName) { 1187 Objects.requireNonNull(packageName); 1188 final Long expiration; 1189 synchronized (mLock) { 1190 final AutofillDisabledInfo info = mCache.get(userId); 1191 expiration = info != null ? info.getAppDisabledExpirationLocked(packageName) : 0; 1192 } 1193 return expiration; 1194 } 1195 1196 @Nullable getAppDisabledActivities(@serIdInt int userId, @NonNull String packageName)1197 ArrayMap<String, Long> getAppDisabledActivities(@UserIdInt int userId, 1198 @NonNull String packageName) { 1199 Objects.requireNonNull(packageName); 1200 final ArrayMap<String, Long> disabledList; 1201 synchronized (mLock) { 1202 final AutofillDisabledInfo info = mCache.get(userId); 1203 disabledList = 1204 info != null ? info.getAppDisabledActivitiesLocked(packageName) : null; 1205 } 1206 return disabledList; 1207 } 1208 dump(@serIdInt int userId, String prefix, PrintWriter pw)1209 void dump(@UserIdInt int userId, String prefix, PrintWriter pw) { 1210 synchronized (mLock) { 1211 final AutofillDisabledInfo info = mCache.get(userId); 1212 if (info != null) { 1213 info.dumpLocked(prefix, pw); 1214 } 1215 } 1216 } 1217 1218 @NonNull getOrCreateAutofillDisabledInfoByUserIdLocked( @serIdInt int userId)1219 private AutofillDisabledInfo getOrCreateAutofillDisabledInfoByUserIdLocked( 1220 @UserIdInt int userId) { 1221 AutofillDisabledInfo info = mCache.get(userId); 1222 if (info == null) { 1223 info = new AutofillDisabledInfo(); 1224 mCache.put(userId, info); 1225 } 1226 return info; 1227 } 1228 } 1229 1230 /** 1231 * The autofill disable information. 1232 * <p> 1233 * This contains disable information set by the AutofillService, e.g. disabled application 1234 * expiration, disable activity expiration. 1235 */ 1236 private static final class AutofillDisabledInfo { 1237 /** 1238 * Apps disabled by the service; key is package name, value is when they will be enabled 1239 * again. 1240 */ 1241 private ArrayMap<String, Long> mDisabledApps; 1242 /** 1243 * Activities disabled by the service; key is component name, value is when they will be 1244 * enabled again. 1245 */ 1246 private ArrayMap<ComponentName, Long> mDisabledActivities; 1247 putDisableAppsLocked(@onNull String packageName, long expiration)1248 void putDisableAppsLocked(@NonNull String packageName, long expiration) { 1249 if (mDisabledApps == null) { 1250 mDisabledApps = new ArrayMap<>(1); 1251 } 1252 mDisabledApps.put(packageName, expiration); 1253 } 1254 putDisableActivityLocked(@onNull ComponentName componentName, long expiration)1255 void putDisableActivityLocked(@NonNull ComponentName componentName, long expiration) { 1256 if (mDisabledActivities == null) { 1257 mDisabledActivities = new ArrayMap<>(1); 1258 } 1259 mDisabledActivities.put(componentName, expiration); 1260 } 1261 getAppDisabledExpirationLocked(@onNull String packageName)1262 long getAppDisabledExpirationLocked(@NonNull String packageName) { 1263 if (mDisabledApps == null) { 1264 return 0; 1265 } 1266 final Long expiration = mDisabledApps.get(packageName); 1267 return expiration != null ? expiration : 0; 1268 } 1269 getAppDisabledActivitiesLocked(@onNull String packageName)1270 ArrayMap<String, Long> getAppDisabledActivitiesLocked(@NonNull String packageName) { 1271 if (mDisabledActivities != null) { 1272 final int size = mDisabledActivities.size(); 1273 ArrayMap<String, Long> disabledList = null; 1274 for (int i = 0; i < size; i++) { 1275 final ComponentName component = mDisabledActivities.keyAt(i); 1276 if (packageName.equals(component.getPackageName())) { 1277 if (disabledList == null) { 1278 disabledList = new ArrayMap<>(); 1279 } 1280 final long expiration = mDisabledActivities.valueAt(i); 1281 disabledList.put(component.flattenToShortString(), expiration); 1282 } 1283 } 1284 return disabledList; 1285 } 1286 return null; 1287 } 1288 isAutofillDisabledLocked(@onNull ComponentName componentName)1289 boolean isAutofillDisabledLocked(@NonNull ComponentName componentName) { 1290 // Check activities first. 1291 long elapsedTime = 0; 1292 if (mDisabledActivities != null) { 1293 elapsedTime = SystemClock.elapsedRealtime(); 1294 final Long expiration = mDisabledActivities.get(componentName); 1295 if (expiration != null) { 1296 if (expiration >= elapsedTime) return true; 1297 // Restriction expired - clean it up. 1298 if (sVerbose) { 1299 Slog.v(TAG, "Removing " + componentName.toShortString() 1300 + " from disabled list"); 1301 } 1302 mDisabledActivities.remove(componentName); 1303 } 1304 } 1305 1306 // Then check apps. 1307 final String packageName = componentName.getPackageName(); 1308 if (mDisabledApps == null) return false; 1309 1310 final Long expiration = mDisabledApps.get(packageName); 1311 if (expiration == null) return false; 1312 1313 if (elapsedTime == 0) { 1314 elapsedTime = SystemClock.elapsedRealtime(); 1315 } 1316 1317 if (expiration >= elapsedTime) return true; 1318 1319 // Restriction expired - clean it up. 1320 if (sVerbose) Slog.v(TAG, "Removing " + packageName + " from disabled list"); 1321 mDisabledApps.remove(packageName); 1322 return false; 1323 } 1324 dumpLocked(String prefix, PrintWriter pw)1325 void dumpLocked(String prefix, PrintWriter pw) { 1326 pw.print(prefix); pw.print("Disabled apps: "); 1327 if (mDisabledApps == null) { 1328 pw.println("N/A"); 1329 } else { 1330 final int size = mDisabledApps.size(); 1331 pw.println(size); 1332 final StringBuilder builder = new StringBuilder(); 1333 final long now = SystemClock.elapsedRealtime(); 1334 for (int i = 0; i < size; i++) { 1335 final String packageName = mDisabledApps.keyAt(i); 1336 final long expiration = mDisabledApps.valueAt(i); 1337 builder.append(prefix).append(prefix) 1338 .append(i).append(". ").append(packageName).append(": "); 1339 TimeUtils.formatDuration((expiration - now), builder); 1340 builder.append('\n'); 1341 } 1342 pw.println(builder); 1343 } 1344 1345 pw.print(prefix); pw.print("Disabled activities: "); 1346 if (mDisabledActivities == null) { 1347 pw.println("N/A"); 1348 } else { 1349 final int size = mDisabledActivities.size(); 1350 pw.println(size); 1351 final StringBuilder builder = new StringBuilder(); 1352 final long now = SystemClock.elapsedRealtime(); 1353 for (int i = 0; i < size; i++) { 1354 final ComponentName component = mDisabledActivities.keyAt(i); 1355 final long expiration = mDisabledActivities.valueAt(i); 1356 builder.append(prefix).append(prefix) 1357 .append(i).append(". ").append(component).append(": "); 1358 TimeUtils.formatDuration((expiration - now), builder); 1359 builder.append('\n'); 1360 } 1361 pw.println(builder); 1362 } 1363 } 1364 } 1365 1366 /** 1367 * Compatibility mode metadata associated with all services. 1368 * 1369 * <p>This object is defined here instead of on each {@link AutofillManagerServiceImpl} because 1370 * it cannot hold a lock on the main lock when 1371 * {@link AutofillCompatState#isCompatibilityModeRequested(String, long, int)} is called by 1372 * external services. 1373 */ 1374 static final class AutofillCompatState { 1375 private final Object mLock = new Object(); 1376 1377 /** 1378 * Map of app->compat_state per user. 1379 */ 1380 @GuardedBy("mLock") 1381 private SparseArray<ArrayMap<String, PackageCompatState>> mUserSpecs; 1382 isCompatibilityModeRequested(@onNull String packageName, long versionCode, @UserIdInt int userId)1383 boolean isCompatibilityModeRequested(@NonNull String packageName, 1384 long versionCode, @UserIdInt int userId) { 1385 synchronized (mLock) { 1386 if (mUserSpecs == null) { 1387 return false; 1388 } 1389 final ArrayMap<String, PackageCompatState> userSpec = mUserSpecs.get(userId); 1390 if (userSpec == null) { 1391 return false; 1392 } 1393 final PackageCompatState metadata = userSpec.get(packageName); 1394 if (metadata == null) { 1395 return false; 1396 } 1397 return versionCode <= metadata.maxVersionCode; 1398 } 1399 } 1400 1401 @Nullable getUrlBarResourceIds(@onNull String packageName, @UserIdInt int userId)1402 String[] getUrlBarResourceIds(@NonNull String packageName, @UserIdInt int userId) { 1403 synchronized (mLock) { 1404 if (mUserSpecs == null) { 1405 return null; 1406 } 1407 final ArrayMap<String, PackageCompatState> userSpec = mUserSpecs.get(userId); 1408 if (userSpec == null) { 1409 return null; 1410 } 1411 final PackageCompatState metadata = userSpec.get(packageName); 1412 if (metadata == null) { 1413 return null; 1414 } 1415 return metadata.urlBarResourceIds; 1416 } 1417 } 1418 addCompatibilityModeRequest(@onNull String packageName, long versionCode, @Nullable String[] urlBarResourceIds, @UserIdInt int userId)1419 void addCompatibilityModeRequest(@NonNull String packageName, 1420 long versionCode, @Nullable String[] urlBarResourceIds, @UserIdInt int userId) { 1421 synchronized (mLock) { 1422 if (mUserSpecs == null) { 1423 mUserSpecs = new SparseArray<>(); 1424 } 1425 ArrayMap<String, PackageCompatState> userSpec = mUserSpecs.get(userId); 1426 if (userSpec == null) { 1427 userSpec = new ArrayMap<>(); 1428 mUserSpecs.put(userId, userSpec); 1429 } 1430 userSpec.put(packageName, 1431 new PackageCompatState(versionCode, urlBarResourceIds)); 1432 } 1433 } 1434 removeCompatibilityModeRequests(@serIdInt int userId)1435 void removeCompatibilityModeRequests(@UserIdInt int userId) { 1436 synchronized (mLock) { 1437 if (mUserSpecs != null) { 1438 mUserSpecs.remove(userId); 1439 if (mUserSpecs.size() <= 0) { 1440 mUserSpecs = null; 1441 } 1442 } 1443 } 1444 } 1445 reset(int userId)1446 void reset(int userId) { 1447 synchronized (mLock) { 1448 if (mUserSpecs != null) { 1449 mUserSpecs.delete(userId); 1450 final int newSize = mUserSpecs.size(); 1451 if (newSize == 0) { 1452 if (sVerbose) Slog.v(TAG, "reseting mUserSpecs"); 1453 mUserSpecs = null; 1454 } else { 1455 if (sVerbose) Slog.v(TAG, "mUserSpecs down to " + newSize); 1456 } 1457 } 1458 } 1459 } 1460 dump(String prefix, PrintWriter pw)1461 private void dump(String prefix, PrintWriter pw) { 1462 synchronized (mLock) { 1463 if (mUserSpecs == null) { 1464 pw.println("N/A"); 1465 return; 1466 } 1467 pw.println(); 1468 final String prefix2 = prefix + " "; 1469 for (int i = 0; i < mUserSpecs.size(); i++) { 1470 final int user = mUserSpecs.keyAt(i); 1471 pw.print(prefix); 1472 pw.print("User: "); 1473 pw.println(user); 1474 final ArrayMap<String, PackageCompatState> perUser = mUserSpecs.valueAt(i); 1475 for (int j = 0; j < perUser.size(); j++) { 1476 final String packageName = perUser.keyAt(j); 1477 final PackageCompatState state = perUser.valueAt(j); 1478 pw.print(prefix2); pw.print(packageName); pw.print(": "); pw.println(state); 1479 } 1480 } 1481 } 1482 } 1483 } 1484 1485 /** 1486 * Augmented autofill metadata associated with all services. 1487 * 1488 * <p>This object is defined here instead of on each {@link AutofillManagerServiceImpl} because 1489 * it cannot hold a lock on the main lock when 1490 * {@link AugmentedAutofillState#injectAugmentedAutofillInfo(AutofillOptions, int, String)} 1491 * is called by external services. 1492 */ 1493 static final class AugmentedAutofillState extends GlobalWhitelistState { 1494 1495 @GuardedBy("mGlobalWhitelistStateLock") 1496 private final SparseArray<String> mServicePackages = new SparseArray<>(); 1497 @GuardedBy("mGlobalWhitelistStateLock") 1498 private final SparseBooleanArray mTemporaryServices = new SparseBooleanArray(); 1499 setServiceInfo(@serIdInt int userId, @Nullable String serviceName, boolean isTemporary)1500 private void setServiceInfo(@UserIdInt int userId, @Nullable String serviceName, 1501 boolean isTemporary) { 1502 synchronized (mGlobalWhitelistStateLock) { 1503 if (isTemporary) { 1504 mTemporaryServices.put(userId, true); 1505 } else { 1506 mTemporaryServices.delete(userId); 1507 } 1508 if (serviceName != null) { 1509 final ComponentName componentName = 1510 ComponentName.unflattenFromString(serviceName); 1511 if (componentName == null) { 1512 Slog.w(TAG, "setServiceInfo(): invalid name: " + serviceName); 1513 mServicePackages.remove(userId); 1514 } else { 1515 mServicePackages.put(userId, componentName.getPackageName()); 1516 } 1517 } else { 1518 mServicePackages.remove(userId); 1519 } 1520 } 1521 } 1522 injectAugmentedAutofillInfo(@onNull AutofillOptions options, @UserIdInt int userId, @NonNull String packageName)1523 public void injectAugmentedAutofillInfo(@NonNull AutofillOptions options, 1524 @UserIdInt int userId, @NonNull String packageName) { 1525 synchronized (mGlobalWhitelistStateLock) { 1526 if (mWhitelisterHelpers == null) return; 1527 final WhitelistHelper helper = mWhitelisterHelpers.get(userId); 1528 if (helper != null) { 1529 options.augmentedAutofillEnabled = helper.isWhitelisted(packageName); 1530 options.whitelistedActivitiesForAugmentedAutofill = helper 1531 .getWhitelistedComponents(packageName); 1532 } 1533 } 1534 } 1535 1536 @Override isWhitelisted(@serIdInt int userId, @NonNull ComponentName componentName)1537 public boolean isWhitelisted(@UserIdInt int userId, @NonNull ComponentName componentName) { 1538 synchronized (mGlobalWhitelistStateLock) { 1539 if (!super.isWhitelisted(userId, componentName)) return false; 1540 1541 if (Build.IS_USER && mTemporaryServices.get(userId)) { 1542 final String packageName = componentName.getPackageName(); 1543 if (!packageName.equals(mServicePackages.get(userId))) { 1544 Slog.w(TAG, "Ignoring package " + packageName + " for augmented autofill " 1545 + "while using temporary service " + mServicePackages.get(userId)); 1546 return false; 1547 } 1548 } 1549 } 1550 return true; 1551 } 1552 1553 @Override dump(@onNull String prefix, @NonNull PrintWriter pw)1554 public void dump(@NonNull String prefix, @NonNull PrintWriter pw) { 1555 super.dump(prefix, pw); 1556 1557 synchronized (mGlobalWhitelistStateLock) { 1558 if (mServicePackages.size() > 0) { 1559 pw.print(prefix); pw.print("Service packages: "); pw.println(mServicePackages); 1560 } 1561 if (mTemporaryServices.size() > 0) { 1562 pw.print(prefix); pw.print("Temp services: "); pw.println(mTemporaryServices); 1563 } 1564 } 1565 } 1566 } 1567 1568 final class AutoFillManagerServiceStub extends IAutoFillManager.Stub { 1569 @Override addClient(IAutoFillManagerClient client, ComponentName componentName, int userId, IResultReceiver receiver)1570 public void addClient(IAutoFillManagerClient client, ComponentName componentName, 1571 int userId, IResultReceiver receiver) { 1572 int flags = 0; 1573 try { 1574 synchronized (mLock) { 1575 final int enabledFlags = 1576 getServiceForUserWithLocalBinderIdentityLocked(userId) 1577 .addClientLocked(client, componentName); 1578 if (enabledFlags != 0) { 1579 flags |= enabledFlags; 1580 } 1581 if (sDebug) { 1582 flags |= AutofillManager.FLAG_ADD_CLIENT_DEBUG; 1583 } 1584 if (sVerbose) { 1585 flags |= AutofillManager.FLAG_ADD_CLIENT_VERBOSE; 1586 } 1587 } 1588 } catch (Exception ex) { 1589 // Don't do anything, send back default flags 1590 Log.wtf(TAG, "addClient(): failed " + ex.toString()); 1591 } finally { 1592 send(receiver, flags); 1593 } 1594 } 1595 1596 @Override removeClient(IAutoFillManagerClient client, int userId)1597 public void removeClient(IAutoFillManagerClient client, int userId) { 1598 synchronized (mLock) { 1599 final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId); 1600 if (service != null) { 1601 service.removeClientLocked(client); 1602 } else if (sVerbose) { 1603 Slog.v(TAG, "removeClient(): no service for " + userId); 1604 } 1605 } 1606 } 1607 1608 @Override setAuthenticationResult(Bundle data, int sessionId, int authenticationId, int userId)1609 public void setAuthenticationResult(Bundle data, int sessionId, int authenticationId, 1610 int userId) { 1611 synchronized (mLock) { 1612 final AutofillManagerServiceImpl service = 1613 getServiceForUserWithLocalBinderIdentityLocked(userId); 1614 service.setAuthenticationResultLocked(data, sessionId, authenticationId, 1615 getCallingUid()); 1616 } 1617 } 1618 1619 @Override setHasCallback(int sessionId, int userId, boolean hasIt)1620 public void setHasCallback(int sessionId, int userId, boolean hasIt) { 1621 synchronized (mLock) { 1622 final AutofillManagerServiceImpl service = 1623 getServiceForUserWithLocalBinderIdentityLocked(userId); 1624 service.setHasCallback(sessionId, getCallingUid(), hasIt); 1625 } 1626 } 1627 1628 @Override startSession(IBinder activityToken, IBinder clientCallback, AutofillId autofillId, Rect bounds, AutofillValue value, int userId, boolean hasCallback, int flags, ComponentName clientActivity, boolean compatMode, IResultReceiver receiver)1629 public void startSession(IBinder activityToken, IBinder clientCallback, 1630 AutofillId autofillId, Rect bounds, AutofillValue value, int userId, 1631 boolean hasCallback, int flags, ComponentName clientActivity, 1632 boolean compatMode, IResultReceiver receiver) { 1633 1634 requireNonNull(activityToken, "activityToken"); 1635 requireNonNull(clientCallback, "clientCallback"); 1636 requireNonNull(autofillId, "autofillId"); 1637 requireNonNull(clientActivity, "clientActivity"); 1638 final String packageName = requireNonNull(clientActivity.getPackageName()); 1639 1640 Preconditions.checkArgument(userId == UserHandle.getUserId(getCallingUid()), "userId"); 1641 1642 try { 1643 getContext().getPackageManager().getPackageInfoAsUser(packageName, 0, userId); 1644 } catch (PackageManager.NameNotFoundException e) { 1645 throw new IllegalArgumentException(packageName + " is not a valid package", e); 1646 } 1647 1648 // TODO(b/113281366): add a callback method on AM to be notified when a task is finished 1649 // so we can clean up sessions kept alive 1650 final int taskId = mAm.getTaskIdForActivity(activityToken, false); 1651 final long result; 1652 synchronized (mLock) { 1653 final AutofillManagerServiceImpl service = 1654 getServiceForUserWithLocalBinderIdentityLocked(userId); 1655 result = service.startSessionLocked(activityToken, taskId, getCallingUid(), 1656 clientCallback, autofillId, bounds, value, hasCallback, clientActivity, 1657 compatMode, mAllowInstantService, flags); 1658 } 1659 final int sessionId = (int) result; 1660 final int resultFlags = (int) (result >> 32); 1661 if (resultFlags != 0) { 1662 send(receiver, sessionId, resultFlags); 1663 } else { 1664 send(receiver, sessionId); 1665 } 1666 } 1667 1668 @Override getFillEventHistory(@onNull IResultReceiver receiver)1669 public void getFillEventHistory(@NonNull IResultReceiver receiver) throws RemoteException { 1670 FillEventHistory fillEventHistory = null; 1671 final int userId = UserHandle.getCallingUserId(); 1672 1673 try { 1674 synchronized (mLock) { 1675 final AutofillManagerServiceImpl service = 1676 peekServiceForUserWithLocalBinderIdentityLocked(userId); 1677 if (service != null) { 1678 fillEventHistory = service.getFillEventHistory(getCallingUid()); 1679 } else if (sVerbose) { 1680 Slog.v(TAG, "getFillEventHistory(): no service for " + userId); 1681 } 1682 } 1683 } catch (Exception ex) { 1684 // Do not raise the exception, just send back the null response 1685 Log.wtf(TAG, "getFillEventHistory(): failed " + ex.toString()); 1686 } finally { 1687 send(receiver, fillEventHistory); 1688 } 1689 } 1690 1691 @Override getUserData(@onNull IResultReceiver receiver)1692 public void getUserData(@NonNull IResultReceiver receiver) throws RemoteException { 1693 UserData userData = null; 1694 final int userId = UserHandle.getCallingUserId(); 1695 1696 try { 1697 synchronized (mLock) { 1698 final AutofillManagerServiceImpl service = 1699 peekServiceForUserWithLocalBinderIdentityLocked(userId); 1700 if (service != null) { 1701 userData = service.getUserData(getCallingUid()); 1702 } else if (sVerbose) { 1703 Slog.v(TAG, "getUserData(): no service for " + userId); 1704 } 1705 } 1706 } catch (Exception ex) { 1707 // Do not raise the exception, just send back the null response 1708 Log.wtf(TAG, "getUserData(): failed " + ex.toString()); 1709 } finally { 1710 send(receiver, userData); 1711 } 1712 } 1713 1714 @Override getUserDataId(@onNull IResultReceiver receiver)1715 public void getUserDataId(@NonNull IResultReceiver receiver) throws RemoteException { 1716 UserData userData = null; 1717 final int userId = UserHandle.getCallingUserId(); 1718 1719 try { 1720 synchronized (mLock) { 1721 final AutofillManagerServiceImpl service = 1722 peekServiceForUserWithLocalBinderIdentityLocked(userId); 1723 if (service != null) { 1724 userData = service.getUserData(getCallingUid()); 1725 } else if (sVerbose) { 1726 Slog.v(TAG, "getUserDataId(): no service for " + userId); 1727 } 1728 } 1729 } catch (Exception ex) { 1730 // Do not raise the exception, just send back the null response 1731 Log.wtf(TAG, "getUserDataId(): failed " + ex.toString()); 1732 } finally { 1733 final String userDataId = userData == null ? null : userData.getId(); 1734 send(receiver, userDataId); 1735 } 1736 } 1737 1738 @Override setUserData(UserData userData)1739 public void setUserData(UserData userData) throws RemoteException { 1740 final int userId = UserHandle.getCallingUserId(); 1741 1742 synchronized (mLock) { 1743 final AutofillManagerServiceImpl service = 1744 peekServiceForUserWithLocalBinderIdentityLocked(userId); 1745 if (service != null) { 1746 service.setUserData(getCallingUid(), userData); 1747 } else if (sVerbose) { 1748 Slog.v(TAG, "setUserData(): no service for " + userId); 1749 } 1750 } 1751 } 1752 1753 @Override isFieldClassificationEnabled(@onNull IResultReceiver receiver)1754 public void isFieldClassificationEnabled(@NonNull IResultReceiver receiver) 1755 throws RemoteException { 1756 boolean enabled = false; 1757 final int userId = UserHandle.getCallingUserId(); 1758 1759 try { 1760 synchronized (mLock) { 1761 final AutofillManagerServiceImpl service = 1762 peekServiceForUserWithLocalBinderIdentityLocked(userId); 1763 if (service != null) { 1764 enabled = service.isFieldClassificationEnabled(getCallingUid()); 1765 } else if (sVerbose) { 1766 Slog.v(TAG, "isFieldClassificationEnabled(): no service for " + userId); 1767 } 1768 } 1769 } catch (Exception ex) { 1770 // Do not raise the exception, just send back false 1771 Log.wtf(TAG, "isFieldClassificationEnabled(): failed " + ex.toString()); 1772 } finally { 1773 send(receiver, enabled); 1774 } 1775 } 1776 1777 @Override getDefaultFieldClassificationAlgorithm(@onNull IResultReceiver receiver)1778 public void getDefaultFieldClassificationAlgorithm(@NonNull IResultReceiver receiver) 1779 throws RemoteException { 1780 String algorithm = null; 1781 final int userId = UserHandle.getCallingUserId(); 1782 1783 try { 1784 synchronized (mLock) { 1785 final AutofillManagerServiceImpl service = 1786 peekServiceForUserWithLocalBinderIdentityLocked(userId); 1787 if (service != null) { 1788 algorithm = service.getDefaultFieldClassificationAlgorithm(getCallingUid()); 1789 } else { 1790 if (sVerbose) { 1791 Slog.v(TAG, "getDefaultFcAlgorithm(): no service for " + userId); 1792 } 1793 } 1794 } 1795 } catch (Exception ex) { 1796 // Do not raise the exception, just send back null 1797 Log.wtf(TAG, "getDefaultFieldClassificationAlgorithm(): failed " + ex.toString()); 1798 } finally { 1799 send(receiver, algorithm); 1800 } 1801 1802 } 1803 1804 @Override setAugmentedAutofillWhitelist(@ullable List<String> packages, @Nullable List<ComponentName> activities, @NonNull IResultReceiver receiver)1805 public void setAugmentedAutofillWhitelist(@Nullable List<String> packages, 1806 @Nullable List<ComponentName> activities, @NonNull IResultReceiver receiver) 1807 throws RemoteException { 1808 boolean ok = false; 1809 final int userId = UserHandle.getCallingUserId(); 1810 1811 try { 1812 synchronized (mLock) { 1813 final AutofillManagerServiceImpl service = 1814 peekServiceForUserWithLocalBinderIdentityLocked(userId); 1815 if (service != null) { 1816 ok = service.setAugmentedAutofillWhitelistLocked(packages, activities, 1817 getCallingUid()); 1818 } else { 1819 if (sVerbose) { 1820 Slog.v(TAG, "setAugmentedAutofillWhitelist(): no service for " 1821 + userId); 1822 } 1823 } 1824 } 1825 } catch (Exception ex) { 1826 // Do not raise the exception, return the default value 1827 Log.wtf(TAG, "setAugmentedAutofillWhitelist(): failed " + ex.toString()); 1828 } finally { 1829 send(receiver, 1830 ok ? AutofillManager.RESULT_OK 1831 : AutofillManager.RESULT_CODE_NOT_SERVICE); 1832 } 1833 } 1834 1835 @Override getAvailableFieldClassificationAlgorithms(@onNull IResultReceiver receiver)1836 public void getAvailableFieldClassificationAlgorithms(@NonNull IResultReceiver receiver) 1837 throws RemoteException { 1838 String[] algorithms = null; 1839 final int userId = UserHandle.getCallingUserId(); 1840 1841 try { 1842 synchronized (mLock) { 1843 final AutofillManagerServiceImpl service = 1844 peekServiceForUserWithLocalBinderIdentityLocked(userId); 1845 if (service != null) { 1846 algorithms = service 1847 .getAvailableFieldClassificationAlgorithms(getCallingUid()); 1848 } else { 1849 if (sVerbose) { 1850 Slog.v(TAG, "getAvailableFcAlgorithms(): no service for " + userId); 1851 } 1852 } 1853 } 1854 } catch (Exception ex) { 1855 // Do not raise the exception, return null 1856 Log.wtf(TAG, "getAvailableFieldClassificationAlgorithms(): failed " 1857 + ex.toString()); 1858 } finally { 1859 send(receiver, algorithms); 1860 } 1861 } 1862 1863 @Override getAutofillServiceComponentName(@onNull IResultReceiver receiver)1864 public void getAutofillServiceComponentName(@NonNull IResultReceiver receiver) 1865 throws RemoteException { 1866 ComponentName componentName = null; 1867 final int userId = UserHandle.getCallingUserId(); 1868 1869 try { 1870 synchronized (mLock) { 1871 final AutofillManagerServiceImpl service = 1872 peekServiceForUserWithLocalBinderIdentityLocked(userId); 1873 if (service != null) { 1874 componentName = service.getServiceComponentName(); 1875 } else if (sVerbose) { 1876 Slog.v(TAG, "getAutofillServiceComponentName(): no service for " + userId); 1877 } 1878 } 1879 } catch (Exception ex) { 1880 Log.wtf(TAG, "getAutofillServiceComponentName(): failed " + ex.toString()); 1881 } finally { 1882 send(receiver, componentName); 1883 } 1884 } 1885 1886 @Override restoreSession(int sessionId, @NonNull IBinder activityToken, @NonNull IBinder appCallback, @NonNull IResultReceiver receiver)1887 public void restoreSession(int sessionId, @NonNull IBinder activityToken, 1888 @NonNull IBinder appCallback, @NonNull IResultReceiver receiver) 1889 throws RemoteException { 1890 boolean restored = false; 1891 final int userId = UserHandle.getCallingUserId(); 1892 1893 try { 1894 Objects.requireNonNull(activityToken, "activityToken"); 1895 Objects.requireNonNull(appCallback, "appCallback"); 1896 1897 synchronized (mLock) { 1898 final AutofillManagerServiceImpl service = 1899 peekServiceForUserWithLocalBinderIdentityLocked(userId); 1900 if (service != null) { 1901 restored = service.restoreSession(sessionId, getCallingUid(), activityToken, 1902 appCallback); 1903 } else if (sVerbose) { 1904 Slog.v(TAG, "restoreSession(): no service for " + userId); 1905 } 1906 } 1907 } catch (Exception ex) { 1908 // Do not propagate exception, send back status 1909 Log.wtf(TAG, "restoreSession(): failed " + ex.toString()); 1910 } finally { 1911 send(receiver, restored); 1912 } 1913 } 1914 1915 @Override updateSession(int sessionId, AutofillId autoFillId, Rect bounds, AutofillValue value, int action, int flags, int userId)1916 public void updateSession(int sessionId, AutofillId autoFillId, Rect bounds, 1917 AutofillValue value, int action, int flags, int userId) { 1918 synchronized (mLock) { 1919 final AutofillManagerServiceImpl service = 1920 peekServiceForUserWithLocalBinderIdentityLocked(userId); 1921 if (service != null) { 1922 service.updateSessionLocked(sessionId, getCallingUid(), autoFillId, bounds, 1923 value, action, flags); 1924 } else if (sVerbose) { 1925 Slog.v(TAG, "updateSession(): no service for " + userId); 1926 } 1927 } 1928 } 1929 1930 @Override setAutofillFailure(int sessionId, @NonNull List<AutofillId> ids, int userId)1931 public void setAutofillFailure(int sessionId, @NonNull List<AutofillId> ids, int userId) { 1932 synchronized (mLock) { 1933 final AutofillManagerServiceImpl service = 1934 peekServiceForUserWithLocalBinderIdentityLocked(userId); 1935 if (service != null) { 1936 service.setAutofillFailureLocked(sessionId, getCallingUid(), ids); 1937 } else if (sVerbose) { 1938 Slog.v(TAG, "setAutofillFailure(): no service for " + userId); 1939 } 1940 } 1941 } 1942 1943 @Override finishSession(int sessionId, int userId, @AutofillCommitReason int commitReason)1944 public void finishSession(int sessionId, int userId, 1945 @AutofillCommitReason int commitReason) { 1946 synchronized (mLock) { 1947 final AutofillManagerServiceImpl service = 1948 peekServiceForUserWithLocalBinderIdentityLocked(userId); 1949 if (service != null) { 1950 service.finishSessionLocked(sessionId, getCallingUid(), commitReason); 1951 } else if (sVerbose) { 1952 Slog.v(TAG, "finishSession(): no service for " + userId); 1953 } 1954 } 1955 } 1956 1957 @Override cancelSession(int sessionId, int userId)1958 public void cancelSession(int sessionId, int userId) { 1959 synchronized (mLock) { 1960 final AutofillManagerServiceImpl service = 1961 peekServiceForUserWithLocalBinderIdentityLocked(userId); 1962 if (service != null) { 1963 service.cancelSessionLocked(sessionId, getCallingUid()); 1964 } else if (sVerbose) { 1965 Slog.v(TAG, "cancelSession(): no service for " + userId); 1966 } 1967 } 1968 1969 } 1970 1971 @Override disableOwnedAutofillServices(int userId)1972 public void disableOwnedAutofillServices(int userId) { 1973 synchronized (mLock) { 1974 final AutofillManagerServiceImpl service = 1975 peekServiceForUserWithLocalBinderIdentityLocked(userId); 1976 if (service != null) { 1977 service.disableOwnedAutofillServicesLocked(Binder.getCallingUid()); 1978 } else if (sVerbose) { 1979 Slog.v(TAG, "cancelSession(): no service for " + userId); 1980 } 1981 } 1982 } 1983 1984 @Override isServiceSupported(int userId, @NonNull IResultReceiver receiver)1985 public void isServiceSupported(int userId, @NonNull IResultReceiver receiver) { 1986 boolean supported = false; 1987 1988 try { 1989 synchronized (mLock) { 1990 supported = !isDisabledLocked(userId); 1991 } 1992 } catch (Exception ex) { 1993 // Do not propagate exception 1994 Log.wtf(TAG, "isServiceSupported(): failed " + ex.toString()); 1995 } finally { 1996 send(receiver, supported); 1997 } 1998 } 1999 2000 @Override isServiceEnabled(int userId, @NonNull String packageName, @NonNull IResultReceiver receiver)2001 public void isServiceEnabled(int userId, @NonNull String packageName, 2002 @NonNull IResultReceiver receiver) { 2003 boolean enabled = false; 2004 2005 try { 2006 synchronized (mLock) { 2007 final AutofillManagerServiceImpl service = 2008 peekServiceForUserWithLocalBinderIdentityLocked(userId); 2009 enabled = Objects.equals(packageName, service.getServicePackageName()); 2010 } 2011 } catch (Exception ex) { 2012 // Do not propagate exception 2013 Log.wtf(TAG, "isServiceEnabled(): failed " + ex.toString()); 2014 } finally { 2015 send(receiver, enabled); 2016 } 2017 } 2018 2019 @Override onPendingSaveUi(int operation, IBinder token)2020 public void onPendingSaveUi(int operation, IBinder token) { 2021 Objects.requireNonNull(token, "token"); 2022 Preconditions.checkArgument(operation == AutofillManager.PENDING_UI_OPERATION_CANCEL 2023 || operation == AutofillManager.PENDING_UI_OPERATION_RESTORE, 2024 "invalid operation: %d", operation); 2025 synchronized (mLock) { 2026 final AutofillManagerServiceImpl service = 2027 peekServiceForUserWithLocalBinderIdentityLocked( 2028 UserHandle.getCallingUserId()); 2029 if (service != null) { 2030 service.onPendingSaveUi(operation, token); 2031 } 2032 } 2033 } 2034 2035 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)2036 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2037 if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) return; 2038 2039 boolean showHistory = true; 2040 boolean uiOnly = false; 2041 if (args != null) { 2042 for (String arg : args) { 2043 switch (arg) { 2044 case "--no-history": 2045 showHistory = false; 2046 break; 2047 case "--ui-only": 2048 uiOnly = true; 2049 break; 2050 case "--help": 2051 pw.println("Usage: dumpsys autofill [--ui-only|--no-history]"); 2052 return; 2053 default: 2054 Slog.w(TAG, "Ignoring invalid dump arg: " + arg); 2055 } 2056 } 2057 } 2058 2059 if (uiOnly) { 2060 mUi.dump(pw); 2061 return; 2062 } 2063 2064 final String prefix = " "; 2065 boolean realDebug = sDebug; 2066 boolean realVerbose = sVerbose; 2067 try { 2068 sDebug = sVerbose = true; 2069 synchronized (mLock) { 2070 pw.print("sDebug: "); 2071 pw.print(realDebug); 2072 pw.print(" sVerbose: "); 2073 pw.println(realVerbose); 2074 pw.print("Flags: "); 2075 synchronized (mFlagLock) { 2076 pw.print("mPccClassificationEnabled="); 2077 pw.print(mPccClassificationEnabled); 2078 pw.print(";"); 2079 pw.print("mPccPreferProviderOverPcc="); 2080 pw.print(mPccPreferProviderOverPcc); 2081 pw.print(";"); 2082 pw.print("mPccUseFallbackDetection="); 2083 pw.print(mPccUseFallbackDetection); 2084 pw.print(";"); 2085 pw.print("mPccProviderHints="); 2086 pw.println(mPccProviderHints); 2087 } 2088 // Dump per-user services 2089 dumpLocked("", pw); 2090 mAugmentedAutofillResolver.dumpShort(pw); 2091 pw.println(); 2092 pw.print("Max partitions per session: "); 2093 pw.println(sPartitionMaxCount); 2094 pw.print("Max visible datasets: "); 2095 pw.println(sVisibleDatasetsMaxCount); 2096 if (sFullScreenMode != null) { 2097 pw.print("Overridden full-screen mode: "); 2098 pw.println(sFullScreenMode); 2099 } 2100 pw.println("User data constraints: "); 2101 UserData.dumpConstraints(prefix, pw); 2102 mUi.dump(pw); 2103 pw.print("Autofill Compat State: "); 2104 mAutofillCompatState.dump(prefix, pw); 2105 pw.print("from device config: "); 2106 pw.println(getAllowedCompatModePackagesFromDeviceConfig()); 2107 if (mSupportedSmartSuggestionModes != 0) { 2108 pw.print("Smart Suggestion modes: "); 2109 pw.println(getSmartSuggestionModeToString(mSupportedSmartSuggestionModes)); 2110 } 2111 pw.print("Augmented Service Idle Unbind Timeout: "); 2112 pw.println(mAugmentedServiceIdleUnbindTimeoutMs); 2113 pw.print("Augmented Service Request Timeout: "); 2114 pw.println(mAugmentedServiceRequestTimeoutMs); 2115 if (showHistory) { 2116 pw.println(); 2117 pw.println("Requests history:"); 2118 pw.println(); 2119 mRequestsHistory.reverseDump(fd, pw, args); 2120 pw.println(); 2121 pw.println("UI latency history:"); 2122 pw.println(); 2123 mUiLatencyHistory.reverseDump(fd, pw, args); 2124 pw.println(); 2125 pw.println("WTF history:"); 2126 pw.println(); 2127 mWtfHistory.reverseDump(fd, pw, args); 2128 } 2129 pw.println("Augmented Autofill State: "); 2130 mAugmentedAutofillState.dump(prefix, pw); 2131 } 2132 } finally { 2133 sDebug = realDebug; 2134 sVerbose = realVerbose; 2135 } 2136 } 2137 2138 @Override onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver)2139 public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, 2140 String[] args, ShellCallback callback, ResultReceiver resultReceiver) { 2141 new AutofillManagerServiceShellCommand(AutofillManagerService.this).exec( 2142 this, in, out, err, args, callback, resultReceiver); 2143 } 2144 } 2145 } 2146