diff options
| -rw-r--r-- | core/java/android/app/Activity.java | 54 | ||||
| -rw-r--r-- | core/java/android/content/pm/PackageManager.java | 35 | ||||
| -rw-r--r-- | core/java/android/service/vr/VrListenerService.java | 45 | ||||
| -rw-r--r-- | core/res/res/values/attrs_manifest.xml | 12 |
4 files changed, 112 insertions, 34 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index f7020cdcd911..9b4c8bd070d8 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. - * - * <p>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.</p> + * Enable or disable virtual reality (VR) mode for this Activity. + * + * <p>VR mode is a hint to Android system to switch to a mode optimized for VR applications + * while this Activity has user focus.</p> + * + * <p>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.</p> + * + * <p>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:</p> + * + * <pre> + * 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); + * } + * } + * </pre> * * @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 a96da09cf67e..b06568ca0b2d 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: + * <ul> + * <li>Deliver 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 for VR + * applications that have called + * {@link android.view.Window#setSustainedPerformanceMode}.</li> + * <li>Implement {@link #FEATURE_HIFI_SENSORS} and have a low sensor latency.</li> + * <li>Include optimizations to lower display persistence while running VR applications.</li> + * <li>Implement an optimized render path to minimize latency to draw to the device's main + * display.</li> + * <li>Include the following EGL extensions: EGL_ANDROID_create_native_client_buffer, + * EGL_ANDROID_front_buffer_auto_refresh, EGL_EXT_protected_content, + * EGL_KHR_mutable_render_buffer, EGL_KHR_reusable_sync, and EGL_KHR_wait_sync.</li> + * <li>Provide at least one CPU core that is reserved for use solely by the top, foreground + * VR application process for critical render threads while such an application is + * running.</li> + * </ul> */ @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 9a5e95d7a4bd..c76d7934a0cf 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> * </pre> * - * <p> - * 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)} - * </p> + * <p>This service is bound when the system enters VR mode and is unbound when the system leaves VR + * mode.</p> + * <p>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.</p> + * + * @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. - * <p/> - * 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. + * + * <p>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.</p> + * + * @param component the {@link ComponentName} of the VR activity that the system has + * switched to. * - * @param component the {@link ComponentName} of the new current VR activity. + * @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. + * + * <p>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.</p> * * @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 191afe5fd521..8c5cb473295e 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -553,12 +553,12 @@ <attr name="immersive" format="boolean" /> <!-- Flag declaring that this activity will be run in VR mode, and specifying - the component of the VrListenerService that should be bound while this - Activity is visible if installed and enabled on this device. This is - equivalent to calling {@link android.app.Activity#setVrModeEnabled} with the - the given component name within this Activity. Declaring this will prevent - the system from leaving VR mode during an Activity transtion one VR activity - to another. --> + 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. --> <attr name="enableVrMode" format="string" /> <!-- Specify the order in which content providers hosted by a process |