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