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