diff options
author | 2016-04-15 11:53:09 -0700 | |
---|---|---|
committer | 2016-04-15 16:42:49 -0700 | |
commit | b56b72a8461dcc1a9dccd4c7019e2ecbf191fc1c (patch) | |
tree | 377f15b30da0522225cf399e597418da5a0097a0 | |
parent | 793f859123ae77c9925d18f2c46c3fea5497b4de (diff) |
Fix VR->VR Activity transitions.
- Briefly delay unBinding VrListenerService and making HAL calls
when leaving VR mode Activity in case subsequent activity will
be immediately re-entering VR mode.
Bug: 28115931
Change-Id: I3f362131ed2beb6a29ce78fe01e9301d8b396520
-rw-r--r-- | services/core/java/com/android/server/vr/VrManagerService.java | 61 |
1 files changed, 59 insertions, 2 deletions
diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java index 49ff385ee27f..2d2ee7a1a745 100644 --- a/services/core/java/com/android/server/vr/VrManagerService.java +++ b/services/core/java/com/android/server/vr/VrManagerService.java @@ -85,6 +85,8 @@ public class VrManagerService extends SystemService implements EnabledComponentC public static final String VR_MANAGER_BINDER_SERVICE = "vrmanager"; + private static final int PENDING_STATE_DELAY_MS = 300; + private static native void initializeNative(); private static native void setVrModeNative(boolean enabled); @@ -107,8 +109,10 @@ public class VrManagerService extends SystemService implements EnabledComponentC private String mPreviousNotificationPolicyAccessPackage; private String mPreviousCoarseLocationPackage; private String mPreviousManageOverlayPackage; + private VrState mPendingState; private static final int MSG_VR_STATE_CHANGE = 0; + private static final int MSG_PENDING_VR_STATE_CHANGE = 1; private final Handler mHandler = new Handler() { @Override @@ -127,12 +131,32 @@ public class VrManagerService extends SystemService implements EnabledComponentC } mRemoteCallbacks.finishBroadcast(); } break; + case MSG_PENDING_VR_STATE_CHANGE : { + synchronized(mLock) { + VrManagerService.this.consumeAndApplyPendingStateLocked(); + } + } break; default : throw new IllegalStateException("Unknown message type: " + msg.what); } } }; + private static class VrState { + final boolean enabled; + final int userId; + final ComponentName targetPackageName; + final ComponentName callingPackage; + + VrState(boolean enabled, ComponentName targetPackageName, int userId, + ComponentName callingPackage) { + this.enabled = enabled; + this.userId = userId; + this.targetPackageName = targetPackageName; + this.callingPackage = callingPackage; + } + }; + private static final BinderChecker sBinderChecker = new BinderChecker() { @Override public IInterface asInterface(IBinder binder) { @@ -156,6 +180,13 @@ public class VrManagerService extends SystemService implements EnabledComponentC return; // No active services } + // If there is a pending state change, we'd better deal with that first + consumeAndApplyPendingStateLocked(); + + if (mCurrentVrService == null) { + return; // No active services + } + // There is an active service, update it if needed updateCurrentVrServiceLocked(mVrModeEnabled, mCurrentVrService.getComponent(), mCurrentVrService.getUserId(), null); @@ -679,14 +710,40 @@ public class VrManagerService extends SystemService implements EnabledComponentC sBinderChecker); } + private void consumeAndApplyPendingStateLocked() { + if (mPendingState != null) { + updateCurrentVrServiceLocked(mPendingState.enabled, + mPendingState.targetPackageName, mPendingState.userId, + mPendingState.callingPackage); + mPendingState = null; + } + } + /* * Implementation of VrManagerInternal calls. These are callable from system services. */ - private boolean setVrMode(boolean enabled, @NonNull ComponentName targetPackageName, + private void setVrMode(boolean enabled, @NonNull ComponentName targetPackageName, int userId, @NonNull ComponentName callingPackage) { + synchronized (mLock) { - return updateCurrentVrServiceLocked(enabled, targetPackageName, userId, callingPackage); + + 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) { + mHandler.sendEmptyMessageDelayed(MSG_PENDING_VR_STATE_CHANGE, + PENDING_STATE_DELAY_MS); + } + + mPendingState = new VrState(enabled, targetPackageName, userId, callingPackage); + return; + } else { + mHandler.removeMessages(MSG_PENDING_VR_STATE_CHANGE); + mPendingState = null; + } + + updateCurrentVrServiceLocked(enabled, targetPackageName, userId, callingPackage); } } |