OSDN Git Service

Merge "DO NOT MERGE. No direct Uri grants from system." into mnc-dev am: e6be8d765f...
[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
105     private static native void initializeNative();
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
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
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
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
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
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
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
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
387         public boolean isCurrentVrListener(String packageName, int userId) {
388             return VrManagerService.this.isCurrentVrListener(packageName, userId);
389         }
390
391         @Override
392         public int hasVrPackage(ComponentName packageName, int userId) {
393             return VrManagerService.this.hasVrPackage(packageName, userId);
394         }
395     }
396
397     public VrManagerService(Context context) {
398         super(context);
399     }
400
401     @Override
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
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
431     public void onStartUser(int userHandle) {
432         synchronized (mLock) {
433             mComponentObserver.onUsersChanged();
434         }
435     }
436
437     @Override
438     public void onSwitchUser(int userHandle) {
439         synchronized (mLock) {
440             mComponentObserver.onUsersChanged();
441         }
442
443     }
444
445     @Override
446     public void onStopUser(int userHandle) {
447         synchronized (mLock) {
448             mComponentObserver.onUsersChanged();
449         }
450
451     }
452
453     @Override
454     public void onCleanupUser(int userHandle) {
455         synchronized (mLock) {
456             mComponentObserver.onUsersChanged();
457         }
458     }
459
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
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      */
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
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
603     private void grantNotificationPolicyAccess(String pkg) {
604         NotificationManager nm = mContext.getSystemService(NotificationManager.class);
605         nm.setNotificationPolicyAccessGranted(pkg, true);
606     }
607
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
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
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
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
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
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
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
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
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      */
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      */
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      */
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
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
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
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
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
850     private int hasVrPackage(@NonNull ComponentName targetPackageName, int userId) {
851         synchronized (mLock) {
852             return mComponentObserver.isValid(targetPackageName, userId);
853         }
854     }
855
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
870     private void addStateCallback(IVrStateCallbacks cb) {
871         mRemoteCallbacks.register(cb);
872     }
873
874     private void removeStateCallback(IVrStateCallbacks cb) {
875         mRemoteCallbacks.unregister(cb);
876     }
877
878     private boolean getVrMode() {
879         synchronized (mLock) {
880             return mVrModeEnabled;
881         }
882     }
883 }