Loading core/java/android/app/VrManager.java +111 −2 Original line number Diff line number Diff line 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. Loading @@ -16,7 +21,33 @@ import android.service.vr.IVrManager; @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} Loading @@ -25,6 +56,84 @@ public class VrManager { mService = service; } /** * 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 Loading core/java/android/app/VrStateCallback.java 0 → 100644 +38 −0 Original line number Diff line number Diff line /* * 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) {} } core/java/android/service/vr/IVrManager.aidl +7 −0 Original line number Diff line number Diff line Loading @@ -58,6 +58,13 @@ interface IVrManager { */ 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 Loading core/res/AndroidManifest.xml +5 −0 Original line number Diff line number Diff line Loading @@ -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" Loading services/core/java/com/android/server/vr/VrManagerService.java +40 −10 Original line number Diff line number Diff line Loading @@ -74,6 +74,7 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.StringBuilder; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collection; Loading Loading @@ -414,7 +415,8 @@ public class VrManagerService extends SystemService implements EnabledComponentC @Override public void registerListener(IVrStateCallbacks cb) { enforceCallerPermission(Manifest.permission.ACCESS_VR_MANAGER); enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER, Manifest.permission.ACCESS_VR_STATE); if (cb == null) { throw new IllegalArgumentException("Callback binder object is null."); } Loading @@ -424,7 +426,8 @@ public class VrManagerService extends SystemService implements EnabledComponentC @Override public void unregisterListener(IVrStateCallbacks cb) { enforceCallerPermission(Manifest.permission.ACCESS_VR_MANAGER); enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER, Manifest.permission.ACCESS_VR_STATE); if (cb == null) { throw new IllegalArgumentException("Callback binder object is null."); } Loading @@ -434,7 +437,8 @@ public class VrManagerService extends SystemService implements EnabledComponentC @Override public void registerPersistentVrStateListener(IPersistentVrStateCallbacks cb) { enforceCallerPermission(Manifest.permission.ACCESS_VR_MANAGER); enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER, Manifest.permission.ACCESS_VR_STATE); if (cb == null) { throw new IllegalArgumentException("Callback binder object is null."); } Loading @@ -444,7 +448,8 @@ public class VrManagerService extends SystemService implements EnabledComponentC @Override public void unregisterPersistentVrStateListener(IPersistentVrStateCallbacks cb) { enforceCallerPermission(Manifest.permission.ACCESS_VR_MANAGER); enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER, Manifest.permission.ACCESS_VR_STATE); if (cb == null) { throw new IllegalArgumentException("Callback binder object is null."); } Loading @@ -454,19 +459,28 @@ public class VrManagerService extends SystemService implements EnabledComponentC @Override public boolean getVrModeState() { enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER, Manifest.permission.ACCESS_VR_STATE); return VrManagerService.this.getVrMode(); } @Override public boolean getPersistentVrModeEnabled() { enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER, Manifest.permission.ACCESS_VR_STATE); return VrManagerService.this.getPersistentVrMode(); } @Override public void setPersistentVrModeEnabled(boolean enabled) { enforceCallerPermission(Manifest.permission.RESTRICTED_VR_ACCESS); enforceCallerPermissionAnyOf(Manifest.permission.RESTRICTED_VR_ACCESS); VrManagerService.this.setPersistentVrModeEnabled(enabled); } @Override public void setVr2dDisplayProperties( Vr2dDisplayProperties vr2dDisplayProp) { enforceCallerPermission(Manifest.permission.RESTRICTED_VR_ACCESS); enforceCallerPermissionAnyOf(Manifest.permission.RESTRICTED_VR_ACCESS); VrManagerService.this.setVr2dDisplayProperties(vr2dDisplayProp); } Loading Loading @@ -530,11 +544,21 @@ public class VrManagerService extends SystemService implements EnabledComponentC }; private void enforceCallerPermission(String permission) { /** * Enforces that at lease one of the specified permissions is held by the caller. * Throws SecurityException if none of the specified permissions are held. * * @param permissions One or more permissions to check against. */ private void enforceCallerPermissionAnyOf(String... permissions) { for (String permission : permissions) { if (mContext.checkCallingOrSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("Caller does not hold the permission " + permission); == PackageManager.PERMISSION_GRANTED) { return; } } throw new SecurityException("Caller does not hold at least one of the permissions: " + Arrays.toString(permissions)); } /** Loading Loading @@ -1204,4 +1228,10 @@ public class VrManagerService extends SystemService implements EnabledComponentC return mVrModeEnabled; } } private boolean getPersistentVrMode() { synchronized (mLock) { return mPersistentVrModeEnabled; } } } Loading
core/java/android/app/VrManager.java +111 −2 Original line number Diff line number Diff line 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. Loading @@ -16,7 +21,33 @@ import android.service.vr.IVrManager; @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} Loading @@ -25,6 +56,84 @@ public class VrManager { mService = service; } /** * 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 Loading
core/java/android/app/VrStateCallback.java 0 → 100644 +38 −0 Original line number Diff line number Diff line /* * 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) {} }
core/java/android/service/vr/IVrManager.aidl +7 −0 Original line number Diff line number Diff line Loading @@ -58,6 +58,13 @@ interface IVrManager { */ 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 Loading
core/res/AndroidManifest.xml +5 −0 Original line number Diff line number Diff line Loading @@ -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" Loading
services/core/java/com/android/server/vr/VrManagerService.java +40 −10 Original line number Diff line number Diff line Loading @@ -74,6 +74,7 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.StringBuilder; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collection; Loading Loading @@ -414,7 +415,8 @@ public class VrManagerService extends SystemService implements EnabledComponentC @Override public void registerListener(IVrStateCallbacks cb) { enforceCallerPermission(Manifest.permission.ACCESS_VR_MANAGER); enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER, Manifest.permission.ACCESS_VR_STATE); if (cb == null) { throw new IllegalArgumentException("Callback binder object is null."); } Loading @@ -424,7 +426,8 @@ public class VrManagerService extends SystemService implements EnabledComponentC @Override public void unregisterListener(IVrStateCallbacks cb) { enforceCallerPermission(Manifest.permission.ACCESS_VR_MANAGER); enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER, Manifest.permission.ACCESS_VR_STATE); if (cb == null) { throw new IllegalArgumentException("Callback binder object is null."); } Loading @@ -434,7 +437,8 @@ public class VrManagerService extends SystemService implements EnabledComponentC @Override public void registerPersistentVrStateListener(IPersistentVrStateCallbacks cb) { enforceCallerPermission(Manifest.permission.ACCESS_VR_MANAGER); enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER, Manifest.permission.ACCESS_VR_STATE); if (cb == null) { throw new IllegalArgumentException("Callback binder object is null."); } Loading @@ -444,7 +448,8 @@ public class VrManagerService extends SystemService implements EnabledComponentC @Override public void unregisterPersistentVrStateListener(IPersistentVrStateCallbacks cb) { enforceCallerPermission(Manifest.permission.ACCESS_VR_MANAGER); enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER, Manifest.permission.ACCESS_VR_STATE); if (cb == null) { throw new IllegalArgumentException("Callback binder object is null."); } Loading @@ -454,19 +459,28 @@ public class VrManagerService extends SystemService implements EnabledComponentC @Override public boolean getVrModeState() { enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER, Manifest.permission.ACCESS_VR_STATE); return VrManagerService.this.getVrMode(); } @Override public boolean getPersistentVrModeEnabled() { enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER, Manifest.permission.ACCESS_VR_STATE); return VrManagerService.this.getPersistentVrMode(); } @Override public void setPersistentVrModeEnabled(boolean enabled) { enforceCallerPermission(Manifest.permission.RESTRICTED_VR_ACCESS); enforceCallerPermissionAnyOf(Manifest.permission.RESTRICTED_VR_ACCESS); VrManagerService.this.setPersistentVrModeEnabled(enabled); } @Override public void setVr2dDisplayProperties( Vr2dDisplayProperties vr2dDisplayProp) { enforceCallerPermission(Manifest.permission.RESTRICTED_VR_ACCESS); enforceCallerPermissionAnyOf(Manifest.permission.RESTRICTED_VR_ACCESS); VrManagerService.this.setVr2dDisplayProperties(vr2dDisplayProp); } Loading Loading @@ -530,11 +544,21 @@ public class VrManagerService extends SystemService implements EnabledComponentC }; private void enforceCallerPermission(String permission) { /** * Enforces that at lease one of the specified permissions is held by the caller. * Throws SecurityException if none of the specified permissions are held. * * @param permissions One or more permissions to check against. */ private void enforceCallerPermissionAnyOf(String... permissions) { for (String permission : permissions) { if (mContext.checkCallingOrSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("Caller does not hold the permission " + permission); == PackageManager.PERMISSION_GRANTED) { return; } } throw new SecurityException("Caller does not hold at least one of the permissions: " + Arrays.toString(permissions)); } /** Loading Loading @@ -1204,4 +1228,10 @@ public class VrManagerService extends SystemService implements EnabledComponentC return mVrModeEnabled; } } private boolean getPersistentVrMode() { synchronized (mLock) { return mPersistentVrModeEnabled; } } }