VrManagerService.java revision 2ff9c01975622ce7b0e1f7679f1337004dca7be9
1/** 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16package com.android.server.vr; 17 18import android.Manifest; 19import android.app.AppOpsManager; 20import android.app.NotificationManager; 21import android.annotation.NonNull; 22import android.content.BroadcastReceiver; 23import android.content.ComponentName; 24import android.content.ContentResolver; 25import android.content.Context; 26import android.content.Intent; 27import android.content.IntentFilter; 28import android.content.pm.ApplicationInfo; 29import android.content.pm.FeatureInfo; 30import android.content.pm.PackageInfo; 31import android.content.pm.PackageManager; 32import android.content.pm.PackageManager.NameNotFoundException; 33import android.os.Binder; 34import android.os.Handler; 35import android.os.IBinder; 36import android.os.IInterface; 37import android.os.Looper; 38import android.os.Message; 39import android.os.RemoteCallbackList; 40import android.os.RemoteException; 41import android.os.UserHandle; 42import android.provider.Settings; 43import android.service.notification.NotificationListenerService; 44import android.service.vr.IVrListener; 45import android.service.vr.IVrManager; 46import android.service.vr.IVrStateCallbacks; 47import android.service.vr.VrListenerService; 48import android.util.ArraySet; 49import android.util.Slog; 50 51import com.android.internal.R; 52import com.android.server.SystemConfig; 53import com.android.server.SystemService; 54import com.android.server.utils.ManagedApplicationService.PendingEvent; 55import com.android.server.vr.EnabledComponentsObserver.EnabledComponentChangeListener; 56import com.android.server.utils.ManagedApplicationService; 57import com.android.server.utils.ManagedApplicationService.BinderChecker; 58 59import java.io.FileDescriptor; 60import java.io.PrintWriter; 61import java.lang.StringBuilder; 62import java.text.SimpleDateFormat; 63import java.util.ArrayDeque; 64import java.util.ArrayList; 65import java.util.Collection; 66import java.util.Date; 67import java.util.List; 68import java.util.Objects; 69 70/** 71 * Service tracking whether VR mode is active, and notifying listening services of state changes. 72 * <p/> 73 * Services running in system server may modify the state of VrManagerService via the interface in 74 * VrManagerInternal, and may register to receive callbacks when the system VR mode changes via the 75 * interface given in VrStateListener. 76 * <p/> 77 * Device vendors may choose to receive VR state changes by implementing the VR mode HAL, e.g.: 78 * hardware/libhardware/modules/vr 79 * <p/> 80 * In general applications may enable or disable VR mode by calling 81 * {@link android.app.Activity#setVrModeEnabled)}. An application may also implement a service to 82 * be run while in VR mode by implementing {@link android.service.vr.VrListenerService}. 83 * 84 * @see {@link android.service.vr.VrListenerService} 85 * @see {@link com.android.server.vr.VrManagerInternal} 86 * @see {@link com.android.server.vr.VrStateListener} 87 * 88 * @hide 89 */ 90public class VrManagerService extends SystemService implements EnabledComponentChangeListener{ 91 92 public static final String TAG = "VrManagerService"; 93 94 public static final String VR_MANAGER_BINDER_SERVICE = "vrmanager"; 95 96 private static final int PENDING_STATE_DELAY_MS = 300; 97 private static final int EVENT_LOG_SIZE = 32; 98 99 private static native void initializeNative(); 100 private static native void setVrModeNative(boolean enabled); 101 102 private final Object mLock = new Object(); 103 104 private final IBinder mOverlayToken = new Binder(); 105 106 // State protected by mLock 107 private boolean mVrModeEnabled; 108 private EnabledComponentsObserver mComponentObserver; 109 private ManagedApplicationService mCurrentVrService; 110 private Context mContext; 111 private ComponentName mCurrentVrModeComponent; 112 private int mCurrentVrModeUser; 113 private boolean mWasDefaultGranted; 114 private boolean mGuard; 115 private final RemoteCallbackList<IVrStateCallbacks> mRemoteCallbacks = 116 new RemoteCallbackList<>(); 117 private final ArraySet<String> mPreviousToggledListenerSettings = new ArraySet<>(); 118 private String mPreviousNotificationPolicyAccessPackage; 119 private String mPreviousCoarseLocationPackage; 120 private String mPreviousManageOverlayPackage; 121 private VrState mPendingState; 122 private final ArrayDeque<VrState> mLoggingDeque = new ArrayDeque<>(EVENT_LOG_SIZE); 123 124 private static final int MSG_VR_STATE_CHANGE = 0; 125 private static final int MSG_PENDING_VR_STATE_CHANGE = 1; 126 127 private final Handler mHandler = new Handler() { 128 @Override 129 public void handleMessage(Message msg) { 130 switch(msg.what) { 131 case MSG_VR_STATE_CHANGE : { 132 boolean state = (msg.arg1 == 1); 133 int i = mRemoteCallbacks.beginBroadcast(); 134 while (i > 0) { 135 i--; 136 try { 137 mRemoteCallbacks.getBroadcastItem(i).onVrStateChanged(state); 138 } catch (RemoteException e) { 139 // Noop 140 } 141 } 142 mRemoteCallbacks.finishBroadcast(); 143 } break; 144 case MSG_PENDING_VR_STATE_CHANGE : { 145 synchronized(mLock) { 146 VrManagerService.this.consumeAndApplyPendingStateLocked(); 147 } 148 } break; 149 default : 150 throw new IllegalStateException("Unknown message type: " + msg.what); 151 } 152 } 153 }; 154 155 private static class VrState { 156 final boolean enabled; 157 final int userId; 158 final ComponentName targetPackageName; 159 final ComponentName callingPackage; 160 final long timestamp; 161 final boolean defaultPermissionsGranted; 162 163 VrState(boolean enabled, ComponentName targetPackageName, int userId, 164 ComponentName callingPackage) { 165 this.enabled = enabled; 166 this.userId = userId; 167 this.targetPackageName = targetPackageName; 168 this.callingPackage = callingPackage; 169 this.defaultPermissionsGranted = false; 170 this.timestamp = System.currentTimeMillis(); 171 } 172 173 VrState(boolean enabled, ComponentName targetPackageName, int userId, 174 ComponentName callingPackage, boolean defaultPermissionsGranted) { 175 this.enabled = enabled; 176 this.userId = userId; 177 this.targetPackageName = targetPackageName; 178 this.callingPackage = callingPackage; 179 this.defaultPermissionsGranted = defaultPermissionsGranted; 180 this.timestamp = System.currentTimeMillis(); 181 } 182 } 183 184 private static final BinderChecker sBinderChecker = new BinderChecker() { 185 @Override 186 public IInterface asInterface(IBinder binder) { 187 return IVrListener.Stub.asInterface(binder); 188 } 189 190 @Override 191 public boolean checkType(IInterface service) { 192 return service instanceof IVrListener; 193 } 194 }; 195 196 /** 197 * Called when a user, package, or setting changes that could affect whether or not the 198 * currently bound VrListenerService is changed. 199 */ 200 @Override 201 public void onEnabledComponentChanged() { 202 synchronized (mLock) { 203 if (mCurrentVrService == null) { 204 return; // No active services 205 } 206 207 // If there is a pending state change, we'd better deal with that first 208 consumeAndApplyPendingStateLocked(); 209 210 if (mCurrentVrService == null) { 211 return; // No active services 212 } 213 214 // There is an active service, update it if needed 215 updateCurrentVrServiceLocked(mVrModeEnabled, mCurrentVrService.getComponent(), 216 mCurrentVrService.getUserId(), null); 217 } 218 } 219 220 private final IVrManager mVrManager = new IVrManager.Stub() { 221 222 @Override 223 public void registerListener(IVrStateCallbacks cb) { 224 enforceCallerPermission(Manifest.permission.ACCESS_VR_MANAGER); 225 if (cb == null) { 226 throw new IllegalArgumentException("Callback binder object is null."); 227 } 228 229 VrManagerService.this.addStateCallback(cb); 230 } 231 232 @Override 233 public void unregisterListener(IVrStateCallbacks cb) { 234 enforceCallerPermission(Manifest.permission.ACCESS_VR_MANAGER); 235 if (cb == null) { 236 throw new IllegalArgumentException("Callback binder object is null."); 237 } 238 239 VrManagerService.this.removeStateCallback(cb); 240 } 241 242 @Override 243 public boolean getVrModeState() { 244 return VrManagerService.this.getVrMode(); 245 } 246 247 @Override 248 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 249 if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 250 != PackageManager.PERMISSION_GRANTED) { 251 pw.println("permission denied: can't dump VrManagerService from pid=" 252 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); 253 return; 254 } 255 pw.println("********* Dump of VrManagerService *********"); 256 pw.println("Previous state transitions:\n"); 257 String tab = " "; 258 dumpStateTransitions(pw); 259 pw.println("\n\nRemote Callbacks:"); 260 int i=mRemoteCallbacks.beginBroadcast(); // create the broadcast item array 261 while(i-->0) { 262 pw.print(tab); 263 pw.print(mRemoteCallbacks.getBroadcastItem(i)); 264 if (i>0) pw.println(","); 265 } 266 mRemoteCallbacks.finishBroadcast(); 267 pw.println("\n"); 268 pw.println("Installed VrListenerService components:"); 269 int userId = mCurrentVrModeUser; 270 ArraySet<ComponentName> installed = mComponentObserver.getInstalled(userId); 271 if (installed == null || installed.size() == 0) { 272 pw.println("None"); 273 } else { 274 for (ComponentName n : installed) { 275 pw.print(tab); 276 pw.println(n.flattenToString()); 277 } 278 } 279 pw.println("Enabled VrListenerService components:"); 280 ArraySet<ComponentName> enabled = mComponentObserver.getEnabled(userId); 281 if (enabled == null || enabled.size() == 0) { 282 pw.println("None"); 283 } else { 284 for (ComponentName n : enabled) { 285 pw.print(tab); 286 pw.println(n.flattenToString()); 287 } 288 } 289 pw.println("\n"); 290 pw.println("********* End of VrManagerService Dump *********"); 291 } 292 293 }; 294 295 private void enforceCallerPermission(String permission) { 296 if (mContext.checkCallingOrSelfPermission(permission) 297 != PackageManager.PERMISSION_GRANTED) { 298 throw new SecurityException("Caller does not hold the permission " + permission); 299 } 300 } 301 302 /** 303 * Implementation of VrManagerInternal. Callable only from system services. 304 */ 305 private final class LocalService extends VrManagerInternal { 306 @Override 307 public void setVrMode(boolean enabled, ComponentName packageName, int userId, 308 ComponentName callingPackage) { 309 VrManagerService.this.setVrMode(enabled, packageName, userId, callingPackage); 310 } 311 312 @Override 313 public boolean isCurrentVrListener(String packageName, int userId) { 314 return VrManagerService.this.isCurrentVrListener(packageName, userId); 315 } 316 317 @Override 318 public int hasVrPackage(ComponentName packageName, int userId) { 319 return VrManagerService.this.hasVrPackage(packageName, userId); 320 } 321 } 322 323 public VrManagerService(Context context) { 324 super(context); 325 } 326 327 @Override 328 public void onStart() { 329 synchronized(mLock) { 330 initializeNative(); 331 mContext = getContext(); 332 } 333 334 publishLocalService(VrManagerInternal.class, new LocalService()); 335 publishBinderService(VR_MANAGER_BINDER_SERVICE, mVrManager.asBinder()); 336 337 // If there are no VR packages installed on the device, then disable VR 338 // components, otherwise, enable them. 339 setEnabledStatusOfVrComponents(); 340 } 341 342 private void setEnabledStatusOfVrComponents() { 343 ArraySet<ComponentName> vrComponents = SystemConfig.getInstance().getDefaultVrComponents(); 344 if (vrComponents == null) { 345 return; 346 } 347 348 // We only want to enable VR components if there is a VR package installed on the device. 349 // The VR components themselves do not quality as a VR package, so exclude them. 350 ArraySet<String> vrComponentPackageNames = new ArraySet<>(); 351 for (ComponentName componentName : vrComponents) { 352 vrComponentPackageNames.add(componentName.getPackageName()); 353 } 354 355 // Check to see if there are any packages on the device, other than the VR component 356 // packages. 357 PackageManager pm = mContext.getPackageManager(); 358 List<PackageInfo> packageInfos = pm.getInstalledPackages( 359 PackageManager.GET_CONFIGURATIONS); 360 boolean vrModeIsUsed = false; 361 for (PackageInfo packageInfo : packageInfos) { 362 if (packageInfo != null && packageInfo.packageName != null && 363 pm.getApplicationEnabledSetting(packageInfo.packageName) == 364 PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) { 365 vrModeIsUsed = enableVrComponentsIfVrModeUsed(pm, packageInfo, 366 vrComponentPackageNames, vrComponents); 367 if (vrModeIsUsed) { 368 break; 369 } 370 } 371 } 372 373 if (!vrModeIsUsed) { 374 Slog.i(TAG, "No VR packages found, disabling VR components"); 375 setVrComponentsEnabledOrDisabled(vrComponents, false); 376 377 // Register to receive an intent when a new package is installed, in case that package 378 // requires VR components. 379 IntentFilter intentFilter = new IntentFilter(); 380 intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED); 381 intentFilter.addDataScheme("package"); 382 mContext.registerReceiver(new BroadcastReceiver() { 383 @Override 384 public void onReceive(Context context, Intent intent) { 385 PackageManager pm = context.getPackageManager(); 386 final String packageName = intent.getData().getSchemeSpecificPart(); 387 if (packageName != null) { 388 try { 389 PackageInfo packageInfo = pm.getPackageInfo(packageName, 390 PackageManager.GET_CONFIGURATIONS); 391 enableVrComponentsIfVrModeUsed(pm, packageInfo, 392 vrComponentPackageNames, vrComponents); 393 } catch (NameNotFoundException e) { 394 } 395 } 396 }; 397 }, intentFilter); 398 } 399 } 400 401 private void setVrComponentsEnabledOrDisabled(ArraySet<ComponentName> vrComponents, 402 boolean enabled) { 403 int state = enabled ? 404 PackageManager.COMPONENT_ENABLED_STATE_ENABLED : 405 PackageManager.COMPONENT_ENABLED_STATE_DISABLED; 406 PackageManager pm = mContext.getPackageManager(); 407 for (ComponentName componentName : vrComponents) { 408 try { 409 // Note that we must first check for the existance of the package before trying 410 // to set its enabled state. This is to prevent PackageManager from throwing 411 // an excepton if the package is not found (not just a NameNotFoundException 412 // exception). 413 PackageInfo packageInfo = pm.getPackageInfo(componentName.getPackageName(), 414 PackageManager.GET_CONFIGURATIONS); 415 pm.setApplicationEnabledSetting(componentName.getPackageName(), state , 0); 416 } catch (NameNotFoundException e) { 417 } 418 } 419 } 420 421 private boolean enableVrComponentsIfVrModeUsed(PackageManager pm, PackageInfo packageInfo, 422 ArraySet<String> vrComponentPackageNames, ArraySet<ComponentName> vrComponents) { 423 boolean isVrComponent = vrComponents != null && 424 vrComponentPackageNames.contains(packageInfo.packageName); 425 if (packageInfo != null && packageInfo.reqFeatures != null && !isVrComponent) { 426 for (FeatureInfo featureInfo : packageInfo.reqFeatures) { 427 if (featureInfo.name != null && 428 (featureInfo.name.equals(PackageManager.FEATURE_VR_MODE) || 429 featureInfo.name.equals(PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE))) { 430 Slog.i(TAG, "VR package found, enabling VR components"); 431 setVrComponentsEnabledOrDisabled(vrComponents, true); 432 return true; 433 } 434 } 435 } 436 return false; 437 } 438 439 @Override 440 public void onBootPhase(int phase) { 441 if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) { 442 synchronized (mLock) { 443 Looper looper = Looper.getMainLooper(); 444 Handler handler = new Handler(looper); 445 ArrayList<EnabledComponentChangeListener> listeners = new ArrayList<>(); 446 listeners.add(this); 447 mComponentObserver = EnabledComponentsObserver.build(mContext, handler, 448 Settings.Secure.ENABLED_VR_LISTENERS, looper, 449 android.Manifest.permission.BIND_VR_LISTENER_SERVICE, 450 VrListenerService.SERVICE_INTERFACE, mLock, listeners); 451 452 mComponentObserver.rebuildAll(); 453 } 454 } 455 } 456 457 @Override 458 public void onStartUser(int userHandle) { 459 synchronized (mLock) { 460 mComponentObserver.onUsersChanged(); 461 } 462 } 463 464 @Override 465 public void onSwitchUser(int userHandle) { 466 synchronized (mLock) { 467 mComponentObserver.onUsersChanged(); 468 } 469 470 } 471 472 @Override 473 public void onStopUser(int userHandle) { 474 synchronized (mLock) { 475 mComponentObserver.onUsersChanged(); 476 } 477 478 } 479 480 @Override 481 public void onCleanupUser(int userHandle) { 482 synchronized (mLock) { 483 mComponentObserver.onUsersChanged(); 484 } 485 } 486 487 private void updateOverlayStateLocked(ComponentName exemptedComponent) { 488 final long identity = Binder.clearCallingIdentity(); 489 try { 490 AppOpsManager appOpsManager = getContext().getSystemService(AppOpsManager.class); 491 if (appOpsManager != null) { 492 String[] exemptions = (exemptedComponent == null) ? new String[0] : 493 new String[] { exemptedComponent.getPackageName() }; 494 495 appOpsManager.setUserRestriction(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, 496 mVrModeEnabled, mOverlayToken, exemptions); 497 } 498 } finally { 499 Binder.restoreCallingIdentity(identity); 500 } 501 } 502 503 /** 504 * Send VR mode changes (if the mode state has changed), and update the bound/unbound state of 505 * the currently selected VR listener service. If the component selected for the VR listener 506 * service has changed, unbind the previous listener and bind the new listener (if enabled). 507 * <p/> 508 * Note: Must be called while holding {@code mLock}. 509 * 510 * @param enabled new state for VR mode. 511 * @param component new component to be bound as a VR listener. 512 * @param userId user owning the component to be bound. 513 * @param calling the component currently using VR mode, or null to leave unchanged. 514 * 515 * @return {@code true} if the component/user combination specified is valid. 516 */ 517 private boolean updateCurrentVrServiceLocked(boolean enabled, @NonNull ComponentName component, 518 int userId, ComponentName calling) { 519 520 boolean sendUpdatedCaller = false; 521 final long identity = Binder.clearCallingIdentity(); 522 try { 523 524 boolean validUserComponent = (mComponentObserver.isValid(component, userId) == 525 EnabledComponentsObserver.NO_ERROR); 526 if (!mVrModeEnabled && !enabled) { 527 return validUserComponent; // Disabled -> Disabled transition does nothing. 528 } 529 530 // Always send mode change events. 531 changeVrModeLocked(enabled, (enabled && validUserComponent) ? component : null); 532 533 if (!enabled || !validUserComponent) { 534 // Unbind whatever is running 535 if (mCurrentVrService != null) { 536 Slog.i(TAG, "Disconnecting " + mCurrentVrService.getComponent() + " for user " + 537 mCurrentVrService.getUserId()); 538 mCurrentVrService.disconnect(); 539 disableImpliedPermissionsLocked(mCurrentVrService.getComponent(), 540 new UserHandle(mCurrentVrService.getUserId())); 541 mCurrentVrService = null; 542 } 543 } else { 544 if (mCurrentVrService != null) { 545 // Unbind any running service that doesn't match the component/user selection 546 if (mCurrentVrService.disconnectIfNotMatching(component, userId)) { 547 Slog.i(TAG, "Disconnecting " + mCurrentVrService.getComponent() + 548 " for user " + mCurrentVrService.getUserId()); 549 disableImpliedPermissionsLocked(mCurrentVrService.getComponent(), 550 new UserHandle(mCurrentVrService.getUserId())); 551 createAndConnectService(component, userId); 552 enableImpliedPermissionsLocked(mCurrentVrService.getComponent(), 553 new UserHandle(mCurrentVrService.getUserId())); 554 sendUpdatedCaller = true; 555 } 556 // The service with the correct component/user is bound 557 } else { 558 // Nothing was previously running, bind a new service 559 createAndConnectService(component, userId); 560 enableImpliedPermissionsLocked(mCurrentVrService.getComponent(), 561 new UserHandle(mCurrentVrService.getUserId())); 562 sendUpdatedCaller = true; 563 } 564 } 565 566 if (calling != null && !Objects.equals(calling, mCurrentVrModeComponent)) { 567 mCurrentVrModeComponent = calling; 568 mCurrentVrModeUser = userId; 569 sendUpdatedCaller = true; 570 } 571 572 if (mCurrentVrService != null && sendUpdatedCaller) { 573 final ComponentName c = mCurrentVrModeComponent; 574 mCurrentVrService.sendEvent(new PendingEvent() { 575 @Override 576 public void runEvent(IInterface service) throws RemoteException { 577 IVrListener l = (IVrListener) service; 578 l.focusedActivityChanged(c); 579 } 580 }); 581 } 582 logStateLocked(); 583 584 return validUserComponent; 585 } finally { 586 Binder.restoreCallingIdentity(identity); 587 } 588 } 589 590 /** 591 * Enable the permission given in {@link #IMPLIED_VR_LISTENER_PERMISSIONS} for the given 592 * component package and user. 593 * 594 * @param component the component whose package should be enabled. 595 * @param userId the user that owns the given component. 596 */ 597 private void enableImpliedPermissionsLocked(ComponentName component, UserHandle userId) { 598 if (mGuard) { 599 // Impossible 600 throw new IllegalStateException("Enabling permissions without disabling."); 601 } 602 mGuard = true; 603 604 PackageManager pm = mContext.getPackageManager(); 605 606 String pName = component.getPackageName(); 607 if (pm == null) { 608 Slog.e(TAG, "Couldn't set implied permissions for " + pName + 609 ", PackageManager isn't running"); 610 return; 611 } 612 613 ApplicationInfo info = null; 614 try { 615 info = pm.getApplicationInfo(pName, PackageManager.GET_META_DATA); 616 } catch (NameNotFoundException e) { 617 } 618 619 if (info == null) { 620 Slog.e(TAG, "Couldn't set implied permissions for " + pName + ", no such package."); 621 return; 622 } 623 624 if (!(info.isSystemApp() || info.isUpdatedSystemApp())) { 625 return; // Application is not pre-installed, avoid setting implied permissions 626 } 627 628 mWasDefaultGranted = true; 629 630 grantCoarseLocationAccess(pName, userId); 631 grantOverlayAccess(pName, userId); 632 grantNotificationPolicyAccess(pName); 633 grantNotificationListenerAccess(pName, userId); 634 } 635 636 /** 637 * Disable the permission given in {@link #IMPLIED_VR_LISTENER_PERMISSIONS} for the given 638 * component package and user. 639 * 640 * @param component the component whose package should be disabled. 641 * @param userId the user that owns the given component. 642 */ 643 private void disableImpliedPermissionsLocked(ComponentName component, UserHandle userId) { 644 if (!mGuard) { 645 // Impossible 646 throw new IllegalStateException("Disabling permissions without enabling."); 647 } 648 mGuard = false; 649 650 PackageManager pm = mContext.getPackageManager(); 651 652 if (pm == null) { 653 Slog.e(TAG, "Couldn't remove implied permissions for " + component + 654 ", PackageManager isn't running"); 655 return; 656 } 657 658 String pName = component.getPackageName(); 659 if (mWasDefaultGranted) { 660 revokeCoarseLocationAccess(userId); 661 revokeOverlayAccess(userId); 662 revokeNotificationPolicyAccess(pName); 663 revokeNotificiationListenerAccess(); 664 mWasDefaultGranted = false; 665 } 666 667 } 668 669 private void grantCoarseLocationAccess(String pkg, UserHandle userId) { 670 PackageManager pm = mContext.getPackageManager(); 671 boolean prev = (PackageManager.PERMISSION_GRANTED == 672 pm.checkPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION, pkg)); 673 mPreviousCoarseLocationPackage = null; 674 if (!prev) { 675 pm.grantRuntimePermission(pkg, android.Manifest.permission.ACCESS_COARSE_LOCATION, 676 userId); 677 mPreviousCoarseLocationPackage = pkg; 678 } 679 } 680 681 private void revokeCoarseLocationAccess(UserHandle userId) { 682 PackageManager pm = mContext.getPackageManager(); 683 if (mPreviousCoarseLocationPackage != null) { 684 pm.revokeRuntimePermission(mPreviousCoarseLocationPackage, 685 android.Manifest.permission.ACCESS_COARSE_LOCATION, userId); 686 mPreviousCoarseLocationPackage = null; 687 } 688 } 689 690 private void grantOverlayAccess(String pkg, UserHandle userId) { 691 PackageManager pm = mContext.getPackageManager(); 692 boolean prev = (PackageManager.PERMISSION_GRANTED == 693 pm.checkPermission(android.Manifest.permission.SYSTEM_ALERT_WINDOW, pkg)); 694 mPreviousManageOverlayPackage = null; 695 if (!prev) { 696 pm.grantRuntimePermission(pkg, android.Manifest.permission.SYSTEM_ALERT_WINDOW, 697 userId); 698 mPreviousManageOverlayPackage = pkg; 699 } 700 } 701 702 private void revokeOverlayAccess(UserHandle userId) { 703 PackageManager pm = mContext.getPackageManager(); 704 if (mPreviousManageOverlayPackage != null) { 705 pm.revokeRuntimePermission(mPreviousManageOverlayPackage, 706 android.Manifest.permission.SYSTEM_ALERT_WINDOW, userId); 707 mPreviousManageOverlayPackage = null; 708 } 709 } 710 711 private void grantNotificationPolicyAccess(String pkg) { 712 NotificationManager nm = mContext.getSystemService(NotificationManager.class); 713 boolean prev = nm.isNotificationPolicyAccessGrantedForPackage(pkg); 714 mPreviousNotificationPolicyAccessPackage = null; 715 if (!prev) { 716 mPreviousNotificationPolicyAccessPackage = pkg; 717 nm.setNotificationPolicyAccessGranted(pkg, true); 718 } 719 } 720 721 private void revokeNotificationPolicyAccess(String pkg) { 722 NotificationManager nm = mContext.getSystemService(NotificationManager.class); 723 if (mPreviousNotificationPolicyAccessPackage != null) { 724 if (mPreviousNotificationPolicyAccessPackage.equals(pkg)) { 725 // Remove any DND zen rules possibly created by the package. 726 nm.removeAutomaticZenRules(mPreviousNotificationPolicyAccessPackage); 727 // Remove Notification Policy Access. 728 nm.setNotificationPolicyAccessGranted(mPreviousNotificationPolicyAccessPackage, false); 729 mPreviousNotificationPolicyAccessPackage = null; 730 } else { 731 Slog.e(TAG, "Couldn't remove Notification Policy Access for package: " + pkg); 732 } 733 } 734 } 735 736 private void grantNotificationListenerAccess(String pkg, UserHandle userId) { 737 PackageManager pm = mContext.getPackageManager(); 738 ArraySet<ComponentName> possibleServices = EnabledComponentsObserver.loadComponentNames(pm, 739 userId.getIdentifier(), NotificationListenerService.SERVICE_INTERFACE, 740 android.Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE); 741 ContentResolver resolver = mContext.getContentResolver(); 742 743 ArraySet<String> current = getCurrentNotifListeners(resolver); 744 745 mPreviousToggledListenerSettings.clear(); 746 747 for (ComponentName c : possibleServices) { 748 String flatName = c.flattenToString(); 749 if (Objects.equals(c.getPackageName(), pkg) 750 && !current.contains(flatName)) { 751 mPreviousToggledListenerSettings.add(flatName); 752 current.add(flatName); 753 } 754 } 755 756 if (current.size() > 0) { 757 String flatSettings = formatSettings(current); 758 Settings.Secure.putString(resolver, Settings.Secure.ENABLED_NOTIFICATION_LISTENERS, 759 flatSettings); 760 } 761 } 762 763 private void revokeNotificiationListenerAccess() { 764 if (mPreviousToggledListenerSettings.isEmpty()) { 765 return; 766 } 767 768 ContentResolver resolver = mContext.getContentResolver(); 769 ArraySet<String> current = getCurrentNotifListeners(resolver); 770 771 current.removeAll(mPreviousToggledListenerSettings); 772 mPreviousToggledListenerSettings.clear(); 773 774 String flatSettings = formatSettings(current); 775 Settings.Secure.putString(resolver, Settings.Secure.ENABLED_NOTIFICATION_LISTENERS, 776 flatSettings); 777 } 778 779 private ArraySet<String> getCurrentNotifListeners(ContentResolver resolver) { 780 String flat = Settings.Secure.getString(resolver, 781 Settings.Secure.ENABLED_NOTIFICATION_LISTENERS); 782 783 ArraySet<String> current = new ArraySet<>(); 784 if (flat != null) { 785 String[] allowed = flat.split(":"); 786 for (String s : allowed) { 787 current.add(s); 788 } 789 } 790 return current; 791 } 792 793 private static String formatSettings(Collection<String> c) { 794 if (c == null || c.isEmpty()) { 795 return ""; 796 } 797 798 StringBuilder b = new StringBuilder(); 799 boolean start = true; 800 for (String s : c) { 801 if ("".equals(s)) { 802 continue; 803 } 804 if (!start) { 805 b.append(':'); 806 } 807 b.append(s); 808 start = false; 809 } 810 return b.toString(); 811 } 812 813 814 815 private void createAndConnectService(@NonNull ComponentName component, int userId) { 816 mCurrentVrService = VrManagerService.create(mContext, component, userId); 817 mCurrentVrService.connect(); 818 Slog.i(TAG, "Connecting " + component + " for user " + userId); 819 } 820 821 /** 822 * Send VR mode change callbacks to HAL and system services if mode has actually changed. 823 * <p/> 824 * Note: Must be called while holding {@code mLock}. 825 * 826 * @param enabled new state of the VR mode. 827 * @param exemptedComponent a component to exempt from AppOps restrictions for overlays. 828 */ 829 private void changeVrModeLocked(boolean enabled, ComponentName exemptedComponent) { 830 if (mVrModeEnabled != enabled) { 831 mVrModeEnabled = enabled; 832 833 // Log mode change event. 834 Slog.i(TAG, "VR mode " + ((mVrModeEnabled) ? "enabled" : "disabled")); 835 setVrModeNative(mVrModeEnabled); 836 837 updateOverlayStateLocked(exemptedComponent); 838 onVrModeChangedLocked(); 839 } 840 } 841 842 /** 843 * Notify system services of VR mode change. 844 * <p/> 845 * Note: Must be called while holding {@code mLock}. 846 */ 847 private void onVrModeChangedLocked() { 848 mHandler.sendMessage(mHandler.obtainMessage(MSG_VR_STATE_CHANGE, 849 (mVrModeEnabled) ? 1 : 0, 0)); 850 } 851 852 /** 853 * Helper function for making ManagedApplicationService instances. 854 */ 855 private static ManagedApplicationService create(@NonNull Context context, 856 @NonNull ComponentName component, int userId) { 857 return ManagedApplicationService.build(context, component, userId, 858 R.string.vr_listener_binding_label, Settings.ACTION_VR_LISTENER_SETTINGS, 859 sBinderChecker); 860 } 861 862 private void consumeAndApplyPendingStateLocked() { 863 if (mPendingState != null) { 864 updateCurrentVrServiceLocked(mPendingState.enabled, 865 mPendingState.targetPackageName, mPendingState.userId, 866 mPendingState.callingPackage); 867 mPendingState = null; 868 } 869 } 870 871 private void logStateLocked() { 872 ComponentName currentBoundService = (mCurrentVrService == null) ? null : 873 mCurrentVrService.getComponent(); 874 VrState current = new VrState(mVrModeEnabled, currentBoundService, mCurrentVrModeUser, 875 mCurrentVrModeComponent, mWasDefaultGranted); 876 if (mLoggingDeque.size() == EVENT_LOG_SIZE) { 877 mLoggingDeque.removeFirst(); 878 } 879 mLoggingDeque.add(current); 880 } 881 882 private void dumpStateTransitions(PrintWriter pw) { 883 SimpleDateFormat d = new SimpleDateFormat("MM-dd HH:mm:ss.SSS"); 884 String tab = " "; 885 if (mLoggingDeque.size() == 0) { 886 pw.print(tab); 887 pw.println("None"); 888 } 889 for (VrState state : mLoggingDeque) { 890 pw.print(d.format(new Date(state.timestamp))); 891 pw.print(tab); 892 pw.print("State changed to:"); 893 pw.print(tab); 894 pw.println((state.enabled) ? "ENABLED" : "DISABLED"); 895 if (state.enabled) { 896 pw.print(tab); 897 pw.print("User="); 898 pw.println(state.userId); 899 pw.print(tab); 900 pw.print("Current VR Activity="); 901 pw.println((state.callingPackage == null) ? 902 "None" : state.callingPackage.flattenToString()); 903 pw.print(tab); 904 pw.print("Bound VrListenerService="); 905 pw.println((state.targetPackageName == null) ? 906 "None" : state.targetPackageName.flattenToString()); 907 if (state.defaultPermissionsGranted) { 908 pw.print(tab); 909 pw.println("Default permissions granted to the bound VrListenerService."); 910 } 911 } 912 } 913 } 914 915 /* 916 * Implementation of VrManagerInternal calls. These are callable from system services. 917 */ 918 919 private void setVrMode(boolean enabled, @NonNull ComponentName targetPackageName, 920 int userId, @NonNull ComponentName callingPackage) { 921 922 synchronized (mLock) { 923 924 if (!enabled && mCurrentVrService != null) { 925 // If we're transitioning out of VR mode, delay briefly to avoid expensive HAL calls 926 // and service bind/unbind in case we are immediately switching to another VR app. 927 if (mPendingState == null) { 928 mHandler.sendEmptyMessageDelayed(MSG_PENDING_VR_STATE_CHANGE, 929 PENDING_STATE_DELAY_MS); 930 } 931 932 mPendingState = new VrState(enabled, targetPackageName, userId, callingPackage); 933 return; 934 } else { 935 mHandler.removeMessages(MSG_PENDING_VR_STATE_CHANGE); 936 mPendingState = null; 937 } 938 939 updateCurrentVrServiceLocked(enabled, targetPackageName, userId, callingPackage); 940 } 941 } 942 943 private int hasVrPackage(@NonNull ComponentName targetPackageName, int userId) { 944 synchronized (mLock) { 945 return mComponentObserver.isValid(targetPackageName, userId); 946 } 947 } 948 949 private boolean isCurrentVrListener(String packageName, int userId) { 950 synchronized (mLock) { 951 if (mCurrentVrService == null) { 952 return false; 953 } 954 return mCurrentVrService.getComponent().getPackageName().equals(packageName) && 955 userId == mCurrentVrService.getUserId(); 956 } 957 } 958 959 /* 960 * Implementation of IVrManager calls. 961 */ 962 963 private void addStateCallback(IVrStateCallbacks cb) { 964 mRemoteCallbacks.register(cb); 965 } 966 967 private void removeStateCallback(IVrStateCallbacks cb) { 968 mRemoteCallbacks.unregister(cb); 969 } 970 971 private boolean getVrMode() { 972 synchronized (mLock) { 973 return mVrModeEnabled; 974 } 975 } 976} 977