diff options
4 files changed, 120 insertions, 7 deletions
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index d25082768407..0d6cd804cdf2 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -236,6 +236,7 @@ import com.android.server.policy.keyguard.KeyguardStateMonitor.StateCallback; import com.android.server.statusbar.StatusBarManagerInternal; import com.android.server.wm.AppTransition; import com.android.server.vr.VrManagerInternal; +import com.android.server.vr.PersistentVrStateListener; import java.io.File; import java.io.FileReader; @@ -416,6 +417,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { AppOpsManager mAppOpsManager; private boolean mHasFeatureWatch; + // Assigned on main thread, accessed on UI thread + volatile VrManagerInternal mVrManagerInternal; + // Vibrator pattern for haptic feedback of a long press. long[] mLongPressVibePattern; @@ -503,6 +507,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { volatile boolean mGoingToSleep; volatile boolean mRecentsVisible; volatile boolean mTvPictureInPictureVisible; + // Written by vr manager thread, only read in this class + volatile boolean mPersistentVrModeEnabled; // Used to hold the last user key used to wake the device. This helps us prevent up events // from being passed to the foregrounded app without a corresponding down event @@ -982,6 +988,14 @@ public class PhoneWindowManager implements WindowManagerPolicy { } MyOrientationListener mOrientationListener; + final PersistentVrStateListener mPersistentVrModeListener = + new PersistentVrStateListener() { + @Override + public void onPersistentVrStateChanged(boolean enabled) { + mPersistentVrModeEnabled = enabled; + } + }; + private final StatusBarController mStatusBarController = new StatusBarController(); private final BarController mNavigationBarController = new BarController("NavigationBar", @@ -1914,24 +1928,36 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (mStatusBar != null) { requestTransientBars(mStatusBar); } + if (mPersistentVrModeEnabled) { + exitPersistentVrMode(); + } } @Override public void onSwipeFromBottom() { if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_BOTTOM) { requestTransientBars(mNavigationBar); } + if (mPersistentVrModeEnabled) { + exitPersistentVrMode(); + } } @Override public void onSwipeFromRight() { if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_RIGHT) { requestTransientBars(mNavigationBar); } + if (mPersistentVrModeEnabled) { + exitPersistentVrMode(); + } } @Override public void onSwipeFromLeft() { if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_LEFT) { requestTransientBars(mNavigationBar); } + if (mPersistentVrModeEnabled) { + exitPersistentVrMode(); + } } @Override public void onFling(int duration) { @@ -6489,11 +6515,17 @@ public class PhoneWindowManager implements WindowManagerPolicy { } private void reportScreenStateToVrManager(boolean isScreenOn) { - VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class); - if (vrService == null) { + if (mVrManagerInternal == null) { return; } - vrService.onScreenStateChanged(isScreenOn); + mVrManagerInternal.onScreenStateChanged(isScreenOn); + } + + private void exitPersistentVrMode() { + if (mVrManagerInternal == null) { + return; + } + mVrManagerInternal.setPersistentVrModeEnabled(false); } private void finishWindowsDrawn() { @@ -6982,6 +7014,11 @@ public class PhoneWindowManager implements WindowManagerPolicy { }); mKeyguardDelegate.onSystemReady(); + mVrManagerInternal = LocalServices.getService(VrManagerInternal.class); + if (mVrManagerInternal != null) { + mVrManagerInternal.addPersistentVrModeStateListener(mPersistentVrModeListener); + } + readCameraLensCoverState(); updateUiMode(); boolean bindKeyguardNow; diff --git a/services/core/java/com/android/server/vr/PersistentVrStateListener.java b/services/core/java/com/android/server/vr/PersistentVrStateListener.java new file mode 100644 index 000000000000..bccd5f165aed --- /dev/null +++ b/services/core/java/com/android/server/vr/PersistentVrStateListener.java @@ -0,0 +1,31 @@ +/** + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.vr; + +/** + * Listener for state changes to persistent VR mode. + * + * @hide Only for use within system server. + */ +public abstract class PersistentVrStateListener { + + /** + * Called when the Persistent VR mode state changes. + * + * @param enabled {@code true} if persistent VR mode is enabled. + */ + public abstract void onPersistentVrStateChanged(boolean enabled); +} diff --git a/services/core/java/com/android/server/vr/VrManagerInternal.java b/services/core/java/com/android/server/vr/VrManagerInternal.java index 45b7baf8e8f5..58e4bdc36e6a 100644 --- a/services/core/java/com/android/server/vr/VrManagerInternal.java +++ b/services/core/java/com/android/server/vr/VrManagerInternal.java @@ -88,4 +88,9 @@ public abstract class VrManagerInternal { * @param enabled true if the device should be placed in persistent VR mode. */ public abstract void setPersistentVrModeEnabled(boolean enabled); + + /** + * Adds listener that reports state changes to persistent VR mode. + */ + public abstract void addPersistentVrModeStateListener(PersistentVrStateListener listener); } diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java index f0ea5272f4da..21a4f74e5a75 100644 --- a/services/core/java/com/android/server/vr/VrManagerService.java +++ b/services/core/java/com/android/server/vr/VrManagerService.java @@ -122,6 +122,8 @@ public class VrManagerService extends SystemService implements EnabledComponentC private boolean mGuard; private final RemoteCallbackList<IVrStateCallbacks> mRemoteCallbacks = new RemoteCallbackList<>(); + private final ArrayList<PersistentVrStateListener> mPersistentVrStateListeners = + new ArrayList<>(); private int mPreviousCoarseLocationMode = INVALID_APPOPS_MODE; private int mPreviousManageOverlayMode = INVALID_APPOPS_MODE; private VrState mPendingState; @@ -132,6 +134,7 @@ public class VrManagerService extends SystemService implements EnabledComponentC private static final int MSG_VR_STATE_CHANGE = 0; private static final int MSG_PENDING_VR_STATE_CHANGE = 1; + private static final int MSG_PERSISTENT_VR_MODE_STATE_CHANGE = 2; /** * Set whether VR mode may be enabled. @@ -151,7 +154,7 @@ public class VrManagerService extends SystemService implements EnabledComponentC } else { // Disable persistent mode when VR mode isn't allowed, allows an escape hatch to // exit persistent VR mode when screen is turned off. - mPersistentVrModeEnabled = false; + setPersistentModeAndNotifyListenersLocked(false); // Set pending state to current state. mPendingState = (mVrModeEnabled && mCurrentVrService != null) @@ -213,6 +216,13 @@ public class VrManagerService extends SystemService implements EnabledComponentC } } } break; + case MSG_PERSISTENT_VR_MODE_STATE_CHANGE : { + boolean state = (msg.arg1 == 1); + for (int i = 0; i < mPersistentVrStateListeners.size(); i++) { + mPersistentVrStateListeners.get(i).onPersistentVrStateChanged( + state); + } + } break; default : throw new IllegalStateException("Unknown message type: " + msg.what); } @@ -424,6 +434,16 @@ public class VrManagerService extends SystemService implements EnabledComponentC pw.println(n.flattenToString()); } } + pw.println("Attached persistent mode listeners:"); + if (mPersistentVrStateListeners == null || + mPersistentVrStateListeners.size() == 0) { + pw.println("None"); + } else { + for (PersistentVrStateListener l : mPersistentVrStateListeners) { + pw.print(tab); + pw.println("listener: " + l); + } + } pw.println("\n"); pw.println("********* End of VrManagerService Dump *********"); } @@ -471,6 +491,11 @@ public class VrManagerService extends SystemService implements EnabledComponentC public void setPersistentVrModeEnabled(boolean enabled) { VrManagerService.this.setPersistentVrModeEnabled(enabled); } + + @Override + public void addPersistentVrModeStateListener(PersistentVrStateListener listener) { + VrManagerService.this.addPersistentVrModeStateListener(listener); + } } public VrManagerService(Context context) { @@ -1013,9 +1038,8 @@ public class VrManagerService extends SystemService implements EnabledComponentC } private void setPersistentVrModeEnabled(boolean enabled) { - synchronized (mLock) { - mPersistentVrModeEnabled = enabled; - + synchronized(mLock) { + setPersistentModeAndNotifyListenersLocked(enabled); // Disabling persistent mode when not showing a VR should disable the overall vr mode. if (!enabled && mCurrentVrModeComponent == null) { setVrMode(false, null, 0, null); @@ -1023,6 +1047,22 @@ public class VrManagerService extends SystemService implements EnabledComponentC } } + private void setPersistentModeAndNotifyListenersLocked(boolean enabled) { + if (mPersistentVrModeEnabled == enabled) { + return; + } + mPersistentVrModeEnabled = enabled; + + mHandler.sendMessage(mHandler.obtainMessage(MSG_PERSISTENT_VR_MODE_STATE_CHANGE, + (mPersistentVrModeEnabled) ? 1 : 0, 0)); + } + + private void addPersistentVrModeStateListener(PersistentVrStateListener listener) { + synchronized (mLock) { + mPersistentVrStateListeners.add(listener); + } + } + private int hasVrPackage(@NonNull ComponentName targetPackageName, int userId) { synchronized (mLock) { return mComponentObserver.isValid(targetPackageName, userId); |