VrManagerService.java revision 99493dbc94989d4493ca6acb0db265a02f49f62e
1/** 2 * Copyright (C) 2015 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 */ 16package com.android.server.vr; 17 18import static android.view.Display.INVALID_DISPLAY; 19 20import android.Manifest; 21import android.app.ActivityManagerInternal; 22import android.app.ActivityManager; 23import android.app.AppOpsManager; 24import android.app.NotificationManager; 25import android.annotation.NonNull; 26import android.content.ComponentName; 27import android.content.ContentResolver; 28import android.content.Context; 29import android.content.pm.ApplicationInfo; 30import android.content.pm.PackageManager; 31import android.content.pm.PackageManager.NameNotFoundException; 32import android.hardware.display.DisplayManager; 33import android.os.Binder; 34import android.os.Handler; 35import android.os.IBinder; 36import android.os.IInterface; 37import android.os.Looper; 38import android.os.Message; 39import android.os.RemoteCallbackList; 40import android.os.RemoteException; 41import android.os.ServiceManager; 42import android.os.UserHandle; 43import android.provider.Settings; 44import android.service.notification.NotificationListenerService; 45import android.service.vr.IPersistentVrStateCallbacks; 46import android.service.vr.IVrListener; 47import android.service.vr.IVrManager; 48import android.service.vr.IVrStateCallbacks; 49import android.service.vr.IVrWindowManager; 50import android.service.vr.VrListenerService; 51import android.text.TextUtils; 52import android.util.ArrayMap; 53import android.util.ArraySet; 54import android.util.Slog; 55import android.util.SparseArray; 56 57import com.android.internal.R; 58import com.android.server.LocalServices; 59import com.android.server.SystemConfig; 60import com.android.server.SystemService; 61import com.android.server.utils.ManagedApplicationService.PendingEvent; 62import com.android.server.vr.EnabledComponentsObserver.EnabledComponentChangeListener; 63import com.android.server.utils.ManagedApplicationService; 64import com.android.server.utils.ManagedApplicationService.BinderChecker; 65 66import java.io.FileDescriptor; 67import java.io.PrintWriter; 68import java.lang.StringBuilder; 69import java.text.SimpleDateFormat; 70import java.util.ArrayDeque; 71import java.util.ArrayList; 72import java.util.Collection; 73import java.util.Date; 74import java.util.Objects; 75 76/** 77 * Service tracking whether VR mode is active, and notifying listening services of state changes. 78 * <p/> 79 * Services running in system server may modify the state of VrManagerService via the interface in 80 * VrManagerInternal, and may register to receive callbacks when the system VR mode changes via the 81 * interface given in VrStateListener. 82 * <p/> 83 * Device vendors may choose to receive VR state changes by implementing the VR mode HAL, e.g.: 84 * hardware/libhardware/modules/vr 85 * <p/> 86 * In general applications may enable or disable VR mode by calling 87 * {@link android.app.Activity#setVrModeEnabled)}. An application may also implement a service to 88 * be run while in VR mode by implementing {@link android.service.vr.VrListenerService}. 89 * 90 * @see android.service.vr.VrListenerService 91 * @see com.android.server.vr.VrManagerInternal 92 * @see com.android.server.vr.VrStateListener 93 * 94 * @hide 95 */ 96public class VrManagerService extends SystemService implements EnabledComponentChangeListener{ 97 98 public static final String TAG = "VrManagerService"; 99 100 private static final int PENDING_STATE_DELAY_MS = 300; 101 private static final int EVENT_LOG_SIZE = 32; 102 private static final int INVALID_APPOPS_MODE = -1; 103 /** Null set of sleep sleep flags. */ 104 private static final int FLAG_NONE = 0; 105 /** Flag set when the device is not sleeping. */ 106 private static final int FLAG_AWAKE = 1; 107 /** Flag set when the screen has been turned on. */ 108 private static final int FLAG_SCREEN_ON = 2; 109 /** Flag indicating that all system sleep flags have been set.*/ 110 private static final int FLAG_ALL = FLAG_AWAKE | FLAG_SCREEN_ON; 111 112 private static native void initializeNative(); 113 private static native void setVrModeNative(boolean enabled); 114 115 private final Object mLock = new Object(); 116 117 private final IBinder mOverlayToken = new Binder(); 118 119 // State protected by mLock 120 private boolean mVrModeAllowed; 121 private boolean mVrModeEnabled; 122 private boolean mPersistentVrModeEnabled; 123 private EnabledComponentsObserver mComponentObserver; 124 private ManagedApplicationService mCurrentVrService; 125 private ComponentName mDefaultVrService; 126 private Context mContext; 127 private ComponentName mCurrentVrModeComponent; 128 private int mCurrentVrModeUser; 129 private boolean mWasDefaultGranted; 130 private boolean mGuard; 131 private final RemoteCallbackList<IVrStateCallbacks> mVrStateRemoteCallbacks = 132 new RemoteCallbackList<>(); 133 private final RemoteCallbackList<IPersistentVrStateCallbacks> 134 mPersistentVrStateRemoteCallbacks = new RemoteCallbackList<>(); 135 private int mPreviousCoarseLocationMode = INVALID_APPOPS_MODE; 136 private int mPreviousManageOverlayMode = INVALID_APPOPS_MODE; 137 private VrState mPendingState; 138 private final ArrayDeque<VrState> mLoggingDeque = new ArrayDeque<>(EVENT_LOG_SIZE); 139 private final NotificationAccessManager mNotifAccessManager = new NotificationAccessManager(); 140 /** Tracks the state of the screen and keyguard UI.*/ 141 private int mSystemSleepFlags = FLAG_AWAKE; 142 private CompatibilityDisplay mCompatibilityDisplay; 143 144 private static final int MSG_VR_STATE_CHANGE = 0; 145 private static final int MSG_PENDING_VR_STATE_CHANGE = 1; 146 private static final int MSG_PERSISTENT_VR_MODE_STATE_CHANGE = 2; 147 148 /** 149 * Set whether VR mode may be enabled. 150 * <p/> 151 * If VR mode is not allowed to be enabled, calls to set VR mode will be cached. When VR mode 152 * is again allowed to be enabled, the most recent cached state will be applied. 153 * 154 * @param allowed {@code true} if calling any of the setVrMode methods may cause the device to 155 * enter VR mode. 156 */ 157 private void setVrModeAllowedLocked(boolean allowed) { 158 if (mVrModeAllowed != allowed) { 159 mVrModeAllowed = allowed; 160 Slog.i(TAG, "VR mode is " + ((allowed) ? "allowed" : "disallowed")); 161 if (mVrModeAllowed) { 162 consumeAndApplyPendingStateLocked(); 163 } else { 164 // Disable persistent mode when VR mode isn't allowed, allows an escape hatch to 165 // exit persistent VR mode when screen is turned off. 166 setPersistentModeAndNotifyListenersLocked(false); 167 168 // Set pending state to current state. 169 mPendingState = (mVrModeEnabled && mCurrentVrService != null) 170 ? new VrState(mVrModeEnabled, mCurrentVrService.getComponent(), 171 mCurrentVrService.getUserId(), mCurrentVrModeComponent) 172 : null; 173 174 // Unbind current VR service and do necessary callbacks. 175 updateCurrentVrServiceLocked(false, null, 0, null); 176 } 177 } 178 } 179 180 private void setSleepState(boolean isAsleep) { 181 synchronized(mLock) { 182 183 if (!isAsleep) { 184 mSystemSleepFlags |= FLAG_AWAKE; 185 } else { 186 mSystemSleepFlags &= ~FLAG_AWAKE; 187 } 188 189 setVrModeAllowedLocked(mSystemSleepFlags == FLAG_ALL); 190 } 191 } 192 193 private void setScreenOn(boolean isScreenOn) { 194 synchronized(mLock) { 195 if (isScreenOn) { 196 mSystemSleepFlags |= FLAG_SCREEN_ON; 197 } else { 198 mSystemSleepFlags &= ~FLAG_SCREEN_ON; 199 } 200 setVrModeAllowedLocked(mSystemSleepFlags == FLAG_ALL); 201 } 202 } 203 204 private final Handler mHandler = new Handler() { 205 @Override 206 public void handleMessage(Message msg) { 207 switch(msg.what) { 208 case MSG_VR_STATE_CHANGE : { 209 boolean state = (msg.arg1 == 1); 210 int i = mVrStateRemoteCallbacks.beginBroadcast(); 211 while (i > 0) { 212 i--; 213 try { 214 mVrStateRemoteCallbacks.getBroadcastItem(i).onVrStateChanged(state); 215 } catch (RemoteException e) { 216 // Noop 217 } 218 } 219 mVrStateRemoteCallbacks.finishBroadcast(); 220 } break; 221 case MSG_PENDING_VR_STATE_CHANGE : { 222 synchronized(mLock) { 223 if (mVrModeAllowed) { 224 VrManagerService.this.consumeAndApplyPendingStateLocked(); 225 } 226 } 227 } break; 228 case MSG_PERSISTENT_VR_MODE_STATE_CHANGE : { 229 boolean state = (msg.arg1 == 1); 230 int i = mPersistentVrStateRemoteCallbacks.beginBroadcast(); 231 while (i > 0) { 232 i--; 233 try { 234 mPersistentVrStateRemoteCallbacks.getBroadcastItem(i) 235 .onPersistentVrStateChanged(state); 236 } catch (RemoteException e) { 237 // Noop 238 } 239 } 240 mPersistentVrStateRemoteCallbacks.finishBroadcast(); 241 } break; 242 default : 243 throw new IllegalStateException("Unknown message type: " + msg.what); 244 } 245 } 246 }; 247 248 private static class VrState { 249 final boolean enabled; 250 final int userId; 251 final ComponentName targetPackageName; 252 final ComponentName callingPackage; 253 final long timestamp; 254 final boolean defaultPermissionsGranted; 255 256 VrState(boolean enabled, ComponentName targetPackageName, int userId, 257 ComponentName callingPackage) { 258 this.enabled = enabled; 259 this.userId = userId; 260 this.targetPackageName = targetPackageName; 261 this.callingPackage = callingPackage; 262 this.defaultPermissionsGranted = false; 263 this.timestamp = System.currentTimeMillis(); 264 } 265 266 VrState(boolean enabled, ComponentName targetPackageName, int userId, 267 ComponentName callingPackage, boolean defaultPermissionsGranted) { 268 this.enabled = enabled; 269 this.userId = userId; 270 this.targetPackageName = targetPackageName; 271 this.callingPackage = callingPackage; 272 this.defaultPermissionsGranted = defaultPermissionsGranted; 273 this.timestamp = System.currentTimeMillis(); 274 } 275 } 276 277 private static final BinderChecker sBinderChecker = new BinderChecker() { 278 @Override 279 public IInterface asInterface(IBinder binder) { 280 return IVrListener.Stub.asInterface(binder); 281 } 282 283 @Override 284 public boolean checkType(IInterface service) { 285 return service instanceof IVrListener; 286 } 287 }; 288 289 private final class NotificationAccessManager { 290 private final SparseArray<ArraySet<String>> mAllowedPackages = new SparseArray<>(); 291 private final ArrayMap<String, Integer> mNotificationAccessPackageToUserId = 292 new ArrayMap<>(); 293 294 public void update(Collection<String> packageNames) { 295 int currentUserId = ActivityManager.getCurrentUser(); 296 297 ArraySet<String> allowed = mAllowedPackages.get(currentUserId); 298 if (allowed == null) { 299 allowed = new ArraySet<>(); 300 } 301 302 // Make sure we revoke notification access for listeners in other users 303 final int listenerCount = mNotificationAccessPackageToUserId.size(); 304 for (int i = listenerCount - 1; i >= 0; i--) { 305 final int grantUserId = mNotificationAccessPackageToUserId.valueAt(i); 306 if (grantUserId != currentUserId) { 307 String packageName = mNotificationAccessPackageToUserId.keyAt(i); 308 revokeNotificationListenerAccess(packageName, grantUserId); 309 revokeNotificationPolicyAccess(packageName); 310 revokeCoarseLocationPermissionIfNeeded(packageName, grantUserId); 311 mNotificationAccessPackageToUserId.removeAt(i); 312 } 313 } 314 315 for (String pkg : allowed) { 316 if (!packageNames.contains(pkg)) { 317 revokeNotificationListenerAccess(pkg, currentUserId); 318 revokeNotificationPolicyAccess(pkg); 319 revokeCoarseLocationPermissionIfNeeded(pkg, currentUserId); 320 mNotificationAccessPackageToUserId.remove(pkg); 321 } 322 } 323 for (String pkg : packageNames) { 324 if (!allowed.contains(pkg)) { 325 grantNotificationPolicyAccess(pkg); 326 grantNotificationListenerAccess(pkg, currentUserId); 327 grantCoarseLocationPermissionIfNeeded(pkg, currentUserId); 328 mNotificationAccessPackageToUserId.put(pkg, currentUserId); 329 } 330 } 331 332 allowed.clear(); 333 allowed.addAll(packageNames); 334 mAllowedPackages.put(currentUserId, allowed); 335 } 336 } 337 338 /** 339 * Called when a user, package, or setting changes that could affect whether or not the 340 * currently bound VrListenerService is changed. 341 */ 342 @Override 343 public void onEnabledComponentChanged() { 344 synchronized (mLock) { 345 int currentUser = ActivityManager.getCurrentUser(); 346 // Update listeners 347 ArraySet<ComponentName> enabledListeners = mComponentObserver.getEnabled(currentUser); 348 349 ArraySet<String> enabledPackages = new ArraySet<>(); 350 for (ComponentName n : enabledListeners) { 351 String pkg = n.getPackageName(); 352 if (isDefaultAllowed(pkg)) { 353 enabledPackages.add(n.getPackageName()); 354 } 355 } 356 mNotifAccessManager.update(enabledPackages); 357 358 if (!mVrModeAllowed) { 359 return; // Don't do anything, we shouldn't be in VR mode. 360 } 361 362 // If there is a pending state change, we'd better deal with that first 363 consumeAndApplyPendingStateLocked(false); 364 365 if (mCurrentVrService == null) { 366 return; // No active services 367 } 368 369 // There is an active service, update it if needed 370 updateCurrentVrServiceLocked(mVrModeEnabled, mCurrentVrService.getComponent(), 371 mCurrentVrService.getUserId(), null); 372 } 373 } 374 375 private final IVrManager mVrManager = new IVrManager.Stub() { 376 377 @Override 378 public void registerListener(IVrStateCallbacks cb) { 379 enforceCallerPermission(Manifest.permission.ACCESS_VR_MANAGER); 380 if (cb == null) { 381 throw new IllegalArgumentException("Callback binder object is null."); 382 } 383 384 VrManagerService.this.addStateCallback(cb); 385 } 386 387 @Override 388 public void unregisterListener(IVrStateCallbacks cb) { 389 enforceCallerPermission(Manifest.permission.ACCESS_VR_MANAGER); 390 if (cb == null) { 391 throw new IllegalArgumentException("Callback binder object is null."); 392 } 393 394 VrManagerService.this.removeStateCallback(cb); 395 } 396 397 @Override 398 public void registerPersistentVrStateListener(IPersistentVrStateCallbacks cb) { 399 enforceCallerPermission(Manifest.permission.ACCESS_VR_MANAGER); 400 if (cb == null) { 401 throw new IllegalArgumentException("Callback binder object is null."); 402 } 403 404 VrManagerService.this.addPersistentStateCallback(cb); 405 } 406 407 @Override 408 public void unregisterPersistentVrStateListener(IPersistentVrStateCallbacks cb) { 409 enforceCallerPermission(Manifest.permission.ACCESS_VR_MANAGER); 410 if (cb == null) { 411 throw new IllegalArgumentException("Callback binder object is null."); 412 } 413 414 VrManagerService.this.removePersistentStateCallback(cb); 415 } 416 417 @Override 418 public boolean getVrModeState() { 419 return VrManagerService.this.getVrMode(); 420 } 421 422 @Override 423 public void setPersistentVrModeEnabled(boolean enabled) { 424 enforceCallerPermission(Manifest.permission.RESTRICTED_VR_ACCESS); 425 VrManagerService.this.setPersistentVrModeEnabled(enabled); 426 } 427 428 @Override 429 public int getCompatibilityDisplayId() { 430 return VrManagerService.this.getCompatibilityDisplayId(); 431 } 432 433 @Override 434 public void connectController(FileDescriptor fd) throws android.os.RemoteException { 435 enforceCallerPermission(Manifest.permission.RESTRICTED_VR_ACCESS); 436 VrManagerService.this.connectController(fd); 437 } 438 439 @Override 440 public void disconnectController() throws android.os.RemoteException { 441 enforceCallerPermission(Manifest.permission.RESTRICTED_VR_ACCESS); 442 VrManagerService.this.disconnectController(); 443 } 444 445 @Override 446 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 447 if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 448 != PackageManager.PERMISSION_GRANTED) { 449 pw.println("Permission Denial: can't dump VrManagerService from pid=" 450 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); 451 return; 452 } 453 pw.println("********* Dump of VrManagerService *********"); 454 pw.println("VR mode is currently: " + ((mVrModeAllowed) ? "allowed" : "disallowed")); 455 pw.println("Persistent VR mode is currently: " + 456 ((mPersistentVrModeEnabled) ? "enabled" : "disabled")); 457 pw.println("Previous state transitions:\n"); 458 String tab = " "; 459 dumpStateTransitions(pw); 460 pw.println("\n\nRemote Callbacks:"); 461 int i=mVrStateRemoteCallbacks.beginBroadcast(); // create the broadcast item array 462 while(i-->0) { 463 pw.print(tab); 464 pw.print(mVrStateRemoteCallbacks.getBroadcastItem(i)); 465 if (i>0) pw.println(","); 466 } 467 mVrStateRemoteCallbacks.finishBroadcast(); 468 pw.println("\n\nPersistent Vr State Remote Callbacks:"); 469 i=mPersistentVrStateRemoteCallbacks.beginBroadcast(); 470 while(i-->0) { 471 pw.print(tab); 472 pw.print(mPersistentVrStateRemoteCallbacks.getBroadcastItem(i)); 473 if (i>0) pw.println(","); 474 } 475 mPersistentVrStateRemoteCallbacks.finishBroadcast(); 476 pw.println("\n"); 477 pw.println("Installed VrListenerService components:"); 478 int userId = mCurrentVrModeUser; 479 ArraySet<ComponentName> installed = mComponentObserver.getInstalled(userId); 480 if (installed == null || installed.size() == 0) { 481 pw.println("None"); 482 } else { 483 for (ComponentName n : installed) { 484 pw.print(tab); 485 pw.println(n.flattenToString()); 486 } 487 } 488 pw.println("Enabled VrListenerService components:"); 489 ArraySet<ComponentName> enabled = mComponentObserver.getEnabled(userId); 490 if (enabled == null || enabled.size() == 0) { 491 pw.println("None"); 492 } else { 493 for (ComponentName n : enabled) { 494 pw.print(tab); 495 pw.println(n.flattenToString()); 496 } 497 } 498 pw.println("\n"); 499 pw.println("********* End of VrManagerService Dump *********"); 500 } 501 502 }; 503 504 private void enforceCallerPermission(String permission) { 505 if (mContext.checkCallingOrSelfPermission(permission) 506 != PackageManager.PERMISSION_GRANTED) { 507 throw new SecurityException("Caller does not hold the permission " + permission); 508 } 509 } 510 511 /** 512 * Implementation of VrManagerInternal. Callable only from system services. 513 */ 514 private final class LocalService extends VrManagerInternal { 515 @Override 516 public void setVrMode(boolean enabled, ComponentName packageName, int userId, 517 ComponentName callingPackage) { 518 VrManagerService.this.setVrMode(enabled, packageName, userId, callingPackage); 519 } 520 521 @Override 522 public void onSleepStateChanged(boolean isAsleep) { 523 VrManagerService.this.setSleepState(isAsleep); 524 } 525 526 @Override 527 public void onScreenStateChanged(boolean isScreenOn) { 528 VrManagerService.this.setScreenOn(isScreenOn); 529 } 530 531 @Override 532 public boolean isCurrentVrListener(String packageName, int userId) { 533 return VrManagerService.this.isCurrentVrListener(packageName, userId); 534 } 535 536 @Override 537 public int hasVrPackage(ComponentName packageName, int userId) { 538 return VrManagerService.this.hasVrPackage(packageName, userId); 539 } 540 541 @Override 542 public void setPersistentVrModeEnabled(boolean enabled) { 543 VrManagerService.this.setPersistentVrModeEnabled(enabled); 544 } 545 546 @Override 547 public int getCompatibilityDisplayId() { 548 return VrManagerService.this.getCompatibilityDisplayId(); 549 } 550 551 @Override 552 public void addPersistentVrModeStateListener(IPersistentVrStateCallbacks listener) { 553 VrManagerService.this.addPersistentStateCallback(listener); 554 } 555 } 556 557 public VrManagerService(Context context) { 558 super(context); 559 } 560 561 @Override 562 public void onStart() { 563 synchronized(mLock) { 564 initializeNative(); 565 mContext = getContext(); 566 } 567 568 publishLocalService(VrManagerInternal.class, new LocalService()); 569 publishBinderService(Context.VR_SERVICE, mVrManager.asBinder()); 570 } 571 572 @Override 573 public void onBootPhase(int phase) { 574 if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) { 575 synchronized (mLock) { 576 Looper looper = Looper.getMainLooper(); 577 Handler handler = new Handler(looper); 578 ArrayList<EnabledComponentChangeListener> listeners = new ArrayList<>(); 579 listeners.add(this); 580 mComponentObserver = EnabledComponentsObserver.build(mContext, handler, 581 Settings.Secure.ENABLED_VR_LISTENERS, looper, 582 android.Manifest.permission.BIND_VR_LISTENER_SERVICE, 583 VrListenerService.SERVICE_INTERFACE, mLock, listeners); 584 585 mComponentObserver.rebuildAll(); 586 } 587 588 //TODO: something more robust than picking the first one 589 ArraySet<ComponentName> defaultVrComponents = 590 SystemConfig.getInstance().getDefaultVrComponents(); 591 if (defaultVrComponents.size() > 0) { 592 mDefaultVrService = defaultVrComponents.valueAt(0); 593 } else { 594 Slog.i(TAG, "No default vr listener service found."); 595 } 596 597 DisplayManager dm = 598 (DisplayManager) getContext().getSystemService(Context.DISPLAY_SERVICE); 599 ActivityManagerInternal ami = LocalServices.getService(ActivityManagerInternal.class); 600 mCompatibilityDisplay = new CompatibilityDisplay(dm, ami, mVrManager); 601 mCompatibilityDisplay.init(getContext()); 602 } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) { 603 synchronized (mLock) { 604 mVrModeAllowed = true; 605 } 606 } 607 } 608 609 @Override 610 public void onStartUser(int userHandle) { 611 synchronized (mLock) { 612 mComponentObserver.onUsersChanged(); 613 } 614 } 615 616 @Override 617 public void onSwitchUser(int userHandle) { 618 synchronized (mLock) { 619 mComponentObserver.onUsersChanged(); 620 } 621 622 } 623 624 @Override 625 public void onStopUser(int userHandle) { 626 synchronized (mLock) { 627 mComponentObserver.onUsersChanged(); 628 } 629 630 } 631 632 @Override 633 public void onCleanupUser(int userHandle) { 634 synchronized (mLock) { 635 mComponentObserver.onUsersChanged(); 636 } 637 } 638 639 private void updateOverlayStateLocked(String exemptedPackage, int newUserId, int oldUserId) { 640 AppOpsManager appOpsManager = getContext().getSystemService(AppOpsManager.class); 641 642 // If user changed drop restrictions for the old user. 643 if (oldUserId != newUserId) { 644 appOpsManager.setUserRestrictionForUser(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, 645 false, mOverlayToken, null, oldUserId); 646 } 647 648 if (!mVrModeEnabled) { 649 return; 650 } 651 652 // Apply the restrictions for the current user based on vr state 653 String[] exemptions = (exemptedPackage == null) ? new String[0] : 654 new String[] { exemptedPackage }; 655 656 appOpsManager.setUserRestrictionForUser(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, 657 true, mOverlayToken, exemptions, newUserId); 658 } 659 660 private void updateDependentAppOpsLocked(String newVrServicePackage, int newUserId, 661 String oldVrServicePackage, int oldUserId) { 662 // If VR state changed and we also have a VR service change. 663 if (Objects.equals(newVrServicePackage, oldVrServicePackage)) { 664 return; 665 } 666 final long identity = Binder.clearCallingIdentity(); 667 try { 668 // Set overlay exception state based on VR enabled and current service 669 updateOverlayStateLocked(newVrServicePackage, newUserId, oldUserId); 670 } finally { 671 Binder.restoreCallingIdentity(identity); 672 } 673 } 674 675 /** 676 * Send VR mode changes (if the mode state has changed), and update the bound/unbound state of 677 * the currently selected VR listener service. If the component selected for the VR listener 678 * service has changed, unbind the previous listener and bind the new listener (if enabled). 679 * <p/> 680 * Note: Must be called while holding {@code mLock}. 681 * 682 * @param enabled new state for VR mode. 683 * @param component new component to be bound as a VR listener. 684 * @param userId user owning the component to be bound. 685 * @param calling the component currently using VR mode, or null to leave unchanged. 686 * 687 * @return {@code true} if the component/user combination specified is valid. 688 */ 689 private boolean updateCurrentVrServiceLocked(boolean enabled, @NonNull ComponentName component, 690 int userId, ComponentName calling) { 691 692 boolean sendUpdatedCaller = false; 693 final long identity = Binder.clearCallingIdentity(); 694 try { 695 696 boolean validUserComponent = (mComponentObserver.isValid(component, userId) == 697 EnabledComponentsObserver.NO_ERROR); 698 boolean goingIntoVrMode = validUserComponent && enabled; 699 if (!mVrModeEnabled && !goingIntoVrMode) { 700 return validUserComponent; // Disabled -> Disabled transition does nothing. 701 } 702 703 String oldVrServicePackage = mCurrentVrService != null 704 ? mCurrentVrService.getComponent().getPackageName() : null; 705 final int oldUserId = mCurrentVrModeUser; 706 707 // Notify system services and VR HAL of mode change. 708 changeVrModeLocked(goingIntoVrMode); 709 710 boolean nothingChanged = false; 711 if (!goingIntoVrMode) { 712 // Not going into VR mode, unbind whatever is running 713 if (mCurrentVrService != null) { 714 Slog.i(TAG, "Leaving VR mode, disconnecting " 715 + mCurrentVrService.getComponent() + " for user " 716 + mCurrentVrService.getUserId()); 717 mCurrentVrService.disconnect(); 718 mCurrentVrService = null; 719 } else { 720 nothingChanged = true; 721 } 722 } else { 723 // Going into VR mode 724 if (mCurrentVrService != null) { 725 // Unbind any running service that doesn't match the latest component/user 726 // selection. 727 if (mCurrentVrService.disconnectIfNotMatching(component, userId)) { 728 Slog.i(TAG, "VR mode component changed to " + component 729 + ", disconnecting " + mCurrentVrService.getComponent() 730 + " for user " + mCurrentVrService.getUserId()); 731 createAndConnectService(component, userId); 732 sendUpdatedCaller = true; 733 } else { 734 nothingChanged = true; 735 } 736 // The service with the correct component/user is already bound, do nothing. 737 } else { 738 // Nothing was previously running, bind a new service for the latest 739 // component/user selection. 740 createAndConnectService(component, userId); 741 sendUpdatedCaller = true; 742 } 743 } 744 745 if (calling != null && !Objects.equals(calling, mCurrentVrModeComponent)) { 746 sendUpdatedCaller = true; 747 } 748 mCurrentVrModeComponent = calling; 749 750 if (mCurrentVrModeUser != userId) { 751 mCurrentVrModeUser = userId; 752 sendUpdatedCaller = true; 753 } 754 755 String newVrServicePackage = mCurrentVrService != null 756 ? mCurrentVrService.getComponent().getPackageName() : null; 757 final int newUserId = mCurrentVrModeUser; 758 759 // Update AppOps settings that change state when entering/exiting VR mode, or changing 760 // the current VrListenerService. 761 updateDependentAppOpsLocked(newVrServicePackage, newUserId, 762 oldVrServicePackage, oldUserId); 763 764 if (mCurrentVrService != null && sendUpdatedCaller) { 765 final ComponentName c = mCurrentVrModeComponent; 766 mCurrentVrService.sendEvent(new PendingEvent() { 767 @Override 768 public void runEvent(IInterface service) throws RemoteException { 769 IVrListener l = (IVrListener) service; 770 l.focusedActivityChanged(c); 771 } 772 }); 773 } 774 775 if (!nothingChanged) { 776 logStateLocked(); 777 } 778 779 return validUserComponent; 780 } finally { 781 Binder.restoreCallingIdentity(identity); 782 } 783 } 784 785 private boolean isDefaultAllowed(String packageName) { 786 PackageManager pm = mContext.getPackageManager(); 787 788 ApplicationInfo info = null; 789 try { 790 info = pm.getApplicationInfo(packageName, PackageManager.GET_META_DATA); 791 } catch (NameNotFoundException e) { 792 } 793 794 if (info == null || !(info.isSystemApp() || info.isUpdatedSystemApp())) { 795 return false; 796 } 797 return true; 798 } 799 800 private void grantNotificationPolicyAccess(String pkg) { 801 NotificationManager nm = mContext.getSystemService(NotificationManager.class); 802 nm.setNotificationPolicyAccessGranted(pkg, true); 803 } 804 805 private void revokeNotificationPolicyAccess(String pkg) { 806 NotificationManager nm = mContext.getSystemService(NotificationManager.class); 807 // Remove any DND zen rules possibly created by the package. 808 nm.removeAutomaticZenRules(pkg); 809 // Remove Notification Policy Access. 810 nm.setNotificationPolicyAccessGranted(pkg, false); 811 } 812 813 private void grantNotificationListenerAccess(String pkg, int userId) { 814 PackageManager pm = mContext.getPackageManager(); 815 ArraySet<ComponentName> possibleServices = EnabledComponentsObserver.loadComponentNames(pm, 816 userId, NotificationListenerService.SERVICE_INTERFACE, 817 android.Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE); 818 ContentResolver resolver = mContext.getContentResolver(); 819 820 ArraySet<String> current = getNotificationListeners(resolver, userId); 821 822 for (ComponentName c : possibleServices) { 823 String flatName = c.flattenToString(); 824 if (Objects.equals(c.getPackageName(), pkg) 825 && !current.contains(flatName)) { 826 current.add(flatName); 827 } 828 } 829 830 if (current.size() > 0) { 831 String flatSettings = formatSettings(current); 832 Settings.Secure.putStringForUser(resolver, 833 Settings.Secure.ENABLED_NOTIFICATION_LISTENERS, 834 flatSettings, userId); 835 } 836 } 837 838 private void revokeNotificationListenerAccess(String pkg, int userId) { 839 ContentResolver resolver = mContext.getContentResolver(); 840 841 ArraySet<String> current = getNotificationListeners(resolver, userId); 842 843 ArrayList<String> toRemove = new ArrayList<>(); 844 845 for (String c : current) { 846 ComponentName component = ComponentName.unflattenFromString(c); 847 if (component != null && component.getPackageName().equals(pkg)) { 848 toRemove.add(c); 849 } 850 } 851 852 current.removeAll(toRemove); 853 854 String flatSettings = formatSettings(current); 855 Settings.Secure.putStringForUser(resolver, 856 Settings.Secure.ENABLED_NOTIFICATION_LISTENERS, 857 flatSettings, userId); 858 } 859 860 private void grantCoarseLocationPermissionIfNeeded(String pkg, int userId) { 861 // Don't clobber the user if permission set in current state explicitly 862 if (!isPermissionUserUpdated(Manifest.permission.ACCESS_COARSE_LOCATION, pkg, userId)) { 863 try { 864 mContext.getPackageManager().grantRuntimePermission(pkg, 865 Manifest.permission.ACCESS_COARSE_LOCATION, new UserHandle(userId)); 866 } catch (IllegalArgumentException e) { 867 // Package was removed during update. 868 Slog.w(TAG, "Could not grant coarse location permission, package " + pkg 869 + " was removed."); 870 } 871 } 872 } 873 874 private void revokeCoarseLocationPermissionIfNeeded(String pkg, int userId) { 875 // Don't clobber the user if permission set in current state explicitly 876 if (!isPermissionUserUpdated(Manifest.permission.ACCESS_COARSE_LOCATION, pkg, userId)) { 877 try { 878 mContext.getPackageManager().revokeRuntimePermission(pkg, 879 Manifest.permission.ACCESS_COARSE_LOCATION, new UserHandle(userId)); 880 } catch (IllegalArgumentException e) { 881 // Package was removed during update. 882 Slog.w(TAG, "Could not revoke coarse location permission, package " + pkg 883 + " was removed."); 884 } 885 } 886 } 887 888 private boolean isPermissionUserUpdated(String permission, String pkg, int userId) { 889 final int flags = mContext.getPackageManager().getPermissionFlags( 890 permission, pkg, new UserHandle(userId)); 891 return (flags & (PackageManager.FLAG_PERMISSION_USER_SET 892 | PackageManager.FLAG_PERMISSION_USER_FIXED)) != 0; 893 } 894 895 private ArraySet<String> getNotificationListeners(ContentResolver resolver, int userId) { 896 String flat = Settings.Secure.getStringForUser(resolver, 897 Settings.Secure.ENABLED_NOTIFICATION_LISTENERS, userId); 898 899 ArraySet<String> current = new ArraySet<>(); 900 if (flat != null) { 901 String[] allowed = flat.split(":"); 902 for (String s : allowed) { 903 if (!TextUtils.isEmpty(s)) { 904 current.add(s); 905 } 906 } 907 } 908 return current; 909 } 910 911 private static String formatSettings(Collection<String> c) { 912 if (c == null || c.isEmpty()) { 913 return ""; 914 } 915 916 StringBuilder b = new StringBuilder(); 917 boolean start = true; 918 for (String s : c) { 919 if ("".equals(s)) { 920 continue; 921 } 922 if (!start) { 923 b.append(':'); 924 } 925 b.append(s); 926 start = false; 927 } 928 return b.toString(); 929 } 930 931 932 933 private void createAndConnectService(@NonNull ComponentName component, int userId) { 934 mCurrentVrService = VrManagerService.create(mContext, component, userId); 935 mCurrentVrService.connect(); 936 Slog.i(TAG, "Connecting " + component + " for user " + userId); 937 } 938 939 /** 940 * Send VR mode change callbacks to HAL and system services if mode has actually changed. 941 * <p/> 942 * Note: Must be called while holding {@code mLock}. 943 * 944 * @param enabled new state of the VR mode. 945 */ 946 private void changeVrModeLocked(boolean enabled) { 947 if (mVrModeEnabled != enabled) { 948 mVrModeEnabled = enabled; 949 950 // Log mode change event. 951 Slog.i(TAG, "VR mode " + ((mVrModeEnabled) ? "enabled" : "disabled")); 952 setVrModeNative(mVrModeEnabled); 953 954 onVrModeChangedLocked(); 955 } 956 } 957 958 /** 959 * Notify system services of VR mode change. 960 * <p/> 961 * Note: Must be called while holding {@code mLock}. 962 */ 963 private void onVrModeChangedLocked() { 964 mHandler.sendMessage(mHandler.obtainMessage(MSG_VR_STATE_CHANGE, 965 (mVrModeEnabled) ? 1 : 0, 0)); 966 } 967 968 /** 969 * Helper function for making ManagedApplicationService instances. 970 */ 971 private static ManagedApplicationService create(@NonNull Context context, 972 @NonNull ComponentName component, int userId) { 973 return ManagedApplicationService.build(context, component, userId, 974 R.string.vr_listener_binding_label, Settings.ACTION_VR_LISTENER_SETTINGS, 975 sBinderChecker); 976 } 977 978 /** 979 * Apply the pending VR state. If no state is pending, disconnect any currently bound 980 * VR listener service. 981 */ 982 private void consumeAndApplyPendingStateLocked() { 983 consumeAndApplyPendingStateLocked(true); 984 } 985 986 /** 987 * Apply the pending VR state. 988 * 989 * @param disconnectIfNoPendingState if {@code true}, then any currently bound VR listener 990 * service will be disconnected if no state is pending. If this is {@code false} then the 991 * nothing will be changed when there is no pending state. 992 */ 993 private void consumeAndApplyPendingStateLocked(boolean disconnectIfNoPendingState) { 994 if (mPendingState != null) { 995 updateCurrentVrServiceLocked(mPendingState.enabled, 996 mPendingState.targetPackageName, mPendingState.userId, 997 mPendingState.callingPackage); 998 mPendingState = null; 999 } else if (disconnectIfNoPendingState) { 1000 updateCurrentVrServiceLocked(false, null, 0, null); 1001 } 1002 } 1003 1004 private void logStateLocked() { 1005 ComponentName currentBoundService = (mCurrentVrService == null) ? null : 1006 mCurrentVrService.getComponent(); 1007 VrState current = new VrState(mVrModeEnabled, currentBoundService, mCurrentVrModeUser, 1008 mCurrentVrModeComponent, mWasDefaultGranted); 1009 if (mLoggingDeque.size() == EVENT_LOG_SIZE) { 1010 mLoggingDeque.removeFirst(); 1011 } 1012 mLoggingDeque.add(current); 1013 } 1014 1015 private void dumpStateTransitions(PrintWriter pw) { 1016 SimpleDateFormat d = new SimpleDateFormat("MM-dd HH:mm:ss.SSS"); 1017 String tab = " "; 1018 if (mLoggingDeque.size() == 0) { 1019 pw.print(tab); 1020 pw.println("None"); 1021 } 1022 for (VrState state : mLoggingDeque) { 1023 pw.print(d.format(new Date(state.timestamp))); 1024 pw.print(tab); 1025 pw.print("State changed to:"); 1026 pw.print(tab); 1027 pw.println((state.enabled) ? "ENABLED" : "DISABLED"); 1028 if (state.enabled) { 1029 pw.print(tab); 1030 pw.print("User="); 1031 pw.println(state.userId); 1032 pw.print(tab); 1033 pw.print("Current VR Activity="); 1034 pw.println((state.callingPackage == null) ? 1035 "None" : state.callingPackage.flattenToString()); 1036 pw.print(tab); 1037 pw.print("Bound VrListenerService="); 1038 pw.println((state.targetPackageName == null) ? 1039 "None" : state.targetPackageName.flattenToString()); 1040 if (state.defaultPermissionsGranted) { 1041 pw.print(tab); 1042 pw.println("Default permissions granted to the bound VrListenerService."); 1043 } 1044 } 1045 } 1046 } 1047 1048 /* 1049 * Implementation of VrManagerInternal calls. These are callable from system services. 1050 */ 1051 private void setVrMode(boolean enabled, @NonNull ComponentName targetPackageName, 1052 int userId, @NonNull ComponentName callingPackage) { 1053 1054 synchronized (mLock) { 1055 VrState pending; 1056 ComponentName targetListener; 1057 ComponentName foregroundVrComponent; 1058 1059 // If the device is in persistent VR mode, then calls to disable VR mode are ignored, 1060 // and the system default VR listener is used. 1061 boolean targetEnabledState = enabled || mPersistentVrModeEnabled; 1062 if (!enabled && mPersistentVrModeEnabled) { 1063 targetListener = mDefaultVrService; 1064 1065 // Current foreground component isn't a VR one (in 2D app case) 1066 foregroundVrComponent = null; 1067 } else { 1068 targetListener = targetPackageName; 1069 foregroundVrComponent = callingPackage; 1070 } 1071 pending = new VrState( 1072 targetEnabledState, targetListener, userId, foregroundVrComponent); 1073 1074 if (!mVrModeAllowed) { 1075 // We're not allowed to be in VR mode. Make this state pending. This will be 1076 // applied the next time we are allowed to enter VR mode unless it is superseded by 1077 // another call. 1078 mPendingState = pending; 1079 return; 1080 } 1081 1082 if (!targetEnabledState && mCurrentVrService != null) { 1083 // If we're transitioning out of VR mode, delay briefly to avoid expensive HAL calls 1084 // and service bind/unbind in case we are immediately switching to another VR app. 1085 if (mPendingState == null) { 1086 mHandler.sendEmptyMessageDelayed(MSG_PENDING_VR_STATE_CHANGE, 1087 PENDING_STATE_DELAY_MS); 1088 } 1089 1090 mPendingState = pending; 1091 return; 1092 } else { 1093 mHandler.removeMessages(MSG_PENDING_VR_STATE_CHANGE); 1094 mPendingState = null; 1095 } 1096 1097 updateCurrentVrServiceLocked( 1098 targetEnabledState, targetListener, userId, foregroundVrComponent); 1099 } 1100 } 1101 1102 private void setPersistentVrModeEnabled(boolean enabled) { 1103 synchronized(mLock) { 1104 setPersistentModeAndNotifyListenersLocked(enabled); 1105 // Disabling persistent mode when not showing a VR should disable the overall vr mode. 1106 if (!enabled && mCurrentVrModeComponent == null) { 1107 setVrMode(false, null, 0, null); 1108 } 1109 } 1110 } 1111 1112 private int getCompatibilityDisplayId() { 1113 if (mCompatibilityDisplay != null) { 1114 return mCompatibilityDisplay.getVirtualDisplayId(); 1115 } 1116 Slog.w(TAG, "CompatibilityDisplay is null!"); 1117 return INVALID_DISPLAY; 1118 } 1119 1120 private void setPersistentModeAndNotifyListenersLocked(boolean enabled) { 1121 if (mPersistentVrModeEnabled == enabled) { 1122 return; 1123 } 1124 mPersistentVrModeEnabled = enabled; 1125 1126 mHandler.sendMessage(mHandler.obtainMessage(MSG_PERSISTENT_VR_MODE_STATE_CHANGE, 1127 (mPersistentVrModeEnabled) ? 1 : 0, 0)); 1128 } 1129 1130 private int hasVrPackage(@NonNull ComponentName targetPackageName, int userId) { 1131 synchronized (mLock) { 1132 return mComponentObserver.isValid(targetPackageName, userId); 1133 } 1134 } 1135 1136 private boolean isCurrentVrListener(String packageName, int userId) { 1137 synchronized (mLock) { 1138 if (mCurrentVrService == null) { 1139 return false; 1140 } 1141 return mCurrentVrService.getComponent().getPackageName().equals(packageName) && 1142 userId == mCurrentVrService.getUserId(); 1143 } 1144 } 1145 1146 /* 1147 * Implementation of IVrManager calls. 1148 */ 1149 1150 private void addStateCallback(IVrStateCallbacks cb) { 1151 mVrStateRemoteCallbacks.register(cb); 1152 } 1153 1154 private void removeStateCallback(IVrStateCallbacks cb) { 1155 mVrStateRemoteCallbacks.unregister(cb); 1156 } 1157 1158 private void addPersistentStateCallback(IPersistentVrStateCallbacks cb) { 1159 mPersistentVrStateRemoteCallbacks.register(cb); 1160 } 1161 1162 private void removePersistentStateCallback(IPersistentVrStateCallbacks cb) { 1163 mPersistentVrStateRemoteCallbacks.unregister(cb); 1164 } 1165 1166 private boolean getVrMode() { 1167 synchronized (mLock) { 1168 return mVrModeEnabled; 1169 } 1170 } 1171 1172 private void connectController(FileDescriptor fd) throws android.os.RemoteException { 1173 // TODO(b/36506799): move vr_wm code to VrCore and remove this. 1174 IVrWindowManager remote = 1175 IVrWindowManager.Stub.asInterface( 1176 ServiceManager.getService(IVrWindowManager.SERVICE_NAME)); 1177 remote.connectController(fd); 1178 } 1179 1180 private void disconnectController() throws android.os.RemoteException { 1181 // TODO(b/36506799): move vr_wm code to VrCore and remove this. 1182 IVrWindowManager remote = 1183 IVrWindowManager.Stub.asInterface( 1184 ServiceManager.getService(IVrWindowManager.SERVICE_NAME)); 1185 remote.disconnectController(); 1186 } 1187} 1188