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