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