Loading services/core/java/com/android/server/am/ActivityManagerService.java +17 −39 Original line number Diff line number Diff line Loading @@ -1212,6 +1212,15 @@ public final class ActivityManagerService extends ActivityManagerNative /** * Set while we are wanting to sleep, to prevent any * activities from being started/resumed. * * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping. * * Currently mSleeping is set to true when transitioning into the sleep state, and remains true * while in the sleep state until there is a pending transition out of sleep, in which case * mSleeping is set to false, and remains false while awake. * * Whether mSleeping can quickly toggled between true/false without the device actually * display changing states is undefined. */ private boolean mSleeping = false; Loading Loading @@ -1537,8 +1546,7 @@ public final class ActivityManagerService extends ActivityManagerNative static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66; static final int NOTIFY_FORCED_RESIZABLE_MSG = 67; static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68; static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69; static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 70; static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 69; static final int FIRST_ACTIVITY_STACK_MSG = 100; static final int FIRST_BROADCAST_QUEUE_MSG = 200; Loading Loading @@ -2355,14 +2363,6 @@ public final class ActivityManagerService extends ActivityManagerNative } vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage); } break; case VR_MODE_APPLY_IF_NEEDED_MSG: { final ActivityRecord r = (ActivityRecord) msg.obj; final boolean needsVrMode = r != null && r.requestedVrComponent != null; if (needsVrMode) { applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId, r.info.getComponentName(), false); } } break; } } }; Loading Loading @@ -3164,20 +3164,12 @@ public final class ActivityManagerService extends ActivityManagerNative mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r)); } private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) { mHandler.sendMessage( mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r)); } private void applyVrMode(boolean enabled, ComponentName packageName, int userId, ComponentName callingPackage, boolean immediate) { VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class); if (immediate) { vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage); } else { vrService.setVrMode(enabled, packageName, userId, callingPackage); private void notifyVrManagerOfSleepState(boolean isSleeping) { final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class); if (vrService == null) { return; } vrService.onSleepStateChanged(isSleeping); } final void showAskCompatModeDialogLocked(ActivityRecord r) { Loading Loading @@ -6770,7 +6762,6 @@ public final class ActivityManagerService extends ActivityManagerNative // Some stack visibility might change (e.g. docked stack) mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); applyVrModeIfNeededLocked(mFocusedActivity, true); } } } finally { Loading Loading @@ -11699,6 +11690,7 @@ public final class ActivityManagerService extends ActivityManagerNative startTimeTrackingFocusedActivityLocked(); mTopProcessState = ActivityManager.PROCESS_STATE_TOP; mStackSupervisor.comeOutOfSleepIfNeededLocked(); notifyVrManagerOfSleepState(false); updateOomAdjLocked(); } else if (!mSleeping && shouldSleepLocked()) { mSleeping = true; Loading @@ -11707,6 +11699,7 @@ public final class ActivityManagerService extends ActivityManagerNative } mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING; mStackSupervisor.goingToSleepLocked(); notifyVrManagerOfSleepState(true); updateOomAdjLocked(); // Initialize the wake times of all processes. Loading Loading @@ -21932,21 +21925,6 @@ public final class ActivityManagerService extends ActivityManagerNative public SleepToken acquireSleepToken(String tag) { Preconditions.checkNotNull(tag); ComponentName requestedVrService = null; ComponentName callingVrActivity = null; int userId = -1; synchronized (ActivityManagerService.this) { if (mFocusedActivity != null) { requestedVrService = mFocusedActivity.requestedVrComponent; callingVrActivity = mFocusedActivity.info.getComponentName(); userId = mFocusedActivity.userId; } } if (requestedVrService != null) { applyVrMode(false, requestedVrService, userId, callingVrActivity, true); } synchronized (ActivityManagerService.this) { SleepTokenImpl token = new SleepTokenImpl(tag); mSleepTokens.add(token); services/core/java/com/android/server/policy/PhoneWindowManager.java +11 −0 Original line number Diff line number Diff line Loading @@ -152,6 +152,7 @@ import com.android.server.LocalServices; import com.android.server.policy.keyguard.KeyguardServiceDelegate; import com.android.server.policy.keyguard.KeyguardServiceDelegate.DrawnListener; import com.android.server.statusbar.StatusBarManagerInternal; import com.android.server.vr.VrManagerInternal; import java.io.File; import java.io.FileReader; Loading Loading @@ -6513,6 +6514,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { mKeyguardDelegate.onScreenTurnedOff(); } } reportScreenStateToVrManager(false); } // Called on the DisplayManager's DisplayPowerController thread. Loading Loading @@ -6548,6 +6550,15 @@ public class PhoneWindowManager implements WindowManagerPolicy { mKeyguardDelegate.onScreenTurnedOn(); } } reportScreenStateToVrManager(true); } private void reportScreenStateToVrManager(boolean isScreenOn) { VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class); if (vrService == null) { return; } vrService.onScreenStateChanged(isScreenOn); } private void finishWindowsDrawn() { Loading services/core/java/com/android/server/vr/VrManagerInternal.java +18 −16 Original line number Diff line number Diff line Loading @@ -56,16 +56,19 @@ public abstract class VrManagerInternal { int userId, @NonNull ComponentName calling); /** * Set the current VR mode state immediately. * Set whether the system has acquired a sleep token. * * @param enabled {@code true} to enable VR mode. * @param packageName The package name of the requested VrListenerService to bind. * @param userId the user requesting the VrListenerService component. * @param calling the component currently using VR mode, or null to leave unchanged. * @param isAsleep is {@code true} if the device is asleep, or {@code false} otherwise. */ public abstract void setVrModeImmediate(boolean enabled, @NonNull ComponentName packageName, int userId, @NonNull ComponentName calling); public abstract void onSleepStateChanged(boolean isAsleep); /** * Set whether the display used for VR output is on. * * @param isScreenOn is {@code true} if the display is on and can receive commands, * or {@code false} otherwise. */ public abstract void onScreenStateChanged(boolean isScreenOn); /** * Return NO_ERROR if the given package is installed on the device and enabled as a Loading @@ -76,5 +79,4 @@ public abstract class VrManagerInternal { * given in {@link android.service.vr.VrModeException} on failure. */ public abstract int hasVrPackage(@NonNull ComponentName packageName, int userId); } services/core/java/com/android/server/vr/VrManagerService.java +121 −21 Original line number Diff line number Diff line Loading @@ -101,6 +101,14 @@ public class VrManagerService extends SystemService implements EnabledComponentC private static final int PENDING_STATE_DELAY_MS = 300; private static final int EVENT_LOG_SIZE = 32; private static final int INVALID_APPOPS_MODE = -1; /** Null set of sleep sleep flags. */ private static final int FLAG_NONE = 0; /** Flag set when the device is not sleeping. */ private static final int FLAG_AWAKE = 1; /** Flag set when the screen has been turned on. */ private static final int FLAG_SCREEN_ON = 2; /** Flag indicating that all system sleep flags have been set.*/ private static final int FLAG_ALL = FLAG_AWAKE | FLAG_SCREEN_ON; private static native void initializeNative(); private static native void setVrModeNative(boolean enabled); Loading @@ -110,6 +118,7 @@ public class VrManagerService extends SystemService implements EnabledComponentC private final IBinder mOverlayToken = new Binder(); // State protected by mLock private boolean mVrModeAllowed; private boolean mVrModeEnabled; private EnabledComponentsObserver mComponentObserver; private ManagedApplicationService mCurrentVrService; Loading @@ -125,10 +134,64 @@ public class VrManagerService extends SystemService implements EnabledComponentC private VrState mPendingState; private final ArrayDeque<VrState> mLoggingDeque = new ArrayDeque<>(EVENT_LOG_SIZE); private final NotificationAccessManager mNotifAccessManager = new NotificationAccessManager(); /** Tracks the state of the screen and keyguard UI.*/ private int mSystemSleepFlags = FLAG_NONE; private static final int MSG_VR_STATE_CHANGE = 0; private static final int MSG_PENDING_VR_STATE_CHANGE = 1; /** * Set whether VR mode may be enabled. * <p/> * If VR mode is not allowed to be enabled, calls to set VR mode will be cached. When VR mode * is again allowed to be enabled, the most recent cached state will be applied. * * @param allowed {@code true} if calling any of the setVrMode methods may cause the device to * enter VR mode. */ private void setVrModeAllowedLocked(boolean allowed) { if (mVrModeAllowed != allowed) { mVrModeAllowed = allowed; Slog.i(TAG, "VR mode is " + ((allowed) ? "allowed" : "disallowed")); if (mVrModeAllowed) { consumeAndApplyPendingStateLocked(); } else { // Set pending state to current state. mPendingState = (mVrModeEnabled && mCurrentVrService != null) ? new VrState(mVrModeEnabled, mCurrentVrService.getComponent(), mCurrentVrService.getUserId(), mCurrentVrModeComponent) : null; // Unbind current VR service and do necessary callbacks. updateCurrentVrServiceLocked(false, null, 0, null); } } } private void setSleepState(boolean isAsleep) { synchronized(mLock) { if (!isAsleep) { mSystemSleepFlags |= FLAG_AWAKE; } else { mSystemSleepFlags &= ~FLAG_AWAKE; } setVrModeAllowedLocked(mSystemSleepFlags == FLAG_ALL); } } private void setScreenOn(boolean isScreenOn) { synchronized(mLock) { if (isScreenOn) { mSystemSleepFlags |= FLAG_SCREEN_ON; } else { mSystemSleepFlags &= ~FLAG_SCREEN_ON; } setVrModeAllowedLocked(mSystemSleepFlags == FLAG_ALL); } } private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { Loading @@ -148,8 +211,10 @@ public class VrManagerService extends SystemService implements EnabledComponentC } break; case MSG_PENDING_VR_STATE_CHANGE : { synchronized(mLock) { if (mVrModeAllowed) { VrManagerService.this.consumeAndApplyPendingStateLocked(); } } } break; default : throw new IllegalStateException("Unknown message type: " + msg.what); Loading Loading @@ -268,8 +333,8 @@ public class VrManagerService extends SystemService implements EnabledComponentC } mNotifAccessManager.update(enabledPackages); if (mCurrentVrService == null) { return; // No active services if (!mVrModeAllowed) { return; // Don't do anything, we shouldn't be in VR mode. } // If there is a pending state change, we'd better deal with that first Loading Loading @@ -321,6 +386,7 @@ public class VrManagerService extends SystemService implements EnabledComponentC return; } pw.println("********* Dump of VrManagerService *********"); pw.println("VR mode is currently: " + ((mVrModeAllowed) ? "allowed" : "disallowed")); pw.println("Previous state transitions:\n"); String tab = " "; dumpStateTransitions(pw); Loading Loading @@ -374,13 +440,17 @@ public class VrManagerService extends SystemService implements EnabledComponentC @Override public void setVrMode(boolean enabled, ComponentName packageName, int userId, ComponentName callingPackage) { VrManagerService.this.setVrMode(enabled, packageName, userId, callingPackage, false); VrManagerService.this.setVrMode(enabled, packageName, userId, callingPackage); } @Override public void setVrModeImmediate(boolean enabled, ComponentName packageName, int userId, ComponentName callingPackage) { VrManagerService.this.setVrMode(enabled, packageName, userId, callingPackage, true); public void onSleepStateChanged(boolean isAsleep) { VrManagerService.this.setSleepState(isAsleep); } @Override public void onScreenStateChanged(boolean isScreenOn) { VrManagerService.this.setScreenOn(isScreenOn); } @Override Loading Loading @@ -424,6 +494,10 @@ public class VrManagerService extends SystemService implements EnabledComponentC mComponentObserver.rebuildAll(); } } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) { synchronized (mLock) { mVrModeAllowed = true; } } } Loading Loading @@ -466,12 +540,16 @@ public class VrManagerService extends SystemService implements EnabledComponentC false, mOverlayToken, null, oldUserId); } if (!mVrModeEnabled) { return; } // Apply the restrictions for the current user based on vr state String[] exemptions = (exemptedPackage == null) ? new String[0] : new String[] { exemptedPackage }; appOpsManager.setUserRestrictionForUser(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, mVrModeEnabled, mOverlayToken, exemptions, newUserId); true, mOverlayToken, exemptions, newUserId); } private void updateDependentAppOpsLocked(String newVrServicePackage, int newUserId, Loading Loading @@ -512,7 +590,8 @@ public class VrManagerService extends SystemService implements EnabledComponentC boolean validUserComponent = (mComponentObserver.isValid(component, userId) == EnabledComponentsObserver.NO_ERROR); if (!mVrModeEnabled && !enabled) { boolean goingIntoVrMode = validUserComponent && enabled; if (!mVrModeEnabled && !goingIntoVrMode) { return validUserComponent; // Disabled -> Disabled transition does nothing. } Loading @@ -520,29 +599,37 @@ public class VrManagerService extends SystemService implements EnabledComponentC ? mCurrentVrService.getComponent().getPackageName() : null; final int oldUserId = mCurrentVrModeUser; // Always send mode change events. changeVrModeLocked(enabled); // Notify system services and VR HAL of mode change. changeVrModeLocked(goingIntoVrMode); if (!enabled || !validUserComponent) { // Unbind whatever is running boolean nothingChanged = false; if (!goingIntoVrMode) { // Not going into VR mode, unbind whatever is running if (mCurrentVrService != null) { Slog.i(TAG, "Disconnecting " + mCurrentVrService.getComponent() + " for user " + mCurrentVrService.getUserId()); mCurrentVrService.disconnect(); mCurrentVrService = null; } else { nothingChanged = true; } } else { // Going into VR mode if (mCurrentVrService != null) { // Unbind any running service that doesn't match the component/user selection // Unbind any running service that doesn't match the latest component/user // selection. if (mCurrentVrService.disconnectIfNotMatching(component, userId)) { Slog.i(TAG, "Disconnecting " + mCurrentVrService.getComponent() + " for user " + mCurrentVrService.getUserId()); createAndConnectService(component, userId); sendUpdatedCaller = true; } else { nothingChanged = true; } // The service with the correct component/user is bound // The service with the correct component/user is already bound, do nothing. } else { // Nothing was previously running, bind a new service // Nothing was previously running, bind a new service for the latest // component/user selection. createAndConnectService(component, userId); sendUpdatedCaller = true; } Loading Loading @@ -577,7 +664,10 @@ public class VrManagerService extends SystemService implements EnabledComponentC } }); } if (!nothingChanged) { logStateLocked(); } return validUserComponent; } finally { Loading Loading @@ -784,7 +874,10 @@ public class VrManagerService extends SystemService implements EnabledComponentC mPendingState.targetPackageName, mPendingState.userId, mPendingState.callingPackage); mPendingState = null; } else { updateCurrentVrServiceLocked(false, null, 0, null); } } private void logStateLocked() { Loading Loading @@ -834,13 +927,20 @@ public class VrManagerService extends SystemService implements EnabledComponentC /* * Implementation of VrManagerInternal calls. These are callable from system services. */ private void setVrMode(boolean enabled, @NonNull ComponentName targetPackageName, int userId, @NonNull ComponentName callingPackage, boolean immediate) { int userId, @NonNull ComponentName callingPackage) { synchronized (mLock) { VrState pending = new VrState(enabled, targetPackageName, userId, callingPackage); if (!mVrModeAllowed) { // We're not allowed to be in VR mode. Make this state pending. This will be // applied the next time we are allowed to enter VR mode unless it is superseded by // another call. mPendingState = pending; return; } if (!enabled && mCurrentVrService != null && !immediate) { if (!enabled && mCurrentVrService != null) { // If we're transitioning out of VR mode, delay briefly to avoid expensive HAL calls // and service bind/unbind in case we are immediately switching to another VR app. if (mPendingState == null) { Loading @@ -848,7 +948,7 @@ public class VrManagerService extends SystemService implements EnabledComponentC PENDING_STATE_DELAY_MS); } mPendingState = new VrState(enabled, targetPackageName, userId, callingPackage); mPendingState = pending; return; } else { mHandler.removeMessages(MSG_PENDING_VR_STATE_CHANGE); Loading Loading
services/core/java/com/android/server/am/ActivityManagerService.java +17 −39 Original line number Diff line number Diff line Loading @@ -1212,6 +1212,15 @@ public final class ActivityManagerService extends ActivityManagerNative /** * Set while we are wanting to sleep, to prevent any * activities from being started/resumed. * * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping. * * Currently mSleeping is set to true when transitioning into the sleep state, and remains true * while in the sleep state until there is a pending transition out of sleep, in which case * mSleeping is set to false, and remains false while awake. * * Whether mSleeping can quickly toggled between true/false without the device actually * display changing states is undefined. */ private boolean mSleeping = false; Loading Loading @@ -1537,8 +1546,7 @@ public final class ActivityManagerService extends ActivityManagerNative static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66; static final int NOTIFY_FORCED_RESIZABLE_MSG = 67; static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68; static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69; static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 70; static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 69; static final int FIRST_ACTIVITY_STACK_MSG = 100; static final int FIRST_BROADCAST_QUEUE_MSG = 200; Loading Loading @@ -2355,14 +2363,6 @@ public final class ActivityManagerService extends ActivityManagerNative } vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage); } break; case VR_MODE_APPLY_IF_NEEDED_MSG: { final ActivityRecord r = (ActivityRecord) msg.obj; final boolean needsVrMode = r != null && r.requestedVrComponent != null; if (needsVrMode) { applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId, r.info.getComponentName(), false); } } break; } } }; Loading Loading @@ -3164,20 +3164,12 @@ public final class ActivityManagerService extends ActivityManagerNative mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r)); } private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) { mHandler.sendMessage( mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r)); } private void applyVrMode(boolean enabled, ComponentName packageName, int userId, ComponentName callingPackage, boolean immediate) { VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class); if (immediate) { vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage); } else { vrService.setVrMode(enabled, packageName, userId, callingPackage); private void notifyVrManagerOfSleepState(boolean isSleeping) { final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class); if (vrService == null) { return; } vrService.onSleepStateChanged(isSleeping); } final void showAskCompatModeDialogLocked(ActivityRecord r) { Loading Loading @@ -6770,7 +6762,6 @@ public final class ActivityManagerService extends ActivityManagerNative // Some stack visibility might change (e.g. docked stack) mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); applyVrModeIfNeededLocked(mFocusedActivity, true); } } } finally { Loading Loading @@ -11699,6 +11690,7 @@ public final class ActivityManagerService extends ActivityManagerNative startTimeTrackingFocusedActivityLocked(); mTopProcessState = ActivityManager.PROCESS_STATE_TOP; mStackSupervisor.comeOutOfSleepIfNeededLocked(); notifyVrManagerOfSleepState(false); updateOomAdjLocked(); } else if (!mSleeping && shouldSleepLocked()) { mSleeping = true; Loading @@ -11707,6 +11699,7 @@ public final class ActivityManagerService extends ActivityManagerNative } mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING; mStackSupervisor.goingToSleepLocked(); notifyVrManagerOfSleepState(true); updateOomAdjLocked(); // Initialize the wake times of all processes. Loading Loading @@ -21932,21 +21925,6 @@ public final class ActivityManagerService extends ActivityManagerNative public SleepToken acquireSleepToken(String tag) { Preconditions.checkNotNull(tag); ComponentName requestedVrService = null; ComponentName callingVrActivity = null; int userId = -1; synchronized (ActivityManagerService.this) { if (mFocusedActivity != null) { requestedVrService = mFocusedActivity.requestedVrComponent; callingVrActivity = mFocusedActivity.info.getComponentName(); userId = mFocusedActivity.userId; } } if (requestedVrService != null) { applyVrMode(false, requestedVrService, userId, callingVrActivity, true); } synchronized (ActivityManagerService.this) { SleepTokenImpl token = new SleepTokenImpl(tag); mSleepTokens.add(token);
services/core/java/com/android/server/policy/PhoneWindowManager.java +11 −0 Original line number Diff line number Diff line Loading @@ -152,6 +152,7 @@ import com.android.server.LocalServices; import com.android.server.policy.keyguard.KeyguardServiceDelegate; import com.android.server.policy.keyguard.KeyguardServiceDelegate.DrawnListener; import com.android.server.statusbar.StatusBarManagerInternal; import com.android.server.vr.VrManagerInternal; import java.io.File; import java.io.FileReader; Loading Loading @@ -6513,6 +6514,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { mKeyguardDelegate.onScreenTurnedOff(); } } reportScreenStateToVrManager(false); } // Called on the DisplayManager's DisplayPowerController thread. Loading Loading @@ -6548,6 +6550,15 @@ public class PhoneWindowManager implements WindowManagerPolicy { mKeyguardDelegate.onScreenTurnedOn(); } } reportScreenStateToVrManager(true); } private void reportScreenStateToVrManager(boolean isScreenOn) { VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class); if (vrService == null) { return; } vrService.onScreenStateChanged(isScreenOn); } private void finishWindowsDrawn() { Loading
services/core/java/com/android/server/vr/VrManagerInternal.java +18 −16 Original line number Diff line number Diff line Loading @@ -56,16 +56,19 @@ public abstract class VrManagerInternal { int userId, @NonNull ComponentName calling); /** * Set the current VR mode state immediately. * Set whether the system has acquired a sleep token. * * @param enabled {@code true} to enable VR mode. * @param packageName The package name of the requested VrListenerService to bind. * @param userId the user requesting the VrListenerService component. * @param calling the component currently using VR mode, or null to leave unchanged. * @param isAsleep is {@code true} if the device is asleep, or {@code false} otherwise. */ public abstract void setVrModeImmediate(boolean enabled, @NonNull ComponentName packageName, int userId, @NonNull ComponentName calling); public abstract void onSleepStateChanged(boolean isAsleep); /** * Set whether the display used for VR output is on. * * @param isScreenOn is {@code true} if the display is on and can receive commands, * or {@code false} otherwise. */ public abstract void onScreenStateChanged(boolean isScreenOn); /** * Return NO_ERROR if the given package is installed on the device and enabled as a Loading @@ -76,5 +79,4 @@ public abstract class VrManagerInternal { * given in {@link android.service.vr.VrModeException} on failure. */ public abstract int hasVrPackage(@NonNull ComponentName packageName, int userId); }
services/core/java/com/android/server/vr/VrManagerService.java +121 −21 Original line number Diff line number Diff line Loading @@ -101,6 +101,14 @@ public class VrManagerService extends SystemService implements EnabledComponentC private static final int PENDING_STATE_DELAY_MS = 300; private static final int EVENT_LOG_SIZE = 32; private static final int INVALID_APPOPS_MODE = -1; /** Null set of sleep sleep flags. */ private static final int FLAG_NONE = 0; /** Flag set when the device is not sleeping. */ private static final int FLAG_AWAKE = 1; /** Flag set when the screen has been turned on. */ private static final int FLAG_SCREEN_ON = 2; /** Flag indicating that all system sleep flags have been set.*/ private static final int FLAG_ALL = FLAG_AWAKE | FLAG_SCREEN_ON; private static native void initializeNative(); private static native void setVrModeNative(boolean enabled); Loading @@ -110,6 +118,7 @@ public class VrManagerService extends SystemService implements EnabledComponentC private final IBinder mOverlayToken = new Binder(); // State protected by mLock private boolean mVrModeAllowed; private boolean mVrModeEnabled; private EnabledComponentsObserver mComponentObserver; private ManagedApplicationService mCurrentVrService; Loading @@ -125,10 +134,64 @@ public class VrManagerService extends SystemService implements EnabledComponentC private VrState mPendingState; private final ArrayDeque<VrState> mLoggingDeque = new ArrayDeque<>(EVENT_LOG_SIZE); private final NotificationAccessManager mNotifAccessManager = new NotificationAccessManager(); /** Tracks the state of the screen and keyguard UI.*/ private int mSystemSleepFlags = FLAG_NONE; private static final int MSG_VR_STATE_CHANGE = 0; private static final int MSG_PENDING_VR_STATE_CHANGE = 1; /** * Set whether VR mode may be enabled. * <p/> * If VR mode is not allowed to be enabled, calls to set VR mode will be cached. When VR mode * is again allowed to be enabled, the most recent cached state will be applied. * * @param allowed {@code true} if calling any of the setVrMode methods may cause the device to * enter VR mode. */ private void setVrModeAllowedLocked(boolean allowed) { if (mVrModeAllowed != allowed) { mVrModeAllowed = allowed; Slog.i(TAG, "VR mode is " + ((allowed) ? "allowed" : "disallowed")); if (mVrModeAllowed) { consumeAndApplyPendingStateLocked(); } else { // Set pending state to current state. mPendingState = (mVrModeEnabled && mCurrentVrService != null) ? new VrState(mVrModeEnabled, mCurrentVrService.getComponent(), mCurrentVrService.getUserId(), mCurrentVrModeComponent) : null; // Unbind current VR service and do necessary callbacks. updateCurrentVrServiceLocked(false, null, 0, null); } } } private void setSleepState(boolean isAsleep) { synchronized(mLock) { if (!isAsleep) { mSystemSleepFlags |= FLAG_AWAKE; } else { mSystemSleepFlags &= ~FLAG_AWAKE; } setVrModeAllowedLocked(mSystemSleepFlags == FLAG_ALL); } } private void setScreenOn(boolean isScreenOn) { synchronized(mLock) { if (isScreenOn) { mSystemSleepFlags |= FLAG_SCREEN_ON; } else { mSystemSleepFlags &= ~FLAG_SCREEN_ON; } setVrModeAllowedLocked(mSystemSleepFlags == FLAG_ALL); } } private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { Loading @@ -148,8 +211,10 @@ public class VrManagerService extends SystemService implements EnabledComponentC } break; case MSG_PENDING_VR_STATE_CHANGE : { synchronized(mLock) { if (mVrModeAllowed) { VrManagerService.this.consumeAndApplyPendingStateLocked(); } } } break; default : throw new IllegalStateException("Unknown message type: " + msg.what); Loading Loading @@ -268,8 +333,8 @@ public class VrManagerService extends SystemService implements EnabledComponentC } mNotifAccessManager.update(enabledPackages); if (mCurrentVrService == null) { return; // No active services if (!mVrModeAllowed) { return; // Don't do anything, we shouldn't be in VR mode. } // If there is a pending state change, we'd better deal with that first Loading Loading @@ -321,6 +386,7 @@ public class VrManagerService extends SystemService implements EnabledComponentC return; } pw.println("********* Dump of VrManagerService *********"); pw.println("VR mode is currently: " + ((mVrModeAllowed) ? "allowed" : "disallowed")); pw.println("Previous state transitions:\n"); String tab = " "; dumpStateTransitions(pw); Loading Loading @@ -374,13 +440,17 @@ public class VrManagerService extends SystemService implements EnabledComponentC @Override public void setVrMode(boolean enabled, ComponentName packageName, int userId, ComponentName callingPackage) { VrManagerService.this.setVrMode(enabled, packageName, userId, callingPackage, false); VrManagerService.this.setVrMode(enabled, packageName, userId, callingPackage); } @Override public void setVrModeImmediate(boolean enabled, ComponentName packageName, int userId, ComponentName callingPackage) { VrManagerService.this.setVrMode(enabled, packageName, userId, callingPackage, true); public void onSleepStateChanged(boolean isAsleep) { VrManagerService.this.setSleepState(isAsleep); } @Override public void onScreenStateChanged(boolean isScreenOn) { VrManagerService.this.setScreenOn(isScreenOn); } @Override Loading Loading @@ -424,6 +494,10 @@ public class VrManagerService extends SystemService implements EnabledComponentC mComponentObserver.rebuildAll(); } } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) { synchronized (mLock) { mVrModeAllowed = true; } } } Loading Loading @@ -466,12 +540,16 @@ public class VrManagerService extends SystemService implements EnabledComponentC false, mOverlayToken, null, oldUserId); } if (!mVrModeEnabled) { return; } // Apply the restrictions for the current user based on vr state String[] exemptions = (exemptedPackage == null) ? new String[0] : new String[] { exemptedPackage }; appOpsManager.setUserRestrictionForUser(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, mVrModeEnabled, mOverlayToken, exemptions, newUserId); true, mOverlayToken, exemptions, newUserId); } private void updateDependentAppOpsLocked(String newVrServicePackage, int newUserId, Loading Loading @@ -512,7 +590,8 @@ public class VrManagerService extends SystemService implements EnabledComponentC boolean validUserComponent = (mComponentObserver.isValid(component, userId) == EnabledComponentsObserver.NO_ERROR); if (!mVrModeEnabled && !enabled) { boolean goingIntoVrMode = validUserComponent && enabled; if (!mVrModeEnabled && !goingIntoVrMode) { return validUserComponent; // Disabled -> Disabled transition does nothing. } Loading @@ -520,29 +599,37 @@ public class VrManagerService extends SystemService implements EnabledComponentC ? mCurrentVrService.getComponent().getPackageName() : null; final int oldUserId = mCurrentVrModeUser; // Always send mode change events. changeVrModeLocked(enabled); // Notify system services and VR HAL of mode change. changeVrModeLocked(goingIntoVrMode); if (!enabled || !validUserComponent) { // Unbind whatever is running boolean nothingChanged = false; if (!goingIntoVrMode) { // Not going into VR mode, unbind whatever is running if (mCurrentVrService != null) { Slog.i(TAG, "Disconnecting " + mCurrentVrService.getComponent() + " for user " + mCurrentVrService.getUserId()); mCurrentVrService.disconnect(); mCurrentVrService = null; } else { nothingChanged = true; } } else { // Going into VR mode if (mCurrentVrService != null) { // Unbind any running service that doesn't match the component/user selection // Unbind any running service that doesn't match the latest component/user // selection. if (mCurrentVrService.disconnectIfNotMatching(component, userId)) { Slog.i(TAG, "Disconnecting " + mCurrentVrService.getComponent() + " for user " + mCurrentVrService.getUserId()); createAndConnectService(component, userId); sendUpdatedCaller = true; } else { nothingChanged = true; } // The service with the correct component/user is bound // The service with the correct component/user is already bound, do nothing. } else { // Nothing was previously running, bind a new service // Nothing was previously running, bind a new service for the latest // component/user selection. createAndConnectService(component, userId); sendUpdatedCaller = true; } Loading Loading @@ -577,7 +664,10 @@ public class VrManagerService extends SystemService implements EnabledComponentC } }); } if (!nothingChanged) { logStateLocked(); } return validUserComponent; } finally { Loading Loading @@ -784,7 +874,10 @@ public class VrManagerService extends SystemService implements EnabledComponentC mPendingState.targetPackageName, mPendingState.userId, mPendingState.callingPackage); mPendingState = null; } else { updateCurrentVrServiceLocked(false, null, 0, null); } } private void logStateLocked() { Loading Loading @@ -834,13 +927,20 @@ public class VrManagerService extends SystemService implements EnabledComponentC /* * Implementation of VrManagerInternal calls. These are callable from system services. */ private void setVrMode(boolean enabled, @NonNull ComponentName targetPackageName, int userId, @NonNull ComponentName callingPackage, boolean immediate) { int userId, @NonNull ComponentName callingPackage) { synchronized (mLock) { VrState pending = new VrState(enabled, targetPackageName, userId, callingPackage); if (!mVrModeAllowed) { // We're not allowed to be in VR mode. Make this state pending. This will be // applied the next time we are allowed to enter VR mode unless it is superseded by // another call. mPendingState = pending; return; } if (!enabled && mCurrentVrService != null && !immediate) { if (!enabled && mCurrentVrService != null) { // If we're transitioning out of VR mode, delay briefly to avoid expensive HAL calls // and service bind/unbind in case we are immediately switching to another VR app. if (mPendingState == null) { Loading @@ -848,7 +948,7 @@ public class VrManagerService extends SystemService implements EnabledComponentC PENDING_STATE_DELAY_MS); } mPendingState = new VrState(enabled, targetPackageName, userId, callingPackage); mPendingState = pending; return; } else { mHandler.removeMessages(MSG_PENDING_VR_STATE_CHANGE); Loading