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