From 90e7116743c43e7f3dd2c4aba4f8f3e11b54afc4 Mon Sep 17 00:00:00 2001 From: Zak Cohen Date: Sun, 29 Jan 2017 12:59:23 -0800 Subject: [PATCH] Make activities that are in VR mode ignore ui mode config changes. Going into VR UI mode, when in VR mode, will not cause an activity recreate on pre-O apps. Bug: 30989383,34849643 Test: ran vr mode activity, checked dumpsys uimode for correct values Change-Id: I0d371cce4920dbf2bdeb84dc6c741d12fc2ce444 --- .../com/android/server/am/ActivityRecord.java | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index 3573b8b3e2d62..58c17ebbeafe8 100644 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -30,6 +30,7 @@ import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION; import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT; import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE; import static android.content.pm.ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE; +import static android.content.pm.ActivityInfo.CONFIG_UI_MODE; import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE; import static android.content.pm.ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS; import static android.content.pm.ActivityInfo.FLAG_IMMERSIVE; @@ -44,7 +45,10 @@ import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE; import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE; import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION; import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE; +import static android.content.res.Configuration.UI_MODE_TYPE_MASK; +import static android.content.res.Configuration.UI_MODE_TYPE_VR_HEADSET; import static android.os.Build.VERSION_CODES.HONEYCOMB; +import static android.os.Build.VERSION_CODES.O; import static android.os.Process.SYSTEM_UID; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SAVED_STATE; @@ -79,6 +83,7 @@ import android.content.res.CompatibilityInfo; import android.content.res.Configuration; import android.graphics.Bitmap; import android.graphics.Rect; +import android.os.Build; import android.os.Bundle; import android.os.Debug; import android.os.IBinder; @@ -2007,7 +2012,8 @@ final class ActivityRecord implements AppWindowContainerListener { + ", newGlobalConfig=" + newGlobalConfig + ", newTaskMergedOverrideConfig=" + newTaskMergedOverrideConfig); - if ((changes&(~info.getRealConfigChanged())) != 0 || forceNewConfig) { + if (shouldRelaunchLocked(changes, newGlobalConfig, newTaskMergedOverrideConfig) + || forceNewConfig) { // Aha, the activity isn't handling the change, so DIE DIE DIE. configChangeFlags |= changes; startFreezingScreenLocked(app, globalChanges); @@ -2058,6 +2064,27 @@ final class ActivityRecord implements AppWindowContainerListener { return true; } + /** + * When assessing a configuration change, decide if the changes flags and the new configurations + * should cause the Activity to relaunch. + */ + private boolean shouldRelaunchLocked(int changes, Configuration newGlobalConfig, + Configuration newTaskMergedOverrideConfig) { + int configChanged = info.getRealConfigChanged(); + + // Override for apps targeting pre-O sdks + // If a device is in VR mode, and we're transitioning into VR ui mode, add ignore ui mode + // to the config change. + // For O and later, apps will be required to add configChanges="uimode" to their manifest. + if (appInfo.targetSdkVersion < O + && requestedVrComponent != null + && (isInVrUiMode(newGlobalConfig) || isInVrUiMode(newTaskMergedOverrideConfig))) { + configChanged |= CONFIG_UI_MODE; + } + + return (changes&(~configChanged)) != 0; + } + private static int getTaskConfigurationChanges(ActivityRecord record, Configuration taskConfig, Configuration oldTaskOverride) { // If we went from full-screen to non-full-screen, make sure to use the correct @@ -2294,6 +2321,10 @@ final class ActivityRecord implements AppWindowContainerListener { } } + private static boolean isInVrUiMode(Configuration config) { + return (config.uiMode & Configuration.UI_MODE_TYPE_MASK) == UI_MODE_TYPE_VR_HEADSET; + } + @Override public String toString() { if (stringName != null) {