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