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