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