Home | History | Annotate | Download | only in app
      1 package android.app;
      2 
      3 import android.annotation.CallbackExecutor;
      4 import android.annotation.NonNull;
      5 import android.annotation.Nullable;
      6 import android.annotation.RequiresPermission;
      7 import android.annotation.SystemApi;
      8 import android.annotation.SystemService;
      9 import android.annotation.UnsupportedAppUsage;
     10 import android.content.ComponentName;
     11 import android.content.Context;
     12 import android.os.RemoteException;
     13 import android.service.vr.IPersistentVrStateCallbacks;
     14 import android.service.vr.IVrManager;
     15 import android.service.vr.IVrStateCallbacks;
     16 import android.util.ArrayMap;
     17 import android.view.Display;
     18 
     19 import java.util.Map;
     20 import java.util.concurrent.Executor;
     21 
     22 /**
     23  * Used to control aspects of a devices Virtual Reality (VR) capabilities.
     24  * @hide
     25  */
     26 @SystemApi
     27 @SystemService(Context.VR_SERVICE)
     28 public class VrManager {
     29 
     30     private static class CallbackEntry {
     31         final IVrStateCallbacks mStateCallback = new IVrStateCallbacks.Stub() {
     32             @Override
     33             public void onVrStateChanged(boolean enabled) {
     34                 mExecutor.execute(() -> mCallback.onVrStateChanged(enabled));
     35             }
     36 
     37         };
     38         final IPersistentVrStateCallbacks mPersistentStateCallback =
     39                 new IPersistentVrStateCallbacks.Stub() {
     40             @Override
     41             public void onPersistentVrStateChanged(boolean enabled) {
     42                 mExecutor.execute(() -> mCallback.onPersistentVrStateChanged(enabled));
     43             }
     44         };
     45         final VrStateCallback mCallback;
     46         final Executor mExecutor;
     47 
     48         CallbackEntry(VrStateCallback callback, Executor executor) {
     49             mCallback = callback;
     50             mExecutor = executor;
     51         }
     52     }
     53 
     54     @UnsupportedAppUsage
     55     private final IVrManager mService;
     56     private Map<VrStateCallback, CallbackEntry> mCallbackMap = new ArrayMap<>();
     57 
     58     /**
     59      * {@hide}
     60      */
     61     public VrManager(IVrManager service) {
     62         mService = service;
     63     }
     64 
     65     /**
     66      * Registers a callback to be notified of changes to the VR Mode state.
     67      *
     68      * @param callback The callback to register.
     69      */
     70     @RequiresPermission(anyOf = {
     71             android.Manifest.permission.RESTRICTED_VR_ACCESS,
     72             android.Manifest.permission.ACCESS_VR_STATE
     73     })
     74     public void registerVrStateCallback(@NonNull @CallbackExecutor Executor executor,
     75             @NonNull VrStateCallback callback) {
     76         if (callback == null || mCallbackMap.containsKey(callback)) {
     77             return;
     78         }
     79 
     80         CallbackEntry entry = new CallbackEntry(callback, executor);
     81         mCallbackMap.put(callback, entry);
     82         try {
     83             mService.registerListener(entry.mStateCallback);
     84             mService.registerPersistentVrStateListener(entry.mPersistentStateCallback);
     85         } catch (RemoteException e) {
     86             try {
     87                 unregisterVrStateCallback(callback);
     88             } catch (Exception ignore) {
     89                 e.rethrowFromSystemServer();
     90             }
     91         }
     92     }
     93 
     94     /**
     95      * Deregisters VR State callbacks.
     96      *
     97      * @param callback The callback to deregister.
     98      */
     99     @RequiresPermission(anyOf = {
    100             android.Manifest.permission.RESTRICTED_VR_ACCESS,
    101             android.Manifest.permission.ACCESS_VR_STATE
    102     })
    103     public void unregisterVrStateCallback(@NonNull VrStateCallback callback) {
    104         CallbackEntry entry = mCallbackMap.remove(callback);
    105         if (entry != null) {
    106             try {
    107                 mService.unregisterListener(entry.mStateCallback);
    108             } catch (RemoteException ignore) {
    109                 // Dont rethrow exceptions from requests to unregister.
    110             }
    111 
    112             try {
    113                 mService.unregisterPersistentVrStateListener(entry.mPersistentStateCallback);
    114             } catch (RemoteException ignore) {
    115                 // Dont rethrow exceptions from requests to unregister.
    116             }
    117         }
    118     }
    119 
    120     /**
    121      * Returns the current VrMode state.
    122      */
    123     @RequiresPermission(anyOf = {
    124             android.Manifest.permission.RESTRICTED_VR_ACCESS,
    125             android.Manifest.permission.ACCESS_VR_STATE
    126     })
    127     public boolean isVrModeEnabled() {
    128         try {
    129             return mService.getVrModeState();
    130         } catch (RemoteException e) {
    131             e.rethrowFromSystemServer();
    132         }
    133         return false;
    134     }
    135 
    136     /**
    137      * Returns the current VrMode state.
    138      */
    139     @RequiresPermission(anyOf = {
    140             android.Manifest.permission.RESTRICTED_VR_ACCESS,
    141             android.Manifest.permission.ACCESS_VR_STATE
    142     })
    143     public boolean isPersistentVrModeEnabled() {
    144         try {
    145             return mService.getPersistentVrModeEnabled();
    146         } catch (RemoteException e) {
    147             e.rethrowFromSystemServer();
    148         }
    149         return false;
    150     }
    151 
    152     /**
    153      * Sets the persistent VR mode state of a device. When a device is in persistent VR mode it will
    154      * remain in VR mode even if the foreground does not specify Vr mode being enabled. Mainly used
    155      * by VR viewers to indicate that a device is placed in a VR viewer.
    156      *
    157      * @see Activity#setVrModeEnabled(boolean, ComponentName)
    158      * @param enabled true if the device should be placed in persistent VR mode.
    159      */
    160     @RequiresPermission(android.Manifest.permission.RESTRICTED_VR_ACCESS)
    161     public void setPersistentVrModeEnabled(boolean enabled) {
    162         try {
    163             mService.setPersistentVrModeEnabled(enabled);
    164         } catch (RemoteException e) {
    165             e.rethrowFromSystemServer();
    166         }
    167     }
    168 
    169     /**
    170      * Sets the resolution and DPI of the vr2d virtual display used to display 2D
    171      * applications in VR mode.
    172      *
    173      * @param vr2dDisplayProp properties to be set to the virtual display for
    174      * 2D applications in VR mode.
    175      *
    176      */
    177     @RequiresPermission(android.Manifest.permission.RESTRICTED_VR_ACCESS)
    178     public void setVr2dDisplayProperties(
    179             @NonNull Vr2dDisplayProperties vr2dDisplayProp) {
    180         try {
    181             mService.setVr2dDisplayProperties(vr2dDisplayProp);
    182         } catch (RemoteException e) {
    183             e.rethrowFromSystemServer();
    184         }
    185     }
    186 
    187     /**
    188      * Set the component name of the compositor service to bind.
    189      *
    190      * @param componentName ComponentName of a Service in the application's compositor process to
    191      * bind to, or null to clear the current binding.
    192      */
    193     @RequiresPermission(android.Manifest.permission.RESTRICTED_VR_ACCESS)
    194     public void setAndBindVrCompositor(ComponentName componentName) {
    195         try {
    196             mService.setAndBindCompositor(
    197                     (componentName == null) ? null : componentName.flattenToString());
    198         } catch (RemoteException e) {
    199             e.rethrowFromSystemServer();
    200         }
    201     }
    202 
    203     /**
    204      * Sets the current standby status of the VR device. Standby mode is only used on standalone vr
    205      * devices. Standby mode is a deep sleep state where it's appropriate to turn off vr mode.
    206      *
    207      * @param standby True if the device is entering standby, false if it's exiting standby.
    208      */
    209     @RequiresPermission(android.Manifest.permission.ACCESS_VR_MANAGER)
    210     public void setStandbyEnabled(boolean standby) {
    211         try {
    212             mService.setStandbyEnabled(standby);
    213         } catch (RemoteException e) {
    214             e.rethrowFromSystemServer();
    215         }
    216     }
    217 
    218     /**
    219      * This method is not implemented.
    220      *
    221      * @param componentName not used
    222      */
    223     @RequiresPermission(android.Manifest.permission.RESTRICTED_VR_ACCESS)
    224     public void setVrInputMethod(@Nullable ComponentName componentName) {
    225     }
    226 
    227     /**
    228      * Returns the display id of VR's {@link VirtualDisplay}.
    229      *
    230      * @see DisplayManager#getDisplay(int)
    231      */
    232     @RequiresPermission(android.Manifest.permission.RESTRICTED_VR_ACCESS)
    233     public int getVr2dDisplayId() {
    234         try {
    235             return mService.getVr2dDisplayId();
    236         } catch (RemoteException e) {
    237             e.rethrowFromSystemServer();
    238         }
    239         return Display.INVALID_DISPLAY;
    240     }
    241 }
    242