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.ActivityManagerInternal.ScreenObserver;
     23 import android.app.ActivityManager;
     24 import android.app.AppOpsManager;
     25 import android.app.INotificationManager;
     26 import android.app.Vr2dDisplayProperties;
     27 import android.app.NotificationManager;
     28 import android.annotation.NonNull;
     29 import android.content.BroadcastReceiver;
     30 import android.content.ComponentName;
     31 import android.content.ContentResolver;
     32 import android.content.Context;
     33 import android.content.Intent;
     34 import android.content.IntentFilter;
     35 import android.content.pm.ApplicationInfo;
     36 import android.content.pm.PackageManager;
     37 import android.content.pm.PackageManager.NameNotFoundException;
     38 import android.hardware.display.DisplayManager;
     39 import android.os.Binder;
     40 import android.os.Handler;
     41 import android.os.IBinder;
     42 import android.os.IInterface;
     43 import android.os.Looper;
     44 import android.os.Message;
     45 import android.os.RemoteCallbackList;
     46 import android.os.RemoteException;
     47 import android.os.ServiceManager;
     48 import android.os.SystemProperties;
     49 import android.os.UserHandle;
     50 import android.provider.Settings;
     51 import android.service.notification.NotificationListenerService;
     52 import android.service.vr.IPersistentVrStateCallbacks;
     53 import android.service.vr.IVrListener;
     54 import android.service.vr.IVrManager;
     55 import android.service.vr.IVrStateCallbacks;
     56 import android.service.vr.VrListenerService;
     57 import android.text.TextUtils;
     58 import android.util.ArrayMap;
     59 import android.util.ArraySet;
     60 import android.util.Slog;
     61 import android.util.SparseArray;
     62 
     63 import com.android.server.FgThread;
     64 import com.android.server.wm.WindowManagerInternal;
     65 import android.view.inputmethod.InputMethodManagerInternal;
     66 
     67 import com.android.internal.R;
     68 import com.android.internal.util.DumpUtils;
     69 import com.android.server.LocalServices;
     70 import com.android.server.SystemConfig;
     71 import com.android.server.SystemService;
     72 import com.android.server.utils.ManagedApplicationService.PendingEvent;
     73 import com.android.server.utils.ManagedApplicationService.LogEvent;
     74 import com.android.server.utils.ManagedApplicationService.LogFormattable;
     75 import com.android.server.vr.EnabledComponentsObserver.EnabledComponentChangeListener;
     76 import com.android.server.utils.ManagedApplicationService;
     77 import com.android.server.utils.ManagedApplicationService.BinderChecker;
     78 
     79 import java.io.FileDescriptor;
     80 import java.io.PrintWriter;
     81 import java.lang.StringBuilder;
     82 import java.text.SimpleDateFormat;
     83 import java.util.Arrays;
     84 import java.util.ArrayDeque;
     85 import java.util.ArrayList;
     86 import java.util.Collection;
     87 import java.util.Date;
     88 import java.util.List;
     89 import java.util.Objects;
     90 
     91 /**
     92  * Service tracking whether VR mode is active, and notifying listening services of state changes.
     93  * <p/>
     94  * Services running in system server may modify the state of VrManagerService via the interface in
     95  * VrManagerInternal, and may register to receive callbacks when the system VR mode changes via the
     96  * interface given in VrStateListener.
     97  * <p/>
     98  * Device vendors may choose to receive VR state changes by implementing the VR mode HAL, e.g.:
     99  *  hardware/libhardware/modules/vr
    100  * <p/>
    101  * In general applications may enable or disable VR mode by calling
    102  * {@link android.app.Activity#setVrModeEnabled)}.  An application may also implement a service to
    103  * be run while in VR mode by implementing {@link android.service.vr.VrListenerService}.
    104  *
    105  * @see android.service.vr.VrListenerService
    106  * @see com.android.server.vr.VrManagerInternal
    107  * @see com.android.server.vr.VrStateListener
    108  *
    109  * @hide
    110  */
    111 public class VrManagerService extends SystemService
    112         implements EnabledComponentChangeListener, ScreenObserver {
    113 
    114     public static final String TAG = "VrManagerService";
    115     static final boolean DBG = false;
    116 
    117     private static final int PENDING_STATE_DELAY_MS = 300;
    118     private static final int EVENT_LOG_SIZE = 64;
    119     private static final int INVALID_APPOPS_MODE = -1;
    120     /** Null set of sleep sleep flags. */
    121     private static final int FLAG_NONE = 0;
    122     /** Flag set when the device is not sleeping. */
    123     private static final int FLAG_AWAKE = 1 << 0;
    124     /** Flag set when the screen has been turned on. */
    125     private static final int FLAG_SCREEN_ON = 1 << 1;
    126     /** Flag set when the keyguard is not active. */
    127     private static final int FLAG_KEYGUARD_UNLOCKED = 1 << 2;
    128     /** Flag indicating that all system sleep flags have been set.*/
    129     private static final int FLAG_ALL = FLAG_AWAKE | FLAG_SCREEN_ON | FLAG_KEYGUARD_UNLOCKED;
    130 
    131     private static native void initializeNative();
    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      */
    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 
    252     private void setScreenOn(boolean isScreenOn) {
    253         setSystemState(FLAG_SCREEN_ON, isScreenOn);
    254     }
    255 
    256     @Override
    257     public void onAwakeStateChanged(boolean isAwake) {
    258         setSystemState(FLAG_AWAKE, isAwake);
    259     }
    260 
    261     @Override
    262     public void onKeyguardStateChanged(boolean isShowing) {
    263         setSystemState(FLAG_KEYGUARD_UNLOCKED, !isShowing);
    264     }
    265 
    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 
    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 
    289     private void setUserUnlocked() {
    290         synchronized(mLock) {
    291             mUserUnlocked = true;
    292             updateVrModeAllowedLocked();
    293         }
    294     }
    295 
    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 
    356         SettingEvent(String what) {
    357             this.timestamp = System.currentTimeMillis();
    358             this.what = what;
    359         }
    360 
    361         @Override
    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 
    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 
    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
    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 
    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
    502     public void onEnabledComponentChanged() {
    503         synchronized (mLock) {
    504             int currentUser = ActivityManager.getCurrentUser();
    505             // Update listeners
    506             ArraySet<ComponentName> enabledListeners = mComponentObserver.getEnabled(currentUser);
    507 
    508             ArraySet<String> enabledPackages = new ArraySet<>();
    509             for (ComponentName n : enabledListeners) {
    510                 String pkg = n.getPackageName();
    511                 if (isDefaultAllowed(pkg)) {
    512                     enabledPackages.add(n.getPackageName());
    513                 }
    514             }
    515             mNotifAccessManager.update(enabledPackages);
    516 
    517             if (!mVrModeAllowed) {
    518                 return; // Don't do anything, we shouldn't be in VR mode.
    519             }
    520 
    521             // If there is a pending state change, we'd better deal with that first
    522             consumeAndApplyPendingStateLocked(false);
    523 
    524             if (mCurrentVrService == null) {
    525                 return; // No active services
    526             }
    527 
    528             // There is an active service, update it if needed
    529             updateCurrentVrServiceLocked(mVrModeEnabled, mRunning2dInVr,
    530                     mCurrentVrService.getComponent(), mCurrentVrService.getUserId(),
    531                     mVrAppProcessId, mCurrentVrModeComponent);
    532         }
    533     }
    534 
    535     private final IVrManager mVrManager = new IVrManager.Stub() {
    536 
    537         @Override
    538         public void registerListener(IVrStateCallbacks cb) {
    539             enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER,
    540                     Manifest.permission.ACCESS_VR_STATE);
    541             if (cb == null) {
    542                 throw new IllegalArgumentException("Callback binder object is null.");
    543             }
    544 
    545             VrManagerService.this.addStateCallback(cb);
    546         }
    547 
    548         @Override
    549         public void unregisterListener(IVrStateCallbacks cb) {
    550             enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER,
    551                     Manifest.permission.ACCESS_VR_STATE);
    552             if (cb == null) {
    553                 throw new IllegalArgumentException("Callback binder object is null.");
    554             }
    555 
    556             VrManagerService.this.removeStateCallback(cb);
    557         }
    558 
    559         @Override
    560         public void registerPersistentVrStateListener(IPersistentVrStateCallbacks cb) {
    561             enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER,
    562                     Manifest.permission.ACCESS_VR_STATE);
    563             if (cb == null) {
    564                 throw new IllegalArgumentException("Callback binder object is null.");
    565             }
    566 
    567             VrManagerService.this.addPersistentStateCallback(cb);
    568         }
    569 
    570         @Override
    571         public void unregisterPersistentVrStateListener(IPersistentVrStateCallbacks cb) {
    572             enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER,
    573                     Manifest.permission.ACCESS_VR_STATE);
    574             if (cb == null) {
    575                 throw new IllegalArgumentException("Callback binder object is null.");
    576             }
    577 
    578             VrManagerService.this.removePersistentStateCallback(cb);
    579         }
    580 
    581         @Override
    582         public boolean getVrModeState() {
    583             enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER,
    584                     Manifest.permission.ACCESS_VR_STATE);
    585             return VrManagerService.this.getVrMode();
    586         }
    587 
    588         @Override
    589         public boolean getPersistentVrModeEnabled() {
    590             enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER,
    591                     Manifest.permission.ACCESS_VR_STATE);
    592             return VrManagerService.this.getPersistentVrMode();
    593         }
    594 
    595         @Override
    596         public void setPersistentVrModeEnabled(boolean enabled) {
    597             enforceCallerPermissionAnyOf(Manifest.permission.RESTRICTED_VR_ACCESS);
    598             VrManagerService.this.setPersistentVrModeEnabled(enabled);
    599         }
    600 
    601         @Override
    602         public void setVr2dDisplayProperties(
    603                 Vr2dDisplayProperties vr2dDisplayProp) {
    604             enforceCallerPermissionAnyOf(Manifest.permission.RESTRICTED_VR_ACCESS);
    605             VrManagerService.this.setVr2dDisplayProperties(vr2dDisplayProp);
    606         }
    607 
    608         @Override
    609         public int getVr2dDisplayId() {
    610             return VrManagerService.this.getVr2dDisplayId();
    611         }
    612 
    613         @Override
    614         public void setAndBindCompositor(String componentName) {
    615             enforceCallerPermissionAnyOf(Manifest.permission.RESTRICTED_VR_ACCESS);
    616             VrManagerService.this.setAndBindCompositor(
    617                 (componentName == null) ? null : ComponentName.unflattenFromString(componentName));
    618         }
    619 
    620         @Override
    621         public void setStandbyEnabled(boolean standby) {
    622             enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER);
    623             VrManagerService.this.setStandbyEnabled(standby);
    624         }
    625 
    626         @Override
    627         public void setVrInputMethod(ComponentName componentName) {
    628             enforceCallerPermissionAnyOf(Manifest.permission.RESTRICTED_VR_ACCESS);
    629             InputMethodManagerInternal imm =
    630                     LocalServices.getService(InputMethodManagerInternal.class);
    631             imm.startVrInputMethodNoCheck(componentName);
    632         }
    633 
    634         @Override
    635         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
    636             if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
    637 
    638             pw.println("********* Dump of VrManagerService *********");
    639             pw.println("VR mode is currently: " + ((mVrModeAllowed) ? "allowed" : "disallowed"));
    640             pw.println("Persistent VR mode is currently: " +
    641                     ((mPersistentVrModeEnabled) ? "enabled" : "disabled"));
    642             pw.println("Currently bound VR listener service: "
    643                     + ((mCurrentVrService == null)
    644                     ? "None" : mCurrentVrService.getComponent().flattenToString()));
    645             pw.println("Currently bound VR compositor service: "
    646                     + ((mCurrentVrCompositorService == null)
    647                     ? "None" : mCurrentVrCompositorService.getComponent().flattenToString()));
    648             pw.println("Previous state transitions:\n");
    649             String tab = "  ";
    650             dumpStateTransitions(pw);
    651             pw.println("\n\nRemote Callbacks:");
    652             int i=mVrStateRemoteCallbacks.beginBroadcast(); // create the broadcast item array
    653             while(i-->0) {
    654                 pw.print(tab);
    655                 pw.print(mVrStateRemoteCallbacks.getBroadcastItem(i));
    656                 if (i>0) pw.println(",");
    657             }
    658             mVrStateRemoteCallbacks.finishBroadcast();
    659             pw.println("\n\nPersistent Vr State Remote Callbacks:");
    660             i=mPersistentVrStateRemoteCallbacks.beginBroadcast();
    661             while(i-->0) {
    662                 pw.print(tab);
    663                 pw.print(mPersistentVrStateRemoteCallbacks.getBroadcastItem(i));
    664                 if (i>0) pw.println(",");
    665             }
    666             mPersistentVrStateRemoteCallbacks.finishBroadcast();
    667             pw.println("\n");
    668             pw.println("Installed VrListenerService components:");
    669             int userId = mCurrentVrModeUser;
    670             ArraySet<ComponentName> installed = mComponentObserver.getInstalled(userId);
    671             if (installed == null || installed.size() == 0) {
    672                 pw.println("None");
    673             } else {
    674                 for (ComponentName n : installed) {
    675                     pw.print(tab);
    676                     pw.println(n.flattenToString());
    677                 }
    678             }
    679             pw.println("Enabled VrListenerService components:");
    680             ArraySet<ComponentName> enabled = mComponentObserver.getEnabled(userId);
    681             if (enabled == null || enabled.size() == 0) {
    682                 pw.println("None");
    683             } else {
    684                 for (ComponentName n : enabled) {
    685                     pw.print(tab);
    686                     pw.println(n.flattenToString());
    687                 }
    688             }
    689             pw.println("\n");
    690             pw.println("********* End of VrManagerService Dump *********");
    691         }
    692 
    693     };
    694 
    695     /**
    696      * Enforces that at lease one of the specified permissions is held by the caller.
    697      * Throws SecurityException if none of the specified permissions are held.
    698      *
    699      * @param permissions One or more permissions to check against.
    700      */
    701     private void enforceCallerPermissionAnyOf(String... permissions) {
    702         for (String permission : permissions) {
    703             if (mContext.checkCallingOrSelfPermission(permission)
    704                     == PackageManager.PERMISSION_GRANTED) {
    705                 return;
    706             }
    707         }
    708         throw new SecurityException("Caller does not hold at least one of the permissions: "
    709                 + Arrays.toString(permissions));
    710     }
    711 
    712     /**
    713      * Implementation of VrManagerInternal.  Callable only from system services.
    714      */
    715     private final class LocalService extends VrManagerInternal {
    716         @Override
    717         public void setVrMode(boolean enabled, ComponentName packageName, int userId, int processId,
    718                 ComponentName callingPackage) {
    719             VrManagerService.this.setVrMode(enabled, packageName, userId, processId, callingPackage);
    720         }
    721 
    722         @Override
    723         public void onScreenStateChanged(boolean isScreenOn) {
    724             VrManagerService.this.setScreenOn(isScreenOn);
    725         }
    726 
    727         @Override
    728         public boolean isCurrentVrListener(String packageName, int userId) {
    729             return VrManagerService.this.isCurrentVrListener(packageName, userId);
    730         }
    731 
    732         @Override
    733         public int hasVrPackage(ComponentName packageName, int userId) {
    734             return VrManagerService.this.hasVrPackage(packageName, userId);
    735         }
    736 
    737         @Override
    738         public void setPersistentVrModeEnabled(boolean enabled) {
    739             VrManagerService.this.setPersistentVrModeEnabled(enabled);
    740         }
    741 
    742         @Override
    743         public void setVr2dDisplayProperties(
    744             Vr2dDisplayProperties compatDisplayProp) {
    745             VrManagerService.this.setVr2dDisplayProperties(compatDisplayProp);
    746         }
    747 
    748         @Override
    749         public int getVr2dDisplayId() {
    750             return VrManagerService.this.getVr2dDisplayId();
    751         }
    752 
    753         @Override
    754         public void addPersistentVrModeStateListener(IPersistentVrStateCallbacks listener) {
    755             VrManagerService.this.addPersistentStateCallback(listener);
    756         }
    757     }
    758 
    759     public VrManagerService(Context context) {
    760         super(context);
    761     }
    762 
    763     @Override
    764     public void onStart() {
    765         synchronized(mLock) {
    766             initializeNative();
    767             mContext = getContext();
    768         }
    769 
    770         mBootsToVr = SystemProperties.getBoolean("ro.boot.vr", false);
    771         mUseStandbyToExitVrMode = mBootsToVr
    772                 && SystemProperties.getBoolean("persist.vr.use_standby_to_exit_vr_mode", true);
    773         publishLocalService(VrManagerInternal.class, new LocalService());
    774         publishBinderService(Context.VR_SERVICE, mVrManager.asBinder());
    775     }
    776 
    777     @Override
    778     public void onBootPhase(int phase) {
    779         if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
    780             LocalServices.getService(ActivityManagerInternal.class)
    781                     .registerScreenObserver(this);
    782 
    783             mNotificationManager = INotificationManager.Stub.asInterface(
    784                     ServiceManager.getService(Context.NOTIFICATION_SERVICE));
    785             synchronized (mLock) {
    786                 Looper looper = Looper.getMainLooper();
    787                 Handler handler = new Handler(looper);
    788                 ArrayList<EnabledComponentChangeListener> listeners = new ArrayList<>();
    789                 listeners.add(this);
    790                 mComponentObserver = EnabledComponentsObserver.build(mContext, handler,
    791                         Settings.Secure.ENABLED_VR_LISTENERS, looper,
    792                         android.Manifest.permission.BIND_VR_LISTENER_SERVICE,
    793                         VrListenerService.SERVICE_INTERFACE, mLock, listeners);
    794 
    795                 mComponentObserver.rebuildAll();
    796             }
    797 
    798             //TODO: something more robust than picking the first one
    799             ArraySet<ComponentName> defaultVrComponents =
    800                     SystemConfig.getInstance().getDefaultVrComponents();
    801             if (defaultVrComponents.size() > 0) {
    802                 mDefaultVrService = defaultVrComponents.valueAt(0);
    803             } else {
    804                 Slog.i(TAG, "No default vr listener service found.");
    805             }
    806 
    807             DisplayManager dm =
    808                     (DisplayManager) getContext().getSystemService(Context.DISPLAY_SERVICE);
    809             mVr2dDisplay = new Vr2dDisplay(
    810                     dm,
    811                     LocalServices.getService(ActivityManagerInternal.class),
    812                     LocalServices.getService(WindowManagerInternal.class),
    813                     mVrManager);
    814             mVr2dDisplay.init(getContext(), mBootsToVr);
    815 
    816             IntentFilter intentFilter = new IntentFilter();
    817             intentFilter.addAction(Intent.ACTION_USER_UNLOCKED);
    818             getContext().registerReceiver(new BroadcastReceiver() {
    819                     @Override
    820                     public void onReceive(Context context, Intent intent) {
    821                         if (Intent.ACTION_USER_UNLOCKED.equals(intent.getAction())) {
    822                             VrManagerService.this.setUserUnlocked();
    823                         }
    824                     }
    825                 }, intentFilter);
    826         }
    827     }
    828 
    829     @Override
    830     public void onStartUser(int userHandle) {
    831         synchronized (mLock) {
    832             mComponentObserver.onUsersChanged();
    833         }
    834     }
    835 
    836     @Override
    837     public void onSwitchUser(int userHandle) {
    838         FgThread.getHandler().post(() -> {
    839             synchronized (mLock) {
    840                 mComponentObserver.onUsersChanged();
    841             }
    842         });
    843 
    844     }
    845 
    846     @Override
    847     public void onStopUser(int userHandle) {
    848         synchronized (mLock) {
    849             mComponentObserver.onUsersChanged();
    850         }
    851 
    852     }
    853 
    854     @Override
    855     public void onCleanupUser(int userHandle) {
    856         synchronized (mLock) {
    857             mComponentObserver.onUsersChanged();
    858         }
    859     }
    860 
    861     private void updateOverlayStateLocked(String exemptedPackage, int newUserId, int oldUserId) {
    862         AppOpsManager appOpsManager = getContext().getSystemService(AppOpsManager.class);
    863 
    864         // If user changed drop restrictions for the old user.
    865         if (oldUserId != newUserId) {
    866             appOpsManager.setUserRestrictionForUser(AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
    867                     false, mOverlayToken, null, oldUserId);
    868         }
    869 
    870         // Apply the restrictions for the current user based on vr state
    871         String[] exemptions = (exemptedPackage == null) ? new String[0] :
    872                 new String[] { exemptedPackage };
    873 
    874         appOpsManager.setUserRestrictionForUser(AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
    875                 mVrModeEnabled, mOverlayToken, exemptions, newUserId);
    876     }
    877 
    878     private void updateDependentAppOpsLocked(String newVrServicePackage, int newUserId,
    879             String oldVrServicePackage, int oldUserId) {
    880         // If VR state changed and we also have a VR service change.
    881         if (Objects.equals(newVrServicePackage, oldVrServicePackage)) {
    882             return;
    883         }
    884         final long identity = Binder.clearCallingIdentity();
    885         try {
    886             // Set overlay exception state based on VR enabled and current service
    887             updateOverlayStateLocked(newVrServicePackage, newUserId, oldUserId);
    888         } finally {
    889             Binder.restoreCallingIdentity(identity);
    890         }
    891     }
    892 
    893     /**
    894      * Send VR mode changes (if the mode state has changed), and update the bound/unbound state of
    895      * the currently selected VR listener service.  If the component selected for the VR listener
    896      * service has changed, unbind the previous listener and bind the new listener (if enabled).
    897      * <p/>
    898      * Note: Must be called while holding {@code mLock}.
    899      *
    900      * @param enabled new state for VR mode.
    901      * @param running2dInVr true if we have a top-level 2D intent.
    902      * @param component new component to be bound as a VR listener.
    903      * @param userId user owning the component to be bound.
    904      * @param processId the process hosting the activity specified by calling.
    905      * @param calling the component currently using VR mode or a 2D intent.
    906      *
    907      * @return {@code true} if the component/user combination specified is valid.
    908      */
    909     private boolean updateCurrentVrServiceLocked(boolean enabled, boolean running2dInVr,
    910             @NonNull ComponentName component, int userId, int processId, ComponentName calling) {
    911 
    912         boolean sendUpdatedCaller = false;
    913         final long identity = Binder.clearCallingIdentity();
    914         try {
    915 
    916             boolean validUserComponent = (mComponentObserver.isValid(component, userId) ==
    917                     EnabledComponentsObserver.NO_ERROR);
    918             boolean goingIntoVrMode = validUserComponent && enabled;
    919             if (!mVrModeEnabled && !goingIntoVrMode) {
    920                 return validUserComponent; // Disabled -> Disabled transition does nothing.
    921             }
    922 
    923             String oldVrServicePackage = mCurrentVrService != null
    924                     ? mCurrentVrService.getComponent().getPackageName() : null;
    925             final int oldUserId = mCurrentVrModeUser;
    926 
    927             // Notify system services and VR HAL of mode change.
    928             changeVrModeLocked(goingIntoVrMode);
    929 
    930             boolean nothingChanged = false;
    931             if (!goingIntoVrMode) {
    932                 // Not going into VR mode, unbind whatever is running
    933                 if (mCurrentVrService != null) {
    934                     Slog.i(TAG, "Leaving VR mode, disconnecting "
    935                         + mCurrentVrService.getComponent() + " for user "
    936                         + mCurrentVrService.getUserId());
    937                     mCurrentVrService.disconnect();
    938                     updateCompositorServiceLocked(UserHandle.USER_NULL, null);
    939                     mCurrentVrService = null;
    940                 } else {
    941                     nothingChanged = true;
    942                 }
    943             } else {
    944                 // Going into VR mode
    945                 if (mCurrentVrService != null) {
    946                     // Unbind any running service that doesn't match the latest component/user
    947                     // selection.
    948                     if (mCurrentVrService.disconnectIfNotMatching(component, userId)) {
    949                         Slog.i(TAG, "VR mode component changed to " + component
    950                             + ", disconnecting " + mCurrentVrService.getComponent()
    951                             + " for user " + mCurrentVrService.getUserId());
    952                         updateCompositorServiceLocked(UserHandle.USER_NULL, null);
    953                         createAndConnectService(component, userId);
    954                         sendUpdatedCaller = true;
    955                     } else {
    956                         nothingChanged = true;
    957                     }
    958                     // The service with the correct component/user is already bound, do nothing.
    959                 } else {
    960                     // Nothing was previously running, bind a new service for the latest
    961                     // component/user selection.
    962                     createAndConnectService(component, userId);
    963                     sendUpdatedCaller = true;
    964                 }
    965             }
    966 
    967             if ((calling != null || mPersistentVrModeEnabled)
    968                     && !Objects.equals(calling, mCurrentVrModeComponent)
    969                     || mRunning2dInVr != running2dInVr) {
    970                 sendUpdatedCaller = true;
    971             }
    972             mCurrentVrModeComponent = calling;
    973             mRunning2dInVr = running2dInVr;
    974             mVrAppProcessId = processId;
    975 
    976             if (mCurrentVrModeUser != userId) {
    977                 mCurrentVrModeUser = userId;
    978                 sendUpdatedCaller = true;
    979             }
    980 
    981             String newVrServicePackage = mCurrentVrService != null
    982                     ? mCurrentVrService.getComponent().getPackageName() : null;
    983             final int newUserId = mCurrentVrModeUser;
    984 
    985             // Update AppOps settings that change state when entering/exiting VR mode, or changing
    986             // the current VrListenerService.
    987             updateDependentAppOpsLocked(newVrServicePackage, newUserId,
    988                     oldVrServicePackage, oldUserId);
    989 
    990             if (mCurrentVrService != null && sendUpdatedCaller) {
    991                 callFocusedActivityChangedLocked();
    992             }
    993 
    994             if (!nothingChanged) {
    995                 logStateLocked();
    996             }
    997 
    998             return validUserComponent;
    999         } finally {
   1000             Binder.restoreCallingIdentity(identity);
   1001         }
   1002     }
   1003 
   1004     private void callFocusedActivityChangedLocked() {
   1005         final ComponentName c = mCurrentVrModeComponent;
   1006         final boolean b = mRunning2dInVr;
   1007         final int pid = mVrAppProcessId;
   1008         mCurrentVrService.sendEvent(new PendingEvent() {
   1009             @Override
   1010             public void runEvent(IInterface service) throws RemoteException {
   1011                 // Under specific (and unlikely) timing scenarios, when VrCore
   1012                 // crashes and is rebound, focusedActivityChanged() may be
   1013                 // called a 2nd time with the same arguments. IVrListeners
   1014                 // should make sure to handle that scenario gracefully.
   1015                 IVrListener l = (IVrListener) service;
   1016                 l.focusedActivityChanged(c, b, pid);
   1017             }
   1018         });
   1019     }
   1020 
   1021     private boolean isDefaultAllowed(String packageName) {
   1022         PackageManager pm = mContext.getPackageManager();
   1023 
   1024         ApplicationInfo info = null;
   1025         try {
   1026             info = pm.getApplicationInfo(packageName, PackageManager.GET_META_DATA);
   1027         } catch (NameNotFoundException e) {
   1028         }
   1029 
   1030         if (info == null || !(info.isSystemApp() || info.isUpdatedSystemApp())) {
   1031             return false;
   1032         }
   1033         return true;
   1034     }
   1035 
   1036     private void grantNotificationPolicyAccess(String pkg) {
   1037         NotificationManager nm = mContext.getSystemService(NotificationManager.class);
   1038         nm.setNotificationPolicyAccessGranted(pkg, true);
   1039     }
   1040 
   1041     private void revokeNotificationPolicyAccess(String pkg) {
   1042         NotificationManager nm = mContext.getSystemService(NotificationManager.class);
   1043         // Remove any DND zen rules possibly created by the package.
   1044         nm.removeAutomaticZenRules(pkg);
   1045         // Remove Notification Policy Access.
   1046         nm.setNotificationPolicyAccessGranted(pkg, false);
   1047     }
   1048 
   1049     private void grantNotificationListenerAccess(String pkg, int userId) {
   1050         NotificationManager nm = mContext.getSystemService(NotificationManager.class);
   1051         PackageManager pm = mContext.getPackageManager();
   1052         ArraySet<ComponentName> possibleServices = EnabledComponentsObserver.loadComponentNames(pm,
   1053                 userId, NotificationListenerService.SERVICE_INTERFACE,
   1054                 android.Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE);
   1055 
   1056         for (ComponentName c : possibleServices) {
   1057             if (Objects.equals(c.getPackageName(), pkg)) {
   1058                 nm.setNotificationListenerAccessGrantedForUser(c, userId, true);
   1059             }
   1060         }
   1061     }
   1062 
   1063     private void revokeNotificationListenerAccess(String pkg, int userId) {
   1064         NotificationManager nm = mContext.getSystemService(NotificationManager.class);
   1065         List<ComponentName> current = nm.getEnabledNotificationListeners(userId);
   1066 
   1067         for (ComponentName component : current) {
   1068             if (component != null && component.getPackageName().equals(pkg)) {
   1069                 nm.setNotificationListenerAccessGrantedForUser(component, userId, false);
   1070             }
   1071         }
   1072     }
   1073 
   1074     private void grantCoarseLocationPermissionIfNeeded(String pkg, int userId) {
   1075         // Don't clobber the user if permission set in current state explicitly
   1076         if (!isPermissionUserUpdated(Manifest.permission.ACCESS_COARSE_LOCATION, pkg, userId)) {
   1077             try {
   1078                 mContext.getPackageManager().grantRuntimePermission(pkg,
   1079                         Manifest.permission.ACCESS_COARSE_LOCATION, new UserHandle(userId));
   1080             } catch (IllegalArgumentException e) {
   1081                 // Package was removed during update.
   1082                 Slog.w(TAG, "Could not grant coarse location permission, package " + pkg
   1083                     + " was removed.");
   1084             }
   1085         }
   1086     }
   1087 
   1088     private void revokeCoarseLocationPermissionIfNeeded(String pkg, int userId) {
   1089         // Don't clobber the user if permission set in current state explicitly
   1090         if (!isPermissionUserUpdated(Manifest.permission.ACCESS_COARSE_LOCATION, pkg, userId)) {
   1091             try {
   1092                 mContext.getPackageManager().revokeRuntimePermission(pkg,
   1093                         Manifest.permission.ACCESS_COARSE_LOCATION, new UserHandle(userId));
   1094             } catch (IllegalArgumentException e) {
   1095                 // Package was removed during update.
   1096                 Slog.w(TAG, "Could not revoke coarse location permission, package " + pkg
   1097                     + " was removed.");
   1098             }
   1099         }
   1100     }
   1101 
   1102     private boolean isPermissionUserUpdated(String permission, String pkg, int userId) {
   1103         final int flags = mContext.getPackageManager().getPermissionFlags(
   1104                 permission, pkg, new UserHandle(userId));
   1105         return (flags & (PackageManager.FLAG_PERMISSION_USER_SET
   1106                 | PackageManager.FLAG_PERMISSION_USER_FIXED)) != 0;
   1107     }
   1108 
   1109     private ArraySet<String> getNotificationListeners(ContentResolver resolver, int userId) {
   1110         String flat = Settings.Secure.getStringForUser(resolver,
   1111                 Settings.Secure.ENABLED_NOTIFICATION_LISTENERS, userId);
   1112 
   1113         ArraySet<String> current = new ArraySet<>();
   1114         if (flat != null) {
   1115             String[] allowed = flat.split(":");
   1116             for (String s : allowed) {
   1117                 if (!TextUtils.isEmpty(s)) {
   1118                     current.add(s);
   1119                 }
   1120             }
   1121         }
   1122         return current;
   1123     }
   1124 
   1125     private static String formatSettings(Collection<String> c) {
   1126         if (c == null || c.isEmpty()) {
   1127             return "";
   1128         }
   1129 
   1130         StringBuilder b = new StringBuilder();
   1131         boolean start = true;
   1132         for (String s : c) {
   1133             if ("".equals(s)) {
   1134                 continue;
   1135             }
   1136             if (!start) {
   1137                 b.append(':');
   1138             }
   1139             b.append(s);
   1140             start = false;
   1141         }
   1142         return b.toString();
   1143     }
   1144 
   1145 
   1146 
   1147     private void createAndConnectService(@NonNull ComponentName component, int userId) {
   1148         mCurrentVrService = createVrListenerService(component, userId);
   1149         mCurrentVrService.connect();
   1150         Slog.i(TAG, "Connecting " + component + " for user " + userId);
   1151     }
   1152 
   1153     /**
   1154      * Send VR mode change callbacks to HAL and system services if mode has actually changed.
   1155      * <p/>
   1156      * Note: Must be called while holding {@code mLock}.
   1157      *
   1158      * @param enabled new state of the VR mode.
   1159      */
   1160     private void changeVrModeLocked(boolean enabled) {
   1161         if (mVrModeEnabled != enabled) {
   1162             mVrModeEnabled = enabled;
   1163 
   1164             // Log mode change event.
   1165             Slog.i(TAG, "VR mode " + ((mVrModeEnabled) ? "enabled" : "disabled"));
   1166             setVrModeNative(mVrModeEnabled);
   1167 
   1168             onVrModeChangedLocked();
   1169         }
   1170     }
   1171 
   1172     /**
   1173      * Notify system services of VR mode change.
   1174      * <p/>
   1175      * Note: Must be called while holding {@code mLock}.
   1176      */
   1177     private void onVrModeChangedLocked() {
   1178         mHandler.sendMessage(mHandler.obtainMessage(MSG_VR_STATE_CHANGE,
   1179                 (mVrModeEnabled) ? 1 : 0, 0));
   1180     }
   1181 
   1182     /**
   1183      * Helper function for making ManagedApplicationService for VrListenerService instances.
   1184      */
   1185     private ManagedApplicationService createVrListenerService(@NonNull ComponentName component,
   1186             int userId) {
   1187         int retryType = (mBootsToVr) ? ManagedApplicationService.RETRY_FOREVER
   1188                 : ManagedApplicationService.RETRY_NEVER;
   1189         return ManagedApplicationService.build(mContext, component, userId,
   1190                 R.string.vr_listener_binding_label, Settings.ACTION_VR_LISTENER_SETTINGS,
   1191                 sBinderChecker, /*isImportant*/true, retryType, mHandler, mEventCallback);
   1192     }
   1193 
   1194     /**
   1195      * Helper function for making ManagedApplicationService for VR Compositor instances.
   1196      */
   1197     private ManagedApplicationService createVrCompositorService(@NonNull ComponentName component,
   1198             int userId) {
   1199         int retryType = (mBootsToVr) ? ManagedApplicationService.RETRY_FOREVER
   1200                 : ManagedApplicationService.RETRY_BEST_EFFORT;
   1201         return ManagedApplicationService.build(mContext, component, userId, /*clientLabel*/0,
   1202                 /*settingsAction*/null, /*binderChecker*/null, /*isImportant*/true, retryType,
   1203                 mHandler, /*disconnectCallback*/mEventCallback);
   1204     }
   1205 
   1206     /**
   1207      * Apply the pending VR state. If no state is pending, disconnect any currently bound
   1208      * VR listener service.
   1209      */
   1210     private void consumeAndApplyPendingStateLocked() {
   1211         consumeAndApplyPendingStateLocked(true);
   1212     }
   1213 
   1214     /**
   1215      * Apply the pending VR state.
   1216      *
   1217      * @param disconnectIfNoPendingState if {@code true}, then any currently bound VR listener
   1218      *     service will be disconnected if no state is pending. If this is {@code false} then the
   1219      *     nothing will be changed when there is no pending state.
   1220      */
   1221     private void consumeAndApplyPendingStateLocked(boolean disconnectIfNoPendingState) {
   1222         if (mPendingState != null) {
   1223             updateCurrentVrServiceLocked(mPendingState.enabled, mPendingState.running2dInVr,
   1224                     mPendingState.targetPackageName, mPendingState.userId, mPendingState.processId,
   1225                     mPendingState.callingPackage);
   1226             mPendingState = null;
   1227         } else if (disconnectIfNoPendingState) {
   1228             updateCurrentVrServiceLocked(false, false, null, 0, -1, null);
   1229         }
   1230     }
   1231 
   1232     private void logStateLocked() {
   1233         ComponentName currentBoundService = (mCurrentVrService == null) ? null :
   1234                 mCurrentVrService.getComponent();
   1235         logEvent(new VrState(mVrModeEnabled, mRunning2dInVr, currentBoundService,
   1236                 mCurrentVrModeUser, mVrAppProcessId, mCurrentVrModeComponent, mWasDefaultGranted));
   1237     }
   1238 
   1239     private void logEvent(LogFormattable event) {
   1240         synchronized (mLoggingDeque) {
   1241             if (mLoggingDeque.size() == EVENT_LOG_SIZE) {
   1242                 mLoggingDeque.removeFirst();
   1243                 mLogLimitHit = true;
   1244             }
   1245             mLoggingDeque.add(event);
   1246         }
   1247     }
   1248 
   1249     private void dumpStateTransitions(PrintWriter pw) {
   1250         SimpleDateFormat d = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
   1251         synchronized (mLoggingDeque) {
   1252             if (mLoggingDeque.size() == 0) {
   1253                 pw.print("  ");
   1254                 pw.println("None");
   1255             }
   1256 
   1257             if (mLogLimitHit) {
   1258                 pw.println("..."); // Indicates log overflow
   1259             }
   1260 
   1261             for (LogFormattable event : mLoggingDeque) {
   1262                 pw.println(event.toLogString(d));
   1263             }
   1264         }
   1265     }
   1266 
   1267     /*
   1268      * Implementation of VrManagerInternal calls.  These are callable from system services.
   1269      */
   1270     private void setVrMode(boolean enabled, @NonNull ComponentName targetPackageName,
   1271             int userId, int processId, @NonNull ComponentName callingPackage) {
   1272 
   1273         synchronized (mLock) {
   1274             VrState pending;
   1275             ComponentName targetListener;
   1276 
   1277             // If the device is in persistent VR mode, then calls to disable VR mode are ignored,
   1278             // and the system default VR listener is used.
   1279             boolean targetEnabledState = enabled || mPersistentVrModeEnabled;
   1280             boolean running2dInVr = !enabled && mPersistentVrModeEnabled;
   1281             if (running2dInVr) {
   1282                 targetListener = mDefaultVrService;
   1283             } else {
   1284                 targetListener = targetPackageName;
   1285             }
   1286 
   1287             pending = new VrState(targetEnabledState, running2dInVr, targetListener,
   1288                     userId, processId, callingPackage);
   1289 
   1290             if (!mVrModeAllowed) {
   1291                 // We're not allowed to be in VR mode.  Make this state pending.  This will be
   1292                 // applied the next time we are allowed to enter VR mode unless it is superseded by
   1293                 // another call.
   1294                 mPendingState = pending;
   1295                 return;
   1296             }
   1297 
   1298             if (!targetEnabledState && mCurrentVrService != null) {
   1299                 // If we're transitioning out of VR mode, delay briefly to avoid expensive HAL calls
   1300                 // and service bind/unbind in case we are immediately switching to another VR app.
   1301                 if (mPendingState == null) {
   1302                     mHandler.sendEmptyMessageDelayed(MSG_PENDING_VR_STATE_CHANGE,
   1303                             PENDING_STATE_DELAY_MS);
   1304                 }
   1305 
   1306                 mPendingState = pending;
   1307                 return;
   1308             } else {
   1309                 mHandler.removeMessages(MSG_PENDING_VR_STATE_CHANGE);
   1310                 mPendingState = null;
   1311             }
   1312 
   1313             updateCurrentVrServiceLocked(targetEnabledState, running2dInVr, targetListener,
   1314                     userId, processId, callingPackage);
   1315         }
   1316     }
   1317 
   1318     private void setPersistentVrModeEnabled(boolean enabled) {
   1319         synchronized(mLock) {
   1320             setPersistentModeAndNotifyListenersLocked(enabled);
   1321             // Disabling persistent mode should disable the overall vr mode.
   1322             if (!enabled) {
   1323                 setVrMode(false, null, 0, -1, null);
   1324             }
   1325         }
   1326     }
   1327 
   1328     public void setVr2dDisplayProperties(
   1329         Vr2dDisplayProperties compatDisplayProp) {
   1330         final long token = Binder.clearCallingIdentity();
   1331         try {
   1332             if (mVr2dDisplay != null) {
   1333                 mVr2dDisplay.setVirtualDisplayProperties(compatDisplayProp);
   1334                 return;
   1335             }
   1336         } finally {
   1337             Binder.restoreCallingIdentity(token);
   1338         }
   1339         Slog.w(TAG, "Vr2dDisplay is null!");
   1340     }
   1341 
   1342     private int getVr2dDisplayId() {
   1343         if (mVr2dDisplay != null) {
   1344             return mVr2dDisplay.getVirtualDisplayId();
   1345         }
   1346         Slog.w(TAG, "Vr2dDisplay is null!");
   1347         return INVALID_DISPLAY;
   1348     }
   1349 
   1350     private void setAndBindCompositor(ComponentName componentName) {
   1351         final int userId = UserHandle.getCallingUserId();
   1352         final long token = Binder.clearCallingIdentity();
   1353         try {
   1354             synchronized (mLock) {
   1355                 updateCompositorServiceLocked(userId, componentName);
   1356             }
   1357         } finally {
   1358             Binder.restoreCallingIdentity(token);
   1359         }
   1360     }
   1361 
   1362     private void updateCompositorServiceLocked(int userId, ComponentName componentName) {
   1363         if (mCurrentVrCompositorService != null
   1364                 && mCurrentVrCompositorService.disconnectIfNotMatching(componentName, userId)) {
   1365             Slog.i(TAG, "Disconnecting compositor service: "
   1366                     + mCurrentVrCompositorService.getComponent());
   1367             // Check if existing service matches the requested one, if not (or if the requested
   1368             // component is null) disconnect it.
   1369             mCurrentVrCompositorService = null;
   1370         }
   1371 
   1372         if (componentName != null && mCurrentVrCompositorService == null) {
   1373             // We don't have an existing service matching the requested component, so attempt to
   1374             // connect one.
   1375             Slog.i(TAG, "Connecting compositor service: " + componentName);
   1376             mCurrentVrCompositorService = createVrCompositorService(componentName, userId);
   1377             mCurrentVrCompositorService.connect();
   1378         }
   1379     }
   1380 
   1381     private void setPersistentModeAndNotifyListenersLocked(boolean enabled) {
   1382         if (mPersistentVrModeEnabled == enabled) {
   1383             return;
   1384         }
   1385         String eventName = "Persistent VR mode " + ((enabled) ? "enabled" : "disabled");
   1386         Slog.i(TAG, eventName);
   1387         logEvent(new SettingEvent(eventName));
   1388         mPersistentVrModeEnabled = enabled;
   1389 
   1390         mHandler.sendMessage(mHandler.obtainMessage(MSG_PERSISTENT_VR_MODE_STATE_CHANGE,
   1391                 (mPersistentVrModeEnabled) ? 1 : 0, 0));
   1392     }
   1393 
   1394     private int hasVrPackage(@NonNull ComponentName targetPackageName, int userId) {
   1395         synchronized (mLock) {
   1396             return mComponentObserver.isValid(targetPackageName, userId);
   1397         }
   1398     }
   1399 
   1400     private boolean isCurrentVrListener(String packageName, int userId) {
   1401         synchronized (mLock) {
   1402             if (mCurrentVrService == null) {
   1403                 return false;
   1404             }
   1405             return mCurrentVrService.getComponent().getPackageName().equals(packageName) &&
   1406                     userId == mCurrentVrService.getUserId();
   1407         }
   1408     }
   1409 
   1410     /*
   1411      * Implementation of IVrManager calls.
   1412      */
   1413 
   1414     private void addStateCallback(IVrStateCallbacks cb) {
   1415         mVrStateRemoteCallbacks.register(cb);
   1416     }
   1417 
   1418     private void removeStateCallback(IVrStateCallbacks cb) {
   1419         mVrStateRemoteCallbacks.unregister(cb);
   1420     }
   1421 
   1422     private void addPersistentStateCallback(IPersistentVrStateCallbacks cb) {
   1423         mPersistentVrStateRemoteCallbacks.register(cb);
   1424     }
   1425 
   1426     private void removePersistentStateCallback(IPersistentVrStateCallbacks cb) {
   1427         mPersistentVrStateRemoteCallbacks.unregister(cb);
   1428     }
   1429 
   1430     private boolean getVrMode() {
   1431         synchronized (mLock) {
   1432             return mVrModeEnabled;
   1433         }
   1434     }
   1435 
   1436     private boolean getPersistentVrMode() {
   1437         synchronized (mLock) {
   1438             return mPersistentVrModeEnabled;
   1439         }
   1440     }
   1441 }
   1442