Merge "Exit persistent VR mode on edge swipe."
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index d250827..0d6cd80 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.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 @@
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 @@
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 @@
}
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 @@
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 @@
}
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 @@
});
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 0000000..bccd5f1
--- /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 45b7baf..58e4bdc 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 @@
* @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 f0ea527..21a4f74 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 @@
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 @@
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 @@
} 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 @@
}
}
} 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 @@
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 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 @@
}
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 @@
}
}
+ 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);