VrManagerService.java revision 99493dbc94989d4493ca6acb0db265a02f49f62e
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 */
16package com.android.server.vr;
17
18import static android.view.Display.INVALID_DISPLAY;
19
20import android.Manifest;
21import android.app.ActivityManagerInternal;
22import android.app.ActivityManager;
23import android.app.AppOpsManager;
24import android.app.NotificationManager;
25import android.annotation.NonNull;
26import android.content.ComponentName;
27import android.content.ContentResolver;
28import android.content.Context;
29import android.content.pm.ApplicationInfo;
30import android.content.pm.PackageManager;
31import android.content.pm.PackageManager.NameNotFoundException;
32import android.hardware.display.DisplayManager;
33import android.os.Binder;
34import android.os.Handler;
35import android.os.IBinder;
36import android.os.IInterface;
37import android.os.Looper;
38import android.os.Message;
39import android.os.RemoteCallbackList;
40import android.os.RemoteException;
41import android.os.ServiceManager;
42import android.os.UserHandle;
43import android.provider.Settings;
44import android.service.notification.NotificationListenerService;
45import android.service.vr.IPersistentVrStateCallbacks;
46import android.service.vr.IVrListener;
47import android.service.vr.IVrManager;
48import android.service.vr.IVrStateCallbacks;
49import android.service.vr.IVrWindowManager;
50import android.service.vr.VrListenerService;
51import android.text.TextUtils;
52import android.util.ArrayMap;
53import android.util.ArraySet;
54import android.util.Slog;
55import android.util.SparseArray;
56
57import com.android.internal.R;
58import com.android.server.LocalServices;
59import com.android.server.SystemConfig;
60import com.android.server.SystemService;
61import com.android.server.utils.ManagedApplicationService.PendingEvent;
62import com.android.server.vr.EnabledComponentsObserver.EnabledComponentChangeListener;
63import com.android.server.utils.ManagedApplicationService;
64import com.android.server.utils.ManagedApplicationService.BinderChecker;
65
66import java.io.FileDescriptor;
67import java.io.PrintWriter;
68import java.lang.StringBuilder;
69import java.text.SimpleDateFormat;
70import java.util.ArrayDeque;
71import java.util.ArrayList;
72import java.util.Collection;
73import java.util.Date;
74import java.util.Objects;
75
76/**
77 * Service tracking whether VR mode is active, and notifying listening services of state changes.
78 * <p/>
79 * Services running in system server may modify the state of VrManagerService via the interface in
80 * VrManagerInternal, and may register to receive callbacks when the system VR mode changes via the
81 * interface given in VrStateListener.
82 * <p/>
83 * Device vendors may choose to receive VR state changes by implementing the VR mode HAL, e.g.:
84 *  hardware/libhardware/modules/vr
85 * <p/>
86 * In general applications may enable or disable VR mode by calling
87 * {@link android.app.Activity#setVrModeEnabled)}.  An application may also implement a service to
88 * be run while in VR mode by implementing {@link android.service.vr.VrListenerService}.
89 *
90 * @see android.service.vr.VrListenerService
91 * @see com.android.server.vr.VrManagerInternal
92 * @see com.android.server.vr.VrStateListener
93 *
94 * @hide
95 */
96public class VrManagerService extends SystemService implements EnabledComponentChangeListener{
97
98    public static final String TAG = "VrManagerService";
99
100    private static final int PENDING_STATE_DELAY_MS = 300;
101    private static final int EVENT_LOG_SIZE = 32;
102    private static final int INVALID_APPOPS_MODE = -1;
103    /** Null set of sleep sleep flags. */
104    private static final int FLAG_NONE = 0;
105    /** Flag set when the device is not sleeping. */
106    private static final int FLAG_AWAKE = 1;
107    /** Flag set when the screen has been turned on. */
108    private static final int FLAG_SCREEN_ON = 2;
109    /** Flag indicating that all system sleep flags have been set.*/
110    private static final int FLAG_ALL = FLAG_AWAKE | FLAG_SCREEN_ON;
111
112    private static native void initializeNative();
113    private static native void setVrModeNative(boolean enabled);
114
115    private final Object mLock = new Object();
116
117    private final IBinder mOverlayToken = new Binder();
118
119    // State protected by mLock
120    private boolean mVrModeAllowed;
121    private boolean mVrModeEnabled;
122    private boolean mPersistentVrModeEnabled;
123    private EnabledComponentsObserver mComponentObserver;
124    private ManagedApplicationService mCurrentVrService;
125    private ComponentName mDefaultVrService;
126    private Context mContext;
127    private ComponentName mCurrentVrModeComponent;
128    private int mCurrentVrModeUser;
129    private boolean mWasDefaultGranted;
130    private boolean mGuard;
131    private final RemoteCallbackList<IVrStateCallbacks> mVrStateRemoteCallbacks =
132            new RemoteCallbackList<>();
133    private final RemoteCallbackList<IPersistentVrStateCallbacks>
134            mPersistentVrStateRemoteCallbacks = new RemoteCallbackList<>();
135    private int mPreviousCoarseLocationMode = INVALID_APPOPS_MODE;
136    private int mPreviousManageOverlayMode = INVALID_APPOPS_MODE;
137    private VrState mPendingState;
138    private final ArrayDeque<VrState> mLoggingDeque = new ArrayDeque<>(EVENT_LOG_SIZE);
139    private final NotificationAccessManager mNotifAccessManager = new NotificationAccessManager();
140    /** Tracks the state of the screen and keyguard UI.*/
141    private int mSystemSleepFlags = FLAG_AWAKE;
142    private CompatibilityDisplay mCompatibilityDisplay;
143
144    private static final int MSG_VR_STATE_CHANGE = 0;
145    private static final int MSG_PENDING_VR_STATE_CHANGE = 1;
146    private static final int MSG_PERSISTENT_VR_MODE_STATE_CHANGE = 2;
147
148    /**
149     * Set whether VR mode may be enabled.
150     * <p/>
151     * If VR mode is not allowed to be enabled, calls to set VR mode will be cached.  When VR mode
152     * is again allowed to be enabled, the most recent cached state will be applied.
153     *
154     * @param allowed {@code true} if calling any of the setVrMode methods may cause the device to
155     *   enter VR mode.
156     */
157    private void setVrModeAllowedLocked(boolean allowed) {
158        if (mVrModeAllowed != allowed) {
159            mVrModeAllowed = allowed;
160            Slog.i(TAG, "VR mode is " + ((allowed) ? "allowed" : "disallowed"));
161            if (mVrModeAllowed) {
162                consumeAndApplyPendingStateLocked();
163            } else {
164                // Disable persistent mode when VR mode isn't allowed, allows an escape hatch to
165                // exit persistent VR mode when screen is turned off.
166                setPersistentModeAndNotifyListenersLocked(false);
167
168                // Set pending state to current state.
169                mPendingState = (mVrModeEnabled && mCurrentVrService != null)
170                    ? new VrState(mVrModeEnabled, mCurrentVrService.getComponent(),
171                        mCurrentVrService.getUserId(), mCurrentVrModeComponent)
172                    : null;
173
174                // Unbind current VR service and do necessary callbacks.
175                updateCurrentVrServiceLocked(false, null, 0, null);
176            }
177        }
178    }
179
180    private void setSleepState(boolean isAsleep) {
181        synchronized(mLock) {
182
183            if (!isAsleep) {
184                mSystemSleepFlags |= FLAG_AWAKE;
185            } else {
186                mSystemSleepFlags &= ~FLAG_AWAKE;
187            }
188
189            setVrModeAllowedLocked(mSystemSleepFlags == FLAG_ALL);
190        }
191    }
192
193    private void setScreenOn(boolean isScreenOn) {
194        synchronized(mLock) {
195            if (isScreenOn) {
196                mSystemSleepFlags |= FLAG_SCREEN_ON;
197            } else {
198                mSystemSleepFlags &= ~FLAG_SCREEN_ON;
199            }
200            setVrModeAllowedLocked(mSystemSleepFlags == FLAG_ALL);
201        }
202    }
203
204    private final Handler mHandler = new Handler() {
205        @Override
206        public void handleMessage(Message msg) {
207            switch(msg.what) {
208                case MSG_VR_STATE_CHANGE : {
209                    boolean state = (msg.arg1 == 1);
210                    int i = mVrStateRemoteCallbacks.beginBroadcast();
211                    while (i > 0) {
212                        i--;
213                        try {
214                            mVrStateRemoteCallbacks.getBroadcastItem(i).onVrStateChanged(state);
215                        } catch (RemoteException e) {
216                            // Noop
217                        }
218                    }
219                    mVrStateRemoteCallbacks.finishBroadcast();
220                } break;
221                case MSG_PENDING_VR_STATE_CHANGE : {
222                    synchronized(mLock) {
223                        if (mVrModeAllowed) {
224                           VrManagerService.this.consumeAndApplyPendingStateLocked();
225                        }
226                    }
227                } break;
228                case MSG_PERSISTENT_VR_MODE_STATE_CHANGE : {
229                    boolean state = (msg.arg1 == 1);
230                    int i = mPersistentVrStateRemoteCallbacks.beginBroadcast();
231                    while (i > 0) {
232                        i--;
233                        try {
234                            mPersistentVrStateRemoteCallbacks.getBroadcastItem(i)
235                                    .onPersistentVrStateChanged(state);
236                        } catch (RemoteException e) {
237                            // Noop
238                        }
239                    }
240                    mPersistentVrStateRemoteCallbacks.finishBroadcast();
241                } break;
242                default :
243                    throw new IllegalStateException("Unknown message type: " + msg.what);
244            }
245        }
246    };
247
248    private static class VrState {
249        final boolean enabled;
250        final int userId;
251        final ComponentName targetPackageName;
252        final ComponentName callingPackage;
253        final long timestamp;
254        final boolean defaultPermissionsGranted;
255
256        VrState(boolean enabled, ComponentName targetPackageName, int userId,
257                ComponentName callingPackage) {
258            this.enabled = enabled;
259            this.userId = userId;
260            this.targetPackageName = targetPackageName;
261            this.callingPackage = callingPackage;
262            this.defaultPermissionsGranted = false;
263            this.timestamp = System.currentTimeMillis();
264        }
265
266        VrState(boolean enabled, ComponentName targetPackageName, int userId,
267            ComponentName callingPackage, boolean defaultPermissionsGranted) {
268            this.enabled = enabled;
269            this.userId = userId;
270            this.targetPackageName = targetPackageName;
271            this.callingPackage = callingPackage;
272            this.defaultPermissionsGranted = defaultPermissionsGranted;
273            this.timestamp = System.currentTimeMillis();
274        }
275    }
276
277    private static final BinderChecker sBinderChecker = new BinderChecker() {
278        @Override
279        public IInterface asInterface(IBinder binder) {
280            return IVrListener.Stub.asInterface(binder);
281        }
282
283        @Override
284        public boolean checkType(IInterface service) {
285            return service instanceof IVrListener;
286        }
287    };
288
289    private final class NotificationAccessManager {
290        private final SparseArray<ArraySet<String>> mAllowedPackages = new SparseArray<>();
291        private final ArrayMap<String, Integer> mNotificationAccessPackageToUserId =
292                new ArrayMap<>();
293
294        public void update(Collection<String> packageNames) {
295            int currentUserId = ActivityManager.getCurrentUser();
296
297            ArraySet<String> allowed = mAllowedPackages.get(currentUserId);
298            if (allowed == null) {
299                allowed = new ArraySet<>();
300            }
301
302            // Make sure we revoke notification access for listeners in other users
303            final int listenerCount = mNotificationAccessPackageToUserId.size();
304            for (int i = listenerCount - 1; i >= 0; i--) {
305                final int grantUserId = mNotificationAccessPackageToUserId.valueAt(i);
306                if (grantUserId != currentUserId) {
307                    String packageName = mNotificationAccessPackageToUserId.keyAt(i);
308                    revokeNotificationListenerAccess(packageName, grantUserId);
309                    revokeNotificationPolicyAccess(packageName);
310                    revokeCoarseLocationPermissionIfNeeded(packageName, grantUserId);
311                    mNotificationAccessPackageToUserId.removeAt(i);
312                }
313            }
314
315            for (String pkg : allowed) {
316                if (!packageNames.contains(pkg)) {
317                    revokeNotificationListenerAccess(pkg, currentUserId);
318                    revokeNotificationPolicyAccess(pkg);
319                    revokeCoarseLocationPermissionIfNeeded(pkg, currentUserId);
320                    mNotificationAccessPackageToUserId.remove(pkg);
321                }
322            }
323            for (String pkg : packageNames) {
324                if (!allowed.contains(pkg)) {
325                    grantNotificationPolicyAccess(pkg);
326                    grantNotificationListenerAccess(pkg, currentUserId);
327                    grantCoarseLocationPermissionIfNeeded(pkg, currentUserId);
328                    mNotificationAccessPackageToUserId.put(pkg, currentUserId);
329                }
330            }
331
332            allowed.clear();
333            allowed.addAll(packageNames);
334            mAllowedPackages.put(currentUserId, allowed);
335        }
336    }
337
338    /**
339     * Called when a user, package, or setting changes that could affect whether or not the
340     * currently bound VrListenerService is changed.
341     */
342    @Override
343    public void onEnabledComponentChanged() {
344        synchronized (mLock) {
345            int currentUser = ActivityManager.getCurrentUser();
346            // Update listeners
347            ArraySet<ComponentName> enabledListeners = mComponentObserver.getEnabled(currentUser);
348
349            ArraySet<String> enabledPackages = new ArraySet<>();
350            for (ComponentName n : enabledListeners) {
351                String pkg = n.getPackageName();
352                if (isDefaultAllowed(pkg)) {
353                    enabledPackages.add(n.getPackageName());
354                }
355            }
356            mNotifAccessManager.update(enabledPackages);
357
358            if (!mVrModeAllowed) {
359                return; // Don't do anything, we shouldn't be in VR mode.
360            }
361
362            // If there is a pending state change, we'd better deal with that first
363            consumeAndApplyPendingStateLocked(false);
364
365            if (mCurrentVrService == null) {
366                return; // No active services
367            }
368
369            // There is an active service, update it if needed
370            updateCurrentVrServiceLocked(mVrModeEnabled, mCurrentVrService.getComponent(),
371                    mCurrentVrService.getUserId(), null);
372        }
373    }
374
375    private final IVrManager mVrManager = new IVrManager.Stub() {
376
377        @Override
378        public void registerListener(IVrStateCallbacks cb) {
379            enforceCallerPermission(Manifest.permission.ACCESS_VR_MANAGER);
380            if (cb == null) {
381                throw new IllegalArgumentException("Callback binder object is null.");
382            }
383
384            VrManagerService.this.addStateCallback(cb);
385        }
386
387        @Override
388        public void unregisterListener(IVrStateCallbacks cb) {
389            enforceCallerPermission(Manifest.permission.ACCESS_VR_MANAGER);
390            if (cb == null) {
391                throw new IllegalArgumentException("Callback binder object is null.");
392            }
393
394            VrManagerService.this.removeStateCallback(cb);
395        }
396
397        @Override
398        public void registerPersistentVrStateListener(IPersistentVrStateCallbacks cb) {
399            enforceCallerPermission(Manifest.permission.ACCESS_VR_MANAGER);
400            if (cb == null) {
401                throw new IllegalArgumentException("Callback binder object is null.");
402            }
403
404            VrManagerService.this.addPersistentStateCallback(cb);
405        }
406
407        @Override
408        public void unregisterPersistentVrStateListener(IPersistentVrStateCallbacks cb) {
409            enforceCallerPermission(Manifest.permission.ACCESS_VR_MANAGER);
410            if (cb == null) {
411                throw new IllegalArgumentException("Callback binder object is null.");
412            }
413
414            VrManagerService.this.removePersistentStateCallback(cb);
415        }
416
417        @Override
418        public boolean getVrModeState() {
419            return VrManagerService.this.getVrMode();
420        }
421
422        @Override
423        public void setPersistentVrModeEnabled(boolean enabled) {
424            enforceCallerPermission(Manifest.permission.RESTRICTED_VR_ACCESS);
425            VrManagerService.this.setPersistentVrModeEnabled(enabled);
426        }
427
428        @Override
429        public int getCompatibilityDisplayId() {
430            return VrManagerService.this.getCompatibilityDisplayId();
431        }
432
433        @Override
434        public void connectController(FileDescriptor fd) throws android.os.RemoteException {
435            enforceCallerPermission(Manifest.permission.RESTRICTED_VR_ACCESS);
436            VrManagerService.this.connectController(fd);
437        }
438
439        @Override
440        public void disconnectController() throws android.os.RemoteException {
441            enforceCallerPermission(Manifest.permission.RESTRICTED_VR_ACCESS);
442            VrManagerService.this.disconnectController();
443        }
444
445        @Override
446        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
447            if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
448                    != PackageManager.PERMISSION_GRANTED) {
449                pw.println("Permission Denial: can't dump VrManagerService from pid="
450                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
451                return;
452            }
453            pw.println("********* Dump of VrManagerService *********");
454            pw.println("VR mode is currently: " + ((mVrModeAllowed) ? "allowed" : "disallowed"));
455            pw.println("Persistent VR mode is currently: " +
456                    ((mPersistentVrModeEnabled) ? "enabled" : "disabled"));
457            pw.println("Previous state transitions:\n");
458            String tab = "  ";
459            dumpStateTransitions(pw);
460            pw.println("\n\nRemote Callbacks:");
461            int i=mVrStateRemoteCallbacks.beginBroadcast(); // create the broadcast item array
462            while(i-->0) {
463                pw.print(tab);
464                pw.print(mVrStateRemoteCallbacks.getBroadcastItem(i));
465                if (i>0) pw.println(",");
466            }
467            mVrStateRemoteCallbacks.finishBroadcast();
468            pw.println("\n\nPersistent Vr State Remote Callbacks:");
469            i=mPersistentVrStateRemoteCallbacks.beginBroadcast();
470            while(i-->0) {
471                pw.print(tab);
472                pw.print(mPersistentVrStateRemoteCallbacks.getBroadcastItem(i));
473                if (i>0) pw.println(",");
474            }
475            mPersistentVrStateRemoteCallbacks.finishBroadcast();
476            pw.println("\n");
477            pw.println("Installed VrListenerService components:");
478            int userId = mCurrentVrModeUser;
479            ArraySet<ComponentName> installed = mComponentObserver.getInstalled(userId);
480            if (installed == null || installed.size() == 0) {
481                pw.println("None");
482            } else {
483                for (ComponentName n : installed) {
484                    pw.print(tab);
485                    pw.println(n.flattenToString());
486                }
487            }
488            pw.println("Enabled VrListenerService components:");
489            ArraySet<ComponentName> enabled = mComponentObserver.getEnabled(userId);
490            if (enabled == null || enabled.size() == 0) {
491                pw.println("None");
492            } else {
493                for (ComponentName n : enabled) {
494                    pw.print(tab);
495                    pw.println(n.flattenToString());
496                }
497            }
498            pw.println("\n");
499            pw.println("********* End of VrManagerService Dump *********");
500        }
501
502    };
503
504    private void enforceCallerPermission(String permission) {
505        if (mContext.checkCallingOrSelfPermission(permission)
506                != PackageManager.PERMISSION_GRANTED) {
507            throw new SecurityException("Caller does not hold the permission " + permission);
508        }
509    }
510
511    /**
512     * Implementation of VrManagerInternal.  Callable only from system services.
513     */
514    private final class LocalService extends VrManagerInternal {
515        @Override
516        public void setVrMode(boolean enabled, ComponentName packageName, int userId,
517                ComponentName callingPackage) {
518            VrManagerService.this.setVrMode(enabled, packageName, userId, callingPackage);
519        }
520
521        @Override
522        public void onSleepStateChanged(boolean isAsleep) {
523            VrManagerService.this.setSleepState(isAsleep);
524        }
525
526        @Override
527        public void onScreenStateChanged(boolean isScreenOn) {
528            VrManagerService.this.setScreenOn(isScreenOn);
529        }
530
531        @Override
532        public boolean isCurrentVrListener(String packageName, int userId) {
533            return VrManagerService.this.isCurrentVrListener(packageName, userId);
534        }
535
536        @Override
537        public int hasVrPackage(ComponentName packageName, int userId) {
538            return VrManagerService.this.hasVrPackage(packageName, userId);
539        }
540
541        @Override
542        public void setPersistentVrModeEnabled(boolean enabled) {
543            VrManagerService.this.setPersistentVrModeEnabled(enabled);
544        }
545
546        @Override
547        public int getCompatibilityDisplayId() {
548            return VrManagerService.this.getCompatibilityDisplayId();
549        }
550
551        @Override
552        public void addPersistentVrModeStateListener(IPersistentVrStateCallbacks listener) {
553            VrManagerService.this.addPersistentStateCallback(listener);
554        }
555    }
556
557    public VrManagerService(Context context) {
558        super(context);
559    }
560
561    @Override
562    public void onStart() {
563        synchronized(mLock) {
564            initializeNative();
565            mContext = getContext();
566        }
567
568        publishLocalService(VrManagerInternal.class, new LocalService());
569        publishBinderService(Context.VR_SERVICE, mVrManager.asBinder());
570    }
571
572    @Override
573    public void onBootPhase(int phase) {
574        if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
575            synchronized (mLock) {
576                Looper looper = Looper.getMainLooper();
577                Handler handler = new Handler(looper);
578                ArrayList<EnabledComponentChangeListener> listeners = new ArrayList<>();
579                listeners.add(this);
580                mComponentObserver = EnabledComponentsObserver.build(mContext, handler,
581                        Settings.Secure.ENABLED_VR_LISTENERS, looper,
582                        android.Manifest.permission.BIND_VR_LISTENER_SERVICE,
583                        VrListenerService.SERVICE_INTERFACE, mLock, listeners);
584
585                mComponentObserver.rebuildAll();
586            }
587
588            //TODO: something more robust than picking the first one
589            ArraySet<ComponentName> defaultVrComponents =
590                    SystemConfig.getInstance().getDefaultVrComponents();
591            if (defaultVrComponents.size() > 0) {
592                mDefaultVrService = defaultVrComponents.valueAt(0);
593            } else {
594                Slog.i(TAG, "No default vr listener service found.");
595            }
596
597            DisplayManager dm =
598                    (DisplayManager) getContext().getSystemService(Context.DISPLAY_SERVICE);
599            ActivityManagerInternal ami = LocalServices.getService(ActivityManagerInternal.class);
600            mCompatibilityDisplay = new CompatibilityDisplay(dm, ami, mVrManager);
601            mCompatibilityDisplay.init(getContext());
602        } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
603            synchronized (mLock) {
604                mVrModeAllowed = true;
605            }
606        }
607    }
608
609    @Override
610    public void onStartUser(int userHandle) {
611        synchronized (mLock) {
612            mComponentObserver.onUsersChanged();
613        }
614    }
615
616    @Override
617    public void onSwitchUser(int userHandle) {
618        synchronized (mLock) {
619            mComponentObserver.onUsersChanged();
620        }
621
622    }
623
624    @Override
625    public void onStopUser(int userHandle) {
626        synchronized (mLock) {
627            mComponentObserver.onUsersChanged();
628        }
629
630    }
631
632    @Override
633    public void onCleanupUser(int userHandle) {
634        synchronized (mLock) {
635            mComponentObserver.onUsersChanged();
636        }
637    }
638
639    private void updateOverlayStateLocked(String exemptedPackage, int newUserId, int oldUserId) {
640        AppOpsManager appOpsManager = getContext().getSystemService(AppOpsManager.class);
641
642        // If user changed drop restrictions for the old user.
643        if (oldUserId != newUserId) {
644            appOpsManager.setUserRestrictionForUser(AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
645                    false, mOverlayToken, null, oldUserId);
646        }
647
648        if (!mVrModeEnabled) {
649            return;
650        }
651
652        // Apply the restrictions for the current user based on vr state
653        String[] exemptions = (exemptedPackage == null) ? new String[0] :
654                new String[] { exemptedPackage };
655
656        appOpsManager.setUserRestrictionForUser(AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
657                true, mOverlayToken, exemptions, newUserId);
658    }
659
660    private void updateDependentAppOpsLocked(String newVrServicePackage, int newUserId,
661            String oldVrServicePackage, int oldUserId) {
662        // If VR state changed and we also have a VR service change.
663        if (Objects.equals(newVrServicePackage, oldVrServicePackage)) {
664            return;
665        }
666        final long identity = Binder.clearCallingIdentity();
667        try {
668            // Set overlay exception state based on VR enabled and current service
669            updateOverlayStateLocked(newVrServicePackage, newUserId, oldUserId);
670        } finally {
671            Binder.restoreCallingIdentity(identity);
672        }
673    }
674
675    /**
676     * Send VR mode changes (if the mode state has changed), and update the bound/unbound state of
677     * the currently selected VR listener service.  If the component selected for the VR listener
678     * service has changed, unbind the previous listener and bind the new listener (if enabled).
679     * <p/>
680     * Note: Must be called while holding {@code mLock}.
681     *
682     * @param enabled new state for VR mode.
683     * @param component new component to be bound as a VR listener.
684     * @param userId user owning the component to be bound.
685     * @param calling the component currently using VR mode, or null to leave unchanged.
686     *
687     * @return {@code true} if the component/user combination specified is valid.
688     */
689    private boolean updateCurrentVrServiceLocked(boolean enabled, @NonNull ComponentName component,
690            int userId, ComponentName calling) {
691
692        boolean sendUpdatedCaller = false;
693        final long identity = Binder.clearCallingIdentity();
694        try {
695
696            boolean validUserComponent = (mComponentObserver.isValid(component, userId) ==
697                    EnabledComponentsObserver.NO_ERROR);
698            boolean goingIntoVrMode = validUserComponent && enabled;
699            if (!mVrModeEnabled && !goingIntoVrMode) {
700                return validUserComponent; // Disabled -> Disabled transition does nothing.
701            }
702
703            String oldVrServicePackage = mCurrentVrService != null
704                    ? mCurrentVrService.getComponent().getPackageName() : null;
705            final int oldUserId = mCurrentVrModeUser;
706
707            // Notify system services and VR HAL of mode change.
708            changeVrModeLocked(goingIntoVrMode);
709
710            boolean nothingChanged = false;
711            if (!goingIntoVrMode) {
712                // Not going into VR mode, unbind whatever is running
713                if (mCurrentVrService != null) {
714                    Slog.i(TAG, "Leaving VR mode, disconnecting "
715                        + mCurrentVrService.getComponent() + " for user "
716                        + mCurrentVrService.getUserId());
717                    mCurrentVrService.disconnect();
718                    mCurrentVrService = null;
719                } else {
720                    nothingChanged = true;
721                }
722            } else {
723                // Going into VR mode
724                if (mCurrentVrService != null) {
725                    // Unbind any running service that doesn't match the latest component/user
726                    // selection.
727                    if (mCurrentVrService.disconnectIfNotMatching(component, userId)) {
728                        Slog.i(TAG, "VR mode component changed to " + component
729                            + ", disconnecting " + mCurrentVrService.getComponent()
730                            + " for user " + mCurrentVrService.getUserId());
731                        createAndConnectService(component, userId);
732                        sendUpdatedCaller = true;
733                    } else {
734                        nothingChanged = true;
735                    }
736                    // The service with the correct component/user is already bound, do nothing.
737                } else {
738                    // Nothing was previously running, bind a new service for the latest
739                    // component/user selection.
740                    createAndConnectService(component, userId);
741                    sendUpdatedCaller = true;
742                }
743            }
744
745            if (calling != null && !Objects.equals(calling, mCurrentVrModeComponent)) {
746                sendUpdatedCaller = true;
747            }
748            mCurrentVrModeComponent = calling;
749
750            if (mCurrentVrModeUser != userId) {
751                mCurrentVrModeUser = userId;
752                sendUpdatedCaller = true;
753            }
754
755            String newVrServicePackage = mCurrentVrService != null
756                    ? mCurrentVrService.getComponent().getPackageName() : null;
757            final int newUserId = mCurrentVrModeUser;
758
759            // Update AppOps settings that change state when entering/exiting VR mode, or changing
760            // the current VrListenerService.
761            updateDependentAppOpsLocked(newVrServicePackage, newUserId,
762                    oldVrServicePackage, oldUserId);
763
764            if (mCurrentVrService != null && sendUpdatedCaller) {
765                final ComponentName c = mCurrentVrModeComponent;
766                mCurrentVrService.sendEvent(new PendingEvent() {
767                    @Override
768                    public void runEvent(IInterface service) throws RemoteException {
769                        IVrListener l = (IVrListener) service;
770                        l.focusedActivityChanged(c);
771                    }
772                });
773            }
774
775            if (!nothingChanged) {
776                logStateLocked();
777            }
778
779            return validUserComponent;
780        } finally {
781            Binder.restoreCallingIdentity(identity);
782        }
783    }
784
785    private boolean isDefaultAllowed(String packageName) {
786        PackageManager pm = mContext.getPackageManager();
787
788        ApplicationInfo info = null;
789        try {
790            info = pm.getApplicationInfo(packageName, PackageManager.GET_META_DATA);
791        } catch (NameNotFoundException e) {
792        }
793
794        if (info == null || !(info.isSystemApp() || info.isUpdatedSystemApp())) {
795            return false;
796        }
797        return true;
798    }
799
800    private void grantNotificationPolicyAccess(String pkg) {
801        NotificationManager nm = mContext.getSystemService(NotificationManager.class);
802        nm.setNotificationPolicyAccessGranted(pkg, true);
803    }
804
805    private void revokeNotificationPolicyAccess(String pkg) {
806        NotificationManager nm = mContext.getSystemService(NotificationManager.class);
807        // Remove any DND zen rules possibly created by the package.
808        nm.removeAutomaticZenRules(pkg);
809        // Remove Notification Policy Access.
810        nm.setNotificationPolicyAccessGranted(pkg, false);
811    }
812
813    private void grantNotificationListenerAccess(String pkg, int userId) {
814        PackageManager pm = mContext.getPackageManager();
815        ArraySet<ComponentName> possibleServices = EnabledComponentsObserver.loadComponentNames(pm,
816                userId, NotificationListenerService.SERVICE_INTERFACE,
817                android.Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE);
818        ContentResolver resolver = mContext.getContentResolver();
819
820        ArraySet<String> current = getNotificationListeners(resolver, userId);
821
822        for (ComponentName c : possibleServices) {
823            String flatName = c.flattenToString();
824            if (Objects.equals(c.getPackageName(), pkg)
825                    && !current.contains(flatName)) {
826                current.add(flatName);
827            }
828        }
829
830        if (current.size() > 0) {
831            String flatSettings = formatSettings(current);
832            Settings.Secure.putStringForUser(resolver,
833                    Settings.Secure.ENABLED_NOTIFICATION_LISTENERS,
834                    flatSettings, userId);
835        }
836    }
837
838    private void revokeNotificationListenerAccess(String pkg, int userId) {
839        ContentResolver resolver = mContext.getContentResolver();
840
841        ArraySet<String> current = getNotificationListeners(resolver, userId);
842
843        ArrayList<String> toRemove = new ArrayList<>();
844
845        for (String c : current) {
846            ComponentName component = ComponentName.unflattenFromString(c);
847            if (component != null && component.getPackageName().equals(pkg)) {
848                toRemove.add(c);
849            }
850        }
851
852        current.removeAll(toRemove);
853
854        String flatSettings = formatSettings(current);
855        Settings.Secure.putStringForUser(resolver,
856                Settings.Secure.ENABLED_NOTIFICATION_LISTENERS,
857                flatSettings, userId);
858    }
859
860    private void grantCoarseLocationPermissionIfNeeded(String pkg, int userId) {
861        // Don't clobber the user if permission set in current state explicitly
862        if (!isPermissionUserUpdated(Manifest.permission.ACCESS_COARSE_LOCATION, pkg, userId)) {
863            try {
864                mContext.getPackageManager().grantRuntimePermission(pkg,
865                        Manifest.permission.ACCESS_COARSE_LOCATION, new UserHandle(userId));
866            } catch (IllegalArgumentException e) {
867                // Package was removed during update.
868                Slog.w(TAG, "Could not grant coarse location permission, package " + pkg
869                    + " was removed.");
870            }
871        }
872    }
873
874    private void revokeCoarseLocationPermissionIfNeeded(String pkg, int userId) {
875        // Don't clobber the user if permission set in current state explicitly
876        if (!isPermissionUserUpdated(Manifest.permission.ACCESS_COARSE_LOCATION, pkg, userId)) {
877            try {
878                mContext.getPackageManager().revokeRuntimePermission(pkg,
879                        Manifest.permission.ACCESS_COARSE_LOCATION, new UserHandle(userId));
880            } catch (IllegalArgumentException e) {
881                // Package was removed during update.
882                Slog.w(TAG, "Could not revoke coarse location permission, package " + pkg
883                    + " was removed.");
884            }
885        }
886    }
887
888    private boolean isPermissionUserUpdated(String permission, String pkg, int userId) {
889        final int flags = mContext.getPackageManager().getPermissionFlags(
890                permission, pkg, new UserHandle(userId));
891        return (flags & (PackageManager.FLAG_PERMISSION_USER_SET
892                | PackageManager.FLAG_PERMISSION_USER_FIXED)) != 0;
893    }
894
895    private ArraySet<String> getNotificationListeners(ContentResolver resolver, int userId) {
896        String flat = Settings.Secure.getStringForUser(resolver,
897                Settings.Secure.ENABLED_NOTIFICATION_LISTENERS, userId);
898
899        ArraySet<String> current = new ArraySet<>();
900        if (flat != null) {
901            String[] allowed = flat.split(":");
902            for (String s : allowed) {
903                if (!TextUtils.isEmpty(s)) {
904                    current.add(s);
905                }
906            }
907        }
908        return current;
909    }
910
911    private static String formatSettings(Collection<String> c) {
912        if (c == null || c.isEmpty()) {
913            return "";
914        }
915
916        StringBuilder b = new StringBuilder();
917        boolean start = true;
918        for (String s : c) {
919            if ("".equals(s)) {
920                continue;
921            }
922            if (!start) {
923                b.append(':');
924            }
925            b.append(s);
926            start = false;
927        }
928        return b.toString();
929    }
930
931
932
933    private void createAndConnectService(@NonNull ComponentName component, int userId) {
934        mCurrentVrService = VrManagerService.create(mContext, component, userId);
935        mCurrentVrService.connect();
936        Slog.i(TAG, "Connecting " + component + " for user " + userId);
937    }
938
939    /**
940     * Send VR mode change callbacks to HAL and system services if mode has actually changed.
941     * <p/>
942     * Note: Must be called while holding {@code mLock}.
943     *
944     * @param enabled new state of the VR mode.
945     */
946    private void changeVrModeLocked(boolean enabled) {
947        if (mVrModeEnabled != enabled) {
948            mVrModeEnabled = enabled;
949
950            // Log mode change event.
951            Slog.i(TAG, "VR mode " + ((mVrModeEnabled) ? "enabled" : "disabled"));
952            setVrModeNative(mVrModeEnabled);
953
954            onVrModeChangedLocked();
955        }
956    }
957
958    /**
959     * Notify system services of VR mode change.
960     * <p/>
961     * Note: Must be called while holding {@code mLock}.
962     */
963    private void onVrModeChangedLocked() {
964        mHandler.sendMessage(mHandler.obtainMessage(MSG_VR_STATE_CHANGE,
965                (mVrModeEnabled) ? 1 : 0, 0));
966    }
967
968    /**
969     * Helper function for making ManagedApplicationService instances.
970     */
971    private static ManagedApplicationService create(@NonNull Context context,
972            @NonNull ComponentName component, int userId) {
973        return ManagedApplicationService.build(context, component, userId,
974                R.string.vr_listener_binding_label, Settings.ACTION_VR_LISTENER_SETTINGS,
975                sBinderChecker);
976    }
977
978    /**
979     * Apply the pending VR state. If no state is pending, disconnect any currently bound
980     * VR listener service.
981     */
982    private void consumeAndApplyPendingStateLocked() {
983        consumeAndApplyPendingStateLocked(true);
984    }
985
986    /**
987     * Apply the pending VR state.
988     *
989     * @param disconnectIfNoPendingState if {@code true}, then any currently bound VR listener
990     *     service will be disconnected if no state is pending. If this is {@code false} then the
991     *     nothing will be changed when there is no pending state.
992     */
993    private void consumeAndApplyPendingStateLocked(boolean disconnectIfNoPendingState) {
994        if (mPendingState != null) {
995            updateCurrentVrServiceLocked(mPendingState.enabled,
996                    mPendingState.targetPackageName, mPendingState.userId,
997                    mPendingState.callingPackage);
998            mPendingState = null;
999        } else if (disconnectIfNoPendingState) {
1000            updateCurrentVrServiceLocked(false, null, 0, null);
1001        }
1002    }
1003
1004    private void logStateLocked() {
1005        ComponentName currentBoundService = (mCurrentVrService == null) ? null :
1006            mCurrentVrService.getComponent();
1007        VrState current = new VrState(mVrModeEnabled, currentBoundService, mCurrentVrModeUser,
1008            mCurrentVrModeComponent, mWasDefaultGranted);
1009        if (mLoggingDeque.size() == EVENT_LOG_SIZE) {
1010            mLoggingDeque.removeFirst();
1011        }
1012        mLoggingDeque.add(current);
1013    }
1014
1015    private void dumpStateTransitions(PrintWriter pw) {
1016        SimpleDateFormat d = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
1017        String tab = "  ";
1018        if (mLoggingDeque.size() == 0) {
1019            pw.print(tab);
1020            pw.println("None");
1021        }
1022        for (VrState state : mLoggingDeque) {
1023            pw.print(d.format(new Date(state.timestamp)));
1024            pw.print(tab);
1025            pw.print("State changed to:");
1026            pw.print(tab);
1027            pw.println((state.enabled) ? "ENABLED" : "DISABLED");
1028            if (state.enabled) {
1029                pw.print(tab);
1030                pw.print("User=");
1031                pw.println(state.userId);
1032                pw.print(tab);
1033                pw.print("Current VR Activity=");
1034                pw.println((state.callingPackage == null) ?
1035                    "None" : state.callingPackage.flattenToString());
1036                pw.print(tab);
1037                pw.print("Bound VrListenerService=");
1038                pw.println((state.targetPackageName == null) ?
1039                    "None" : state.targetPackageName.flattenToString());
1040                if (state.defaultPermissionsGranted) {
1041                    pw.print(tab);
1042                    pw.println("Default permissions granted to the bound VrListenerService.");
1043                }
1044            }
1045        }
1046    }
1047
1048    /*
1049     * Implementation of VrManagerInternal calls.  These are callable from system services.
1050     */
1051    private void setVrMode(boolean enabled, @NonNull ComponentName targetPackageName,
1052            int userId, @NonNull ComponentName callingPackage) {
1053
1054        synchronized (mLock) {
1055            VrState pending;
1056            ComponentName targetListener;
1057            ComponentName foregroundVrComponent;
1058
1059            // If the device is in persistent VR mode, then calls to disable VR mode are ignored,
1060            // and the system default VR listener is used.
1061            boolean targetEnabledState = enabled || mPersistentVrModeEnabled;
1062            if (!enabled && mPersistentVrModeEnabled) {
1063                targetListener = mDefaultVrService;
1064
1065                // Current foreground component isn't a VR one (in 2D app case)
1066                foregroundVrComponent = null;
1067            } else {
1068                targetListener = targetPackageName;
1069                foregroundVrComponent = callingPackage;
1070            }
1071            pending = new VrState(
1072                    targetEnabledState, targetListener, userId, foregroundVrComponent);
1073
1074            if (!mVrModeAllowed) {
1075                // We're not allowed to be in VR mode.  Make this state pending.  This will be
1076                // applied the next time we are allowed to enter VR mode unless it is superseded by
1077                // another call.
1078                mPendingState = pending;
1079                return;
1080            }
1081
1082            if (!targetEnabledState && mCurrentVrService != null) {
1083                // If we're transitioning out of VR mode, delay briefly to avoid expensive HAL calls
1084                // and service bind/unbind in case we are immediately switching to another VR app.
1085                if (mPendingState == null) {
1086                    mHandler.sendEmptyMessageDelayed(MSG_PENDING_VR_STATE_CHANGE,
1087                            PENDING_STATE_DELAY_MS);
1088                }
1089
1090                mPendingState = pending;
1091                return;
1092            } else {
1093                mHandler.removeMessages(MSG_PENDING_VR_STATE_CHANGE);
1094                mPendingState = null;
1095            }
1096
1097            updateCurrentVrServiceLocked(
1098                    targetEnabledState, targetListener, userId, foregroundVrComponent);
1099        }
1100    }
1101
1102    private void setPersistentVrModeEnabled(boolean enabled) {
1103        synchronized(mLock) {
1104            setPersistentModeAndNotifyListenersLocked(enabled);
1105            // Disabling persistent mode when not showing a VR should disable the overall vr mode.
1106            if (!enabled && mCurrentVrModeComponent == null) {
1107                setVrMode(false, null, 0, null);
1108            }
1109        }
1110    }
1111
1112    private int getCompatibilityDisplayId() {
1113        if (mCompatibilityDisplay != null) {
1114            return mCompatibilityDisplay.getVirtualDisplayId();
1115        }
1116        Slog.w(TAG, "CompatibilityDisplay is null!");
1117        return INVALID_DISPLAY;
1118    }
1119
1120    private void setPersistentModeAndNotifyListenersLocked(boolean enabled) {
1121        if (mPersistentVrModeEnabled == enabled) {
1122            return;
1123        }
1124        mPersistentVrModeEnabled = enabled;
1125
1126        mHandler.sendMessage(mHandler.obtainMessage(MSG_PERSISTENT_VR_MODE_STATE_CHANGE,
1127                (mPersistentVrModeEnabled) ? 1 : 0, 0));
1128    }
1129
1130    private int hasVrPackage(@NonNull ComponentName targetPackageName, int userId) {
1131        synchronized (mLock) {
1132            return mComponentObserver.isValid(targetPackageName, userId);
1133        }
1134    }
1135
1136    private boolean isCurrentVrListener(String packageName, int userId) {
1137        synchronized (mLock) {
1138            if (mCurrentVrService == null) {
1139                return false;
1140            }
1141            return mCurrentVrService.getComponent().getPackageName().equals(packageName) &&
1142                    userId == mCurrentVrService.getUserId();
1143        }
1144    }
1145
1146    /*
1147     * Implementation of IVrManager calls.
1148     */
1149
1150    private void addStateCallback(IVrStateCallbacks cb) {
1151        mVrStateRemoteCallbacks.register(cb);
1152    }
1153
1154    private void removeStateCallback(IVrStateCallbacks cb) {
1155        mVrStateRemoteCallbacks.unregister(cb);
1156    }
1157
1158    private void addPersistentStateCallback(IPersistentVrStateCallbacks cb) {
1159        mPersistentVrStateRemoteCallbacks.register(cb);
1160    }
1161
1162    private void removePersistentStateCallback(IPersistentVrStateCallbacks cb) {
1163        mPersistentVrStateRemoteCallbacks.unregister(cb);
1164    }
1165
1166    private boolean getVrMode() {
1167        synchronized (mLock) {
1168            return mVrModeEnabled;
1169        }
1170    }
1171
1172    private void connectController(FileDescriptor fd) throws android.os.RemoteException {
1173        // TODO(b/36506799): move vr_wm code to VrCore and remove this.
1174        IVrWindowManager remote =
1175                IVrWindowManager.Stub.asInterface(
1176                        ServiceManager.getService(IVrWindowManager.SERVICE_NAME));
1177        remote.connectController(fd);
1178    }
1179
1180    private void disconnectController() throws android.os.RemoteException {
1181        // TODO(b/36506799): move vr_wm code to VrCore and remove this.
1182        IVrWindowManager remote =
1183                IVrWindowManager.Stub.asInterface(
1184                        ServiceManager.getService(IVrWindowManager.SERVICE_NAME));
1185        remote.disconnectController();
1186    }
1187}
1188