OSDN Git Service

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