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