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