• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 static android.view.Display.INVALID_DISPLAY;
19 
20 import android.Manifest;
21 import android.annotation.NonNull;
22 import android.annotation.Nullable;
23 import android.app.ActivityManager;
24 import android.app.ActivityManagerInternal;
25 import android.app.AppOpsManager;
26 import android.app.INotificationManager;
27 import android.app.NotificationManager;
28 import android.app.Vr2dDisplayProperties;
29 import android.content.BroadcastReceiver;
30 import android.content.ComponentName;
31 import android.content.ContentResolver;
32 import android.content.Context;
33 import android.content.Intent;
34 import android.content.IntentFilter;
35 import android.content.pm.ApplicationInfo;
36 import android.content.pm.PackageManager;
37 import android.content.pm.PackageManager.NameNotFoundException;
38 import android.hardware.display.DisplayManager;
39 import android.os.Binder;
40 import android.os.Handler;
41 import android.os.IBinder;
42 import android.os.IInterface;
43 import android.os.Looper;
44 import android.os.Message;
45 import android.os.PackageTagsList;
46 import android.os.RemoteCallbackList;
47 import android.os.RemoteException;
48 import android.os.ServiceManager;
49 import android.os.SystemProperties;
50 import android.os.UserHandle;
51 import android.provider.Settings;
52 import android.service.notification.NotificationListenerService;
53 import android.service.vr.IPersistentVrStateCallbacks;
54 import android.service.vr.IVrListener;
55 import android.service.vr.IVrManager;
56 import android.service.vr.IVrStateCallbacks;
57 import android.service.vr.VrListenerService;
58 import android.text.TextUtils;
59 import android.util.ArrayMap;
60 import android.util.ArraySet;
61 import android.util.Slog;
62 import android.util.SparseArray;
63 
64 import com.android.internal.R;
65 import com.android.internal.util.DumpUtils;
66 import com.android.server.FgThread;
67 import com.android.server.LocalServices;
68 import com.android.server.SystemConfig;
69 import com.android.server.SystemService;
70 import com.android.server.utils.LazyJniRegistrar;
71 import com.android.server.utils.ManagedApplicationService;
72 import com.android.server.utils.ManagedApplicationService.BinderChecker;
73 import com.android.server.utils.ManagedApplicationService.LogEvent;
74 import com.android.server.utils.ManagedApplicationService.LogFormattable;
75 import com.android.server.utils.ManagedApplicationService.PendingEvent;
76 import com.android.server.vr.EnabledComponentsObserver.EnabledComponentChangeListener;
77 import com.android.server.wm.ActivityTaskManagerInternal;
78 import com.android.server.wm.ActivityTaskManagerInternal.ScreenObserver;
79 import com.android.server.wm.WindowManagerInternal;
80 
81 import java.io.FileDescriptor;
82 import java.io.PrintWriter;
83 import java.text.SimpleDateFormat;
84 import java.util.ArrayDeque;
85 import java.util.ArrayList;
86 import java.util.Arrays;
87 import java.util.Collection;
88 import java.util.Date;
89 import java.util.List;
90 import java.util.Objects;
91 
92 /**
93  * Service tracking whether VR mode is active, and notifying listening services of state changes.
94  * <p/>
95  * Services running in system server may modify the state of VrManagerService via the interface in
96  * VrManagerInternal, and may register to receive callbacks when the system VR mode changes via the
97  * interface given in VrStateListener.
98  * <p/>
99  * Device vendors may choose to receive VR state changes by implementing the VR mode HAL, e.g.:
100  *  hardware/libhardware/modules/vr
101  * <p/>
102  * In general applications may enable or disable VR mode by calling
103  * {@link android.app.Activity#setVrModeEnabled)}.  An application may also implement a service to
104  * be run while in VR mode by implementing {@link android.service.vr.VrListenerService}.
105  *
106  * @see android.service.vr.VrListenerService
107  * @see com.android.server.vr.VrManagerInternal
108  * @see com.android.server.vr.VrStateListener
109  *
110  * @hide
111  */
112 public class VrManagerService extends SystemService
113         implements EnabledComponentChangeListener, ScreenObserver {
114 
115     public static final String TAG = "VrManagerService";
116     static final boolean DBG = false;
117 
118     private static final int PENDING_STATE_DELAY_MS = 300;
119     private static final int EVENT_LOG_SIZE = 64;
120     private static final int INVALID_APPOPS_MODE = -1;
121     /** Null set of sleep sleep flags. */
122     private static final int FLAG_NONE = 0;
123     /** Flag set when the device is not sleeping. */
124     private static final int FLAG_AWAKE = 1 << 0;
125     /** Flag set when the screen has been turned on. */
126     private static final int FLAG_SCREEN_ON = 1 << 1;
127     /** Flag set when the keyguard is not active. */
128     private static final int FLAG_KEYGUARD_UNLOCKED = 1 << 2;
129     /** Flag indicating that all system sleep flags have been set.*/
130     private static final int FLAG_ALL = FLAG_AWAKE | FLAG_SCREEN_ON | FLAG_KEYGUARD_UNLOCKED;
131 
initializeNative()132     private static native void initializeNative();
setVrModeNative(boolean enabled)133     private static native void setVrModeNative(boolean enabled);
134 
135     static {
LazyJniRegistrar.registerVrManagerService()136         LazyJniRegistrar.registerVrManagerService();
137     }
138 
139     private final Object mLock = new Object();
140 
141     private final IBinder mOverlayToken = new Binder();
142 
143     // State protected by mLock
144     private boolean mVrModeAllowed;
145     private boolean mVrModeEnabled;
146     private boolean mPersistentVrModeEnabled;
147     private boolean mRunning2dInVr;
148     private int mVrAppProcessId;
149     private EnabledComponentsObserver mComponentObserver;
150     private ManagedApplicationService mCurrentVrService;
151     private ManagedApplicationService mCurrentVrCompositorService;
152     private ComponentName mDefaultVrService;
153     private Context mContext;
154     private ComponentName mCurrentVrModeComponent;
155     private int mCurrentVrModeUser;
156     private boolean mWasDefaultGranted;
157     private boolean mGuard;
158     private final RemoteCallbackList<IVrStateCallbacks> mVrStateRemoteCallbacks =
159             new RemoteCallbackList<>();
160     private final RemoteCallbackList<IPersistentVrStateCallbacks>
161             mPersistentVrStateRemoteCallbacks = new RemoteCallbackList<>();
162     private int mPreviousCoarseLocationMode = INVALID_APPOPS_MODE;
163     private int mPreviousManageOverlayMode = INVALID_APPOPS_MODE;
164     private VrState mPendingState;
165     private boolean mLogLimitHit;
166     private final ArrayDeque<LogFormattable> mLoggingDeque = new ArrayDeque<>(EVENT_LOG_SIZE);
167     private final NotificationAccessManager mNotifAccessManager = new NotificationAccessManager();
168     private INotificationManager mNotificationManager;
169     /** Tracks the state of the screen and keyguard UI.*/
170     private int mSystemSleepFlags = FLAG_AWAKE | FLAG_KEYGUARD_UNLOCKED;
171     /**
172      * Set when ACTION_USER_UNLOCKED is fired. We shouldn't try to bind to the
173      * vr service before then. This gets set only once the first time the user unlocks the device
174      * and stays true thereafter.
175      */
176     private boolean mUserUnlocked;
177     private Vr2dDisplay mVr2dDisplay;
178     private boolean mBootsToVr;
179     private boolean mStandby;
180     private boolean mUseStandbyToExitVrMode;
181 
182     // Handles events from the managed services (e.g. VrListenerService and any bound VR compositor
183     // service).
184     private final ManagedApplicationService.EventCallback mEventCallback
185                 = new ManagedApplicationService.EventCallback() {
186         @Override
187         public void onServiceEvent(LogEvent event) {
188             logEvent(event);
189 
190             ComponentName component = null;
191             synchronized (mLock) {
192                 component = ((mCurrentVrService == null) ? null : mCurrentVrService.getComponent());
193 
194                 // If the VrCore main service was disconnected or the binding died we'll rebind
195                 // automatically. Call focusedActivityChanged() once we rebind.
196                 if (component != null && component.equals(event.component) &&
197                         (event.event == LogEvent.EVENT_DISCONNECTED ||
198                          event.event == LogEvent.EVENT_BINDING_DIED)) {
199                     callFocusedActivityChangedLocked();
200                 }
201             }
202 
203             // If not on an AIO device and we permanently stopped trying to connect to the
204             // VrListenerService (or don't have one bound), leave persistent VR mode and VR mode.
205             if (!mBootsToVr && event.event == LogEvent.EVENT_STOPPED_PERMANENTLY &&
206                     (component == null || component.equals(event.component))) {
207                 Slog.e(TAG, "VrListenerSevice has died permanently, leaving system VR mode.");
208                 // We're not a native VR device.  Leave VR + persistent mode.
209                 setPersistentVrModeEnabled(false);
210             }
211         }
212     };
213 
214     private static final int MSG_VR_STATE_CHANGE = 0;
215     private static final int MSG_PENDING_VR_STATE_CHANGE = 1;
216     private static final int MSG_PERSISTENT_VR_MODE_STATE_CHANGE = 2;
217 
218     /**
219      * Set whether VR mode may be enabled.
220      * <p/>
221      * If VR mode is not allowed to be enabled, calls to set VR mode will be cached.  When VR mode
222      * is again allowed to be enabled, the most recent cached state will be applied.
223      *
224      */
updateVrModeAllowedLocked()225     private void updateVrModeAllowedLocked() {
226         boolean ignoreSleepFlags = mBootsToVr && mUseStandbyToExitVrMode;
227         boolean disallowedByStandby = mStandby && mUseStandbyToExitVrMode;
228         boolean allowed = (mSystemSleepFlags == FLAG_ALL || ignoreSleepFlags) && mUserUnlocked
229                 && !disallowedByStandby;
230         if (mVrModeAllowed != allowed) {
231             mVrModeAllowed = allowed;
232             if (DBG) Slog.d(TAG, "VR mode is " + ((allowed) ? "allowed" : "disallowed"));
233             if (mVrModeAllowed) {
234                 if (mBootsToVr) {
235                     setPersistentVrModeEnabled(true);
236                 }
237                 if (mBootsToVr && !mVrModeEnabled) {
238                   setVrMode(true, mDefaultVrService, 0, -1, null);
239                 }
240             } else {
241                 // Disable persistent mode when VR mode isn't allowed, allows an escape hatch to
242                 // exit persistent VR mode when screen is turned off.
243                 setPersistentModeAndNotifyListenersLocked(false);
244 
245                 // Set pending state to current state.
246                 mPendingState = (mVrModeEnabled && mCurrentVrService != null)
247                     ? new VrState(mVrModeEnabled, mRunning2dInVr, mCurrentVrService.getComponent(),
248                         mCurrentVrService.getUserId(), mVrAppProcessId, mCurrentVrModeComponent)
249                     : null;
250 
251                 // Unbind current VR service and do necessary callbacks.
252                 updateCurrentVrServiceLocked(false, false, null, 0, -1, null);
253             }
254         }
255     }
256 
setScreenOn(boolean isScreenOn)257     private void setScreenOn(boolean isScreenOn) {
258         setSystemState(FLAG_SCREEN_ON, isScreenOn);
259     }
260 
261     @Override
onAwakeStateChanged(boolean isAwake)262     public void onAwakeStateChanged(boolean isAwake) {
263         setSystemState(FLAG_AWAKE, isAwake);
264     }
265 
266     @Override
onKeyguardStateChanged(boolean isShowing)267     public void onKeyguardStateChanged(boolean isShowing) {
268         setSystemState(FLAG_KEYGUARD_UNLOCKED, !isShowing);
269     }
270 
setSystemState(int flags, boolean isOn)271     private void setSystemState(int flags, boolean isOn) {
272         synchronized(mLock) {
273             int oldState = mSystemSleepFlags;
274             if (isOn) {
275                 mSystemSleepFlags |= flags;
276             } else {
277                 mSystemSleepFlags &= ~flags;
278             }
279             if (oldState != mSystemSleepFlags) {
280                 if (DBG) Slog.d(TAG, "System state: " + getStateAsString());
281                 updateVrModeAllowedLocked();
282             }
283         }
284     }
285 
getStateAsString()286     private String getStateAsString() {
287         return new StringBuilder()
288                 .append((mSystemSleepFlags & FLAG_AWAKE) != 0 ? "awake, " : "")
289                 .append((mSystemSleepFlags & FLAG_SCREEN_ON) != 0 ? "screen_on, " : "")
290                 .append((mSystemSleepFlags & FLAG_KEYGUARD_UNLOCKED) != 0 ? "keyguard_off" : "")
291                 .toString();
292     }
293 
setUserUnlocked()294     private void setUserUnlocked() {
295         synchronized(mLock) {
296             mUserUnlocked = true;
297             updateVrModeAllowedLocked();
298         }
299     }
300 
setStandbyEnabled(boolean standby)301     private void setStandbyEnabled(boolean standby) {
302         synchronized(mLock) {
303             if (!mBootsToVr) {
304                 Slog.e(TAG, "Attempting to set standby mode on a non-standalone device");
305                 return;
306             }
307             mStandby = standby;
308             updateVrModeAllowedLocked();
309         }
310     }
311 
312     private final Handler mHandler = new Handler() {
313         @Override
314         public void handleMessage(Message msg) {
315             switch(msg.what) {
316                 case MSG_VR_STATE_CHANGE : {
317                     boolean state = (msg.arg1 == 1);
318                     int i = mVrStateRemoteCallbacks.beginBroadcast();
319                     while (i > 0) {
320                         i--;
321                         try {
322                             mVrStateRemoteCallbacks.getBroadcastItem(i).onVrStateChanged(state);
323                         } catch (RemoteException e) {
324                             // Noop
325                         }
326                     }
327                     mVrStateRemoteCallbacks.finishBroadcast();
328                 } break;
329                 case MSG_PENDING_VR_STATE_CHANGE : {
330                     synchronized(mLock) {
331                         if (mVrModeAllowed) {
332                            VrManagerService.this.consumeAndApplyPendingStateLocked();
333                         }
334                     }
335                 } break;
336                 case MSG_PERSISTENT_VR_MODE_STATE_CHANGE : {
337                     boolean state = (msg.arg1 == 1);
338                     int i = mPersistentVrStateRemoteCallbacks.beginBroadcast();
339                     while (i > 0) {
340                         i--;
341                         try {
342                             mPersistentVrStateRemoteCallbacks.getBroadcastItem(i)
343                                     .onPersistentVrStateChanged(state);
344                         } catch (RemoteException e) {
345                             // Noop
346                         }
347                     }
348                     mPersistentVrStateRemoteCallbacks.finishBroadcast();
349                 } break;
350                 default :
351                     throw new IllegalStateException("Unknown message type: " + msg.what);
352             }
353         }
354     };
355 
356     // Event used to log when settings are changed for dumpsys logs.
357     private static class SettingEvent implements LogFormattable {
358         public final long timestamp;
359         public final String what;
360 
SettingEvent(String what)361         SettingEvent(String what) {
362             this.timestamp = System.currentTimeMillis();
363             this.what = what;
364         }
365 
366         @Override
toLogString(SimpleDateFormat dateFormat)367         public String toLogString(SimpleDateFormat dateFormat) {
368             return dateFormat.format(new Date(timestamp)) + "   " + what;
369         }
370     }
371 
372     // Event used to track changes of the primary on-screen VR activity.
373     private static class VrState implements LogFormattable {
374         final boolean enabled;
375         final boolean running2dInVr;
376         final int userId;
377         final int processId;
378         final ComponentName targetPackageName;
379         final ComponentName callingPackage;
380         final long timestamp;
381         final boolean defaultPermissionsGranted;
382 
VrState(boolean enabled, boolean running2dInVr, ComponentName targetPackageName, int userId, int processId, ComponentName callingPackage)383         VrState(boolean enabled, boolean running2dInVr, ComponentName targetPackageName, int userId,
384                 int processId, ComponentName callingPackage) {
385             this.enabled = enabled;
386             this.running2dInVr = running2dInVr;
387             this.userId = userId;
388             this.processId = processId;
389             this.targetPackageName = targetPackageName;
390             this.callingPackage = callingPackage;
391             this.defaultPermissionsGranted = false;
392             this.timestamp = System.currentTimeMillis();
393         }
394 
VrState(boolean enabled, boolean running2dInVr, ComponentName targetPackageName, int userId, int processId, ComponentName callingPackage, boolean defaultPermissionsGranted)395         VrState(boolean enabled, boolean running2dInVr, ComponentName targetPackageName, int userId,
396             int processId, ComponentName callingPackage, boolean defaultPermissionsGranted) {
397             this.enabled = enabled;
398             this.running2dInVr = running2dInVr;
399             this.userId = userId;
400             this.processId = processId;
401             this.targetPackageName = targetPackageName;
402             this.callingPackage = callingPackage;
403             this.defaultPermissionsGranted = defaultPermissionsGranted;
404             this.timestamp = System.currentTimeMillis();
405         }
406 
407         @Override
toLogString(SimpleDateFormat dateFormat)408         public String toLogString(SimpleDateFormat dateFormat) {
409             String tab = "  ";
410             String newLine = "\n";
411             StringBuilder sb = new StringBuilder(dateFormat.format(new Date(timestamp)));
412             sb.append(tab);
413             sb.append("State changed to:");
414             sb.append(tab);
415             sb.append((enabled) ? "ENABLED" : "DISABLED");
416             sb.append(newLine);
417             if (enabled) {
418                 sb.append(tab);
419                 sb.append("User=");
420                 sb.append(userId);
421                 sb.append(newLine);
422                 sb.append(tab);
423                 sb.append("Current VR Activity=");
424                 sb.append((callingPackage == null) ? "None" : callingPackage.flattenToString());
425                 sb.append(newLine);
426                 sb.append(tab);
427                 sb.append("Bound VrListenerService=");
428                 sb.append((targetPackageName == null) ? "None"
429                         : targetPackageName.flattenToString());
430                 sb.append(newLine);
431                 if (defaultPermissionsGranted) {
432                     sb.append(tab);
433                     sb.append("Default permissions granted to the bound VrListenerService.");
434                     sb.append(newLine);
435                 }
436             }
437             return sb.toString();
438         }
439     }
440 
441     private static final BinderChecker sBinderChecker = new BinderChecker() {
442         @Override
443         public IInterface asInterface(IBinder binder) {
444             return IVrListener.Stub.asInterface(binder);
445         }
446 
447         @Override
448         public boolean checkType(IInterface service) {
449             return service instanceof IVrListener;
450         }
451     };
452 
453     private final class NotificationAccessManager {
454         private final SparseArray<ArraySet<String>> mAllowedPackages = new SparseArray<>();
455         private final ArrayMap<String, Integer> mNotificationAccessPackageToUserId =
456                 new ArrayMap<>();
457 
update(Collection<String> packageNames)458         public void update(Collection<String> packageNames) {
459             int currentUserId = ActivityManager.getCurrentUser();
460 
461             ArraySet<String> allowed = mAllowedPackages.get(currentUserId);
462             if (allowed == null) {
463                 allowed = new ArraySet<>();
464             }
465 
466             // Make sure we revoke notification access for listeners in other users
467             final int listenerCount = mNotificationAccessPackageToUserId.size();
468             for (int i = listenerCount - 1; i >= 0; i--) {
469                 final int grantUserId = mNotificationAccessPackageToUserId.valueAt(i);
470                 if (grantUserId != currentUserId) {
471                     String packageName = mNotificationAccessPackageToUserId.keyAt(i);
472                     revokeNotificationListenerAccess(packageName, grantUserId);
473                     revokeNotificationPolicyAccess(packageName);
474                     revokeCoarseLocationPermissionIfNeeded(packageName, grantUserId);
475                     mNotificationAccessPackageToUserId.removeAt(i);
476                 }
477             }
478 
479             for (String pkg : allowed) {
480                 if (!packageNames.contains(pkg)) {
481                     revokeNotificationListenerAccess(pkg, currentUserId);
482                     revokeNotificationPolicyAccess(pkg);
483                     revokeCoarseLocationPermissionIfNeeded(pkg, currentUserId);
484                     mNotificationAccessPackageToUserId.remove(pkg);
485                 }
486             }
487             for (String pkg : packageNames) {
488                 if (!allowed.contains(pkg)) {
489                     grantNotificationPolicyAccess(pkg);
490                     grantNotificationListenerAccess(pkg, currentUserId);
491                     grantCoarseLocationPermissionIfNeeded(pkg, currentUserId);
492                     mNotificationAccessPackageToUserId.put(pkg, currentUserId);
493                 }
494             }
495 
496             allowed.clear();
497             allowed.addAll(packageNames);
498             mAllowedPackages.put(currentUserId, allowed);
499         }
500     }
501 
502     /**
503      * Called when a user, package, or setting changes that could affect whether or not the
504      * currently bound VrListenerService is changed.
505      */
506     @Override
onEnabledComponentChanged()507     public void onEnabledComponentChanged() {
508         synchronized (mLock) {
509             int currentUser = ActivityManager.getCurrentUser();
510             // Update listeners
511             ArraySet<ComponentName> enabledListeners = mComponentObserver.getEnabled(currentUser);
512 
513             ArraySet<String> enabledPackages = new ArraySet<>();
514             for (ComponentName n : enabledListeners) {
515                 String pkg = n.getPackageName();
516                 if (isDefaultAllowed(pkg)) {
517                     enabledPackages.add(n.getPackageName());
518                 }
519             }
520             mNotifAccessManager.update(enabledPackages);
521 
522             if (!mVrModeAllowed) {
523                 return; // Don't do anything, we shouldn't be in VR mode.
524             }
525 
526             // If there is a pending state change, we'd better deal with that first
527             consumeAndApplyPendingStateLocked(false);
528 
529             if (mCurrentVrService == null) {
530                 return; // No active services
531             }
532 
533             // There is an active service, update it if needed
534             updateCurrentVrServiceLocked(mVrModeEnabled, mRunning2dInVr,
535                     mCurrentVrService.getComponent(), mCurrentVrService.getUserId(),
536                     mVrAppProcessId, mCurrentVrModeComponent);
537         }
538     }
539 
540     private final IVrManager mVrManager = new IVrManager.Stub() {
541 
542         @Override
543         public void registerListener(IVrStateCallbacks cb) {
544             enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER,
545                     Manifest.permission.ACCESS_VR_STATE);
546             if (cb == null) {
547                 throw new IllegalArgumentException("Callback binder object is null.");
548             }
549 
550             VrManagerService.this.addStateCallback(cb);
551         }
552 
553         @Override
554         public void unregisterListener(IVrStateCallbacks cb) {
555             enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER,
556                     Manifest.permission.ACCESS_VR_STATE);
557             if (cb == null) {
558                 throw new IllegalArgumentException("Callback binder object is null.");
559             }
560 
561             VrManagerService.this.removeStateCallback(cb);
562         }
563 
564         @Override
565         public void registerPersistentVrStateListener(IPersistentVrStateCallbacks cb) {
566             enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER,
567                     Manifest.permission.ACCESS_VR_STATE);
568             if (cb == null) {
569                 throw new IllegalArgumentException("Callback binder object is null.");
570             }
571 
572             VrManagerService.this.addPersistentStateCallback(cb);
573         }
574 
575         @Override
576         public void unregisterPersistentVrStateListener(IPersistentVrStateCallbacks cb) {
577             enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER,
578                     Manifest.permission.ACCESS_VR_STATE);
579             if (cb == null) {
580                 throw new IllegalArgumentException("Callback binder object is null.");
581             }
582 
583             VrManagerService.this.removePersistentStateCallback(cb);
584         }
585 
586         @Override
587         public boolean getVrModeState() {
588             enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER,
589                     Manifest.permission.ACCESS_VR_STATE);
590             return VrManagerService.this.getVrMode();
591         }
592 
593         @Override
594         public boolean getPersistentVrModeEnabled() {
595             enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER,
596                     Manifest.permission.ACCESS_VR_STATE);
597             return VrManagerService.this.getPersistentVrMode();
598         }
599 
600         @Override
601         public void setPersistentVrModeEnabled(boolean enabled) {
602             enforceCallerPermissionAnyOf(Manifest.permission.RESTRICTED_VR_ACCESS);
603             VrManagerService.this.setPersistentVrModeEnabled(enabled);
604         }
605 
606         @Override
607         public void setVr2dDisplayProperties(
608                 Vr2dDisplayProperties vr2dDisplayProp) {
609             enforceCallerPermissionAnyOf(Manifest.permission.RESTRICTED_VR_ACCESS);
610             VrManagerService.this.setVr2dDisplayProperties(vr2dDisplayProp);
611         }
612 
613         @Override
614         public int getVr2dDisplayId() {
615             return VrManagerService.this.getVr2dDisplayId();
616         }
617 
618         @Override
619         public void setAndBindCompositor(String componentName) {
620             enforceCallerPermissionAnyOf(Manifest.permission.RESTRICTED_VR_ACCESS);
621             VrManagerService.this.setAndBindCompositor(
622                 (componentName == null) ? null : ComponentName.unflattenFromString(componentName));
623         }
624 
625         @Override
626         public void setStandbyEnabled(boolean standby) {
627             enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER);
628             VrManagerService.this.setStandbyEnabled(standby);
629         }
630 
631         @Override
632         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
633             if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
634 
635             pw.println("********* Dump of VrManagerService *********");
636             pw.println("VR mode is currently: " + ((mVrModeAllowed) ? "allowed" : "disallowed"));
637             pw.println("Persistent VR mode is currently: " +
638                     ((mPersistentVrModeEnabled) ? "enabled" : "disabled"));
639             pw.println("Currently bound VR listener service: "
640                     + ((mCurrentVrService == null)
641                     ? "None" : mCurrentVrService.getComponent().flattenToString()));
642             pw.println("Currently bound VR compositor service: "
643                     + ((mCurrentVrCompositorService == null)
644                     ? "None" : mCurrentVrCompositorService.getComponent().flattenToString()));
645             pw.println("Previous state transitions:\n");
646             String tab = "  ";
647             dumpStateTransitions(pw);
648             pw.println("\n\nRemote Callbacks:");
649             int i=mVrStateRemoteCallbacks.beginBroadcast(); // create the broadcast item array
650             while(i-->0) {
651                 pw.print(tab);
652                 pw.print(mVrStateRemoteCallbacks.getBroadcastItem(i));
653                 if (i>0) pw.println(",");
654             }
655             mVrStateRemoteCallbacks.finishBroadcast();
656             pw.println("\n\nPersistent Vr State Remote Callbacks:");
657             i=mPersistentVrStateRemoteCallbacks.beginBroadcast();
658             while(i-->0) {
659                 pw.print(tab);
660                 pw.print(mPersistentVrStateRemoteCallbacks.getBroadcastItem(i));
661                 if (i>0) pw.println(",");
662             }
663             mPersistentVrStateRemoteCallbacks.finishBroadcast();
664             pw.println("\n");
665             pw.println("Installed VrListenerService components:");
666             int userId = mCurrentVrModeUser;
667             ArraySet<ComponentName> installed = mComponentObserver.getInstalled(userId);
668             if (installed == null || installed.size() == 0) {
669                 pw.println("None");
670             } else {
671                 for (ComponentName n : installed) {
672                     pw.print(tab);
673                     pw.println(n.flattenToString());
674                 }
675             }
676             pw.println("Enabled VrListenerService components:");
677             ArraySet<ComponentName> enabled = mComponentObserver.getEnabled(userId);
678             if (enabled == null || enabled.size() == 0) {
679                 pw.println("None");
680             } else {
681                 for (ComponentName n : enabled) {
682                     pw.print(tab);
683                     pw.println(n.flattenToString());
684                 }
685             }
686             pw.println("\n");
687             pw.println("********* End of VrManagerService Dump *********");
688         }
689 
690     };
691 
692     /**
693      * Enforces that at lease one of the specified permissions is held by the caller.
694      * Throws SecurityException if none of the specified permissions are held.
695      *
696      * @param permissions One or more permissions to check against.
697      */
enforceCallerPermissionAnyOf(String... permissions)698     private void enforceCallerPermissionAnyOf(String... permissions) {
699         for (String permission : permissions) {
700             if (mContext.checkCallingOrSelfPermission(permission)
701                     == PackageManager.PERMISSION_GRANTED) {
702                 return;
703             }
704         }
705         throw new SecurityException("Caller does not hold at least one of the permissions: "
706                 + Arrays.toString(permissions));
707     }
708 
709     /**
710      * Implementation of VrManagerInternal.  Callable only from system services.
711      */
712     private final class LocalService extends VrManagerInternal {
713         @Override
setVrMode(boolean enabled, ComponentName packageName, int userId, int processId, ComponentName callingPackage)714         public void setVrMode(boolean enabled, ComponentName packageName, int userId, int processId,
715                 ComponentName callingPackage) {
716             VrManagerService.this.setVrMode(enabled, packageName, userId, processId, callingPackage);
717         }
718 
719         @Override
onScreenStateChanged(boolean isScreenOn)720         public void onScreenStateChanged(boolean isScreenOn) {
721             VrManagerService.this.setScreenOn(isScreenOn);
722         }
723 
724         @Override
isCurrentVrListener(String packageName, int userId)725         public boolean isCurrentVrListener(String packageName, int userId) {
726             return VrManagerService.this.isCurrentVrListener(packageName, userId);
727         }
728 
729         @Override
hasVrPackage(ComponentName packageName, int userId)730         public int hasVrPackage(ComponentName packageName, int userId) {
731             return VrManagerService.this.hasVrPackage(packageName, userId);
732         }
733 
734         @Override
setPersistentVrModeEnabled(boolean enabled)735         public void setPersistentVrModeEnabled(boolean enabled) {
736             VrManagerService.this.setPersistentVrModeEnabled(enabled);
737         }
738 
739         @Override
setVr2dDisplayProperties( Vr2dDisplayProperties compatDisplayProp)740         public void setVr2dDisplayProperties(
741             Vr2dDisplayProperties compatDisplayProp) {
742             VrManagerService.this.setVr2dDisplayProperties(compatDisplayProp);
743         }
744 
745         @Override
getVr2dDisplayId()746         public int getVr2dDisplayId() {
747             return VrManagerService.this.getVr2dDisplayId();
748         }
749 
750         @Override
addPersistentVrModeStateListener(IPersistentVrStateCallbacks listener)751         public void addPersistentVrModeStateListener(IPersistentVrStateCallbacks listener) {
752             VrManagerService.this.addPersistentStateCallback(listener);
753         }
754     }
755 
VrManagerService(Context context)756     public VrManagerService(Context context) {
757         super(context);
758     }
759 
760     @Override
onStart()761     public void onStart() {
762         synchronized(mLock) {
763             initializeNative();
764             mContext = getContext();
765         }
766 
767         mBootsToVr = SystemProperties.getBoolean("ro.boot.vr", false);
768         mUseStandbyToExitVrMode = mBootsToVr
769                 && SystemProperties.getBoolean("persist.vr.use_standby_to_exit_vr_mode", true);
770         publishLocalService(VrManagerInternal.class, new LocalService());
771         publishBinderService(Context.VR_SERVICE, mVrManager.asBinder());
772     }
773 
774     @Override
onBootPhase(int phase)775     public void onBootPhase(int phase) {
776         if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
777             LocalServices.getService(ActivityTaskManagerInternal.class)
778                     .registerScreenObserver(this);
779 
780             mNotificationManager = INotificationManager.Stub.asInterface(
781                     ServiceManager.getService(Context.NOTIFICATION_SERVICE));
782             synchronized (mLock) {
783                 Looper looper = Looper.getMainLooper();
784                 Handler handler = new Handler(looper);
785                 ArrayList<EnabledComponentChangeListener> listeners = new ArrayList<>();
786                 listeners.add(this);
787                 mComponentObserver = EnabledComponentsObserver.build(mContext, handler,
788                         Settings.Secure.ENABLED_VR_LISTENERS, looper,
789                         android.Manifest.permission.BIND_VR_LISTENER_SERVICE,
790                         VrListenerService.SERVICE_INTERFACE, mLock, listeners);
791 
792                 mComponentObserver.rebuildAll();
793             }
794 
795             //TODO: something more robust than picking the first one
796             ArraySet<ComponentName> defaultVrComponents =
797                     SystemConfig.getInstance().getDefaultVrComponents();
798             if (defaultVrComponents.size() > 0) {
799                 mDefaultVrService = defaultVrComponents.valueAt(0);
800             } else {
801                 Slog.i(TAG, "No default vr listener service found.");
802             }
803 
804             DisplayManager dm =
805                     (DisplayManager) getContext().getSystemService(Context.DISPLAY_SERVICE);
806             mVr2dDisplay = new Vr2dDisplay(
807                     dm,
808                     LocalServices.getService(ActivityManagerInternal.class),
809                     LocalServices.getService(WindowManagerInternal.class),
810                     mVrManager);
811             mVr2dDisplay.init(getContext(), mBootsToVr);
812 
813             IntentFilter intentFilter = new IntentFilter();
814             intentFilter.addAction(Intent.ACTION_USER_UNLOCKED);
815             getContext().registerReceiver(new BroadcastReceiver() {
816                     @Override
817                     public void onReceive(Context context, Intent intent) {
818                         if (Intent.ACTION_USER_UNLOCKED.equals(intent.getAction())) {
819                             VrManagerService.this.setUserUnlocked();
820                         }
821                     }
822                 }, intentFilter);
823         }
824     }
825 
826     @Override
onUserStarting(@onNull TargetUser user)827     public void onUserStarting(@NonNull TargetUser user) {
828         synchronized (mLock) {
829             mComponentObserver.onUsersChanged();
830         }
831     }
832 
833     @Override
onUserSwitching(@ullable TargetUser from, @NonNull TargetUser to)834     public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
835         FgThread.getHandler().post(() -> {
836             synchronized (mLock) {
837                 mComponentObserver.onUsersChanged();
838             }
839         });
840 
841     }
842 
843     @Override
onUserStopping(@onNull TargetUser user)844     public void onUserStopping(@NonNull TargetUser user) {
845         synchronized (mLock) {
846             mComponentObserver.onUsersChanged();
847         }
848 
849     }
850 
851     @Override
onUserStopped(@onNull TargetUser user)852     public void onUserStopped(@NonNull TargetUser user) {
853         synchronized (mLock) {
854             mComponentObserver.onUsersChanged();
855         }
856     }
857 
updateOverlayStateLocked(String exemptedPackage, int newUserId, int oldUserId)858     private void updateOverlayStateLocked(String exemptedPackage, int newUserId, int oldUserId) {
859         AppOpsManager appOpsManager = getContext().getSystemService(AppOpsManager.class);
860 
861         // If user changed drop restrictions for the old user.
862         if (oldUserId != newUserId) {
863             appOpsManager.setUserRestrictionForUser(AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
864                     false, mOverlayToken, null, oldUserId);
865         }
866 
867         // Apply the restrictions for the current user based on vr state
868         PackageTagsList exemptions = null;
869         if (exemptedPackage != null) {
870             exemptions = new PackageTagsList.Builder(1).add(exemptedPackage).build();
871         }
872 
873         appOpsManager.setUserRestrictionForUser(AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
874                 mVrModeEnabled, mOverlayToken, exemptions, newUserId);
875     }
876 
updateDependentAppOpsLocked(String newVrServicePackage, int newUserId, String oldVrServicePackage, int oldUserId)877     private void updateDependentAppOpsLocked(String newVrServicePackage, int newUserId,
878             String oldVrServicePackage, int oldUserId) {
879         // If VR state changed and we also have a VR service change.
880         if (Objects.equals(newVrServicePackage, oldVrServicePackage)) {
881             return;
882         }
883         final long identity = Binder.clearCallingIdentity();
884         try {
885             // Set overlay exception state based on VR enabled and current service
886             updateOverlayStateLocked(newVrServicePackage, newUserId, oldUserId);
887         } finally {
888             Binder.restoreCallingIdentity(identity);
889         }
890     }
891 
892     /**
893      * Send VR mode changes (if the mode state has changed), and update the bound/unbound state of
894      * the currently selected VR listener service.  If the component selected for the VR listener
895      * service has changed, unbind the previous listener and bind the new listener (if enabled).
896      * <p/>
897      * Note: Must be called while holding {@code mLock}.
898      *
899      * @param enabled new state for VR mode.
900      * @param running2dInVr true if we have a top-level 2D intent.
901      * @param component new component to be bound as a VR listener.
902      * @param userId user owning the component to be bound.
903      * @param processId the process hosting the activity specified by calling.
904      * @param calling the component currently using VR mode or a 2D intent.
905      *
906      * @return {@code true} if the component/user combination specified is valid.
907      */
updateCurrentVrServiceLocked(boolean enabled, boolean running2dInVr, @NonNull ComponentName component, int userId, int processId, ComponentName calling)908     private boolean updateCurrentVrServiceLocked(boolean enabled, boolean running2dInVr,
909             @NonNull ComponentName component, int userId, int processId, ComponentName calling) {
910 
911         boolean sendUpdatedCaller = false;
912         final long identity = Binder.clearCallingIdentity();
913         try {
914 
915             boolean validUserComponent = (mComponentObserver.isValid(component, userId) ==
916                     EnabledComponentsObserver.NO_ERROR);
917             boolean goingIntoVrMode = validUserComponent && enabled;
918             if (!mVrModeEnabled && !goingIntoVrMode) {
919                 return validUserComponent; // Disabled -> Disabled transition does nothing.
920             }
921 
922             String oldVrServicePackage = mCurrentVrService != null
923                     ? mCurrentVrService.getComponent().getPackageName() : null;
924             final int oldUserId = mCurrentVrModeUser;
925 
926             // Notify system services and VR HAL of mode change.
927             changeVrModeLocked(goingIntoVrMode);
928 
929             boolean nothingChanged = false;
930             if (!goingIntoVrMode) {
931                 // Not going into VR mode, unbind whatever is running
932                 if (mCurrentVrService != null) {
933                     Slog.i(TAG, "Leaving VR mode, disconnecting "
934                         + mCurrentVrService.getComponent() + " for user "
935                         + mCurrentVrService.getUserId());
936                     mCurrentVrService.disconnect();
937                     updateCompositorServiceLocked(UserHandle.USER_NULL, null);
938                     mCurrentVrService = null;
939                 } else {
940                     nothingChanged = true;
941                 }
942             } else {
943                 // Going into VR mode
944                 if (mCurrentVrService != null) {
945                     // Unbind any running service that doesn't match the latest component/user
946                     // selection.
947                     if (mCurrentVrService.disconnectIfNotMatching(component, userId)) {
948                         Slog.i(TAG, "VR mode component changed to " + component
949                             + ", disconnecting " + mCurrentVrService.getComponent()
950                             + " for user " + mCurrentVrService.getUserId());
951                         updateCompositorServiceLocked(UserHandle.USER_NULL, null);
952                         createAndConnectService(component, userId);
953                         sendUpdatedCaller = true;
954                     } else {
955                         nothingChanged = true;
956                     }
957                     // The service with the correct component/user is already bound, do nothing.
958                 } else {
959                     // Nothing was previously running, bind a new service for the latest
960                     // component/user selection.
961                     createAndConnectService(component, userId);
962                     sendUpdatedCaller = true;
963                 }
964             }
965 
966             if ((calling != null || mPersistentVrModeEnabled)
967                     && !Objects.equals(calling, mCurrentVrModeComponent)
968                     || mRunning2dInVr != running2dInVr) {
969                 sendUpdatedCaller = true;
970             }
971             mCurrentVrModeComponent = calling;
972             mRunning2dInVr = running2dInVr;
973             mVrAppProcessId = processId;
974 
975             if (mCurrentVrModeUser != userId) {
976                 mCurrentVrModeUser = userId;
977                 sendUpdatedCaller = true;
978             }
979 
980             String newVrServicePackage = mCurrentVrService != null
981                     ? mCurrentVrService.getComponent().getPackageName() : null;
982             final int newUserId = mCurrentVrModeUser;
983 
984             // Update AppOps settings that change state when entering/exiting VR mode, or changing
985             // the current VrListenerService.
986             updateDependentAppOpsLocked(newVrServicePackage, newUserId,
987                     oldVrServicePackage, oldUserId);
988 
989             if (mCurrentVrService != null && sendUpdatedCaller) {
990                 callFocusedActivityChangedLocked();
991             }
992 
993             if (!nothingChanged) {
994                 logStateLocked();
995             }
996 
997             return validUserComponent;
998         } finally {
999             Binder.restoreCallingIdentity(identity);
1000         }
1001     }
1002 
callFocusedActivityChangedLocked()1003     private void callFocusedActivityChangedLocked() {
1004         final ComponentName c = mCurrentVrModeComponent;
1005         final boolean b = mRunning2dInVr;
1006         final int pid = mVrAppProcessId;
1007         mCurrentVrService.sendEvent(new PendingEvent() {
1008             @Override
1009             public void runEvent(IInterface service) throws RemoteException {
1010                 // Under specific (and unlikely) timing scenarios, when VrCore
1011                 // crashes and is rebound, focusedActivityChanged() may be
1012                 // called a 2nd time with the same arguments. IVrListeners
1013                 // should make sure to handle that scenario gracefully.
1014                 IVrListener l = (IVrListener) service;
1015                 l.focusedActivityChanged(c, b, pid);
1016             }
1017         });
1018     }
1019 
isDefaultAllowed(String packageName)1020     private boolean isDefaultAllowed(String packageName) {
1021         PackageManager pm = mContext.getPackageManager();
1022 
1023         ApplicationInfo info = null;
1024         try {
1025             info = pm.getApplicationInfo(packageName, PackageManager.GET_META_DATA);
1026         } catch (NameNotFoundException e) {
1027         }
1028 
1029         if (info == null || !(info.isSystemApp() || info.isUpdatedSystemApp())) {
1030             return false;
1031         }
1032         return true;
1033     }
1034 
grantNotificationPolicyAccess(String pkg)1035     private void grantNotificationPolicyAccess(String pkg) {
1036         NotificationManager nm = mContext.getSystemService(NotificationManager.class);
1037         nm.setNotificationPolicyAccessGranted(pkg, true);
1038     }
1039 
revokeNotificationPolicyAccess(String pkg)1040     private void revokeNotificationPolicyAccess(String pkg) {
1041         NotificationManager nm = mContext.getSystemService(NotificationManager.class);
1042         // Remove any DND zen rules possibly created by the package.
1043         nm.removeAutomaticZenRules(pkg);
1044         // Remove Notification Policy Access.
1045         nm.setNotificationPolicyAccessGranted(pkg, false);
1046     }
1047 
grantNotificationListenerAccess(String pkg, int userId)1048     private void grantNotificationListenerAccess(String pkg, int userId) {
1049         NotificationManager nm = mContext.getSystemService(NotificationManager.class);
1050         PackageManager pm = mContext.getPackageManager();
1051         ArraySet<ComponentName> possibleServices = EnabledComponentsObserver.loadComponentNames(pm,
1052                 userId, NotificationListenerService.SERVICE_INTERFACE,
1053                 android.Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE);
1054 
1055         for (ComponentName c : possibleServices) {
1056             if (Objects.equals(c.getPackageName(), pkg)) {
1057                 try {
1058                     nm.setNotificationListenerAccessGrantedForUser(c, userId, true);
1059                 } catch (Exception e) {
1060                     Slog.w(TAG, "Could not grant NLS access to package " + pkg, e);
1061                 }
1062             }
1063         }
1064     }
1065 
revokeNotificationListenerAccess(String pkg, int userId)1066     private void revokeNotificationListenerAccess(String pkg, int userId) {
1067         NotificationManager nm = mContext.getSystemService(NotificationManager.class);
1068         List<ComponentName> current = nm.getEnabledNotificationListeners(userId);
1069 
1070         for (ComponentName component : current) {
1071             if (component != null && component.getPackageName().equals(pkg)) {
1072                 nm.setNotificationListenerAccessGrantedForUser(component, userId, false);
1073             }
1074         }
1075     }
1076 
grantCoarseLocationPermissionIfNeeded(String pkg, int userId)1077     private void grantCoarseLocationPermissionIfNeeded(String pkg, int userId) {
1078         // Don't clobber the user if permission set in current state explicitly
1079         if (!isPermissionUserUpdated(Manifest.permission.ACCESS_COARSE_LOCATION, pkg, userId)) {
1080             try {
1081                 mContext.getPackageManager().grantRuntimePermission(pkg,
1082                         Manifest.permission.ACCESS_COARSE_LOCATION, new UserHandle(userId));
1083             } catch (IllegalArgumentException e) {
1084                 // Package was removed during update.
1085                 Slog.w(TAG, "Could not grant coarse location permission, package " + pkg
1086                     + " was removed.");
1087             }
1088         }
1089     }
1090 
revokeCoarseLocationPermissionIfNeeded(String pkg, int userId)1091     private void revokeCoarseLocationPermissionIfNeeded(String pkg, int userId) {
1092         // Don't clobber the user if permission set in current state explicitly
1093         if (!isPermissionUserUpdated(Manifest.permission.ACCESS_COARSE_LOCATION, pkg, userId)) {
1094             try {
1095                 mContext.getPackageManager().revokeRuntimePermission(pkg,
1096                         Manifest.permission.ACCESS_COARSE_LOCATION, new UserHandle(userId));
1097             } catch (IllegalArgumentException e) {
1098                 // Package was removed during update.
1099                 Slog.w(TAG, "Could not revoke coarse location permission, package " + pkg
1100                     + " was removed.");
1101             }
1102         }
1103     }
1104 
isPermissionUserUpdated(String permission, String pkg, int userId)1105     private boolean isPermissionUserUpdated(String permission, String pkg, int userId) {
1106         final int flags = mContext.getPackageManager().getPermissionFlags(
1107                 permission, pkg, new UserHandle(userId));
1108         return (flags & (PackageManager.FLAG_PERMISSION_USER_SET
1109                 | PackageManager.FLAG_PERMISSION_USER_FIXED)) != 0;
1110     }
1111 
getNotificationListeners(ContentResolver resolver, int userId)1112     private ArraySet<String> getNotificationListeners(ContentResolver resolver, int userId) {
1113         String flat = Settings.Secure.getStringForUser(resolver,
1114                 Settings.Secure.ENABLED_NOTIFICATION_LISTENERS, userId);
1115 
1116         ArraySet<String> current = new ArraySet<>();
1117         if (flat != null) {
1118             String[] allowed = flat.split(":");
1119             for (String s : allowed) {
1120                 if (!TextUtils.isEmpty(s)) {
1121                     current.add(s);
1122                 }
1123             }
1124         }
1125         return current;
1126     }
1127 
formatSettings(Collection<String> c)1128     private static String formatSettings(Collection<String> c) {
1129         if (c == null || c.isEmpty()) {
1130             return "";
1131         }
1132 
1133         StringBuilder b = new StringBuilder();
1134         boolean start = true;
1135         for (String s : c) {
1136             if ("".equals(s)) {
1137                 continue;
1138             }
1139             if (!start) {
1140                 b.append(':');
1141             }
1142             b.append(s);
1143             start = false;
1144         }
1145         return b.toString();
1146     }
1147 
1148 
1149 
createAndConnectService(@onNull ComponentName component, int userId)1150     private void createAndConnectService(@NonNull ComponentName component, int userId) {
1151         mCurrentVrService = createVrListenerService(component, userId);
1152         mCurrentVrService.connect();
1153         Slog.i(TAG, "Connecting " + component + " for user " + userId);
1154     }
1155 
1156     /**
1157      * Send VR mode change callbacks to HAL and system services if mode has actually changed.
1158      * <p/>
1159      * Note: Must be called while holding {@code mLock}.
1160      *
1161      * @param enabled new state of the VR mode.
1162      */
changeVrModeLocked(boolean enabled)1163     private void changeVrModeLocked(boolean enabled) {
1164         if (mVrModeEnabled != enabled) {
1165             mVrModeEnabled = enabled;
1166 
1167             // Log mode change event.
1168             Slog.i(TAG, "VR mode " + ((mVrModeEnabled) ? "enabled" : "disabled"));
1169             setVrModeNative(mVrModeEnabled);
1170 
1171             onVrModeChangedLocked();
1172         }
1173     }
1174 
1175     /**
1176      * Notify system services of VR mode change.
1177      * <p/>
1178      * Note: Must be called while holding {@code mLock}.
1179      */
onVrModeChangedLocked()1180     private void onVrModeChangedLocked() {
1181         mHandler.sendMessage(mHandler.obtainMessage(MSG_VR_STATE_CHANGE,
1182                 (mVrModeEnabled) ? 1 : 0, 0));
1183     }
1184 
1185     /**
1186      * Helper function for making ManagedApplicationService for VrListenerService instances.
1187      */
createVrListenerService(@onNull ComponentName component, int userId)1188     private ManagedApplicationService createVrListenerService(@NonNull ComponentName component,
1189             int userId) {
1190         int retryType = (mBootsToVr) ? ManagedApplicationService.RETRY_FOREVER
1191                 : ManagedApplicationService.RETRY_NEVER;
1192         return ManagedApplicationService.build(mContext, component, userId,
1193                 R.string.vr_listener_binding_label, Settings.ACTION_VR_LISTENER_SETTINGS,
1194                 sBinderChecker, /*isImportant*/true, retryType, mHandler, mEventCallback);
1195     }
1196 
1197     /**
1198      * Helper function for making ManagedApplicationService for VR Compositor instances.
1199      */
createVrCompositorService(@onNull ComponentName component, int userId)1200     private ManagedApplicationService createVrCompositorService(@NonNull ComponentName component,
1201             int userId) {
1202         int retryType = (mBootsToVr) ? ManagedApplicationService.RETRY_FOREVER
1203                 : ManagedApplicationService.RETRY_BEST_EFFORT;
1204         return ManagedApplicationService.build(mContext, component, userId, /*clientLabel*/0,
1205                 /*settingsAction*/null, /*binderChecker*/null, /*isImportant*/true, retryType,
1206                 mHandler, /*disconnectCallback*/mEventCallback);
1207     }
1208 
1209     /**
1210      * Apply the pending VR state. If no state is pending, disconnect any currently bound
1211      * VR listener service.
1212      */
consumeAndApplyPendingStateLocked()1213     private void consumeAndApplyPendingStateLocked() {
1214         consumeAndApplyPendingStateLocked(true);
1215     }
1216 
1217     /**
1218      * Apply the pending VR state.
1219      *
1220      * @param disconnectIfNoPendingState if {@code true}, then any currently bound VR listener
1221      *     service will be disconnected if no state is pending. If this is {@code false} then the
1222      *     nothing will be changed when there is no pending state.
1223      */
consumeAndApplyPendingStateLocked(boolean disconnectIfNoPendingState)1224     private void consumeAndApplyPendingStateLocked(boolean disconnectIfNoPendingState) {
1225         if (mPendingState != null) {
1226             updateCurrentVrServiceLocked(mPendingState.enabled, mPendingState.running2dInVr,
1227                     mPendingState.targetPackageName, mPendingState.userId, mPendingState.processId,
1228                     mPendingState.callingPackage);
1229             mPendingState = null;
1230         } else if (disconnectIfNoPendingState) {
1231             updateCurrentVrServiceLocked(false, false, null, 0, -1, null);
1232         }
1233     }
1234 
logStateLocked()1235     private void logStateLocked() {
1236         ComponentName currentBoundService = (mCurrentVrService == null) ? null :
1237                 mCurrentVrService.getComponent();
1238         logEvent(new VrState(mVrModeEnabled, mRunning2dInVr, currentBoundService,
1239                 mCurrentVrModeUser, mVrAppProcessId, mCurrentVrModeComponent, mWasDefaultGranted));
1240     }
1241 
logEvent(LogFormattable event)1242     private void logEvent(LogFormattable event) {
1243         synchronized (mLoggingDeque) {
1244             if (mLoggingDeque.size() == EVENT_LOG_SIZE) {
1245                 mLoggingDeque.removeFirst();
1246                 mLogLimitHit = true;
1247             }
1248             mLoggingDeque.add(event);
1249         }
1250     }
1251 
dumpStateTransitions(PrintWriter pw)1252     private void dumpStateTransitions(PrintWriter pw) {
1253         SimpleDateFormat d = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
1254         synchronized (mLoggingDeque) {
1255             if (mLoggingDeque.size() == 0) {
1256                 pw.print("  ");
1257                 pw.println("None");
1258             }
1259 
1260             if (mLogLimitHit) {
1261                 pw.println("..."); // Indicates log overflow
1262             }
1263 
1264             for (LogFormattable event : mLoggingDeque) {
1265                 pw.println(event.toLogString(d));
1266             }
1267         }
1268     }
1269 
1270     /*
1271      * Implementation of VrManagerInternal calls.  These are callable from system services.
1272      */
setVrMode(boolean enabled, @NonNull ComponentName targetPackageName, int userId, int processId, @NonNull ComponentName callingPackage)1273     private void setVrMode(boolean enabled, @NonNull ComponentName targetPackageName,
1274             int userId, int processId, @NonNull ComponentName callingPackage) {
1275 
1276         synchronized (mLock) {
1277             VrState pending;
1278             ComponentName targetListener;
1279 
1280             // If the device is in persistent VR mode, then calls to disable VR mode are ignored,
1281             // and the system default VR listener is used.
1282             boolean targetEnabledState = enabled || mPersistentVrModeEnabled;
1283             boolean running2dInVr = !enabled && mPersistentVrModeEnabled;
1284             if (running2dInVr) {
1285                 targetListener = mDefaultVrService;
1286             } else {
1287                 targetListener = targetPackageName;
1288             }
1289 
1290             pending = new VrState(targetEnabledState, running2dInVr, targetListener,
1291                     userId, processId, callingPackage);
1292 
1293             if (!mVrModeAllowed) {
1294                 // We're not allowed to be in VR mode.  Make this state pending.  This will be
1295                 // applied the next time we are allowed to enter VR mode unless it is superseded by
1296                 // another call.
1297                 mPendingState = pending;
1298                 return;
1299             }
1300 
1301             if (!targetEnabledState && mCurrentVrService != null) {
1302                 // If we're transitioning out of VR mode, delay briefly to avoid expensive HAL calls
1303                 // and service bind/unbind in case we are immediately switching to another VR app.
1304                 if (mPendingState == null) {
1305                     mHandler.sendEmptyMessageDelayed(MSG_PENDING_VR_STATE_CHANGE,
1306                             PENDING_STATE_DELAY_MS);
1307                 }
1308 
1309                 mPendingState = pending;
1310                 return;
1311             } else {
1312                 mHandler.removeMessages(MSG_PENDING_VR_STATE_CHANGE);
1313                 mPendingState = null;
1314             }
1315 
1316             updateCurrentVrServiceLocked(targetEnabledState, running2dInVr, targetListener,
1317                     userId, processId, callingPackage);
1318         }
1319     }
1320 
setPersistentVrModeEnabled(boolean enabled)1321     private void setPersistentVrModeEnabled(boolean enabled) {
1322         synchronized(mLock) {
1323             setPersistentModeAndNotifyListenersLocked(enabled);
1324             // Disabling persistent mode should disable the overall vr mode.
1325             if (!enabled) {
1326                 setVrMode(false, null, 0, -1, null);
1327             }
1328         }
1329     }
1330 
setVr2dDisplayProperties( Vr2dDisplayProperties compatDisplayProp)1331     public void setVr2dDisplayProperties(
1332         Vr2dDisplayProperties compatDisplayProp) {
1333         final long token = Binder.clearCallingIdentity();
1334         try {
1335             if (mVr2dDisplay != null) {
1336                 mVr2dDisplay.setVirtualDisplayProperties(compatDisplayProp);
1337                 return;
1338             }
1339         } finally {
1340             Binder.restoreCallingIdentity(token);
1341         }
1342         Slog.w(TAG, "Vr2dDisplay is null!");
1343     }
1344 
getVr2dDisplayId()1345     private int getVr2dDisplayId() {
1346         if (mVr2dDisplay != null) {
1347             return mVr2dDisplay.getVirtualDisplayId();
1348         }
1349         Slog.w(TAG, "Vr2dDisplay is null!");
1350         return INVALID_DISPLAY;
1351     }
1352 
setAndBindCompositor(ComponentName componentName)1353     private void setAndBindCompositor(ComponentName componentName) {
1354         final int userId = UserHandle.getCallingUserId();
1355         final long token = Binder.clearCallingIdentity();
1356         try {
1357             synchronized (mLock) {
1358                 updateCompositorServiceLocked(userId, componentName);
1359             }
1360         } finally {
1361             Binder.restoreCallingIdentity(token);
1362         }
1363     }
1364 
updateCompositorServiceLocked(int userId, ComponentName componentName)1365     private void updateCompositorServiceLocked(int userId, ComponentName componentName) {
1366         if (mCurrentVrCompositorService != null
1367                 && mCurrentVrCompositorService.disconnectIfNotMatching(componentName, userId)) {
1368             Slog.i(TAG, "Disconnecting compositor service: "
1369                     + mCurrentVrCompositorService.getComponent());
1370             // Check if existing service matches the requested one, if not (or if the requested
1371             // component is null) disconnect it.
1372             mCurrentVrCompositorService = null;
1373         }
1374 
1375         if (componentName != null && mCurrentVrCompositorService == null) {
1376             // We don't have an existing service matching the requested component, so attempt to
1377             // connect one.
1378             Slog.i(TAG, "Connecting compositor service: " + componentName);
1379             mCurrentVrCompositorService = createVrCompositorService(componentName, userId);
1380             mCurrentVrCompositorService.connect();
1381         }
1382     }
1383 
setPersistentModeAndNotifyListenersLocked(boolean enabled)1384     private void setPersistentModeAndNotifyListenersLocked(boolean enabled) {
1385         if (mPersistentVrModeEnabled == enabled) {
1386             return;
1387         }
1388         String eventName = "Persistent VR mode " + ((enabled) ? "enabled" : "disabled");
1389         Slog.i(TAG, eventName);
1390         logEvent(new SettingEvent(eventName));
1391         mPersistentVrModeEnabled = enabled;
1392 
1393         mHandler.sendMessage(mHandler.obtainMessage(MSG_PERSISTENT_VR_MODE_STATE_CHANGE,
1394                 (mPersistentVrModeEnabled) ? 1 : 0, 0));
1395     }
1396 
hasVrPackage(@onNull ComponentName targetPackageName, int userId)1397     private int hasVrPackage(@NonNull ComponentName targetPackageName, int userId) {
1398         synchronized (mLock) {
1399             return mComponentObserver.isValid(targetPackageName, userId);
1400         }
1401     }
1402 
isCurrentVrListener(String packageName, int userId)1403     private boolean isCurrentVrListener(String packageName, int userId) {
1404         synchronized (mLock) {
1405             if (mCurrentVrService == null) {
1406                 return false;
1407             }
1408             return mCurrentVrService.getComponent().getPackageName().equals(packageName) &&
1409                     userId == mCurrentVrService.getUserId();
1410         }
1411     }
1412 
1413     /*
1414      * Implementation of IVrManager calls.
1415      */
1416 
addStateCallback(IVrStateCallbacks cb)1417     private void addStateCallback(IVrStateCallbacks cb) {
1418         mVrStateRemoteCallbacks.register(cb);
1419     }
1420 
removeStateCallback(IVrStateCallbacks cb)1421     private void removeStateCallback(IVrStateCallbacks cb) {
1422         mVrStateRemoteCallbacks.unregister(cb);
1423     }
1424 
addPersistentStateCallback(IPersistentVrStateCallbacks cb)1425     private void addPersistentStateCallback(IPersistentVrStateCallbacks cb) {
1426         mPersistentVrStateRemoteCallbacks.register(cb);
1427     }
1428 
removePersistentStateCallback(IPersistentVrStateCallbacks cb)1429     private void removePersistentStateCallback(IPersistentVrStateCallbacks cb) {
1430         mPersistentVrStateRemoteCallbacks.unregister(cb);
1431     }
1432 
getVrMode()1433     private boolean getVrMode() {
1434         synchronized (mLock) {
1435             return mVrModeEnabled;
1436         }
1437     }
1438 
getPersistentVrMode()1439     private boolean getPersistentVrMode() {
1440         synchronized (mLock) {
1441             return mPersistentVrModeEnabled;
1442         }
1443     }
1444 }
1445