VrManagerService.java revision 2ec8d8403ea13f77dd2a1fe9f11fff084ba85cea
1dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu/** 2dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * Copyright (C) 2015 The Android Open Source Project 3dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * 4dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * Licensed under the Apache License, Version 2.0 (the "License"); 5dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * you may not use this file except in compliance with the License. 6dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * You may obtain a copy of the License at 7dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * 8dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * http://www.apache.org/licenses/LICENSE-2.0 9dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * 10dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * Unless required by applicable law or agreed to in writing, software 11dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * distributed under the License is distributed on an "AS IS" BASIS, 12dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * See the License for the specific language governing permissions and 14dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * limitations under the License. 15dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu */ 16dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhupackage com.android.server.vr; 17dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 18dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport android.Manifest; 19dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport android.app.ActivityManager; 20dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport android.app.AppOpsManager; 21dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport android.app.NotificationManager; 22dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport android.annotation.NonNull; 23dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport android.content.ComponentName; 24dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport android.content.ContentResolver; 25dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport android.content.Context; 26dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport android.content.pm.ApplicationInfo; 27dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport android.content.pm.PackageManager; 28dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport android.content.pm.PackageManager.NameNotFoundException; 29dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport android.os.Binder; 30dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport android.os.Handler; 31dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport android.os.IBinder; 32dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport android.os.IInterface; 3336e04c3847e93ccf4c3e0cde617eecea72c2605dTeng-Hui Zhuimport android.os.Looper; 34dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport android.os.Message; 35dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport android.os.RemoteCallbackList; 36dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport android.os.RemoteException; 37dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport android.os.UserHandle; 38dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport android.provider.Settings; 39dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport android.service.notification.NotificationListenerService; 40dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport android.service.vr.IVrListener; 41dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport android.service.vr.IVrManager; 42dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport android.service.vr.IVrStateCallbacks; 43dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport android.service.vr.VrListenerService; 44dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport android.text.TextUtils; 45dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport android.util.ArrayMap; 46dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport android.util.ArraySet; 47dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport android.util.Slog; 48dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport android.util.SparseArray; 49dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 50dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport com.android.internal.R; 51dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport com.android.server.SystemConfig; 52dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport com.android.server.SystemService; 53dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport com.android.server.utils.ManagedApplicationService.PendingEvent; 54dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport com.android.server.vr.EnabledComponentsObserver.EnabledComponentChangeListener; 55dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport com.android.server.utils.ManagedApplicationService; 56dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport com.android.server.utils.ManagedApplicationService.BinderChecker; 57dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 58dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.io.FileDescriptor; 59dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.io.PrintWriter; 60dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.lang.StringBuilder; 61dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.text.SimpleDateFormat; 62dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.util.ArrayDeque; 63dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.util.ArrayList; 64dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.util.Collection; 65dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.util.Date; 66dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.util.Objects; 67dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 68dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu/** 69dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * Service tracking whether VR mode is active, and notifying listening services of state changes. 70dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * <p/> 71dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * Services running in system server may modify the state of VrManagerService via the interface in 72dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * VrManagerInternal, and may register to receive callbacks when the system VR mode changes via the 73dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * interface given in VrStateListener. 74dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * <p/> 75dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * Device vendors may choose to receive VR state changes by implementing the VR mode HAL, e.g.: 76dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * hardware/libhardware/modules/vr 77dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * <p/> 78dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * In general applications may enable or disable VR mode by calling 79dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * {@link android.app.Activity#setVrModeEnabled)}. An application may also implement a service to 80dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * be run while in VR mode by implementing {@link android.service.vr.VrListenerService}. 81dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * 82dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * @see android.service.vr.VrListenerService 8336e04c3847e93ccf4c3e0cde617eecea72c2605dTeng-Hui Zhu * @see com.android.server.vr.VrManagerInternal 8436e04c3847e93ccf4c3e0cde617eecea72c2605dTeng-Hui Zhu * @see com.android.server.vr.VrStateListener 8536e04c3847e93ccf4c3e0cde617eecea72c2605dTeng-Hui Zhu * 8636e04c3847e93ccf4c3e0cde617eecea72c2605dTeng-Hui Zhu * @hide 8736e04c3847e93ccf4c3e0cde617eecea72c2605dTeng-Hui Zhu */ 8836e04c3847e93ccf4c3e0cde617eecea72c2605dTeng-Hui Zhupublic class VrManagerService extends SystemService implements EnabledComponentChangeListener{ 8936e04c3847e93ccf4c3e0cde617eecea72c2605dTeng-Hui Zhu 9036e04c3847e93ccf4c3e0cde617eecea72c2605dTeng-Hui Zhu public static final String TAG = "VrManagerService"; 91dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 92dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private static final int PENDING_STATE_DELAY_MS = 300; 93dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private static final int EVENT_LOG_SIZE = 32; 94dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private static final int INVALID_APPOPS_MODE = -1; 95dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu /** Null set of sleep sleep flags. */ 96dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private static final int FLAG_NONE = 0; 97dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu /** Flag set when the device is not sleeping. */ 98dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private static final int FLAG_AWAKE = 1; 99dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu /** Flag set when the screen has been turned on. */ 100dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private static final int FLAG_SCREEN_ON = 2; 101dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu /** Flag indicating that all system sleep flags have been set.*/ 102dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private static final int FLAG_ALL = FLAG_AWAKE | FLAG_SCREEN_ON; 103dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 104dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private static native void initializeNative(); 105dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private static native void setVrModeNative(boolean enabled); 106dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 107dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private final Object mLock = new Object(); 108dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 109dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private final IBinder mOverlayToken = new Binder(); 110dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 111dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu // State protected by mLock 112dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private boolean mVrModeAllowed; 113dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private boolean mVrModeEnabled; 114dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private boolean mPersistentVrModeEnabled; 115dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private EnabledComponentsObserver mComponentObserver; 116dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private ManagedApplicationService mCurrentVrService; 117dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private ComponentName mDefaultVrService; 118dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private Context mContext; 119dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private ComponentName mCurrentVrModeComponent; 120dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private int mCurrentVrModeUser; 121dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private boolean mWasDefaultGranted; 122dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private boolean mGuard; 123dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private final RemoteCallbackList<IVrStateCallbacks> mRemoteCallbacks = 124dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu new RemoteCallbackList<>(); 125dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private final ArrayList<PersistentVrStateListener> mPersistentVrStateListeners = 126dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu new ArrayList<>(); 127dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private int mPreviousCoarseLocationMode = INVALID_APPOPS_MODE; 128dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private int mPreviousManageOverlayMode = INVALID_APPOPS_MODE; 129dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private VrState mPendingState; 130dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private final ArrayDeque<VrState> mLoggingDeque = new ArrayDeque<>(EVENT_LOG_SIZE); 131dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private final NotificationAccessManager mNotifAccessManager = new NotificationAccessManager(); 132dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu /** Tracks the state of the screen and keyguard UI.*/ 133dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private int mSystemSleepFlags = FLAG_NONE; 134dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 135dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private static final int MSG_VR_STATE_CHANGE = 0; 136dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private static final int MSG_PENDING_VR_STATE_CHANGE = 1; 137dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private static final int MSG_PERSISTENT_VR_MODE_STATE_CHANGE = 2; 138dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 139dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu /** 140 * Set whether VR mode may be enabled. 141 * <p/> 142 * If VR mode is not allowed to be enabled, calls to set VR mode will be cached. When VR mode 143 * is again allowed to be enabled, the most recent cached state will be applied. 144 * 145 * @param allowed {@code true} if calling any of the setVrMode methods may cause the device to 146 * enter VR mode. 147 */ 148 private void setVrModeAllowedLocked(boolean allowed) { 149 if (mVrModeAllowed != allowed) { 150 mVrModeAllowed = allowed; 151 Slog.i(TAG, "VR mode is " + ((allowed) ? "allowed" : "disallowed")); 152 if (mVrModeAllowed) { 153 consumeAndApplyPendingStateLocked(); 154 } else { 155 // Disable persistent mode when VR mode isn't allowed, allows an escape hatch to 156 // exit persistent VR mode when screen is turned off. 157 setPersistentModeAndNotifyListenersLocked(false); 158 159 // Set pending state to current state. 160 mPendingState = (mVrModeEnabled && mCurrentVrService != null) 161 ? new VrState(mVrModeEnabled, mCurrentVrService.getComponent(), 162 mCurrentVrService.getUserId(), mCurrentVrModeComponent) 163 : null; 164 165 // Unbind current VR service and do necessary callbacks. 166 updateCurrentVrServiceLocked(false, null, 0, null); 167 } 168 } 169 } 170 171 private void setSleepState(boolean isAsleep) { 172 synchronized(mLock) { 173 174 if (!isAsleep) { 175 mSystemSleepFlags |= FLAG_AWAKE; 176 } else { 177 mSystemSleepFlags &= ~FLAG_AWAKE; 178 } 179 180 setVrModeAllowedLocked(mSystemSleepFlags == FLAG_ALL); 181 } 182 } 183 184 private void setScreenOn(boolean isScreenOn) { 185 synchronized(mLock) { 186 if (isScreenOn) { 187 mSystemSleepFlags |= FLAG_SCREEN_ON; 188 } else { 189 mSystemSleepFlags &= ~FLAG_SCREEN_ON; 190 } 191 setVrModeAllowedLocked(mSystemSleepFlags == FLAG_ALL); 192 } 193 } 194 195 private final Handler mHandler = new Handler() { 196 @Override 197 public void handleMessage(Message msg) { 198 switch(msg.what) { 199 case MSG_VR_STATE_CHANGE : { 200 boolean state = (msg.arg1 == 1); 201 int i = mRemoteCallbacks.beginBroadcast(); 202 while (i > 0) { 203 i--; 204 try { 205 mRemoteCallbacks.getBroadcastItem(i).onVrStateChanged(state); 206 } catch (RemoteException e) { 207 // Noop 208 } 209 } 210 mRemoteCallbacks.finishBroadcast(); 211 } break; 212 case MSG_PENDING_VR_STATE_CHANGE : { 213 synchronized(mLock) { 214 if (mVrModeAllowed) { 215 VrManagerService.this.consumeAndApplyPendingStateLocked(); 216 } 217 } 218 } break; 219 case MSG_PERSISTENT_VR_MODE_STATE_CHANGE : { 220 boolean state = (msg.arg1 == 1); 221 for (int i = 0; i < mPersistentVrStateListeners.size(); i++) { 222 mPersistentVrStateListeners.get(i).onPersistentVrStateChanged( 223 state); 224 } 225 } break; 226 default : 227 throw new IllegalStateException("Unknown message type: " + msg.what); 228 } 229 } 230 }; 231 232 private static class VrState { 233 final boolean enabled; 234 final int userId; 235 final ComponentName targetPackageName; 236 final ComponentName callingPackage; 237 final long timestamp; 238 final boolean defaultPermissionsGranted; 239 240 VrState(boolean enabled, ComponentName targetPackageName, int userId, 241 ComponentName callingPackage) { 242 this.enabled = enabled; 243 this.userId = userId; 244 this.targetPackageName = targetPackageName; 245 this.callingPackage = callingPackage; 246 this.defaultPermissionsGranted = false; 247 this.timestamp = System.currentTimeMillis(); 248 } 249 250 VrState(boolean enabled, ComponentName targetPackageName, int userId, 251 ComponentName callingPackage, boolean defaultPermissionsGranted) { 252 this.enabled = enabled; 253 this.userId = userId; 254 this.targetPackageName = targetPackageName; 255 this.callingPackage = callingPackage; 256 this.defaultPermissionsGranted = defaultPermissionsGranted; 257 this.timestamp = System.currentTimeMillis(); 258 } 259 } 260 261 private static final BinderChecker sBinderChecker = new BinderChecker() { 262 @Override 263 public IInterface asInterface(IBinder binder) { 264 return IVrListener.Stub.asInterface(binder); 265 } 266 267 @Override 268 public boolean checkType(IInterface service) { 269 return service instanceof IVrListener; 270 } 271 }; 272 273 private final class NotificationAccessManager { 274 private final SparseArray<ArraySet<String>> mAllowedPackages = new SparseArray<>(); 275 private final ArrayMap<String, Integer> mNotificationAccessPackageToUserId = 276 new ArrayMap<>(); 277 278 public void update(Collection<String> packageNames) { 279 int currentUserId = ActivityManager.getCurrentUser(); 280 281 ArraySet<String> allowed = mAllowedPackages.get(currentUserId); 282 if (allowed == null) { 283 allowed = new ArraySet<>(); 284 } 285 286 // Make sure we revoke notification access for listeners in other users 287 final int listenerCount = mNotificationAccessPackageToUserId.size(); 288 for (int i = listenerCount - 1; i >= 0; i--) { 289 final int grantUserId = mNotificationAccessPackageToUserId.valueAt(i); 290 if (grantUserId != currentUserId) { 291 String packageName = mNotificationAccessPackageToUserId.keyAt(i); 292 revokeNotificationListenerAccess(packageName, grantUserId); 293 revokeNotificationPolicyAccess(packageName); 294 revokeCoarseLocationPermissionIfNeeded(packageName, grantUserId); 295 mNotificationAccessPackageToUserId.removeAt(i); 296 } 297 } 298 299 for (String pkg : allowed) { 300 if (!packageNames.contains(pkg)) { 301 revokeNotificationListenerAccess(pkg, currentUserId); 302 revokeNotificationPolicyAccess(pkg); 303 revokeCoarseLocationPermissionIfNeeded(pkg, currentUserId); 304 mNotificationAccessPackageToUserId.remove(pkg); 305 } 306 } 307 for (String pkg : packageNames) { 308 if (!allowed.contains(pkg)) { 309 grantNotificationPolicyAccess(pkg); 310 grantNotificationListenerAccess(pkg, currentUserId); 311 grantCoarseLocationPermissionIfNeeded(pkg, currentUserId); 312 mNotificationAccessPackageToUserId.put(pkg, currentUserId); 313 } 314 } 315 316 allowed.clear(); 317 allowed.addAll(packageNames); 318 mAllowedPackages.put(currentUserId, allowed); 319 } 320 } 321 322 /** 323 * Called when a user, package, or setting changes that could affect whether or not the 324 * currently bound VrListenerService is changed. 325 */ 326 @Override 327 public void onEnabledComponentChanged() { 328 synchronized (mLock) { 329 int currentUser = ActivityManager.getCurrentUser(); 330 // Update listeners 331 ArraySet<ComponentName> enabledListeners = mComponentObserver.getEnabled(currentUser); 332 333 ArraySet<String> enabledPackages = new ArraySet<>(); 334 for (ComponentName n : enabledListeners) { 335 String pkg = n.getPackageName(); 336 if (isDefaultAllowed(pkg)) { 337 enabledPackages.add(n.getPackageName()); 338 } 339 } 340 mNotifAccessManager.update(enabledPackages); 341 342 if (!mVrModeAllowed) { 343 return; // Don't do anything, we shouldn't be in VR mode. 344 } 345 346 // If there is a pending state change, we'd better deal with that first 347 consumeAndApplyPendingStateLocked(false); 348 349 if (mCurrentVrService == null) { 350 return; // No active services 351 } 352 353 // There is an active service, update it if needed 354 updateCurrentVrServiceLocked(mVrModeEnabled, mCurrentVrService.getComponent(), 355 mCurrentVrService.getUserId(), null); 356 } 357 } 358 359 private final IVrManager mVrManager = new IVrManager.Stub() { 360 361 @Override 362 public void registerListener(IVrStateCallbacks cb) { 363 enforceCallerPermission(Manifest.permission.ACCESS_VR_MANAGER); 364 if (cb == null) { 365 throw new IllegalArgumentException("Callback binder object is null."); 366 } 367 368 VrManagerService.this.addStateCallback(cb); 369 } 370 371 @Override 372 public void unregisterListener(IVrStateCallbacks cb) { 373 enforceCallerPermission(Manifest.permission.ACCESS_VR_MANAGER); 374 if (cb == null) { 375 throw new IllegalArgumentException("Callback binder object is null."); 376 } 377 378 VrManagerService.this.removeStateCallback(cb); 379 } 380 381 @Override 382 public boolean getVrModeState() { 383 return VrManagerService.this.getVrMode(); 384 } 385 386 @Override 387 public void setPersistentVrModeEnabled(boolean enabled) { 388 enforceCallerPermission(Manifest.permission.RESTRICTED_VR_ACCESS); 389 VrManagerService.this.setPersistentVrModeEnabled(enabled); 390 } 391 392 @Override 393 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 394 if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 395 != PackageManager.PERMISSION_GRANTED) { 396 pw.println("Permission Denial: can't dump VrManagerService from pid=" 397 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); 398 return; 399 } 400 pw.println("********* Dump of VrManagerService *********"); 401 pw.println("VR mode is currently: " + ((mVrModeAllowed) ? "allowed" : "disallowed")); 402 pw.println("Persistent VR mode is currently: " + 403 ((mPersistentVrModeEnabled) ? "enabled" : "disabled")); 404 pw.println("Previous state transitions:\n"); 405 String tab = " "; 406 dumpStateTransitions(pw); 407 pw.println("\n\nRemote Callbacks:"); 408 int i=mRemoteCallbacks.beginBroadcast(); // create the broadcast item array 409 while(i-->0) { 410 pw.print(tab); 411 pw.print(mRemoteCallbacks.getBroadcastItem(i)); 412 if (i>0) pw.println(","); 413 } 414 mRemoteCallbacks.finishBroadcast(); 415 pw.println("\n"); 416 pw.println("Installed VrListenerService components:"); 417 int userId = mCurrentVrModeUser; 418 ArraySet<ComponentName> installed = mComponentObserver.getInstalled(userId); 419 if (installed == null || installed.size() == 0) { 420 pw.println("None"); 421 } else { 422 for (ComponentName n : installed) { 423 pw.print(tab); 424 pw.println(n.flattenToString()); 425 } 426 } 427 pw.println("Enabled VrListenerService components:"); 428 ArraySet<ComponentName> enabled = mComponentObserver.getEnabled(userId); 429 if (enabled == null || enabled.size() == 0) { 430 pw.println("None"); 431 } else { 432 for (ComponentName n : enabled) { 433 pw.print(tab); 434 pw.println(n.flattenToString()); 435 } 436 } 437 pw.println("Attached persistent mode listeners:"); 438 if (mPersistentVrStateListeners == null || 439 mPersistentVrStateListeners.size() == 0) { 440 pw.println("None"); 441 } else { 442 for (PersistentVrStateListener l : mPersistentVrStateListeners) { 443 pw.print(tab); 444 pw.println("listener: " + l); 445 } 446 } 447 pw.println("\n"); 448 pw.println("********* End of VrManagerService Dump *********"); 449 } 450 451 }; 452 453 private void enforceCallerPermission(String permission) { 454 if (mContext.checkCallingOrSelfPermission(permission) 455 != PackageManager.PERMISSION_GRANTED) { 456 throw new SecurityException("Caller does not hold the permission " + permission); 457 } 458 } 459 460 /** 461 * Implementation of VrManagerInternal. Callable only from system services. 462 */ 463 private final class LocalService extends VrManagerInternal { 464 @Override 465 public void setVrMode(boolean enabled, ComponentName packageName, int userId, 466 ComponentName callingPackage) { 467 VrManagerService.this.setVrMode(enabled, packageName, userId, callingPackage); 468 } 469 470 @Override 471 public void onSleepStateChanged(boolean isAsleep) { 472 VrManagerService.this.setSleepState(isAsleep); 473 } 474 475 @Override 476 public void onScreenStateChanged(boolean isScreenOn) { 477 VrManagerService.this.setScreenOn(isScreenOn); 478 } 479 480 @Override 481 public boolean isCurrentVrListener(String packageName, int userId) { 482 return VrManagerService.this.isCurrentVrListener(packageName, userId); 483 } 484 485 @Override 486 public int hasVrPackage(ComponentName packageName, int userId) { 487 return VrManagerService.this.hasVrPackage(packageName, userId); 488 } 489 490 @Override 491 public void setPersistentVrModeEnabled(boolean enabled) { 492 VrManagerService.this.setPersistentVrModeEnabled(enabled); 493 } 494 495 @Override 496 public void addPersistentVrModeStateListener(PersistentVrStateListener listener) { 497 VrManagerService.this.addPersistentVrModeStateListener(listener); 498 } 499 } 500 501 public VrManagerService(Context context) { 502 super(context); 503 } 504 505 @Override 506 public void onStart() { 507 synchronized(mLock) { 508 initializeNative(); 509 mContext = getContext(); 510 } 511 512 publishLocalService(VrManagerInternal.class, new LocalService()); 513 publishBinderService(Context.VR_SERVICE, mVrManager.asBinder()); 514 } 515 516 @Override 517 public void onBootPhase(int phase) { 518 if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) { 519 synchronized (mLock) { 520 Looper looper = Looper.getMainLooper(); 521 Handler handler = new Handler(looper); 522 ArrayList<EnabledComponentChangeListener> listeners = new ArrayList<>(); 523 listeners.add(this); 524 mComponentObserver = EnabledComponentsObserver.build(mContext, handler, 525 Settings.Secure.ENABLED_VR_LISTENERS, looper, 526 android.Manifest.permission.BIND_VR_LISTENER_SERVICE, 527 VrListenerService.SERVICE_INTERFACE, mLock, listeners); 528 529 mComponentObserver.rebuildAll(); 530 } 531 532 //TODO: something more robust than picking the first one 533 ArraySet<ComponentName> defaultVrComponents = 534 SystemConfig.getInstance().getDefaultVrComponents(); 535 if (defaultVrComponents.size() > 0) { 536 mDefaultVrService = defaultVrComponents.valueAt(0); 537 } else { 538 Slog.i(TAG, "No default vr listener service found."); 539 } 540 } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) { 541 synchronized (mLock) { 542 mVrModeAllowed = true; 543 } 544 } 545 } 546 547 @Override 548 public void onStartUser(int userHandle) { 549 synchronized (mLock) { 550 mComponentObserver.onUsersChanged(); 551 } 552 } 553 554 @Override 555 public void onSwitchUser(int userHandle) { 556 synchronized (mLock) { 557 mComponentObserver.onUsersChanged(); 558 } 559 560 } 561 562 @Override 563 public void onStopUser(int userHandle) { 564 synchronized (mLock) { 565 mComponentObserver.onUsersChanged(); 566 } 567 568 } 569 570 @Override 571 public void onCleanupUser(int userHandle) { 572 synchronized (mLock) { 573 mComponentObserver.onUsersChanged(); 574 } 575 } 576 577 private void updateOverlayStateLocked(String exemptedPackage, int newUserId, int oldUserId) { 578 AppOpsManager appOpsManager = getContext().getSystemService(AppOpsManager.class); 579 580 // If user changed drop restrictions for the old user. 581 if (oldUserId != newUserId) { 582 appOpsManager.setUserRestrictionForUser(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, 583 false, mOverlayToken, null, oldUserId); 584 } 585 586 if (!mVrModeEnabled) { 587 return; 588 } 589 590 // Apply the restrictions for the current user based on vr state 591 String[] exemptions = (exemptedPackage == null) ? new String[0] : 592 new String[] { exemptedPackage }; 593 594 appOpsManager.setUserRestrictionForUser(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, 595 true, mOverlayToken, exemptions, newUserId); 596 } 597 598 private void updateDependentAppOpsLocked(String newVrServicePackage, int newUserId, 599 String oldVrServicePackage, int oldUserId) { 600 // If VR state changed and we also have a VR service change. 601 if (Objects.equals(newVrServicePackage, oldVrServicePackage)) { 602 return; 603 } 604 final long identity = Binder.clearCallingIdentity(); 605 try { 606 // Set overlay exception state based on VR enabled and current service 607 updateOverlayStateLocked(newVrServicePackage, newUserId, oldUserId); 608 } finally { 609 Binder.restoreCallingIdentity(identity); 610 } 611 } 612 613 /** 614 * Send VR mode changes (if the mode state has changed), and update the bound/unbound state of 615 * the currently selected VR listener service. If the component selected for the VR listener 616 * service has changed, unbind the previous listener and bind the new listener (if enabled). 617 * <p/> 618 * Note: Must be called while holding {@code mLock}. 619 * 620 * @param enabled new state for VR mode. 621 * @param component new component to be bound as a VR listener. 622 * @param userId user owning the component to be bound. 623 * @param calling the component currently using VR mode, or null to leave unchanged. 624 * 625 * @return {@code true} if the component/user combination specified is valid. 626 */ 627 private boolean updateCurrentVrServiceLocked(boolean enabled, @NonNull ComponentName component, 628 int userId, ComponentName calling) { 629 630 boolean sendUpdatedCaller = false; 631 final long identity = Binder.clearCallingIdentity(); 632 try { 633 634 boolean validUserComponent = (mComponentObserver.isValid(component, userId) == 635 EnabledComponentsObserver.NO_ERROR); 636 boolean goingIntoVrMode = validUserComponent && enabled; 637 if (!mVrModeEnabled && !goingIntoVrMode) { 638 return validUserComponent; // Disabled -> Disabled transition does nothing. 639 } 640 641 String oldVrServicePackage = mCurrentVrService != null 642 ? mCurrentVrService.getComponent().getPackageName() : null; 643 final int oldUserId = mCurrentVrModeUser; 644 645 // Notify system services and VR HAL of mode change. 646 changeVrModeLocked(goingIntoVrMode); 647 648 boolean nothingChanged = false; 649 if (!goingIntoVrMode) { 650 // Not going into VR mode, unbind whatever is running 651 if (mCurrentVrService != null) { 652 Slog.i(TAG, "Leaving VR mode, disconnecting " 653 + mCurrentVrService.getComponent() + " for user " 654 + mCurrentVrService.getUserId()); 655 mCurrentVrService.disconnect(); 656 mCurrentVrService = null; 657 } else { 658 nothingChanged = true; 659 } 660 } else { 661 // Going into VR mode 662 if (mCurrentVrService != null) { 663 // Unbind any running service that doesn't match the latest component/user 664 // selection. 665 if (mCurrentVrService.disconnectIfNotMatching(component, userId)) { 666 Slog.i(TAG, "VR mode component changed to " + component 667 + ", disconnecting " + mCurrentVrService.getComponent() 668 + " for user " + mCurrentVrService.getUserId()); 669 createAndConnectService(component, userId); 670 sendUpdatedCaller = true; 671 } else { 672 nothingChanged = true; 673 } 674 // The service with the correct component/user is already bound, do nothing. 675 } else { 676 // Nothing was previously running, bind a new service for the latest 677 // component/user selection. 678 createAndConnectService(component, userId); 679 sendUpdatedCaller = true; 680 } 681 } 682 683 mCurrentVrModeComponent = calling; 684 if (calling != null && !Objects.equals(calling, mCurrentVrModeComponent)) { 685 sendUpdatedCaller = true; 686 } 687 688 if (mCurrentVrModeUser != userId) { 689 mCurrentVrModeUser = userId; 690 sendUpdatedCaller = true; 691 } 692 693 String newVrServicePackage = mCurrentVrService != null 694 ? mCurrentVrService.getComponent().getPackageName() : null; 695 final int newUserId = mCurrentVrModeUser; 696 697 // Update AppOps settings that change state when entering/exiting VR mode, or changing 698 // the current VrListenerService. 699 updateDependentAppOpsLocked(newVrServicePackage, newUserId, 700 oldVrServicePackage, oldUserId); 701 702 if (mCurrentVrService != null && sendUpdatedCaller) { 703 final ComponentName c = mCurrentVrModeComponent; 704 mCurrentVrService.sendEvent(new PendingEvent() { 705 @Override 706 public void runEvent(IInterface service) throws RemoteException { 707 IVrListener l = (IVrListener) service; 708 l.focusedActivityChanged(c); 709 } 710 }); 711 } 712 713 if (!nothingChanged) { 714 logStateLocked(); 715 } 716 717 return validUserComponent; 718 } finally { 719 Binder.restoreCallingIdentity(identity); 720 } 721 } 722 723 private boolean isDefaultAllowed(String packageName) { 724 PackageManager pm = mContext.getPackageManager(); 725 726 ApplicationInfo info = null; 727 try { 728 info = pm.getApplicationInfo(packageName, PackageManager.GET_META_DATA); 729 } catch (NameNotFoundException e) { 730 } 731 732 if (info == null || !(info.isSystemApp() || info.isUpdatedSystemApp())) { 733 return false; 734 } 735 return true; 736 } 737 738 private void grantNotificationPolicyAccess(String pkg) { 739 NotificationManager nm = mContext.getSystemService(NotificationManager.class); 740 nm.setNotificationPolicyAccessGranted(pkg, true); 741 } 742 743 private void revokeNotificationPolicyAccess(String pkg) { 744 NotificationManager nm = mContext.getSystemService(NotificationManager.class); 745 // Remove any DND zen rules possibly created by the package. 746 nm.removeAutomaticZenRules(pkg); 747 // Remove Notification Policy Access. 748 nm.setNotificationPolicyAccessGranted(pkg, false); 749 } 750 751 private void grantNotificationListenerAccess(String pkg, int userId) { 752 PackageManager pm = mContext.getPackageManager(); 753 ArraySet<ComponentName> possibleServices = EnabledComponentsObserver.loadComponentNames(pm, 754 userId, NotificationListenerService.SERVICE_INTERFACE, 755 android.Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE); 756 ContentResolver resolver = mContext.getContentResolver(); 757 758 ArraySet<String> current = getNotificationListeners(resolver, userId); 759 760 for (ComponentName c : possibleServices) { 761 String flatName = c.flattenToString(); 762 if (Objects.equals(c.getPackageName(), pkg) 763 && !current.contains(flatName)) { 764 current.add(flatName); 765 } 766 } 767 768 if (current.size() > 0) { 769 String flatSettings = formatSettings(current); 770 Settings.Secure.putStringForUser(resolver, 771 Settings.Secure.ENABLED_NOTIFICATION_LISTENERS, 772 flatSettings, userId); 773 } 774 } 775 776 private void revokeNotificationListenerAccess(String pkg, int userId) { 777 ContentResolver resolver = mContext.getContentResolver(); 778 779 ArraySet<String> current = getNotificationListeners(resolver, userId); 780 781 ArrayList<String> toRemove = new ArrayList<>(); 782 783 for (String c : current) { 784 ComponentName component = ComponentName.unflattenFromString(c); 785 if (component != null && component.getPackageName().equals(pkg)) { 786 toRemove.add(c); 787 } 788 } 789 790 current.removeAll(toRemove); 791 792 String flatSettings = formatSettings(current); 793 Settings.Secure.putStringForUser(resolver, 794 Settings.Secure.ENABLED_NOTIFICATION_LISTENERS, 795 flatSettings, userId); 796 } 797 798 private void grantCoarseLocationPermissionIfNeeded(String pkg, int userId) { 799 // Don't clobber the user if permission set in current state explicitly 800 if (!isPermissionUserUpdated(Manifest.permission.ACCESS_COARSE_LOCATION, pkg, userId)) { 801 try { 802 mContext.getPackageManager().grantRuntimePermission(pkg, 803 Manifest.permission.ACCESS_COARSE_LOCATION, new UserHandle(userId)); 804 } catch (IllegalArgumentException e) { 805 // Package was removed during update. 806 Slog.w(TAG, "Could not grant coarse location permission, package " + pkg 807 + " was removed."); 808 } 809 } 810 } 811 812 private void revokeCoarseLocationPermissionIfNeeded(String pkg, int userId) { 813 // Don't clobber the user if permission set in current state explicitly 814 if (!isPermissionUserUpdated(Manifest.permission.ACCESS_COARSE_LOCATION, pkg, userId)) { 815 try { 816 mContext.getPackageManager().revokeRuntimePermission(pkg, 817 Manifest.permission.ACCESS_COARSE_LOCATION, new UserHandle(userId)); 818 } catch (IllegalArgumentException e) { 819 // Package was removed during update. 820 Slog.w(TAG, "Could not revoke coarse location permission, package " + pkg 821 + " was removed."); 822 } 823 } 824 } 825 826 private boolean isPermissionUserUpdated(String permission, String pkg, int userId) { 827 final int flags = mContext.getPackageManager().getPermissionFlags( 828 permission, pkg, new UserHandle(userId)); 829 return (flags & (PackageManager.FLAG_PERMISSION_USER_SET 830 | PackageManager.FLAG_PERMISSION_USER_FIXED)) != 0; 831 } 832 833 private ArraySet<String> getNotificationListeners(ContentResolver resolver, int userId) { 834 String flat = Settings.Secure.getStringForUser(resolver, 835 Settings.Secure.ENABLED_NOTIFICATION_LISTENERS, userId); 836 837 ArraySet<String> current = new ArraySet<>(); 838 if (flat != null) { 839 String[] allowed = flat.split(":"); 840 for (String s : allowed) { 841 if (!TextUtils.isEmpty(s)) { 842 current.add(s); 843 } 844 } 845 } 846 return current; 847 } 848 849 private static String formatSettings(Collection<String> c) { 850 if (c == null || c.isEmpty()) { 851 return ""; 852 } 853 854 StringBuilder b = new StringBuilder(); 855 boolean start = true; 856 for (String s : c) { 857 if ("".equals(s)) { 858 continue; 859 } 860 if (!start) { 861 b.append(':'); 862 } 863 b.append(s); 864 start = false; 865 } 866 return b.toString(); 867 } 868 869 870 871 private void createAndConnectService(@NonNull ComponentName component, int userId) { 872 mCurrentVrService = VrManagerService.create(mContext, component, userId); 873 mCurrentVrService.connect(); 874 Slog.i(TAG, "Connecting " + component + " for user " + userId); 875 } 876 877 /** 878 * Send VR mode change callbacks to HAL and system services if mode has actually changed. 879 * <p/> 880 * Note: Must be called while holding {@code mLock}. 881 * 882 * @param enabled new state of the VR mode. 883 */ 884 private void changeVrModeLocked(boolean enabled) { 885 if (mVrModeEnabled != enabled) { 886 mVrModeEnabled = enabled; 887 888 // Log mode change event. 889 Slog.i(TAG, "VR mode " + ((mVrModeEnabled) ? "enabled" : "disabled")); 890 setVrModeNative(mVrModeEnabled); 891 892 onVrModeChangedLocked(); 893 } 894 } 895 896 /** 897 * Notify system services of VR mode change. 898 * <p/> 899 * Note: Must be called while holding {@code mLock}. 900 */ 901 private void onVrModeChangedLocked() { 902 mHandler.sendMessage(mHandler.obtainMessage(MSG_VR_STATE_CHANGE, 903 (mVrModeEnabled) ? 1 : 0, 0)); 904 } 905 906 /** 907 * Helper function for making ManagedApplicationService instances. 908 */ 909 private static ManagedApplicationService create(@NonNull Context context, 910 @NonNull ComponentName component, int userId) { 911 return ManagedApplicationService.build(context, component, userId, 912 R.string.vr_listener_binding_label, Settings.ACTION_VR_LISTENER_SETTINGS, 913 sBinderChecker); 914 } 915 916 /** 917 * Apply the pending VR state. If no state is pending, disconnect any currently bound 918 * VR listener service. 919 */ 920 private void consumeAndApplyPendingStateLocked() { 921 consumeAndApplyPendingStateLocked(true); 922 } 923 924 /** 925 * Apply the pending VR state. 926 * 927 * @param disconnectIfNoPendingState if {@code true}, then any currently bound VR listener 928 * service will be disconnected if no state is pending. If this is {@code false} then the 929 * nothing will be changed when there is no pending state. 930 */ 931 private void consumeAndApplyPendingStateLocked(boolean disconnectIfNoPendingState) { 932 if (mPendingState != null) { 933 updateCurrentVrServiceLocked(mPendingState.enabled, 934 mPendingState.targetPackageName, mPendingState.userId, 935 mPendingState.callingPackage); 936 mPendingState = null; 937 } else if (disconnectIfNoPendingState) { 938 updateCurrentVrServiceLocked(false, null, 0, null); 939 } 940 } 941 942 private void logStateLocked() { 943 ComponentName currentBoundService = (mCurrentVrService == null) ? null : 944 mCurrentVrService.getComponent(); 945 VrState current = new VrState(mVrModeEnabled, currentBoundService, mCurrentVrModeUser, 946 mCurrentVrModeComponent, mWasDefaultGranted); 947 if (mLoggingDeque.size() == EVENT_LOG_SIZE) { 948 mLoggingDeque.removeFirst(); 949 } 950 mLoggingDeque.add(current); 951 } 952 953 private void dumpStateTransitions(PrintWriter pw) { 954 SimpleDateFormat d = new SimpleDateFormat("MM-dd HH:mm:ss.SSS"); 955 String tab = " "; 956 if (mLoggingDeque.size() == 0) { 957 pw.print(tab); 958 pw.println("None"); 959 } 960 for (VrState state : mLoggingDeque) { 961 pw.print(d.format(new Date(state.timestamp))); 962 pw.print(tab); 963 pw.print("State changed to:"); 964 pw.print(tab); 965 pw.println((state.enabled) ? "ENABLED" : "DISABLED"); 966 if (state.enabled) { 967 pw.print(tab); 968 pw.print("User="); 969 pw.println(state.userId); 970 pw.print(tab); 971 pw.print("Current VR Activity="); 972 pw.println((state.callingPackage == null) ? 973 "None" : state.callingPackage.flattenToString()); 974 pw.print(tab); 975 pw.print("Bound VrListenerService="); 976 pw.println((state.targetPackageName == null) ? 977 "None" : state.targetPackageName.flattenToString()); 978 if (state.defaultPermissionsGranted) { 979 pw.print(tab); 980 pw.println("Default permissions granted to the bound VrListenerService."); 981 } 982 } 983 } 984 } 985 986 /* 987 * Implementation of VrManagerInternal calls. These are callable from system services. 988 */ 989 private void setVrMode(boolean enabled, @NonNull ComponentName targetPackageName, 990 int userId, @NonNull ComponentName callingPackage) { 991 992 synchronized (mLock) { 993 VrState pending; 994 ComponentName targetListener; 995 ComponentName foregroundVrComponent; 996 997 // If the device is in persistent VR mode, then calls to disable VR mode are ignored, 998 // and the system default VR listener is used. 999 boolean targetEnabledState = enabled || mPersistentVrModeEnabled; 1000 if (!enabled && mPersistentVrModeEnabled) { 1001 targetListener = mDefaultVrService; 1002 1003 // Current foreground component isn't a VR one (in 2D app case) 1004 foregroundVrComponent = null; 1005 } else { 1006 targetListener = targetPackageName; 1007 foregroundVrComponent = callingPackage; 1008 } 1009 pending = new VrState( 1010 targetEnabledState, targetListener, userId, foregroundVrComponent); 1011 1012 if (!mVrModeAllowed) { 1013 // We're not allowed to be in VR mode. Make this state pending. This will be 1014 // applied the next time we are allowed to enter VR mode unless it is superseded by 1015 // another call. 1016 mPendingState = pending; 1017 return; 1018 } 1019 1020 if (!targetEnabledState && mCurrentVrService != null) { 1021 // If we're transitioning out of VR mode, delay briefly to avoid expensive HAL calls 1022 // and service bind/unbind in case we are immediately switching to another VR app. 1023 if (mPendingState == null) { 1024 mHandler.sendEmptyMessageDelayed(MSG_PENDING_VR_STATE_CHANGE, 1025 PENDING_STATE_DELAY_MS); 1026 } 1027 1028 mPendingState = pending; 1029 return; 1030 } else { 1031 mHandler.removeMessages(MSG_PENDING_VR_STATE_CHANGE); 1032 mPendingState = null; 1033 } 1034 1035 updateCurrentVrServiceLocked( 1036 targetEnabledState, targetListener, userId, foregroundVrComponent); 1037 } 1038 } 1039 1040 private void setPersistentVrModeEnabled(boolean enabled) { 1041 synchronized(mLock) { 1042 setPersistentModeAndNotifyListenersLocked(enabled); 1043 // Disabling persistent mode when not showing a VR should disable the overall vr mode. 1044 if (!enabled && mCurrentVrModeComponent == null) { 1045 setVrMode(false, null, 0, null); 1046 } 1047 } 1048 } 1049 1050 private void setPersistentModeAndNotifyListenersLocked(boolean enabled) { 1051 if (mPersistentVrModeEnabled == enabled) { 1052 return; 1053 } 1054 mPersistentVrModeEnabled = enabled; 1055 1056 mHandler.sendMessage(mHandler.obtainMessage(MSG_PERSISTENT_VR_MODE_STATE_CHANGE, 1057 (mPersistentVrModeEnabled) ? 1 : 0, 0)); 1058 } 1059 1060 private void addPersistentVrModeStateListener(PersistentVrStateListener listener) { 1061 synchronized (mLock) { 1062 mPersistentVrStateListeners.add(listener); 1063 } 1064 } 1065 1066 private int hasVrPackage(@NonNull ComponentName targetPackageName, int userId) { 1067 synchronized (mLock) { 1068 return mComponentObserver.isValid(targetPackageName, userId); 1069 } 1070 } 1071 1072 private boolean isCurrentVrListener(String packageName, int userId) { 1073 synchronized (mLock) { 1074 if (mCurrentVrService == null) { 1075 return false; 1076 } 1077 return mCurrentVrService.getComponent().getPackageName().equals(packageName) && 1078 userId == mCurrentVrService.getUserId(); 1079 } 1080 } 1081 1082 /* 1083 * Implementation of IVrManager calls. 1084 */ 1085 1086 private void addStateCallback(IVrStateCallbacks cb) { 1087 mRemoteCallbacks.register(cb); 1088 } 1089 1090 private void removeStateCallback(IVrStateCallbacks cb) { 1091 mRemoteCallbacks.unregister(cb); 1092 } 1093 1094 private boolean getVrMode() { 1095 synchronized (mLock) { 1096 return mVrModeEnabled; 1097 } 1098 } 1099} 1100