blob: 08a210b069b901dd0004ca207c9fb4ae5c6cc06d [file] [log] [blame]
package android.app;
import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Context;
import android.os.RemoteException;
import android.service.vr.IPersistentVrStateCallbacks;
import android.service.vr.IVrManager;
import android.service.vr.IVrStateCallbacks;
import android.util.ArrayMap;
import android.view.Display;
import java.util.Map;
import java.util.concurrent.Executor;
/**
* Used to control aspects of a devices Virtual Reality (VR) capabilities.
* @hide
*/
@SystemApi
@SystemService(Context.VR_SERVICE)
public class VrManager {
private static class CallbackEntry {
final IVrStateCallbacks mStateCallback = new IVrStateCallbacks.Stub() {
@Override
public void onVrStateChanged(boolean enabled) {
mExecutor.execute(() -> mCallback.onVrStateChanged(enabled));
}
};
final IPersistentVrStateCallbacks mPersistentStateCallback =
new IPersistentVrStateCallbacks.Stub() {
@Override
public void onPersistentVrStateChanged(boolean enabled) {
mExecutor.execute(() -> mCallback.onPersistentVrStateChanged(enabled));
}
};
final VrStateCallback mCallback;
final Executor mExecutor;
CallbackEntry(VrStateCallback callback, Executor executor) {
mCallback = callback;
mExecutor = executor;
}
}
@UnsupportedAppUsage
private final IVrManager mService;
private Map<VrStateCallback, CallbackEntry> mCallbackMap = new ArrayMap<>();
/**
* {@hide}
*/
public VrManager(IVrManager service) {
mService = service;
}
/**
* Registers a callback to be notified of changes to the VR Mode state.
*
* @param callback The callback to register.
*/
@RequiresPermission(anyOf = {
android.Manifest.permission.RESTRICTED_VR_ACCESS,
android.Manifest.permission.ACCESS_VR_STATE
})
public void registerVrStateCallback(@NonNull @CallbackExecutor Executor executor,
@NonNull VrStateCallback callback) {
if (callback == null || mCallbackMap.containsKey(callback)) {
return;
}
CallbackEntry entry = new CallbackEntry(callback, executor);
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.
*/
@RequiresPermission(anyOf = {
android.Manifest.permission.RESTRICTED_VR_ACCESS,
android.Manifest.permission.ACCESS_VR_STATE
})
public void unregisterVrStateCallback(@NonNull 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.
*/
@RequiresPermission(anyOf = {
android.Manifest.permission.RESTRICTED_VR_ACCESS,
android.Manifest.permission.ACCESS_VR_STATE
})
public boolean isVrModeEnabled() {
try {
return mService.getVrModeState();
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
return false;
}
/**
* Returns the current VrMode state.
*/
@RequiresPermission(anyOf = {
android.Manifest.permission.RESTRICTED_VR_ACCESS,
android.Manifest.permission.ACCESS_VR_STATE
})
public boolean isPersistentVrModeEnabled() {
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.
*
* @see Activity#setVrModeEnabled(boolean, ComponentName)
* @param enabled true if the device should be placed in persistent VR mode.
*/
@RequiresPermission(android.Manifest.permission.RESTRICTED_VR_ACCESS)
public void setPersistentVrModeEnabled(boolean enabled) {
try {
mService.setPersistentVrModeEnabled(enabled);
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
}
/**
* Sets the resolution and DPI of the vr2d virtual display used to display 2D
* applications in VR mode.
*
* @param vr2dDisplayProp properties to be set to the virtual display for
* 2D applications in VR mode.
*
*/
@RequiresPermission(android.Manifest.permission.RESTRICTED_VR_ACCESS)
public void setVr2dDisplayProperties(
@NonNull Vr2dDisplayProperties vr2dDisplayProp) {
try {
mService.setVr2dDisplayProperties(vr2dDisplayProp);
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
}
/**
* Set the component name of the compositor service to bind.
*
* @param componentName ComponentName of a Service in the application's compositor process to
* bind to, or null to clear the current binding.
*/
@RequiresPermission(android.Manifest.permission.RESTRICTED_VR_ACCESS)
public void setAndBindVrCompositor(ComponentName componentName) {
try {
mService.setAndBindCompositor(
(componentName == null) ? null : componentName.flattenToString());
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
}
/**
* Sets the current standby status of the VR device. Standby mode is only used on standalone vr
* devices. Standby mode is a deep sleep state where it's appropriate to turn off vr mode.
*
* @param standby True if the device is entering standby, false if it's exiting standby.
*/
@RequiresPermission(android.Manifest.permission.ACCESS_VR_MANAGER)
public void setStandbyEnabled(boolean standby) {
try {
mService.setStandbyEnabled(standby);
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
}
/**
* This method is not implemented.
*
* @param componentName not used
*/
@RequiresPermission(android.Manifest.permission.RESTRICTED_VR_ACCESS)
public void setVrInputMethod(@Nullable ComponentName componentName) {
}
/**
* Returns the display id of VR's {@link VirtualDisplay}.
*
* @see DisplayManager#getDisplay(int)
*/
@RequiresPermission(android.Manifest.permission.RESTRICTED_VR_ACCESS)
public int getVr2dDisplayId() {
try {
return mService.getVr2dDisplayId();
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
return Display.INVALID_DISPLAY;
}
}