diff options
| author | 2016-12-14 08:22:29 +0000 | |
|---|---|---|
| committer | 2016-12-14 08:22:33 +0000 | |
| commit | 3661a6f91b29de855597effaed555f64e316f458 (patch) | |
| tree | 61c856df395194c63ae0d4384341440620ae4166 | |
| parent | 5625d486b9a4eb602b13f6f2d261f1a27126b9b9 (diff) | |
| parent | 040484cf902d70d7c4b5af8f35cbf33f5c3ef4a7 (diff) | |
Merge "Fix VR interaction with screen on/off/lockscreen." into nyc-mr2-dev
4 files changed, 167 insertions, 76 deletions
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index d2babe32e9df..d00783e546ae 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -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; @@ -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; @@ -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; } } }; @@ -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) { @@ -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 { @@ -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; @@ -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. @@ -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); diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index b2f6cd2fd900..889c52afa379 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -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; @@ -6513,6 +6514,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { mKeyguardDelegate.onScreenTurnedOff(); } } + reportScreenStateToVrManager(false); } // Called on the DisplayManager's DisplayPowerController thread. @@ -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() { diff --git a/services/core/java/com/android/server/vr/VrManagerInternal.java b/services/core/java/com/android/server/vr/VrManagerInternal.java index ad87a885348e..0fc1900166e2 100644 --- a/services/core/java/com/android/server/vr/VrManagerInternal.java +++ b/services/core/java/com/android/server/vr/VrManagerInternal.java @@ -56,25 +56,27 @@ 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 - * VrListenerService for the given current user, or a negative error code indicating a failure. - * - * @param packageName the name of the package to check, or null to select the default package. - * @return NO_ERROR if the given package is installed and is enabled, or a negative error code - * given in {@link android.service.vr.VrModeException} on failure. - */ + /** + * Return NO_ERROR if the given package is installed on the device and enabled as a + * VrListenerService for the given current user, or a negative error code indicating a failure. + * + * @param packageName the name of the package to check, or null to select the default package. + * @return NO_ERROR if the given package is installed and is enabled, or a negative error code + * given in {@link android.service.vr.VrModeException} on failure. + */ public abstract int hasVrPackage(@NonNull ComponentName packageName, int userId); - } diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java index 10a0f6f5c6ba..1083e0ada55d 100644 --- a/services/core/java/com/android/server/vr/VrManagerService.java +++ b/services/core/java/com/android/server/vr/VrManagerService.java @@ -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); @@ -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; @@ -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) { @@ -148,7 +211,9 @@ public class VrManagerService extends SystemService implements EnabledComponentC } break; case MSG_PENDING_VR_STATE_CHANGE : { synchronized(mLock) { - VrManagerService.this.consumeAndApplyPendingStateLocked(); + if (mVrModeAllowed) { + VrManagerService.this.consumeAndApplyPendingStateLocked(); + } } } break; default : @@ -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 @@ -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); @@ -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 @@ -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; + } } } @@ -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, @@ -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. } @@ -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; } @@ -577,7 +664,10 @@ public class VrManagerService extends SystemService implements EnabledComponentC } }); } - logStateLocked(); + + if (!nothingChanged) { + logStateLocked(); + } return validUserComponent; } finally { @@ -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() { @@ -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) { @@ -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); |