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