Allow VR State Listeners with RESTRICTED_VR_ACCESS permission.
Extend the ability to use VrStateListeners to applications that
have RESTRICTED_VR_ACCESS permission. Previously, it required
ACCESS_VR_MANAGER only.
Add VrStateCallback object and methods to VrManager to access the
functionality outside of frameworks.
Bug: 64360244
Test: Manual. Tested ability from VrCore.
Change-Id: I01f1c75b1ccd44a09364df84218168cf6caab322
diff --git a/core/java/android/app/VrManager.java b/core/java/android/app/VrManager.java
index b40c96c..363e20a 100644
--- a/core/java/android/app/VrManager.java
+++ b/core/java/android/app/VrManager.java
@@ -1,13 +1,18 @@
package android.app;
-
+import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
-import android.content.ComponentName;
import android.content.Context;
+import android.os.Handler;
import android.os.RemoteException;
+import android.service.vr.IPersistentVrStateCallbacks;
import android.service.vr.IVrManager;
+import android.service.vr.IVrStateCallbacks;
+import android.util.ArrayMap;
+
+import java.util.Map;
/**
* Used to control aspects of a devices Virtual Reality (VR) capabilities.
@@ -16,7 +21,33 @@
@SystemApi
@SystemService(Context.VR_SERVICE)
public class VrManager {
+
+ private static class CallbackEntry {
+ final IVrStateCallbacks mStateCallback = new IVrStateCallbacks.Stub() {
+ @Override
+ public void onVrStateChanged(boolean enabled) {
+ mHandler.post(() -> mCallback.onVrStateChanged(enabled));
+ }
+
+ };
+ final IPersistentVrStateCallbacks mPersistentStateCallback =
+ new IPersistentVrStateCallbacks.Stub() {
+ @Override
+ public void onPersistentVrStateChanged(boolean enabled) {
+ mHandler.post(() -> mCallback.onPersistentVrStateChanged(enabled));
+ }
+ };
+ final VrStateCallback mCallback;
+ final Handler mHandler;
+
+ CallbackEntry(VrStateCallback callback, Handler handler) {
+ mCallback = callback;
+ mHandler = handler;
+ }
+ }
+
private final IVrManager mService;
+ private Map<VrStateCallback, CallbackEntry> mCallbackMap = new ArrayMap<>();
/**
* {@hide}
@@ -26,6 +57,84 @@
}
/**
+ * Registers a callback to be notified of changes to the VR Mode state.
+ *
+ * @param callback The callback to register.
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.RESTRICTED_VR_ACCESS)
+ public void registerVrStateCallback(VrStateCallback callback, @NonNull Handler handler) {
+ if (callback == null || mCallbackMap.containsKey(callback)) {
+ return;
+ }
+
+ CallbackEntry entry = new CallbackEntry(callback, handler);
+ mCallbackMap.put(callback, entry);
+ try {
+ mService.registerListener(entry.mStateCallback);
+ mService.registerPersistentVrStateListener(entry.mPersistentStateCallback);
+ } catch (RemoteException e) {
+ try {
+ unregisterVrStateCallback(callback);
+ } catch (Exception ignore) {
+ e.rethrowFromSystemServer();
+ }
+ }
+ }
+
+ /**
+ * Deregisters VR State callbacks.
+ *
+ * @param callback The callback to deregister.
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.RESTRICTED_VR_ACCESS)
+ public void unregisterVrStateCallback(VrStateCallback callback) {
+ CallbackEntry entry = mCallbackMap.remove(callback);
+ if (entry != null) {
+ try {
+ mService.unregisterListener(entry.mStateCallback);
+ } catch (RemoteException ignore) {
+ // Dont rethrow exceptions from requests to unregister.
+ }
+
+ try {
+ mService.unregisterPersistentVrStateListener(entry.mPersistentStateCallback);
+ } catch (RemoteException ignore) {
+ // Dont rethrow exceptions from requests to unregister.
+ }
+ }
+ }
+
+ /**
+ * Returns the current VrMode state.
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.ACCESS_VR_STATE)
+ public boolean getVrModeEnabled() {
+ try {
+ return mService.getVrModeState();
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ return false;
+ }
+
+ /**
+ * Returns the current VrMode state.
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.ACCESS_VR_STATE)
+ public boolean getPersistentVrModeEnabled() {
+ try {
+ return mService.getPersistentVrModeEnabled();
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ return false;
+ }
+
+ /**
* Sets the persistent VR mode state of a device. When a device is in persistent VR mode it will
* remain in VR mode even if the foreground does not specify Vr mode being enabled. Mainly used
* by VR viewers to indicate that a device is placed in a VR viewer.
diff --git a/core/java/android/app/VrStateCallback.java b/core/java/android/app/VrStateCallback.java
new file mode 100644
index 0000000..742faa06
--- /dev/null
+++ b/core/java/android/app/VrStateCallback.java
@@ -0,0 +1,38 @@
+/*
+ * 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 android.app;
+
+/**
+ * Listens to VR Mode state changes. Use with methods in {@link VrManager}.
+ *
+ * @hide
+ */
+public abstract class VrStateCallback {
+
+ /**
+ * Callback triggered when there is a change to Persistent VR State.
+ *
+ * @param enabled True when VR State is in persistent mode, false otherwise.
+ */
+ public void onPersistentVrStateChanged(boolean enabled) {}
+
+ /**
+ * Callback triggered when there is a change to Vr State.
+ *
+ * @param enabled True when VR State is in VR mode, false otherwise.
+ */
+ public void onVrStateChanged(boolean enabled) {}
+}
diff --git a/core/java/android/service/vr/IVrManager.aidl b/core/java/android/service/vr/IVrManager.aidl
index 9b37a65..c38fab1 100644
--- a/core/java/android/service/vr/IVrManager.aidl
+++ b/core/java/android/service/vr/IVrManager.aidl
@@ -59,6 +59,13 @@
boolean getVrModeState();
/**
+ * Returns the current Persistent VR mode state.
+ *
+ * @return {@code true} if Persistent VR mode is enabled.
+ */
+ boolean getPersistentVrModeEnabled();
+
+ /**
* Sets the persistent VR mode state of a device. When a device is in persistent VR mode it will
* remain in VR mode even if the foreground does not specify VR mode being enabled. Mainly used
* by VR viewers to indicate that a device is placed in a VR viewer.
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 86c0b43..89bbec2 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -3512,6 +3512,11 @@
<permission android:name="android.permission.ACCESS_VR_MANAGER"
android:protectionLevel="signature" />
+ <!-- Required to access VR-Mode state and state change events via {android.app.VrStateCallback}
+ @hide -->
+ <permission android:name="android.permission.ACCESS_VR_STATE"
+ android:protectionLevel="signature|preinstalled" />
+
<!-- Allows an application to whitelist tasks during lock task mode
@hide <p>Not for use by third-party applications.</p> -->
<permission android:name="android.permission.UPDATE_LOCK_TASK_PACKAGES"