diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index f7020cdcd911c..9b4c8bd070d81 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -6224,17 +6224,59 @@ public class Activity extends ContextThemeWrapper } /** - * Enable or disable virtual reality (VR) mode. + * Enable or disable virtual reality (VR) mode for this Activity. * - *
VR mode is a hint to Android system services to switch to a mode optimized for - * high-performance stereoscopic rendering. This mode will be enabled while this Activity has - * focus.
+ *VR mode is a hint to Android system to switch to a mode optimized for VR applications + * while this Activity has user focus.
+ * + *It is recommended that applications additionally declare + * {@link android.R.attr#enableVrMode} in their manifest to allow for smooth activity + * transitions when switching between VR activities.
+ * + *If the requested {@link android.service.vr.VrListenerService} component is not available, + * VR mode will not be started. Developers can handle this case as follows:
+ * + *
+ * String servicePackage = "com.whatever.app";
+ * String serviceClass = "com.whatever.app.MyVrListenerService";
+ *
+ * // Name of the component of the VrListenerService to start.
+ * ComponentName serviceComponent = new ComponentName(servicePackage, serviceClass);
+ *
+ * try {
+ * setVrModeEnabled(true, myComponentName);
+ * } catch (PackageManager.NameNotFoundException e) {
+ * List<ApplicationInfo> installed = getPackageManager().getInstalledApplications(0);
+ * boolean isInstalled = false;
+ * for (ApplicationInfo app : installed) {
+ * if (app.packageName.equals(servicePackage)) {
+ * isInstalled = true;
+ * break;
+ * }
+ * }
+ * if (isInstalled) {
+ * // Package is installed, but not enabled in Settings. Let user enable it.
+ * startActivity(new Intent(Settings.ACTION_VR_LISTENER_SETTINGS));
+ * } else {
+ * // Package is not installed. Send an intent to download this.
+ * sentIntentToLaunchAppStore(servicePackage);
+ * }
+ * }
+ *
*
* @param enabled {@code true} to enable this mode.
* @param requestedComponent the name of the component to use as a
* {@link android.service.vr.VrListenerService} while VR mode is enabled.
*
- * @throws android.content.pm.PackageManager.NameNotFoundException;
+ * @throws android.content.pm.PackageManager.NameNotFoundException if the given component
+ * to run as a {@link android.service.vr.VrListenerService} is not installed, or has
+ * not been enabled in user settings.
+ *
+ * @see android.content.pm.PackageManager#FEATURE_VR_MODE
+ * @see android.content.pm.PackageManager#FEATURE_VR_MODE_HIGH_PERFORMANCE
+ * @see android.service.vr.VrListenerService
+ * @see android.provider.Settings#ACTION_VR_LISTENER_SETTINGS
+ * @see android.R.attr#enableVrMode
*/
public void setVrModeEnabled(boolean enabled, @NonNull ComponentName requestedComponent)
throws PackageManager.NameNotFoundException {
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index a96da09cf67e4..b06568ca0b2da 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -2180,22 +2180,37 @@ public abstract class PackageManager {
/**
* Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}:
- * The device implements a an optimized mode for virtual reality (VR) applications that handles
- * stereoscopic rendering of notifications, and may potentially also include optimizations to
- * reduce latency in the graphics, display, and sensor stacks.
+ * The device implements an optimized mode for virtual reality (VR) applications that handles
+ * stereoscopic rendering of notifications, and disables most monocular system UI components
+ * while a VR application has user focus.
+ * Devices declaring this feature must include an application implementing a
+ * {@link android.service.vr.VrListenerService} that can be targeted by VR applications via
+ * {@link android.app.Activity#setVrModeEnabled}.
*/
@SdkConstant(SdkConstantType.FEATURE)
public static final String FEATURE_VR_MODE = "android.software.vr.mode";
/**
* Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}:
- * The device implements {@link #FEATURE_VR_MODE} but additionally meets all CDD requirements
- * to be certified as a "VR Ready" device, which guarantees that the device is capable of
- * delivering consistent performance at a high framerate over an extended period of time for
- * typical VR application CPU/GPU workloads with a minimal number of frame drops, implements
- * {@link #FEATURE_HIFI_SENSORS} with a low sensor latency, implements an optimized render path
- * to minimize latency to draw to the device's main display, and includes optimizations to
- * lower display persistence to an acceptable level.
+ * The device implements {@link #FEATURE_VR_MODE} but additionally meets extra CDD requirements
+ * to provide a high-quality VR experience. In general, devices declaring this feature will
+ * additionally:
+ * - * This service is bound when the system enters VR mode and is unbound when the system leaves VR - * mode. - * {@see android.app.Activity#setVrMode(boolean)} - *
+ *This service is bound when the system enters VR mode and is unbound when the system leaves VR + * mode.
+ *The system will enter VR mode when an application that has previously called + * {@link android.app.Activity#setVrModeEnabled} gains user focus. The system will only start this + * service if the VR application has specifically targeted this service by specifying + * its {@link ComponentName} in the call to {@link android.app.Activity#setVrModeEnabled} and if + * this service is installed and enabled in the current user's settings.
+ * + * @see android.provider.Settings#ACTION_VR_LISTENER_SETTINGS + * @see android.app.Activity#setVrModeEnabled + * @see android.R.attr#enableVrMode */ public abstract class VrListenerService extends Service { @@ -94,25 +100,40 @@ public abstract class VrListenerService extends Service { } /** - * Called when the current activity using VR mode is changed. - * - * This will be called immediately when this service is initially bound, but is - * not guaranteed to be called before onUnbind. + * Called when the current activity using VR mode has changed. * - * @param component the {@link ComponentName} of the new current VR activity. + *This will be called when this service is initially bound, but is not + * guaranteed to be called before onUnbind. In general, this is intended to be used to + * determine when user focus has transitioned between two VR activities. If both activities + * have declared {@link android.R.attr#enableVrMode} with this service (and this + * service is present and enabled), this service will not be unbound during the activity + * transition.
+ * + * @param component the {@link ComponentName} of the VR activity that the system has + * switched to. + * + * @see android.app.Activity#setVrModeEnabled + * @see android.R.attr#enableVrMode */ public void onCurrentVrActivityChanged(ComponentName component) { // Override to implement } /** - * Check if the given package is available to be enabled/disabled in VR mode settings. + * Checks if the given component is enabled in user settings. + * + *If this component is not enabled in the user's settings, it will not be started when + * the system enters VR mode. The user interface for enabling VrListenerService components + * can be started by sending the {@link android.provider.Settings#ACTION_VR_LISTENER_SETTINGS} + * intent.
* * @param context the {@link Context} to use for looking up the requested component. * @param requestedComponent the name of the component that implements * {@link android.service.vr.VrListenerService} to check. * - * @return {@code true} if this package is enabled in settings. + * @return {@code true} if this component is enabled in settings. + * + * @see android.provider.Settings#ACTION_VR_LISTENER_SETTINGS */ public static final boolean isVrModePackageEnabled(@NonNull Context context, @NonNull ComponentName requestedComponent) { diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index 191afe5fd5211..8c5cb473295ef 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -553,12 +553,12 @@