OSDN Git Service

Use correct APIs to detect conditions for round scrollbars.
[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         if (!mVrModeEnabled) {
543             return;
544         }
545
546         // Apply the restrictions for the current user based on vr state
547         String[] exemptions = (exemptedPackage == null) ? new String[0] :
548                 new String[] { exemptedPackage };
549
550         appOpsManager.setUserRestrictionForUser(AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
551                 true, mOverlayToken, exemptions, newUserId);
552     }
553
554     private void updateDependentAppOpsLocked(String newVrServicePackage, int newUserId,
555             String oldVrServicePackage, int oldUserId) {
556         // If VR state changed and we also have a VR service change.
557         if (Objects.equals(newVrServicePackage, oldVrServicePackage)) {
558             return;
559         }
560         final long identity = Binder.clearCallingIdentity();
561         try {
562             // Set overlay exception state based on VR enabled and current service
563             updateOverlayStateLocked(newVrServicePackage, newUserId, oldUserId);
564         } finally {
565             Binder.restoreCallingIdentity(identity);
566         }
567     }
568
569     /**
570      * Send VR mode changes (if the mode state has changed), and update the bound/unbound state of
571      * the currently selected VR listener service.  If the component selected for the VR listener
572      * service has changed, unbind the previous listener and bind the new listener (if enabled).
573      * <p/>
574      * Note: Must be called while holding {@code mLock}.
575      *
576      * @param enabled new state for VR mode.
577      * @param component new component to be bound as a VR listener.
578      * @param userId user owning the component to be bound.
579      * @param calling the component currently using VR mode, or null to leave unchanged.
580      *
581      * @return {@code true} if the component/user combination specified is valid.
582      */
583     private boolean updateCurrentVrServiceLocked(boolean enabled, @NonNull ComponentName component,
584             int userId, ComponentName calling) {
585
586         boolean sendUpdatedCaller = false;
587         final long identity = Binder.clearCallingIdentity();
588         try {
589
590             boolean validUserComponent = (mComponentObserver.isValid(component, userId) ==
591                     EnabledComponentsObserver.NO_ERROR);
592             boolean goingIntoVrMode = validUserComponent && enabled;
593             if (!mVrModeEnabled && !goingIntoVrMode) {
594                 return validUserComponent; // Disabled -> Disabled transition does nothing.
595             }
596
597             String oldVrServicePackage = mCurrentVrService != null
598                     ? mCurrentVrService.getComponent().getPackageName() : null;
599             final int oldUserId = mCurrentVrModeUser;
600
601             // Notify system services and VR HAL of mode change.
602             changeVrModeLocked(goingIntoVrMode);
603
604             boolean nothingChanged = false;
605             if (!goingIntoVrMode) {
606                 // Not going into VR mode, unbind whatever is running
607                 if (mCurrentVrService != null) {
608                     Slog.i(TAG, "Leaving VR mode, disconnecting "
609                         + mCurrentVrService.getComponent() + " for user "
610                         + mCurrentVrService.getUserId());
611                     mCurrentVrService.disconnect();
612                     mCurrentVrService = null;
613                 } else {
614                     nothingChanged = true;
615                 }
616             } else {
617                 // Going into VR mode
618                 if (mCurrentVrService != null) {
619                     // Unbind any running service that doesn't match the latest component/user
620                     // selection.
621                     if (mCurrentVrService.disconnectIfNotMatching(component, userId)) {
622                         Slog.i(TAG, "VR mode component changed to " + component
623                             + ", disconnecting " + mCurrentVrService.getComponent()
624                             + " for user " + mCurrentVrService.getUserId());
625                         createAndConnectService(component, userId);
626                         sendUpdatedCaller = true;
627                     } else {
628                         nothingChanged = true;
629                     }
630                     // The service with the correct component/user is already bound, do nothing.
631                 } else {
632                     // Nothing was previously running, bind a new service for the latest
633                     // component/user selection.
634                     createAndConnectService(component, userId);
635                     sendUpdatedCaller = true;
636                 }
637             }
638
639             if (calling != null && !Objects.equals(calling, mCurrentVrModeComponent)) {
640                 mCurrentVrModeComponent = calling;
641                 sendUpdatedCaller = true;
642             }
643
644             if (mCurrentVrModeUser != userId) {
645                 mCurrentVrModeUser = userId;
646                 sendUpdatedCaller = true;
647             }
648
649             String newVrServicePackage = mCurrentVrService != null
650                     ? mCurrentVrService.getComponent().getPackageName() : null;
651             final int newUserId = mCurrentVrModeUser;
652
653             // Update AppOps settings that change state when entering/exiting VR mode, or changing
654             // the current VrListenerService.
655             updateDependentAppOpsLocked(newVrServicePackage, newUserId,
656                     oldVrServicePackage, oldUserId);
657
658             if (mCurrentVrService != null && sendUpdatedCaller) {
659                 final ComponentName c = mCurrentVrModeComponent;
660                 mCurrentVrService.sendEvent(new PendingEvent() {
661                     @Override
662                     public void runEvent(IInterface service) throws RemoteException {
663                         IVrListener l = (IVrListener) service;
664                         l.focusedActivityChanged(c);
665                     }
666                 });
667             }
668
669             if (!nothingChanged) {
670                 logStateLocked();
671             }
672
673             return validUserComponent;
674         } finally {
675             Binder.restoreCallingIdentity(identity);
676         }
677     }
678
679     private boolean isDefaultAllowed(String packageName) {
680         PackageManager pm = mContext.getPackageManager();
681
682         ApplicationInfo info = null;
683         try {
684             info = pm.getApplicationInfo(packageName, PackageManager.GET_META_DATA);
685         } catch (NameNotFoundException e) {
686         }
687
688         if (info == null || !(info.isSystemApp() || info.isUpdatedSystemApp())) {
689             return false;
690         }
691         return true;
692     }
693
694     private void grantNotificationPolicyAccess(String pkg) {
695         NotificationManager nm = mContext.getSystemService(NotificationManager.class);
696         nm.setNotificationPolicyAccessGranted(pkg, true);
697     }
698
699     private void revokeNotificationPolicyAccess(String pkg) {
700         NotificationManager nm = mContext.getSystemService(NotificationManager.class);
701         // Remove any DND zen rules possibly created by the package.
702         nm.removeAutomaticZenRules(pkg);
703         // Remove Notification Policy Access.
704         nm.setNotificationPolicyAccessGranted(pkg, false);
705     }
706
707     private void grantNotificationListenerAccess(String pkg, int userId) {
708         PackageManager pm = mContext.getPackageManager();
709         ArraySet<ComponentName> possibleServices = EnabledComponentsObserver.loadComponentNames(pm,
710                 userId, NotificationListenerService.SERVICE_INTERFACE,
711                 android.Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE);
712         ContentResolver resolver = mContext.getContentResolver();
713
714         ArraySet<String> current = getNotificationListeners(resolver, userId);
715
716         for (ComponentName c : possibleServices) {
717             String flatName = c.flattenToString();
718             if (Objects.equals(c.getPackageName(), pkg)
719                     && !current.contains(flatName)) {
720                 current.add(flatName);
721             }
722         }
723
724         if (current.size() > 0) {
725             String flatSettings = formatSettings(current);
726             Settings.Secure.putStringForUser(resolver,
727                     Settings.Secure.ENABLED_NOTIFICATION_LISTENERS,
728                     flatSettings, userId);
729         }
730     }
731
732     private void revokeNotificationListenerAccess(String pkg, int userId) {
733         ContentResolver resolver = mContext.getContentResolver();
734
735         ArraySet<String> current = getNotificationListeners(resolver, userId);
736
737         ArrayList<String> toRemove = new ArrayList<>();
738
739         for (String c : current) {
740             ComponentName component = ComponentName.unflattenFromString(c);
741             if (component != null && component.getPackageName().equals(pkg)) {
742                 toRemove.add(c);
743             }
744         }
745
746         current.removeAll(toRemove);
747
748         String flatSettings = formatSettings(current);
749         Settings.Secure.putStringForUser(resolver,
750                 Settings.Secure.ENABLED_NOTIFICATION_LISTENERS,
751                 flatSettings, userId);
752     }
753
754     private void grantCoarseLocationPermissionIfNeeded(String pkg, int userId) {
755         // Don't clobber the user if permission set in current state explicitly
756         if (!isPermissionUserUpdated(Manifest.permission.ACCESS_COARSE_LOCATION, pkg, userId)) {
757             try {
758                 mContext.getPackageManager().grantRuntimePermission(pkg,
759                         Manifest.permission.ACCESS_COARSE_LOCATION, new UserHandle(userId));
760             } catch (IllegalArgumentException e) {
761                 // Package was removed during update.
762                 Slog.w(TAG, "Could not grant coarse location permission, package " + pkg
763                     + " was removed.");
764             }
765         }
766     }
767
768     private void revokeCoarseLocationPermissionIfNeeded(String pkg, int userId) {
769         // Don't clobber the user if permission set in current state explicitly
770         if (!isPermissionUserUpdated(Manifest.permission.ACCESS_COARSE_LOCATION, pkg, userId)) {
771             try {
772                 mContext.getPackageManager().revokeRuntimePermission(pkg,
773                         Manifest.permission.ACCESS_COARSE_LOCATION, new UserHandle(userId));
774             } catch (IllegalArgumentException e) {
775                 // Package was removed during update.
776                 Slog.w(TAG, "Could not revoke coarse location permission, package " + pkg
777                     + " was removed.");
778             }
779         }
780     }
781
782     private boolean isPermissionUserUpdated(String permission, String pkg, int userId) {
783         final int flags = mContext.getPackageManager().getPermissionFlags(
784                 permission, pkg, new UserHandle(userId));
785         return (flags & (PackageManager.FLAG_PERMISSION_USER_SET
786                 | PackageManager.FLAG_PERMISSION_USER_FIXED)) != 0;
787     }
788
789     private ArraySet<String> getNotificationListeners(ContentResolver resolver, int userId) {
790         String flat = Settings.Secure.getStringForUser(resolver,
791                 Settings.Secure.ENABLED_NOTIFICATION_LISTENERS, userId);
792
793         ArraySet<String> current = new ArraySet<>();
794         if (flat != null) {
795             String[] allowed = flat.split(":");
796             for (String s : allowed) {
797                 if (!TextUtils.isEmpty(s)) {
798                     current.add(s);
799                 }
800             }
801         }
802         return current;
803     }
804
805     private static String formatSettings(Collection<String> c) {
806         if (c == null || c.isEmpty()) {
807             return "";
808         }
809
810         StringBuilder b = new StringBuilder();
811         boolean start = true;
812         for (String s : c) {
813             if ("".equals(s)) {
814                 continue;
815             }
816             if (!start) {
817                 b.append(':');
818             }
819             b.append(s);
820             start = false;
821         }
822         return b.toString();
823     }
824
825
826
827     private void createAndConnectService(@NonNull ComponentName component, int userId) {
828         mCurrentVrService = VrManagerService.create(mContext, component, userId);
829         mCurrentVrService.connect();
830         Slog.i(TAG, "Connecting " + component + " for user " + userId);
831     }
832
833     /**
834      * Send VR mode change callbacks to HAL and system services if mode has actually changed.
835      * <p/>
836      * Note: Must be called while holding {@code mLock}.
837      *
838      * @param enabled new state of the VR mode.
839      */
840     private void changeVrModeLocked(boolean enabled) {
841         if (mVrModeEnabled != enabled) {
842             mVrModeEnabled = enabled;
843
844             // Log mode change event.
845             Slog.i(TAG, "VR mode " + ((mVrModeEnabled) ? "enabled" : "disabled"));
846             setVrModeNative(mVrModeEnabled);
847
848             onVrModeChangedLocked();
849         }
850     }
851
852     /**
853      * Notify system services of VR mode change.
854      * <p/>
855      * Note: Must be called while holding {@code mLock}.
856      */
857     private void onVrModeChangedLocked() {
858         mHandler.sendMessage(mHandler.obtainMessage(MSG_VR_STATE_CHANGE,
859                 (mVrModeEnabled) ? 1 : 0, 0));
860     }
861
862     /**
863      * Helper function for making ManagedApplicationService instances.
864      */
865     private static ManagedApplicationService create(@NonNull Context context,
866             @NonNull ComponentName component, int userId) {
867         return ManagedApplicationService.build(context, component, userId,
868                 R.string.vr_listener_binding_label, Settings.ACTION_VR_LISTENER_SETTINGS,
869                 sBinderChecker);
870     }
871
872     /**
873      * Apply the pending VR state. If no state is pending, disconnect any currently bound
874      * VR listener service.
875      */
876     private void consumeAndApplyPendingStateLocked() {
877         consumeAndApplyPendingStateLocked(true);
878     }
879
880     /**
881      * Apply the pending VR state.
882      *
883      * @param disconnectIfNoPendingState if {@code true}, then any currently bound VR listener
884      *     service will be disconnected if no state is pending. If this is {@code false} then the
885      *     nothing will be changed when there is no pending state.
886      */
887     private void consumeAndApplyPendingStateLocked(boolean disconnectIfNoPendingState) {
888         if (mPendingState != null) {
889             updateCurrentVrServiceLocked(mPendingState.enabled,
890                     mPendingState.targetPackageName, mPendingState.userId,
891                     mPendingState.callingPackage);
892             mPendingState = null;
893         } else if (disconnectIfNoPendingState) {
894             updateCurrentVrServiceLocked(false, null, 0, null);
895         }
896     }
897
898     private void logStateLocked() {
899         ComponentName currentBoundService = (mCurrentVrService == null) ? null :
900             mCurrentVrService.getComponent();
901         VrState current = new VrState(mVrModeEnabled, currentBoundService, mCurrentVrModeUser,
902             mCurrentVrModeComponent, mWasDefaultGranted);
903         if (mLoggingDeque.size() == EVENT_LOG_SIZE) {
904             mLoggingDeque.removeFirst();
905         }
906         mLoggingDeque.add(current);
907     }
908
909     private void dumpStateTransitions(PrintWriter pw) {
910         SimpleDateFormat d = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
911         String tab = "  ";
912         if (mLoggingDeque.size() == 0) {
913             pw.print(tab);
914             pw.println("None");
915         }
916         for (VrState state : mLoggingDeque) {
917             pw.print(d.format(new Date(state.timestamp)));
918             pw.print(tab);
919             pw.print("State changed to:");
920             pw.print(tab);
921             pw.println((state.enabled) ? "ENABLED" : "DISABLED");
922             if (state.enabled) {
923                 pw.print(tab);
924                 pw.print("User=");
925                 pw.println(state.userId);
926                 pw.print(tab);
927                 pw.print("Current VR Activity=");
928                 pw.println((state.callingPackage == null) ?
929                     "None" : state.callingPackage.flattenToString());
930                 pw.print(tab);
931                 pw.print("Bound VrListenerService=");
932                 pw.println((state.targetPackageName == null) ?
933                     "None" : state.targetPackageName.flattenToString());
934                 if (state.defaultPermissionsGranted) {
935                     pw.print(tab);
936                     pw.println("Default permissions granted to the bound VrListenerService.");
937                 }
938             }
939         }
940     }
941
942     /*
943      * Implementation of VrManagerInternal calls.  These are callable from system services.
944      */
945     private void setVrMode(boolean enabled, @NonNull ComponentName targetPackageName,
946             int userId, @NonNull ComponentName callingPackage) {
947
948         synchronized (mLock) {
949             VrState pending = new VrState(enabled, targetPackageName, userId, callingPackage);
950             if (!mVrModeAllowed) {
951                 // We're not allowed to be in VR mode.  Make this state pending.  This will be
952                 // applied the next time we are allowed to enter VR mode unless it is superseded by
953                 // another call.
954                 mPendingState = pending;
955                 return;
956             }
957
958             if (!enabled && mCurrentVrService != null) {
959                 // If we're transitioning out of VR mode, delay briefly to avoid expensive HAL calls
960                 // and service bind/unbind in case we are immediately switching to another VR app.
961                 if (mPendingState == null) {
962                     mHandler.sendEmptyMessageDelayed(MSG_PENDING_VR_STATE_CHANGE,
963                             PENDING_STATE_DELAY_MS);
964                 }
965
966                 mPendingState = pending;
967                 return;
968             } else {
969                 mHandler.removeMessages(MSG_PENDING_VR_STATE_CHANGE);
970                 mPendingState = null;
971             }
972
973             updateCurrentVrServiceLocked(enabled, targetPackageName, userId, callingPackage);
974         }
975     }
976
977     private int hasVrPackage(@NonNull ComponentName targetPackageName, int userId) {
978         synchronized (mLock) {
979             return mComponentObserver.isValid(targetPackageName, userId);
980         }
981     }
982
983     private boolean isCurrentVrListener(String packageName, int userId) {
984         synchronized (mLock) {
985             if (mCurrentVrService == null) {
986                 return false;
987             }
988             return mCurrentVrService.getComponent().getPackageName().equals(packageName) &&
989                     userId == mCurrentVrService.getUserId();
990         }
991     }
992
993     /*
994      * Implementation of IVrManager calls.
995      */
996
997     private void addStateCallback(IVrStateCallbacks cb) {
998         mRemoteCallbacks.register(cb);
999     }
1000
1001     private void removeStateCallback(IVrStateCallbacks cb) {
1002         mRemoteCallbacks.unregister(cb);
1003     }
1004
1005     private boolean getVrMode() {
1006         synchronized (mLock) {
1007             return mVrModeEnabled;
1008         }
1009     }
1010 }