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.ManagedApplicationService;
71 import com.android.server.utils.ManagedApplicationService.BinderChecker;
72 import com.android.server.utils.ManagedApplicationService.LogEvent;
73 import com.android.server.utils.ManagedApplicationService.LogFormattable;
74 import com.android.server.utils.ManagedApplicationService.PendingEvent;
75 import com.android.server.vr.EnabledComponentsObserver.EnabledComponentChangeListener;
76 import com.android.server.wm.ActivityTaskManagerInternal;
77 import com.android.server.wm.ActivityTaskManagerInternal.ScreenObserver;
78 import com.android.server.wm.WindowManagerInternal;
79 
80 import java.io.FileDescriptor;
81 import java.io.PrintWriter;
82 import java.text.SimpleDateFormat;
83 import java.util.ArrayDeque;
84 import java.util.ArrayList;
85 import java.util.Arrays;
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         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
628             if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
629 
630             pw.println("********* Dump of VrManagerService *********");
631             pw.println("VR mode is currently: " + ((mVrModeAllowed) ? "allowed" : "disallowed"));
632             pw.println("Persistent VR mode is currently: " +
633                     ((mPersistentVrModeEnabled) ? "enabled" : "disabled"));
634             pw.println("Currently bound VR listener service: "
635                     + ((mCurrentVrService == null)
636                     ? "None" : mCurrentVrService.getComponent().flattenToString()));
637             pw.println("Currently bound VR compositor service: "
638                     + ((mCurrentVrCompositorService == null)
639                     ? "None" : mCurrentVrCompositorService.getComponent().flattenToString()));
640             pw.println("Previous state transitions:\n");
641             String tab = "  ";
642             dumpStateTransitions(pw);
643             pw.println("\n\nRemote Callbacks:");
644             int i=mVrStateRemoteCallbacks.beginBroadcast(); // create the broadcast item array
645             while(i-->0) {
646                 pw.print(tab);
647                 pw.print(mVrStateRemoteCallbacks.getBroadcastItem(i));
648                 if (i>0) pw.println(",");
649             }
650             mVrStateRemoteCallbacks.finishBroadcast();
651             pw.println("\n\nPersistent Vr State Remote Callbacks:");
652             i=mPersistentVrStateRemoteCallbacks.beginBroadcast();
653             while(i-->0) {
654                 pw.print(tab);
655                 pw.print(mPersistentVrStateRemoteCallbacks.getBroadcastItem(i));
656                 if (i>0) pw.println(",");
657             }
658             mPersistentVrStateRemoteCallbacks.finishBroadcast();
659             pw.println("\n");
660             pw.println("Installed VrListenerService components:");
661             int userId = mCurrentVrModeUser;
662             ArraySet<ComponentName> installed = mComponentObserver.getInstalled(userId);
663             if (installed == null || installed.size() == 0) {
664                 pw.println("None");
665             } else {
666                 for (ComponentName n : installed) {
667                     pw.print(tab);
668                     pw.println(n.flattenToString());
669                 }
670             }
671             pw.println("Enabled VrListenerService components:");
672             ArraySet<ComponentName> enabled = mComponentObserver.getEnabled(userId);
673             if (enabled == null || enabled.size() == 0) {
674                 pw.println("None");
675             } else {
676                 for (ComponentName n : enabled) {
677                     pw.print(tab);
678                     pw.println(n.flattenToString());
679                 }
680             }
681             pw.println("\n");
682             pw.println("********* End of VrManagerService Dump *********");
683         }
684 
685     };
686 
687     /**
688      * Enforces that at lease one of the specified permissions is held by the caller.
689      * Throws SecurityException if none of the specified permissions are held.
690      *
691      * @param permissions One or more permissions to check against.
692      */
enforceCallerPermissionAnyOf(String... permissions)693     private void enforceCallerPermissionAnyOf(String... permissions) {
694         for (String permission : permissions) {
695             if (mContext.checkCallingOrSelfPermission(permission)
696                     == PackageManager.PERMISSION_GRANTED) {
697                 return;
698             }
699         }
700         throw new SecurityException("Caller does not hold at least one of the permissions: "
701                 + Arrays.toString(permissions));
702     }
703 
704     /**
705      * Implementation of VrManagerInternal.  Callable only from system services.
706      */
707     private final class LocalService extends VrManagerInternal {
708         @Override
setVrMode(boolean enabled, ComponentName packageName, int userId, int processId, ComponentName callingPackage)709         public void setVrMode(boolean enabled, ComponentName packageName, int userId, int processId,
710                 ComponentName callingPackage) {
711             VrManagerService.this.setVrMode(enabled, packageName, userId, processId, callingPackage);
712         }
713 
714         @Override
onScreenStateChanged(boolean isScreenOn)715         public void onScreenStateChanged(boolean isScreenOn) {
716             VrManagerService.this.setScreenOn(isScreenOn);
717         }
718 
719         @Override
isCurrentVrListener(String packageName, int userId)720         public boolean isCurrentVrListener(String packageName, int userId) {
721             return VrManagerService.this.isCurrentVrListener(packageName, userId);
722         }
723 
724         @Override
hasVrPackage(ComponentName packageName, int userId)725         public int hasVrPackage(ComponentName packageName, int userId) {
726             return VrManagerService.this.hasVrPackage(packageName, userId);
727         }
728 
729         @Override
setPersistentVrModeEnabled(boolean enabled)730         public void setPersistentVrModeEnabled(boolean enabled) {
731             VrManagerService.this.setPersistentVrModeEnabled(enabled);
732         }
733 
734         @Override
setVr2dDisplayProperties( Vr2dDisplayProperties compatDisplayProp)735         public void setVr2dDisplayProperties(
736             Vr2dDisplayProperties compatDisplayProp) {
737             VrManagerService.this.setVr2dDisplayProperties(compatDisplayProp);
738         }
739 
740         @Override
getVr2dDisplayId()741         public int getVr2dDisplayId() {
742             return VrManagerService.this.getVr2dDisplayId();
743         }
744 
745         @Override
addPersistentVrModeStateListener(IPersistentVrStateCallbacks listener)746         public void addPersistentVrModeStateListener(IPersistentVrStateCallbacks listener) {
747             VrManagerService.this.addPersistentStateCallback(listener);
748         }
749     }
750 
VrManagerService(Context context)751     public VrManagerService(Context context) {
752         super(context);
753     }
754 
755     @Override
onStart()756     public void onStart() {
757         synchronized(mLock) {
758             initializeNative();
759             mContext = getContext();
760         }
761 
762         mBootsToVr = SystemProperties.getBoolean("ro.boot.vr", false);
763         mUseStandbyToExitVrMode = mBootsToVr
764                 && SystemProperties.getBoolean("persist.vr.use_standby_to_exit_vr_mode", true);
765         publishLocalService(VrManagerInternal.class, new LocalService());
766         publishBinderService(Context.VR_SERVICE, mVrManager.asBinder());
767     }
768 
769     @Override
onBootPhase(int phase)770     public void onBootPhase(int phase) {
771         if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
772             LocalServices.getService(ActivityTaskManagerInternal.class)
773                     .registerScreenObserver(this);
774 
775             mNotificationManager = INotificationManager.Stub.asInterface(
776                     ServiceManager.getService(Context.NOTIFICATION_SERVICE));
777             synchronized (mLock) {
778                 Looper looper = Looper.getMainLooper();
779                 Handler handler = new Handler(looper);
780                 ArrayList<EnabledComponentChangeListener> listeners = new ArrayList<>();
781                 listeners.add(this);
782                 mComponentObserver = EnabledComponentsObserver.build(mContext, handler,
783                         Settings.Secure.ENABLED_VR_LISTENERS, looper,
784                         android.Manifest.permission.BIND_VR_LISTENER_SERVICE,
785                         VrListenerService.SERVICE_INTERFACE, mLock, listeners);
786 
787                 mComponentObserver.rebuildAll();
788             }
789 
790             //TODO: something more robust than picking the first one
791             ArraySet<ComponentName> defaultVrComponents =
792                     SystemConfig.getInstance().getDefaultVrComponents();
793             if (defaultVrComponents.size() > 0) {
794                 mDefaultVrService = defaultVrComponents.valueAt(0);
795             } else {
796                 Slog.i(TAG, "No default vr listener service found.");
797             }
798 
799             DisplayManager dm =
800                     (DisplayManager) getContext().getSystemService(Context.DISPLAY_SERVICE);
801             mVr2dDisplay = new Vr2dDisplay(
802                     dm,
803                     LocalServices.getService(ActivityManagerInternal.class),
804                     LocalServices.getService(WindowManagerInternal.class),
805                     mVrManager);
806             mVr2dDisplay.init(getContext(), mBootsToVr);
807 
808             IntentFilter intentFilter = new IntentFilter();
809             intentFilter.addAction(Intent.ACTION_USER_UNLOCKED);
810             getContext().registerReceiver(new BroadcastReceiver() {
811                     @Override
812                     public void onReceive(Context context, Intent intent) {
813                         if (Intent.ACTION_USER_UNLOCKED.equals(intent.getAction())) {
814                             VrManagerService.this.setUserUnlocked();
815                         }
816                     }
817                 }, intentFilter);
818         }
819     }
820 
821     @Override
onUserStarting(@onNull TargetUser user)822     public void onUserStarting(@NonNull TargetUser user) {
823         synchronized (mLock) {
824             mComponentObserver.onUsersChanged();
825         }
826     }
827 
828     @Override
onUserSwitching(@ullable TargetUser from, @NonNull TargetUser to)829     public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
830         FgThread.getHandler().post(() -> {
831             synchronized (mLock) {
832                 mComponentObserver.onUsersChanged();
833             }
834         });
835 
836     }
837 
838     @Override
onUserStopping(@onNull TargetUser user)839     public void onUserStopping(@NonNull TargetUser user) {
840         synchronized (mLock) {
841             mComponentObserver.onUsersChanged();
842         }
843 
844     }
845 
846     @Override
onUserStopped(@onNull TargetUser user)847     public void onUserStopped(@NonNull TargetUser user) {
848         synchronized (mLock) {
849             mComponentObserver.onUsersChanged();
850         }
851     }
852 
updateOverlayStateLocked(String exemptedPackage, int newUserId, int oldUserId)853     private void updateOverlayStateLocked(String exemptedPackage, int newUserId, int oldUserId) {
854         AppOpsManager appOpsManager = getContext().getSystemService(AppOpsManager.class);
855 
856         // If user changed drop restrictions for the old user.
857         if (oldUserId != newUserId) {
858             appOpsManager.setUserRestrictionForUser(AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
859                     false, mOverlayToken, null, oldUserId);
860         }
861 
862         // Apply the restrictions for the current user based on vr state
863         PackageTagsList exemptions = null;
864         if (exemptedPackage != null) {
865             exemptions = new PackageTagsList.Builder(1).add(exemptedPackage).build();
866         }
867 
868         appOpsManager.setUserRestrictionForUser(AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
869                 mVrModeEnabled, mOverlayToken, exemptions, newUserId);
870     }
871 
updateDependentAppOpsLocked(String newVrServicePackage, int newUserId, String oldVrServicePackage, int oldUserId)872     private void updateDependentAppOpsLocked(String newVrServicePackage, int newUserId,
873             String oldVrServicePackage, int oldUserId) {
874         // If VR state changed and we also have a VR service change.
875         if (Objects.equals(newVrServicePackage, oldVrServicePackage)) {
876             return;
877         }
878         final long identity = Binder.clearCallingIdentity();
879         try {
880             // Set overlay exception state based on VR enabled and current service
881             updateOverlayStateLocked(newVrServicePackage, newUserId, oldUserId);
882         } finally {
883             Binder.restoreCallingIdentity(identity);
884         }
885     }
886 
887     /**
888      * Send VR mode changes (if the mode state has changed), and update the bound/unbound state of
889      * the currently selected VR listener service.  If the component selected for the VR listener
890      * service has changed, unbind the previous listener and bind the new listener (if enabled).
891      * <p/>
892      * Note: Must be called while holding {@code mLock}.
893      *
894      * @param enabled new state for VR mode.
895      * @param running2dInVr true if we have a top-level 2D intent.
896      * @param component new component to be bound as a VR listener.
897      * @param userId user owning the component to be bound.
898      * @param processId the process hosting the activity specified by calling.
899      * @param calling the component currently using VR mode or a 2D intent.
900      *
901      * @return {@code true} if the component/user combination specified is valid.
902      */
updateCurrentVrServiceLocked(boolean enabled, boolean running2dInVr, @NonNull ComponentName component, int userId, int processId, ComponentName calling)903     private boolean updateCurrentVrServiceLocked(boolean enabled, boolean running2dInVr,
904             @NonNull ComponentName component, int userId, int processId, ComponentName calling) {
905 
906         boolean sendUpdatedCaller = false;
907         final long identity = Binder.clearCallingIdentity();
908         try {
909 
910             boolean validUserComponent = (mComponentObserver.isValid(component, userId) ==
911                     EnabledComponentsObserver.NO_ERROR);
912             boolean goingIntoVrMode = validUserComponent && enabled;
913             if (!mVrModeEnabled && !goingIntoVrMode) {
914                 return validUserComponent; // Disabled -> Disabled transition does nothing.
915             }
916 
917             String oldVrServicePackage = mCurrentVrService != null
918                     ? mCurrentVrService.getComponent().getPackageName() : null;
919             final int oldUserId = mCurrentVrModeUser;
920 
921             // Notify system services and VR HAL of mode change.
922             changeVrModeLocked(goingIntoVrMode);
923 
924             boolean nothingChanged = false;
925             if (!goingIntoVrMode) {
926                 // Not going into VR mode, unbind whatever is running
927                 if (mCurrentVrService != null) {
928                     Slog.i(TAG, "Leaving VR mode, disconnecting "
929                         + mCurrentVrService.getComponent() + " for user "
930                         + mCurrentVrService.getUserId());
931                     mCurrentVrService.disconnect();
932                     updateCompositorServiceLocked(UserHandle.USER_NULL, null);
933                     mCurrentVrService = null;
934                 } else {
935                     nothingChanged = true;
936                 }
937             } else {
938                 // Going into VR mode
939                 if (mCurrentVrService != null) {
940                     // Unbind any running service that doesn't match the latest component/user
941                     // selection.
942                     if (mCurrentVrService.disconnectIfNotMatching(component, userId)) {
943                         Slog.i(TAG, "VR mode component changed to " + component
944                             + ", disconnecting " + mCurrentVrService.getComponent()
945                             + " for user " + mCurrentVrService.getUserId());
946                         updateCompositorServiceLocked(UserHandle.USER_NULL, null);
947                         createAndConnectService(component, userId);
948                         sendUpdatedCaller = true;
949                     } else {
950                         nothingChanged = true;
951                     }
952                     // The service with the correct component/user is already bound, do nothing.
953                 } else {
954                     // Nothing was previously running, bind a new service for the latest
955                     // component/user selection.
956                     createAndConnectService(component, userId);
957                     sendUpdatedCaller = true;
958                 }
959             }
960 
961             if ((calling != null || mPersistentVrModeEnabled)
962                     && !Objects.equals(calling, mCurrentVrModeComponent)
963                     || mRunning2dInVr != running2dInVr) {
964                 sendUpdatedCaller = true;
965             }
966             mCurrentVrModeComponent = calling;
967             mRunning2dInVr = running2dInVr;
968             mVrAppProcessId = processId;
969 
970             if (mCurrentVrModeUser != userId) {
971                 mCurrentVrModeUser = userId;
972                 sendUpdatedCaller = true;
973             }
974 
975             String newVrServicePackage = mCurrentVrService != null
976                     ? mCurrentVrService.getComponent().getPackageName() : null;
977             final int newUserId = mCurrentVrModeUser;
978 
979             // Update AppOps settings that change state when entering/exiting VR mode, or changing
980             // the current VrListenerService.
981             updateDependentAppOpsLocked(newVrServicePackage, newUserId,
982                     oldVrServicePackage, oldUserId);
983 
984             if (mCurrentVrService != null && sendUpdatedCaller) {
985                 callFocusedActivityChangedLocked();
986             }
987 
988             if (!nothingChanged) {
989                 logStateLocked();
990             }
991 
992             return validUserComponent;
993         } finally {
994             Binder.restoreCallingIdentity(identity);
995         }
996     }
997 
callFocusedActivityChangedLocked()998     private void callFocusedActivityChangedLocked() {
999         final ComponentName c = mCurrentVrModeComponent;
1000         final boolean b = mRunning2dInVr;
1001         final int pid = mVrAppProcessId;
1002         mCurrentVrService.sendEvent(new PendingEvent() {
1003             @Override
1004             public void runEvent(IInterface service) throws RemoteException {
1005                 // Under specific (and unlikely) timing scenarios, when VrCore
1006                 // crashes and is rebound, focusedActivityChanged() may be
1007                 // called a 2nd time with the same arguments. IVrListeners
1008                 // should make sure to handle that scenario gracefully.
1009                 IVrListener l = (IVrListener) service;
1010                 l.focusedActivityChanged(c, b, pid);
1011             }
1012         });
1013     }
1014 
isDefaultAllowed(String packageName)1015     private boolean isDefaultAllowed(String packageName) {
1016         PackageManager pm = mContext.getPackageManager();
1017 
1018         ApplicationInfo info = null;
1019         try {
1020             info = pm.getApplicationInfo(packageName, PackageManager.GET_META_DATA);
1021         } catch (NameNotFoundException e) {
1022         }
1023 
1024         if (info == null || !(info.isSystemApp() || info.isUpdatedSystemApp())) {
1025             return false;
1026         }
1027         return true;
1028     }
1029 
grantNotificationPolicyAccess(String pkg)1030     private void grantNotificationPolicyAccess(String pkg) {
1031         NotificationManager nm = mContext.getSystemService(NotificationManager.class);
1032         nm.setNotificationPolicyAccessGranted(pkg, true);
1033     }
1034 
revokeNotificationPolicyAccess(String pkg)1035     private void revokeNotificationPolicyAccess(String pkg) {
1036         NotificationManager nm = mContext.getSystemService(NotificationManager.class);
1037         // Remove any DND zen rules possibly created by the package.
1038         nm.removeAutomaticZenRules(pkg);
1039         // Remove Notification Policy Access.
1040         nm.setNotificationPolicyAccessGranted(pkg, false);
1041     }
1042 
grantNotificationListenerAccess(String pkg, int userId)1043     private void grantNotificationListenerAccess(String pkg, int userId) {
1044         NotificationManager nm = mContext.getSystemService(NotificationManager.class);
1045         PackageManager pm = mContext.getPackageManager();
1046         ArraySet<ComponentName> possibleServices = EnabledComponentsObserver.loadComponentNames(pm,
1047                 userId, NotificationListenerService.SERVICE_INTERFACE,
1048                 android.Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE);
1049 
1050         for (ComponentName c : possibleServices) {
1051             if (Objects.equals(c.getPackageName(), pkg)) {
1052                 try {
1053                     nm.setNotificationListenerAccessGrantedForUser(c, userId, true);
1054                 } catch (Exception e) {
1055                     Slog.w(TAG, "Could not grant NLS access to package " + pkg, e);
1056                 }
1057             }
1058         }
1059     }
1060 
revokeNotificationListenerAccess(String pkg, int userId)1061     private void revokeNotificationListenerAccess(String pkg, int userId) {
1062         NotificationManager nm = mContext.getSystemService(NotificationManager.class);
1063         List<ComponentName> current = nm.getEnabledNotificationListeners(userId);
1064 
1065         for (ComponentName component : current) {
1066             if (component != null && component.getPackageName().equals(pkg)) {
1067                 nm.setNotificationListenerAccessGrantedForUser(component, userId, false);
1068             }
1069         }
1070     }
1071 
grantCoarseLocationPermissionIfNeeded(String pkg, int userId)1072     private void grantCoarseLocationPermissionIfNeeded(String pkg, int userId) {
1073         // Don't clobber the user if permission set in current state explicitly
1074         if (!isPermissionUserUpdated(Manifest.permission.ACCESS_COARSE_LOCATION, pkg, userId)) {
1075             try {
1076                 mContext.getPackageManager().grantRuntimePermission(pkg,
1077                         Manifest.permission.ACCESS_COARSE_LOCATION, new UserHandle(userId));
1078             } catch (IllegalArgumentException e) {
1079                 // Package was removed during update.
1080                 Slog.w(TAG, "Could not grant coarse location permission, package " + pkg
1081                     + " was removed.");
1082             }
1083         }
1084     }
1085 
revokeCoarseLocationPermissionIfNeeded(String pkg, int userId)1086     private void revokeCoarseLocationPermissionIfNeeded(String pkg, int userId) {
1087         // Don't clobber the user if permission set in current state explicitly
1088         if (!isPermissionUserUpdated(Manifest.permission.ACCESS_COARSE_LOCATION, pkg, userId)) {
1089             try {
1090                 mContext.getPackageManager().revokeRuntimePermission(pkg,
1091                         Manifest.permission.ACCESS_COARSE_LOCATION, new UserHandle(userId));
1092             } catch (IllegalArgumentException e) {
1093                 // Package was removed during update.
1094                 Slog.w(TAG, "Could not revoke coarse location permission, package " + pkg
1095                     + " was removed.");
1096             }
1097         }
1098     }
1099 
isPermissionUserUpdated(String permission, String pkg, int userId)1100     private boolean isPermissionUserUpdated(String permission, String pkg, int userId) {
1101         final int flags = mContext.getPackageManager().getPermissionFlags(
1102                 permission, pkg, new UserHandle(userId));
1103         return (flags & (PackageManager.FLAG_PERMISSION_USER_SET
1104                 | PackageManager.FLAG_PERMISSION_USER_FIXED)) != 0;
1105     }
1106 
getNotificationListeners(ContentResolver resolver, int userId)1107     private ArraySet<String> getNotificationListeners(ContentResolver resolver, int userId) {
1108         String flat = Settings.Secure.getStringForUser(resolver,
1109                 Settings.Secure.ENABLED_NOTIFICATION_LISTENERS, userId);
1110 
1111         ArraySet<String> current = new ArraySet<>();
1112         if (flat != null) {
1113             String[] allowed = flat.split(":");
1114             for (String s : allowed) {
1115                 if (!TextUtils.isEmpty(s)) {
1116                     current.add(s);
1117                 }
1118             }
1119         }
1120         return current;
1121     }
1122 
formatSettings(Collection<String> c)1123     private static String formatSettings(Collection<String> c) {
1124         if (c == null || c.isEmpty()) {
1125             return "";
1126         }
1127 
1128         StringBuilder b = new StringBuilder();
1129         boolean start = true;
1130         for (String s : c) {
1131             if ("".equals(s)) {
1132                 continue;
1133             }
1134             if (!start) {
1135                 b.append(':');
1136             }
1137             b.append(s);
1138             start = false;
1139         }
1140         return b.toString();
1141     }
1142 
1143 
1144 
createAndConnectService(@onNull ComponentName component, int userId)1145     private void createAndConnectService(@NonNull ComponentName component, int userId) {
1146         mCurrentVrService = createVrListenerService(component, userId);
1147         mCurrentVrService.connect();
1148         Slog.i(TAG, "Connecting " + component + " for user " + userId);
1149     }
1150 
1151     /**
1152      * Send VR mode change callbacks to HAL and system services if mode has actually changed.
1153      * <p/>
1154      * Note: Must be called while holding {@code mLock}.
1155      *
1156      * @param enabled new state of the VR mode.
1157      */
changeVrModeLocked(boolean enabled)1158     private void changeVrModeLocked(boolean enabled) {
1159         if (mVrModeEnabled != enabled) {
1160             mVrModeEnabled = enabled;
1161 
1162             // Log mode change event.
1163             Slog.i(TAG, "VR mode " + ((mVrModeEnabled) ? "enabled" : "disabled"));
1164             setVrModeNative(mVrModeEnabled);
1165 
1166             onVrModeChangedLocked();
1167         }
1168     }
1169 
1170     /**
1171      * Notify system services of VR mode change.
1172      * <p/>
1173      * Note: Must be called while holding {@code mLock}.
1174      */
onVrModeChangedLocked()1175     private void onVrModeChangedLocked() {
1176         mHandler.sendMessage(mHandler.obtainMessage(MSG_VR_STATE_CHANGE,
1177                 (mVrModeEnabled) ? 1 : 0, 0));
1178     }
1179 
1180     /**
1181      * Helper function for making ManagedApplicationService for VrListenerService instances.
1182      */
createVrListenerService(@onNull ComponentName component, int userId)1183     private ManagedApplicationService createVrListenerService(@NonNull ComponentName component,
1184             int userId) {
1185         int retryType = (mBootsToVr) ? ManagedApplicationService.RETRY_FOREVER
1186                 : ManagedApplicationService.RETRY_NEVER;
1187         return ManagedApplicationService.build(mContext, component, userId,
1188                 R.string.vr_listener_binding_label, Settings.ACTION_VR_LISTENER_SETTINGS,
1189                 sBinderChecker, /*isImportant*/true, retryType, mHandler, mEventCallback);
1190     }
1191 
1192     /**
1193      * Helper function for making ManagedApplicationService for VR Compositor instances.
1194      */
createVrCompositorService(@onNull ComponentName component, int userId)1195     private ManagedApplicationService createVrCompositorService(@NonNull ComponentName component,
1196             int userId) {
1197         int retryType = (mBootsToVr) ? ManagedApplicationService.RETRY_FOREVER
1198                 : ManagedApplicationService.RETRY_BEST_EFFORT;
1199         return ManagedApplicationService.build(mContext, component, userId, /*clientLabel*/0,
1200                 /*settingsAction*/null, /*binderChecker*/null, /*isImportant*/true, retryType,
1201                 mHandler, /*disconnectCallback*/mEventCallback);
1202     }
1203 
1204     /**
1205      * Apply the pending VR state. If no state is pending, disconnect any currently bound
1206      * VR listener service.
1207      */
consumeAndApplyPendingStateLocked()1208     private void consumeAndApplyPendingStateLocked() {
1209         consumeAndApplyPendingStateLocked(true);
1210     }
1211 
1212     /**
1213      * Apply the pending VR state.
1214      *
1215      * @param disconnectIfNoPendingState if {@code true}, then any currently bound VR listener
1216      *     service will be disconnected if no state is pending. If this is {@code false} then the
1217      *     nothing will be changed when there is no pending state.
1218      */
consumeAndApplyPendingStateLocked(boolean disconnectIfNoPendingState)1219     private void consumeAndApplyPendingStateLocked(boolean disconnectIfNoPendingState) {
1220         if (mPendingState != null) {
1221             updateCurrentVrServiceLocked(mPendingState.enabled, mPendingState.running2dInVr,
1222                     mPendingState.targetPackageName, mPendingState.userId, mPendingState.processId,
1223                     mPendingState.callingPackage);
1224             mPendingState = null;
1225         } else if (disconnectIfNoPendingState) {
1226             updateCurrentVrServiceLocked(false, false, null, 0, -1, null);
1227         }
1228     }
1229 
logStateLocked()1230     private void logStateLocked() {
1231         ComponentName currentBoundService = (mCurrentVrService == null) ? null :
1232                 mCurrentVrService.getComponent();
1233         logEvent(new VrState(mVrModeEnabled, mRunning2dInVr, currentBoundService,
1234                 mCurrentVrModeUser, mVrAppProcessId, mCurrentVrModeComponent, mWasDefaultGranted));
1235     }
1236 
logEvent(LogFormattable event)1237     private void logEvent(LogFormattable event) {
1238         synchronized (mLoggingDeque) {
1239             if (mLoggingDeque.size() == EVENT_LOG_SIZE) {
1240                 mLoggingDeque.removeFirst();
1241                 mLogLimitHit = true;
1242             }
1243             mLoggingDeque.add(event);
1244         }
1245     }
1246 
dumpStateTransitions(PrintWriter pw)1247     private void dumpStateTransitions(PrintWriter pw) {
1248         SimpleDateFormat d = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
1249         synchronized (mLoggingDeque) {
1250             if (mLoggingDeque.size() == 0) {
1251                 pw.print("  ");
1252                 pw.println("None");
1253             }
1254 
1255             if (mLogLimitHit) {
1256                 pw.println("..."); // Indicates log overflow
1257             }
1258 
1259             for (LogFormattable event : mLoggingDeque) {
1260                 pw.println(event.toLogString(d));
1261             }
1262         }
1263     }
1264 
1265     /*
1266      * Implementation of VrManagerInternal calls.  These are callable from system services.
1267      */
setVrMode(boolean enabled, @NonNull ComponentName targetPackageName, int userId, int processId, @NonNull ComponentName callingPackage)1268     private void setVrMode(boolean enabled, @NonNull ComponentName targetPackageName,
1269             int userId, int processId, @NonNull ComponentName callingPackage) {
1270 
1271         synchronized (mLock) {
1272             VrState pending;
1273             ComponentName targetListener;
1274 
1275             // If the device is in persistent VR mode, then calls to disable VR mode are ignored,
1276             // and the system default VR listener is used.
1277             boolean targetEnabledState = enabled || mPersistentVrModeEnabled;
1278             boolean running2dInVr = !enabled && mPersistentVrModeEnabled;
1279             if (running2dInVr) {
1280                 targetListener = mDefaultVrService;
1281             } else {
1282                 targetListener = targetPackageName;
1283             }
1284 
1285             pending = new VrState(targetEnabledState, running2dInVr, targetListener,
1286                     userId, processId, callingPackage);
1287 
1288             if (!mVrModeAllowed) {
1289                 // We're not allowed to be in VR mode.  Make this state pending.  This will be
1290                 // applied the next time we are allowed to enter VR mode unless it is superseded by
1291                 // another call.
1292                 mPendingState = pending;
1293                 return;
1294             }
1295 
1296             if (!targetEnabledState && mCurrentVrService != null) {
1297                 // If we're transitioning out of VR mode, delay briefly to avoid expensive HAL calls
1298                 // and service bind/unbind in case we are immediately switching to another VR app.
1299                 if (mPendingState == null) {
1300                     mHandler.sendEmptyMessageDelayed(MSG_PENDING_VR_STATE_CHANGE,
1301                             PENDING_STATE_DELAY_MS);
1302                 }
1303 
1304                 mPendingState = pending;
1305                 return;
1306             } else {
1307                 mHandler.removeMessages(MSG_PENDING_VR_STATE_CHANGE);
1308                 mPendingState = null;
1309             }
1310 
1311             updateCurrentVrServiceLocked(targetEnabledState, running2dInVr, targetListener,
1312                     userId, processId, callingPackage);
1313         }
1314     }
1315 
setPersistentVrModeEnabled(boolean enabled)1316     private void setPersistentVrModeEnabled(boolean enabled) {
1317         synchronized(mLock) {
1318             setPersistentModeAndNotifyListenersLocked(enabled);
1319             // Disabling persistent mode should disable the overall vr mode.
1320             if (!enabled) {
1321                 setVrMode(false, null, 0, -1, null);
1322             }
1323         }
1324     }
1325 
setVr2dDisplayProperties( Vr2dDisplayProperties compatDisplayProp)1326     public void setVr2dDisplayProperties(
1327         Vr2dDisplayProperties compatDisplayProp) {
1328         final long token = Binder.clearCallingIdentity();
1329         try {
1330             if (mVr2dDisplay != null) {
1331                 mVr2dDisplay.setVirtualDisplayProperties(compatDisplayProp);
1332                 return;
1333             }
1334         } finally {
1335             Binder.restoreCallingIdentity(token);
1336         }
1337         Slog.w(TAG, "Vr2dDisplay is null!");
1338     }
1339 
getVr2dDisplayId()1340     private int getVr2dDisplayId() {
1341         if (mVr2dDisplay != null) {
1342             return mVr2dDisplay.getVirtualDisplayId();
1343         }
1344         Slog.w(TAG, "Vr2dDisplay is null!");
1345         return INVALID_DISPLAY;
1346     }
1347 
setAndBindCompositor(ComponentName componentName)1348     private void setAndBindCompositor(ComponentName componentName) {
1349         final int userId = UserHandle.getCallingUserId();
1350         final long token = Binder.clearCallingIdentity();
1351         try {
1352             synchronized (mLock) {
1353                 updateCompositorServiceLocked(userId, componentName);
1354             }
1355         } finally {
1356             Binder.restoreCallingIdentity(token);
1357         }
1358     }
1359 
updateCompositorServiceLocked(int userId, ComponentName componentName)1360     private void updateCompositorServiceLocked(int userId, ComponentName componentName) {
1361         if (mCurrentVrCompositorService != null
1362                 && mCurrentVrCompositorService.disconnectIfNotMatching(componentName, userId)) {
1363             Slog.i(TAG, "Disconnecting compositor service: "
1364                     + mCurrentVrCompositorService.getComponent());
1365             // Check if existing service matches the requested one, if not (or if the requested
1366             // component is null) disconnect it.
1367             mCurrentVrCompositorService = null;
1368         }
1369 
1370         if (componentName != null && mCurrentVrCompositorService == null) {
1371             // We don't have an existing service matching the requested component, so attempt to
1372             // connect one.
1373             Slog.i(TAG, "Connecting compositor service: " + componentName);
1374             mCurrentVrCompositorService = createVrCompositorService(componentName, userId);
1375             mCurrentVrCompositorService.connect();
1376         }
1377     }
1378 
setPersistentModeAndNotifyListenersLocked(boolean enabled)1379     private void setPersistentModeAndNotifyListenersLocked(boolean enabled) {
1380         if (mPersistentVrModeEnabled == enabled) {
1381             return;
1382         }
1383         String eventName = "Persistent VR mode " + ((enabled) ? "enabled" : "disabled");
1384         Slog.i(TAG, eventName);
1385         logEvent(new SettingEvent(eventName));
1386         mPersistentVrModeEnabled = enabled;
1387 
1388         mHandler.sendMessage(mHandler.obtainMessage(MSG_PERSISTENT_VR_MODE_STATE_CHANGE,
1389                 (mPersistentVrModeEnabled) ? 1 : 0, 0));
1390     }
1391 
hasVrPackage(@onNull ComponentName targetPackageName, int userId)1392     private int hasVrPackage(@NonNull ComponentName targetPackageName, int userId) {
1393         synchronized (mLock) {
1394             return mComponentObserver.isValid(targetPackageName, userId);
1395         }
1396     }
1397 
isCurrentVrListener(String packageName, int userId)1398     private boolean isCurrentVrListener(String packageName, int userId) {
1399         synchronized (mLock) {
1400             if (mCurrentVrService == null) {
1401                 return false;
1402             }
1403             return mCurrentVrService.getComponent().getPackageName().equals(packageName) &&
1404                     userId == mCurrentVrService.getUserId();
1405         }
1406     }
1407 
1408     /*
1409      * Implementation of IVrManager calls.
1410      */
1411 
addStateCallback(IVrStateCallbacks cb)1412     private void addStateCallback(IVrStateCallbacks cb) {
1413         mVrStateRemoteCallbacks.register(cb);
1414     }
1415 
removeStateCallback(IVrStateCallbacks cb)1416     private void removeStateCallback(IVrStateCallbacks cb) {
1417         mVrStateRemoteCallbacks.unregister(cb);
1418     }
1419 
addPersistentStateCallback(IPersistentVrStateCallbacks cb)1420     private void addPersistentStateCallback(IPersistentVrStateCallbacks cb) {
1421         mPersistentVrStateRemoteCallbacks.register(cb);
1422     }
1423 
removePersistentStateCallback(IPersistentVrStateCallbacks cb)1424     private void removePersistentStateCallback(IPersistentVrStateCallbacks cb) {
1425         mPersistentVrStateRemoteCallbacks.unregister(cb);
1426     }
1427 
getVrMode()1428     private boolean getVrMode() {
1429         synchronized (mLock) {
1430             return mVrModeEnabled;
1431         }
1432     }
1433 
getPersistentVrMode()1434     private boolean getPersistentVrMode() {
1435         synchronized (mLock) {
1436             return mPersistentVrModeEnabled;
1437         }
1438     }
1439 }
1440