From 927d3453d39a9048c41eddf2418a97562757e930 Mon Sep 17 00:00:00 2001 From: Ruben Brunk Date: Mon, 2 May 2016 19:30:51 -0700 Subject: [PATCH] Update VR API docs. Bug: 28526281 Change-Id: Iff48d02a2fee542c5ded7fc8cd6cf74957eb738c --- core/java/android/app/Activity.java | 52 +++++++++++++++++-- .../android/content/pm/PackageManager.java | 35 +++++++++---- .../android/service/vr/VrListenerService.java | 45 +++++++++++----- core/res/res/values/attrs_manifest.xml | 12 ++--- 4 files changed, 111 insertions(+), 33 deletions(-) diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 0149952ae2cd4..28386f8ec9a90 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -6205,17 +6205,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: + * */ @SdkConstant(SdkConstantType.FEATURE) public static final String FEATURE_VR_MODE_HIGH_PERFORMANCE diff --git a/core/java/android/service/vr/VrListenerService.java b/core/java/android/service/vr/VrListenerService.java index 9a5e95d7a4bdf..c76d7934a0cff 100644 --- a/core/java/android/service/vr/VrListenerService.java +++ b/core/java/android/service/vr/VrListenerService.java @@ -44,11 +44,17 @@ import android.os.Message; * </service> * * - *

- * 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 @@ + the component of the {@link android.service.vr.VrListenerService} that should be + bound while this Activity is visible if it is installed and enabled on this device. + This is equivalent to calling {@link android.app.Activity#setVrModeEnabled} with the + the given component name within the Activity that this attribute is set for. + Declaring this will prevent the system from leaving VR mode during an Activity + transtion from one VR activity to another. -->