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