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 22 import static com.android.server.autofill.Helper.bundleToString; 23 import static com.android.server.autofill.Helper.sDebug; 24 import static com.android.server.autofill.Helper.sPartitionMaxCount; 25 import static com.android.server.autofill.Helper.sVerbose; 26 27 import android.annotation.NonNull; 28 import android.annotation.Nullable; 29 import android.app.ActivityManager; 30 import android.app.ActivityThread; 31 import android.content.BroadcastReceiver; 32 import android.content.ComponentName; 33 import android.content.ContentResolver; 34 import android.content.Context; 35 import android.content.Intent; 36 import android.content.IntentFilter; 37 import android.content.pm.PackageManager; 38 import android.content.pm.UserInfo; 39 import android.database.ContentObserver; 40 import android.graphics.Rect; 41 import android.net.Uri; 42 import android.os.Binder; 43 import android.os.Build; 44 import android.os.Bundle; 45 import android.os.Handler; 46 import android.os.IBinder; 47 import android.os.RemoteException; 48 import android.os.ResultReceiver; 49 import android.os.ShellCallback; 50 import android.os.UserHandle; 51 import android.os.UserManager; 52 import android.os.UserManagerInternal; 53 import android.provider.Settings; 54 import android.service.autofill.FillEventHistory; 55 import android.util.LocalLog; 56 import android.util.Slog; 57 import android.util.SparseArray; 58 import android.util.SparseBooleanArray; 59 import android.view.autofill.AutofillId; 60 import android.view.autofill.AutofillManager; 61 import android.view.autofill.AutofillManagerInternal; 62 import android.view.autofill.AutofillValue; 63 import android.view.autofill.IAutoFillManager; 64 import android.view.autofill.IAutoFillManagerClient; 65 66 import com.android.internal.annotations.GuardedBy; 67 import com.android.internal.content.PackageMonitor; 68 import com.android.internal.os.BackgroundThread; 69 import com.android.internal.os.IResultReceiver; 70 import com.android.internal.util.DumpUtils; 71 import com.android.internal.util.Preconditions; 72 import com.android.server.FgThread; 73 import com.android.server.LocalServices; 74 import com.android.server.SystemService; 75 import com.android.server.autofill.ui.AutoFillUI; 76 77 import java.io.FileDescriptor; 78 import java.io.PrintWriter; 79 import java.util.ArrayList; 80 import java.util.List; 81 import java.util.Objects; 82 83 /** 84 * Entry point service for autofill management. 85 * 86 * <p>This service provides the {@link IAutoFillManager} implementation and keeps a list of 87 * {@link AutofillManagerServiceImpl} per user; the real work is done by 88 * {@link AutofillManagerServiceImpl} itself. 89 */ 90 public final class AutofillManagerService extends SystemService { 91 92 private static final String TAG = "AutofillManagerService"; 93 94 static final String RECEIVER_BUNDLE_EXTRA_SESSIONS = "sessions"; 95 96 private final Context mContext; 97 private final AutoFillUI mUi; 98 99 private final Object mLock = new Object(); 100 101 /** 102 * Cache of {@link AutofillManagerServiceImpl} per user id. 103 * <p> 104 * It has to be mapped by user id because the same current user could have simultaneous sessions 105 * associated to different user profiles (for example, in a multi-window environment or when 106 * device has work profiles). 107 */ 108 @GuardedBy("mLock") 109 private SparseArray<AutofillManagerServiceImpl> mServicesCache = new SparseArray<>(); 110 111 /** 112 * Users disabled due to {@link UserManager} restrictions. 113 */ 114 @GuardedBy("mLock") 115 private final SparseBooleanArray mDisabledUsers = new SparseBooleanArray(); 116 117 private final LocalLog mRequestsHistory = new LocalLog(20); 118 private final LocalLog mUiLatencyHistory = new LocalLog(20); 119 120 private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 121 @Override 122 public void onReceive(Context context, Intent intent) { 123 if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction())) { 124 if (sDebug) Slog.d(TAG, "Close system dialogs"); 125 126 // TODO(b/64940307): we need to destroy all sessions that are finished but showing 127 // Save UI because there is no way to show the Save UI back when the activity 128 // beneath it is brought back to top. Ideally, we should just hide the UI and 129 // bring it back when the activity resumes. 130 synchronized (mLock) { 131 for (int i = 0; i < mServicesCache.size(); i++) { 132 mServicesCache.valueAt(i).destroyFinishedSessionsLocked(); 133 } 134 } 135 136 mUi.hideAll(null); 137 } 138 } 139 }; 140 AutofillManagerService(Context context)141 public AutofillManagerService(Context context) { 142 super(context); 143 mContext = context; 144 mUi = new AutoFillUI(ActivityThread.currentActivityThread().getSystemUiContext()); 145 146 final boolean debug = Build.IS_DEBUGGABLE; 147 Slog.i(TAG, "Setting debug to " + debug); 148 setDebugLocked(debug); 149 150 final IntentFilter filter = new IntentFilter(); 151 filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 152 mContext.registerReceiver(mBroadcastReceiver, filter, null, FgThread.getHandler()); 153 154 // Hookup with UserManager to disable service when necessary. 155 final UserManager um = context.getSystemService(UserManager.class); 156 final UserManagerInternal umi = LocalServices.getService(UserManagerInternal.class); 157 final List<UserInfo> users = um.getUsers(); 158 for (int i = 0; i < users.size(); i++) { 159 final int userId = users.get(i).id; 160 final boolean disabled = umi.getUserRestriction(userId, UserManager.DISALLOW_AUTOFILL); 161 if (disabled) { 162 if (disabled) { 163 Slog.i(TAG, "Disabling Autofill for user " + userId); 164 } 165 mDisabledUsers.put(userId, disabled); 166 } 167 } 168 umi.addUserRestrictionsListener((userId, newRestrictions, prevRestrictions) -> { 169 final boolean disabledNow = 170 newRestrictions.getBoolean(UserManager.DISALLOW_AUTOFILL, false); 171 synchronized (mLock) { 172 final boolean disabledBefore = mDisabledUsers.get(userId); 173 if (disabledBefore == disabledNow) { 174 // Nothing changed, do nothing. 175 if (sDebug) { 176 Slog.d(TAG, "Autofill restriction did not change for user " + userId + ": " 177 + bundleToString(newRestrictions)); 178 return; 179 } 180 } 181 Slog.i(TAG, "Updating Autofill for user " + userId + ": disabled=" + disabledNow); 182 mDisabledUsers.put(userId, disabledNow); 183 updateCachedServiceLocked(userId, disabledNow); 184 } 185 }); 186 startTrackingPackageChanges(); 187 } 188 startTrackingPackageChanges()189 private void startTrackingPackageChanges() { 190 PackageMonitor monitor = new PackageMonitor() { 191 @Override 192 public void onSomePackagesChanged() { 193 synchronized (mLock) { 194 updateCachedServiceLocked(getChangingUserId()); 195 } 196 } 197 198 @Override 199 public void onPackageUpdateFinished(String packageName, int uid) { 200 synchronized (mLock) { 201 final String activePackageName = getActiveAutofillServicePackageName(); 202 if (packageName.equals(activePackageName)) { 203 removeCachedServiceLocked(getChangingUserId()); 204 } 205 } 206 } 207 208 @Override 209 public void onPackageRemoved(String packageName, int uid) { 210 synchronized (mLock) { 211 final int userId = getChangingUserId(); 212 final AutofillManagerServiceImpl userState = peekServiceForUserLocked(userId); 213 if (userState != null) { 214 final ComponentName componentName = userState.getServiceComponentName(); 215 if (componentName != null) { 216 if (packageName.equals(componentName.getPackageName())) { 217 handleActiveAutofillServiceRemoved(userId); 218 } 219 } 220 } 221 } 222 } 223 224 @Override 225 public boolean onHandleForceStop(Intent intent, String[] packages, 226 int uid, boolean doit) { 227 synchronized (mLock) { 228 final String activePackageName = getActiveAutofillServicePackageName(); 229 for (String pkg : packages) { 230 if (pkg.equals(activePackageName)) { 231 if (!doit) { 232 return true; 233 } 234 removeCachedServiceLocked(getChangingUserId()); 235 } 236 } 237 } 238 return false; 239 } 240 241 private void handleActiveAutofillServiceRemoved(int userId) { 242 removeCachedServiceLocked(userId); 243 Settings.Secure.putStringForUser(mContext.getContentResolver(), 244 Settings.Secure.AUTOFILL_SERVICE, null, userId); 245 } 246 247 private String getActiveAutofillServicePackageName() { 248 final int userId = getChangingUserId(); 249 final AutofillManagerServiceImpl userState = peekServiceForUserLocked(userId); 250 if (userState == null) { 251 return null; 252 } 253 final ComponentName serviceComponent = userState.getServiceComponentName(); 254 if (serviceComponent == null) { 255 return null; 256 } 257 return serviceComponent.getPackageName(); 258 } 259 }; 260 261 // package changes 262 monitor.register(mContext, null, UserHandle.ALL, true); 263 } 264 265 @Override onStart()266 public void onStart() { 267 publishBinderService(AUTOFILL_MANAGER_SERVICE, new AutoFillManagerServiceStub()); 268 publishLocalService(AutofillManagerInternal.class, new LocalService()); 269 } 270 271 @Override onBootPhase(int phase)272 public void onBootPhase(int phase) { 273 if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) { 274 new SettingsObserver(BackgroundThread.getHandler()); 275 } 276 } 277 278 @Override onUnlockUser(int userId)279 public void onUnlockUser(int userId) { 280 synchronized (mLock) { 281 updateCachedServiceLocked(userId); 282 } 283 } 284 285 @Override onSwitchUser(int userHandle)286 public void onSwitchUser(int userHandle) { 287 if (sDebug) Slog.d(TAG, "Hiding UI when user switched"); 288 mUi.hideAll(null); 289 } 290 291 @Override onCleanupUser(int userId)292 public void onCleanupUser(int userId) { 293 synchronized (mLock) { 294 removeCachedServiceLocked(userId); 295 } 296 } 297 298 /** 299 * Gets the service instance for an user. 300 * 301 * @return service instance. 302 */ 303 @NonNull getServiceForUserLocked(int userId)304 AutofillManagerServiceImpl getServiceForUserLocked(int userId) { 305 final int resolvedUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), 306 Binder.getCallingUid(), userId, false, false, null, null); 307 AutofillManagerServiceImpl service = mServicesCache.get(resolvedUserId); 308 if (service == null) { 309 service = new AutofillManagerServiceImpl(mContext, mLock, mRequestsHistory, 310 mUiLatencyHistory, resolvedUserId, mUi, mDisabledUsers.get(resolvedUserId)); 311 mServicesCache.put(userId, service); 312 } 313 return service; 314 } 315 316 /** 317 * Peeks the service instance for a user. 318 * 319 * @return service instance or {@code null} if not already present 320 */ 321 @Nullable peekServiceForUserLocked(int userId)322 AutofillManagerServiceImpl peekServiceForUserLocked(int userId) { 323 final int resolvedUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), 324 Binder.getCallingUid(), userId, false, false, null, null); 325 return mServicesCache.get(resolvedUserId); 326 } 327 328 // Called by Shell command. destroySessions(int userId, IResultReceiver receiver)329 void destroySessions(int userId, IResultReceiver receiver) { 330 Slog.i(TAG, "destroySessions() for userId " + userId); 331 mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG); 332 333 synchronized (mLock) { 334 if (userId != UserHandle.USER_ALL) { 335 AutofillManagerServiceImpl service = peekServiceForUserLocked(userId); 336 if (service != null) { 337 service.destroySessionsLocked(); 338 } 339 } else { 340 final int size = mServicesCache.size(); 341 for (int i = 0; i < size; i++) { 342 mServicesCache.valueAt(i).destroySessionsLocked(); 343 } 344 } 345 } 346 347 try { 348 receiver.send(0, new Bundle()); 349 } catch (RemoteException e) { 350 // Just ignore it... 351 } 352 } 353 354 // Called by Shell command. listSessions(int userId, IResultReceiver receiver)355 void listSessions(int userId, IResultReceiver receiver) { 356 Slog.i(TAG, "listSessions() for userId " + userId); 357 mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG); 358 359 final Bundle resultData = new Bundle(); 360 final ArrayList<String> sessions = new ArrayList<>(); 361 362 synchronized (mLock) { 363 if (userId != UserHandle.USER_ALL) { 364 AutofillManagerServiceImpl service = peekServiceForUserLocked(userId); 365 if (service != null) { 366 service.listSessionsLocked(sessions); 367 } 368 } else { 369 final int size = mServicesCache.size(); 370 for (int i = 0; i < size; i++) { 371 mServicesCache.valueAt(i).listSessionsLocked(sessions); 372 } 373 } 374 } 375 376 resultData.putStringArrayList(RECEIVER_BUNDLE_EXTRA_SESSIONS, sessions); 377 try { 378 receiver.send(0, resultData); 379 } catch (RemoteException e) { 380 // Just ignore it... 381 } 382 } 383 384 // Called by Shell command. reset()385 void reset() { 386 Slog.i(TAG, "reset()"); 387 mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG); 388 389 synchronized (mLock) { 390 final int size = mServicesCache.size(); 391 for (int i = 0; i < size; i++) { 392 mServicesCache.valueAt(i).destroyLocked(); 393 } 394 mServicesCache.clear(); 395 } 396 } 397 398 // Called by Shell command. setLogLevel(int level)399 void setLogLevel(int level) { 400 Slog.i(TAG, "setLogLevel(): " + level); 401 mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG); 402 403 boolean debug = false; 404 boolean verbose = false; 405 if (level == AutofillManager.FLAG_ADD_CLIENT_VERBOSE) { 406 debug = verbose = true; 407 } else if (level == AutofillManager.FLAG_ADD_CLIENT_DEBUG) { 408 debug = true; 409 } 410 synchronized (mLock) { 411 setDebugLocked(debug); 412 setVerboseLocked(verbose); 413 } 414 } 415 416 // Called by Shell command. getLogLevel()417 int getLogLevel() { 418 mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG); 419 420 synchronized (mLock) { 421 if (sVerbose) return AutofillManager.FLAG_ADD_CLIENT_VERBOSE; 422 if (sDebug) return AutofillManager.FLAG_ADD_CLIENT_DEBUG; 423 return 0; 424 } 425 } 426 427 // Called by Shell command. getMaxPartitions()428 public int getMaxPartitions() { 429 mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG); 430 431 synchronized (mLock) { 432 return sPartitionMaxCount; 433 } 434 } 435 436 // Called by Shell command. setMaxPartitions(int max)437 public void setMaxPartitions(int max) { 438 mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG); 439 Slog.i(TAG, "setMaxPartitions(): " + max); 440 synchronized (mLock) { 441 sPartitionMaxCount = max; 442 } 443 } 444 setDebugLocked(boolean debug)445 private void setDebugLocked(boolean debug) { 446 com.android.server.autofill.Helper.sDebug = debug; 447 android.view.autofill.Helper.sDebug = debug; 448 } 449 450 setVerboseLocked(boolean verbose)451 private void setVerboseLocked(boolean verbose) { 452 com.android.server.autofill.Helper.sVerbose = verbose; 453 android.view.autofill.Helper.sVerbose = verbose; 454 } 455 456 /** 457 * Removes a cached service for a given user. 458 */ removeCachedServiceLocked(int userId)459 private void removeCachedServiceLocked(int userId) { 460 final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId); 461 if (service != null) { 462 mServicesCache.delete(userId); 463 service.destroyLocked(); 464 } 465 } 466 467 /** 468 * Updates a cached service for a given user. 469 */ updateCachedServiceLocked(int userId)470 private void updateCachedServiceLocked(int userId) { 471 updateCachedServiceLocked(userId, mDisabledUsers.get(userId)); 472 } 473 474 /** 475 * Updates a cached service for a given user. 476 */ updateCachedServiceLocked(int userId, boolean disabled)477 private void updateCachedServiceLocked(int userId, boolean disabled) { 478 AutofillManagerServiceImpl service = getServiceForUserLocked(userId); 479 if (service != null) { 480 service.destroySessionsLocked(); 481 service.updateLocked(disabled); 482 if (!service.isEnabled()) { 483 removeCachedServiceLocked(userId); 484 } 485 } 486 } 487 488 private final class LocalService extends AutofillManagerInternal { 489 490 @Override onBackKeyPressed()491 public void onBackKeyPressed() { 492 if (sDebug) Slog.d(TAG, "onBackKeyPressed()"); 493 mUi.hideAll(null); 494 } 495 } 496 497 final class AutoFillManagerServiceStub extends IAutoFillManager.Stub { 498 @Override addClient(IAutoFillManagerClient client, int userId)499 public int addClient(IAutoFillManagerClient client, int userId) { 500 synchronized (mLock) { 501 int flags = 0; 502 if (getServiceForUserLocked(userId).addClientLocked(client)) { 503 flags |= AutofillManager.FLAG_ADD_CLIENT_ENABLED; 504 } 505 if (sDebug) { 506 flags |= AutofillManager.FLAG_ADD_CLIENT_DEBUG; 507 } 508 if (sVerbose) { 509 flags |= AutofillManager.FLAG_ADD_CLIENT_VERBOSE; 510 } 511 return flags; 512 } 513 } 514 515 @Override setAuthenticationResult(Bundle data, int sessionId, int authenticationId, int userId)516 public void setAuthenticationResult(Bundle data, int sessionId, int authenticationId, 517 int userId) { 518 synchronized (mLock) { 519 final AutofillManagerServiceImpl service = getServiceForUserLocked(userId); 520 service.setAuthenticationResultLocked(data, sessionId, authenticationId, 521 getCallingUid()); 522 } 523 } 524 525 @Override setHasCallback(int sessionId, int userId, boolean hasIt)526 public void setHasCallback(int sessionId, int userId, boolean hasIt) { 527 synchronized (mLock) { 528 final AutofillManagerServiceImpl service = getServiceForUserLocked(userId); 529 service.setHasCallback(sessionId, getCallingUid(), hasIt); 530 } 531 } 532 533 @Override startSession(IBinder activityToken, IBinder appCallback, AutofillId autofillId, Rect bounds, AutofillValue value, int userId, boolean hasCallback, int flags, ComponentName componentName)534 public int startSession(IBinder activityToken, IBinder appCallback, AutofillId autofillId, 535 Rect bounds, AutofillValue value, int userId, boolean hasCallback, int flags, 536 ComponentName componentName) { 537 538 activityToken = Preconditions.checkNotNull(activityToken, "activityToken"); 539 appCallback = Preconditions.checkNotNull(appCallback, "appCallback"); 540 autofillId = Preconditions.checkNotNull(autofillId, "autoFillId"); 541 componentName = Preconditions.checkNotNull(componentName, "componentName"); 542 final String packageName = Preconditions.checkNotNull(componentName.getPackageName()); 543 544 Preconditions.checkArgument(userId == UserHandle.getUserId(getCallingUid()), "userId"); 545 546 try { 547 mContext.getPackageManager().getPackageInfoAsUser(packageName, 0, userId); 548 } catch (PackageManager.NameNotFoundException e) { 549 throw new IllegalArgumentException(componentName + " is not a valid package", e); 550 } 551 552 synchronized (mLock) { 553 final AutofillManagerServiceImpl service = getServiceForUserLocked(userId); 554 return service.startSessionLocked(activityToken, getCallingUid(), appCallback, 555 autofillId, bounds, value, hasCallback, flags, componentName); 556 } 557 } 558 559 @Override getFillEventHistory()560 public FillEventHistory getFillEventHistory() throws RemoteException { 561 UserHandle user = getCallingUserHandle(); 562 int uid = getCallingUid(); 563 564 synchronized (mLock) { 565 AutofillManagerServiceImpl service = peekServiceForUserLocked(user.getIdentifier()); 566 if (service != null) { 567 return service.getFillEventHistory(uid); 568 } 569 } 570 571 return null; 572 } 573 574 @Override restoreSession(int sessionId, IBinder activityToken, IBinder appCallback)575 public boolean restoreSession(int sessionId, IBinder activityToken, IBinder appCallback) 576 throws RemoteException { 577 activityToken = Preconditions.checkNotNull(activityToken, "activityToken"); 578 appCallback = Preconditions.checkNotNull(appCallback, "appCallback"); 579 580 synchronized (mLock) { 581 final AutofillManagerServiceImpl service = mServicesCache.get( 582 UserHandle.getCallingUserId()); 583 if (service != null) { 584 return service.restoreSession(sessionId, getCallingUid(), activityToken, 585 appCallback); 586 } 587 } 588 589 return false; 590 } 591 592 @Override updateSession(int sessionId, AutofillId autoFillId, Rect bounds, AutofillValue value, int action, int flags, int userId)593 public void updateSession(int sessionId, AutofillId autoFillId, Rect bounds, 594 AutofillValue value, int action, int flags, int userId) { 595 synchronized (mLock) { 596 final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId); 597 if (service != null) { 598 service.updateSessionLocked(sessionId, getCallingUid(), autoFillId, bounds, 599 value, action, flags); 600 } 601 } 602 } 603 604 @Override updateOrRestartSession(IBinder activityToken, IBinder appCallback, AutofillId autoFillId, Rect bounds, AutofillValue value, int userId, boolean hasCallback, int flags, ComponentName componentName, int sessionId, int action)605 public int updateOrRestartSession(IBinder activityToken, IBinder appCallback, 606 AutofillId autoFillId, Rect bounds, AutofillValue value, int userId, 607 boolean hasCallback, int flags, ComponentName componentName, int sessionId, 608 int action) { 609 boolean restart = false; 610 synchronized (mLock) { 611 final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId); 612 if (service != null) { 613 restart = service.updateSessionLocked(sessionId, getCallingUid(), autoFillId, 614 bounds, value, action, flags); 615 } 616 } 617 if (restart) { 618 return startSession(activityToken, appCallback, autoFillId, bounds, value, userId, 619 hasCallback, flags, componentName); 620 } 621 622 // Nothing changed... 623 return sessionId; 624 } 625 626 @Override finishSession(int sessionId, int userId)627 public void finishSession(int sessionId, int userId) { 628 synchronized (mLock) { 629 final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId); 630 if (service != null) { 631 service.finishSessionLocked(sessionId, getCallingUid()); 632 } 633 } 634 } 635 636 @Override cancelSession(int sessionId, int userId)637 public void cancelSession(int sessionId, int userId) { 638 synchronized (mLock) { 639 final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId); 640 if (service != null) { 641 service.cancelSessionLocked(sessionId, getCallingUid()); 642 } 643 } 644 } 645 646 @Override disableOwnedAutofillServices(int userId)647 public void disableOwnedAutofillServices(int userId) { 648 synchronized (mLock) { 649 final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId); 650 if (service != null) { 651 service.disableOwnedAutofillServicesLocked(Binder.getCallingUid()); 652 } 653 } 654 } 655 656 @Override isServiceSupported(int userId)657 public boolean isServiceSupported(int userId) { 658 synchronized (mLock) { 659 return !mDisabledUsers.get(userId); 660 } 661 } 662 663 @Override isServiceEnabled(int userId, String packageName)664 public boolean isServiceEnabled(int userId, String packageName) { 665 synchronized (mLock) { 666 final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId); 667 if (service == null) return false; 668 return Objects.equals(packageName, service.getServicePackageName()); 669 } 670 } 671 672 @Override onPendingSaveUi(int operation, IBinder token)673 public void onPendingSaveUi(int operation, IBinder token) { 674 Preconditions.checkNotNull(token, "token"); 675 Preconditions.checkArgument(operation == AutofillManager.PENDING_UI_OPERATION_CANCEL 676 || operation == AutofillManager.PENDING_UI_OPERATION_RESTORE, 677 "invalid operation: %d", operation); 678 synchronized (mLock) { 679 final AutofillManagerServiceImpl service = peekServiceForUserLocked( 680 UserHandle.getCallingUserId()); 681 if (service != null) { 682 service.onPendingSaveUi(operation, token); 683 } 684 } 685 } 686 687 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)688 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 689 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; 690 691 boolean showHistory = true; 692 boolean uiOnly = false; 693 if (args != null) { 694 for (String arg : args) { 695 switch(arg) { 696 case "--no-history": 697 showHistory = false; 698 break; 699 case "--ui-only": 700 uiOnly = true; 701 break; 702 case "--help": 703 pw.println("Usage: dumpsys autofill [--ui-only|--no-history]"); 704 return; 705 default: 706 Slog.w(TAG, "Ignoring invalid dump arg: " + arg); 707 } 708 } 709 } 710 711 if (uiOnly) { 712 mUi.dump(pw); 713 return; 714 } 715 716 boolean oldDebug = sDebug; 717 try { 718 synchronized (mLock) { 719 oldDebug = sDebug; 720 setDebugLocked(true); 721 pw.print("Debug mode: "); pw.println(oldDebug); 722 pw.print("Verbose mode: "); pw.println(sVerbose); 723 pw.print("Disabled users: "); pw.println(mDisabledUsers); 724 pw.print("Max partitions per session: "); pw.println(sPartitionMaxCount); 725 final int size = mServicesCache.size(); 726 pw.print("Cached services: "); 727 if (size == 0) { 728 pw.println("none"); 729 } else { 730 pw.println(size); 731 for (int i = 0; i < size; i++) { 732 pw.print("\nService at index "); pw.println(i); 733 final AutofillManagerServiceImpl impl = mServicesCache.valueAt(i); 734 impl.dumpLocked(" ", pw); 735 } 736 } 737 mUi.dump(pw); 738 } 739 if (showHistory) { 740 pw.println("Requests history:"); 741 mRequestsHistory.reverseDump(fd, pw, args); 742 pw.println("UI latency history:"); 743 mUiLatencyHistory.reverseDump(fd, pw, args); 744 } 745 } finally { 746 setDebugLocked(oldDebug); 747 } 748 } 749 750 @Override onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver)751 public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, 752 String[] args, ShellCallback callback, ResultReceiver resultReceiver) { 753 (new AutofillManagerServiceShellCommand(AutofillManagerService.this)).exec( 754 this, in, out, err, args, callback, resultReceiver); 755 } 756 } 757 758 private final class SettingsObserver extends ContentObserver { SettingsObserver(Handler handler)759 SettingsObserver(Handler handler) { 760 super(handler); 761 ContentResolver resolver = mContext.getContentResolver(); 762 resolver.registerContentObserver(Settings.Secure.getUriFor( 763 Settings.Secure.AUTOFILL_SERVICE), false, this, UserHandle.USER_ALL); 764 resolver.registerContentObserver(Settings.Secure.getUriFor( 765 Settings.Secure.USER_SETUP_COMPLETE), false, this, UserHandle.USER_ALL); 766 } 767 768 @Override onChange(boolean selfChange, Uri uri, int userId)769 public void onChange(boolean selfChange, Uri uri, int userId) { 770 if (sVerbose) Slog.v(TAG, "onChange(): uri=" + uri + ", userId=" + userId); 771 synchronized (mLock) { 772 updateCachedServiceLocked(userId); 773 } 774 } 775 } 776 } 777