summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlags.kt94
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlagsTest.kt137
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt15
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/NotificationPlayer.java2
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodManagerService.java62
-rw-r--r--services/core/java/com/android/server/wm/BackNavigationController.java10
-rw-r--r--services/java/com/android/server/SystemServer.java20
-rw-r--r--services/java/com/android/server/flags.aconfig7
-rw-r--r--services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceTestBase.java2
9 files changed, 251 insertions, 98 deletions
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlags.kt b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlags.kt
index dfc9c82d85ff..8f7fdd6a7b84 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlags.kt
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlags.kt
@@ -37,15 +37,12 @@ enum class DesktopModeFlags(
// All desktop mode related flags will be added here
DESKTOP_WINDOWING_MODE(DesktopModeStatus::isDesktopModeFlagEnabled, true);
- private val TAG = "DesktopModeFlags"
-
- // Cache for toggle override, which is initialized once on its first access. It needs to be refreshed
- // only on reboots as overridden state takes effect on reboots.
+ // Local cache for toggle override, which is initialized once on its first access. It needs to be
+ // refreshed only on reboots as overridden state takes effect on reboots.
private var cachedToggleOverride: ToggleOverride? = null
/**
- * Determines state of flag based on the actual flag and desktop mode developer option
- * overrides.
+ * Determines state of flag based on the actual flag and desktop mode developer option overrides.
*
* Note, this method makes sure that a constant developer toggle overrides is read until reboot.
*/
@@ -63,34 +60,44 @@ enum class DesktopModeFlags(
}
private fun getToggleOverride(context: Context): ToggleOverride {
- val override = cachedToggleOverride ?: run {
- // Cache toggle override the first time we encounter context. Override does not change
- // with context, as context is just used to fetch a system property.
+ val override =
+ cachedToggleOverride
+ ?: run {
+ val override = getToggleOverrideFromSystem(context)
+ // Cache toggle override the first time we encounter context. Override does not change
+ // with context, as context is just used to fetch System Property and Settings.Global
+ cachedToggleOverride = override
+ Log.d(TAG, "Toggle override initialized to: $override")
+ override
+ }
- // TODO(b/348193756): Cache a persistent value for Settings.Global until reboot. Current
- // cache will change with process restart.
- val toggleOverride =
- Settings.Global.getInt(
- context.contentResolver,
- Settings.Global.DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES,
- ToggleOverride.OVERRIDE_UNSET.setting)
+ return override
+ }
- val newOverride =
- settingToToggleOverrideMap[toggleOverride]
- ?: run {
- Log.w(TAG, "Unknown toggleOverride $toggleOverride")
- ToggleOverride.OVERRIDE_UNSET
- }
- cachedToggleOverride = newOverride
- Log.d(TAG, "Toggle override initialized to: $newOverride")
- newOverride
- }
+ private fun getToggleOverrideFromSystem(context: Context): ToggleOverride {
+ // A non-persistent System Property is used to store override to ensure it remains
+ // constant till reboot.
+ val overrideFromSystemProperties: ToggleOverride? =
+ System.getProperty(SYSTEM_PROPERTY_OVERRIDE_KEY, null).convertToToggleOverride()
+ return overrideFromSystemProperties
+ ?: run {
+ // Read Setting Global if System Property is not present (just after reboot)
+ // or not valid (user manually changed the value)
+ val overrideFromSettingsGlobal =
+ Settings.Global.getInt(
+ context.contentResolver,
+ Settings.Global.DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES,
+ ToggleOverride.OVERRIDE_UNSET.setting)
+ .convertToToggleOverrideWithFallback(ToggleOverride.OVERRIDE_UNSET)
+ // Initialize System Property
+ System.setProperty(
+ SYSTEM_PROPERTY_OVERRIDE_KEY, overrideFromSettingsGlobal.setting.toString())
- return override
+ overrideFromSettingsGlobal
+ }
}
- // TODO(b/348193756): Share ToggleOverride enum with Settings
- // 'DesktopModePreferenceController'
+ // TODO(b/348193756): Share ToggleOverride enum with Settings 'DesktopModePreferenceController'
/**
* Override state of desktop mode developer option toggle.
*
@@ -107,4 +114,33 @@ enum class DesktopModeFlags(
}
private val settingToToggleOverrideMap = ToggleOverride.entries.associateBy { it.setting }
+
+ private fun String?.convertToToggleOverride(): ToggleOverride? {
+ val intValue = this?.toIntOrNull() ?: return null
+ return settingToToggleOverrideMap[intValue]
+ ?: run {
+ Log.w(TAG, "Unknown toggleOverride int $intValue")
+ null
+ }
+ }
+
+ private fun Int.convertToToggleOverrideWithFallback(
+ fallbackOverride: ToggleOverride
+ ): ToggleOverride {
+ return settingToToggleOverrideMap[this]
+ ?: run {
+ Log.w(TAG, "Unknown toggleOverride int $this")
+ fallbackOverride
+ }
+ }
+
+ private companion object {
+ const val TAG = "DesktopModeFlags"
+
+ /**
+ * Key for non-persistent System Property which is used to store desktop windowing developer
+ * option overrides.
+ */
+ const val SYSTEM_PROPERTY_OVERRIDE_KEY = "sys.wmshell.desktopmode.dev_toggle_override"
+ }
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlagsTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlagsTest.kt
index 115b218f2e82..17983b27f4e8 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlagsTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlagsTest.kt
@@ -82,7 +82,7 @@ class DesktopModeFlagsTest : ShellTestCase() {
@Test
@EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
- fun isEnabled_flagOverridable_unsetOverride_featureFlagOn_returnsTrue() {
+ fun isEnabled_overrideUnset_featureFlagOn_returnsTrue() {
setOverride(OVERRIDE_UNSET.setting)
// For overridableFlag, for unset overrides, follow flag
@@ -92,7 +92,7 @@ class DesktopModeFlagsTest : ShellTestCase() {
@Test
@EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
@DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
- fun isEnabled_flagOverridable_unsetOverride_featureFlagOff_returnsFalse() {
+ fun isEnabled_overrideUnset_featureFlagOff_returnsFalse() {
setOverride(OVERRIDE_UNSET.setting)
// For overridableFlag, for unset overrides, follow flag
@@ -101,7 +101,7 @@ class DesktopModeFlagsTest : ShellTestCase() {
@Test
@EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
- fun isEnabled_flagOverridable_noOverride_featureFlagOn_returnsTrue() {
+ fun isEnabled_noOverride_featureFlagOn_returnsTrue() {
setOverride(null)
// For overridableFlag, in absence of overrides, follow flag
@@ -111,7 +111,7 @@ class DesktopModeFlagsTest : ShellTestCase() {
@Test
@EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
@DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
- fun isEnabled_flagOverridable_noOverride_featureFlagOff_returnsFalse() {
+ fun isEnabled_noOverride_featureFlagOff_returnsFalse() {
setOverride(null)
// For overridableFlag, in absence of overrides, follow flag
@@ -120,7 +120,7 @@ class DesktopModeFlagsTest : ShellTestCase() {
@Test
@EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
- fun isEnabled_flagOverridable_unrecognizableOverride_featureFlagOn_returnsTrue() {
+ fun isEnabled_unrecognizableOverride_featureFlagOn_returnsTrue() {
setOverride(-2)
// For overridableFlag, for recognizable overrides, follow flag
@@ -130,7 +130,7 @@ class DesktopModeFlagsTest : ShellTestCase() {
@Test
@EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
@DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
- fun isEnabled_flagOverridable_unrecognizableOverride_featureFlagOff_returnsFalse() {
+ fun isEnabled_unrecognizableOverride_featureFlagOff_returnsFalse() {
setOverride(-2)
// For overridableFlag, for recognizable overrides, follow flag
@@ -139,7 +139,7 @@ class DesktopModeFlagsTest : ShellTestCase() {
@Test
@EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
- fun isEnabled_flagOverridable_overrideOff_featureFlagOn_returnsFalse() {
+ fun isEnabled_overrideOff_featureFlagOn_returnsFalse() {
setOverride(OVERRIDE_OFF.setting)
// For overridableFlag, follow override if they exist
@@ -149,7 +149,7 @@ class DesktopModeFlagsTest : ShellTestCase() {
@Test
@EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
@DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
- fun isEnabled_flagOverridable_overrideOn_featureFlagOff_returnsTrue() {
+ fun isEnabled_overrideOn_featureFlagOff_returnsTrue() {
setOverride(OVERRIDE_ON.setting)
// For overridableFlag, follow override if they exist
@@ -158,7 +158,7 @@ class DesktopModeFlagsTest : ShellTestCase() {
@Test
@EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
- fun isEnabled_flagOverridable_overrideOffThenOn_featureFlagOn_returnsFalseAndFalse() {
+ fun isEnabled_overrideOffThenOn_featureFlagOn_returnsFalseAndFalse() {
setOverride(OVERRIDE_OFF.setting)
// For overridableFlag, follow override if they exist
@@ -173,7 +173,7 @@ class DesktopModeFlagsTest : ShellTestCase() {
@Test
@EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
@DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
- fun isEnabled_flagOverridable_overrideOnThenOff_featureFlagOff_returnsTrueAndTrue() {
+ fun isEnabled_overrideOnThenOff_featureFlagOff_returnsTrueAndTrue() {
setOverride(OVERRIDE_ON.setting)
// For overridableFlag, follow override if they exist
@@ -187,7 +187,7 @@ class DesktopModeFlagsTest : ShellTestCase() {
@Test
@EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
- fun isEnabled_flagOverridable_noOverride_featureFlagOnThenOff_returnsTrueAndFalse() {
+ fun isEnabled_noOverride_featureFlagOnThenOff_returnsTrueAndFalse() {
setOverride(null)
// For overridableFlag, in absence of overrides, follow flag
assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isTrue()
@@ -206,6 +206,108 @@ class DesktopModeFlagsTest : ShellTestCase() {
}
}
+ @Test
+ @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
+ @DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ fun isEnabled_noSystemProperty_overrideOn_featureFlagOff_returnsTrueAndStoresPropertyOn() {
+ System.clearProperty(SYSTEM_PROPERTY_OVERRIDE_KEY)
+ setOverride(OVERRIDE_ON.setting)
+
+ assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isTrue()
+ // Store System Property if not present
+ assertThat(System.getProperty(SYSTEM_PROPERTY_OVERRIDE_KEY))
+ .isEqualTo(OVERRIDE_ON.setting.toString())
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ fun isEnabled_noSystemProperty_overrideUnset_featureFlagOn_returnsTrueAndStoresPropertyUnset() {
+ System.clearProperty(SYSTEM_PROPERTY_OVERRIDE_KEY)
+ setOverride(OVERRIDE_UNSET.setting)
+
+ assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isTrue()
+ // Store System Property if not present
+ assertThat(System.getProperty(SYSTEM_PROPERTY_OVERRIDE_KEY))
+ .isEqualTo(OVERRIDE_UNSET.setting.toString())
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
+ @DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ fun isEnabled_noSystemProperty_overrideUnset_featureFlagOff_returnsFalseAndStoresPropertyUnset() {
+ System.clearProperty(SYSTEM_PROPERTY_OVERRIDE_KEY)
+ setOverride(OVERRIDE_UNSET.setting)
+
+ assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isFalse()
+ // Store System Property if not present
+ assertThat(System.getProperty(SYSTEM_PROPERTY_OVERRIDE_KEY))
+ .isEqualTo(OVERRIDE_UNSET.setting.toString())
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ @Suppress("ktlint:standard:max-line-length")
+ fun isEnabled_systemPropertyNotInteger_overrideOff_featureFlagOn_returnsFalseAndStoresPropertyOff() {
+ System.setProperty(SYSTEM_PROPERTY_OVERRIDE_KEY, "abc")
+ setOverride(OVERRIDE_OFF.setting)
+
+ assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isFalse()
+ // Store System Property if currently invalid
+ assertThat(System.getProperty(SYSTEM_PROPERTY_OVERRIDE_KEY))
+ .isEqualTo(OVERRIDE_OFF.setting.toString())
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ @Suppress("ktlint:standard:max-line-length")
+ fun isEnabled_systemPropertyInvalidInteger_overrideOff_featureFlagOn_returnsFalseAndStoresPropertyOff() {
+ System.setProperty(SYSTEM_PROPERTY_OVERRIDE_KEY, "-2")
+ setOverride(OVERRIDE_OFF.setting)
+
+ assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isFalse()
+ // Store System Property if currently invalid
+ assertThat(System.getProperty(SYSTEM_PROPERTY_OVERRIDE_KEY))
+ .isEqualTo(OVERRIDE_OFF.setting.toString())
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ fun isEnabled_systemPropertyOff_overrideOn_featureFlagOn_returnsFalseAndDoesNotUpdateProperty() {
+ System.setProperty(SYSTEM_PROPERTY_OVERRIDE_KEY, OVERRIDE_OFF.setting.toString())
+ setOverride(OVERRIDE_ON.setting)
+
+ // Have a consistent override until reboot
+ assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isFalse()
+ assertThat(System.getProperty(SYSTEM_PROPERTY_OVERRIDE_KEY))
+ .isEqualTo(OVERRIDE_OFF.setting.toString())
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
+ @DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ fun isEnabled_systemPropertyOn_overrideOff_featureFlagOff_returnsTrueAndDoesNotUpdateProperty() {
+ System.setProperty(SYSTEM_PROPERTY_OVERRIDE_KEY, OVERRIDE_ON.setting.toString())
+ setOverride(OVERRIDE_OFF.setting)
+
+ // Have a consistent override until reboot
+ assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isTrue()
+ assertThat(System.getProperty(SYSTEM_PROPERTY_OVERRIDE_KEY))
+ .isEqualTo(OVERRIDE_ON.setting.toString())
+ }
+
+ @Test
+ @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ @Suppress("ktlint:standard:max-line-length")
+ fun isEnabled_systemPropertyUnset_overrideOff_featureFlagOn_returnsTrueAndDoesNotUpdateProperty() {
+ System.setProperty(SYSTEM_PROPERTY_OVERRIDE_KEY, OVERRIDE_UNSET.setting.toString())
+ setOverride(OVERRIDE_OFF.setting)
+
+ // Have a consistent override until reboot
+ assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isTrue()
+ assertThat(System.getProperty(SYSTEM_PROPERTY_OVERRIDE_KEY))
+ .isEqualTo(OVERRIDE_UNSET.setting.toString())
+ }
+
private fun setOverride(setting: Int?) {
val contentResolver = mContext.contentResolver
val key = Settings.Global.DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES
@@ -217,9 +319,16 @@ class DesktopModeFlagsTest : ShellTestCase() {
}
private fun resetCache() {
- val cacheToggleOverride =
+ val cachedToggleOverride =
DESKTOP_WINDOWING_MODE::class.java.getDeclaredField("cachedToggleOverride")
- cacheToggleOverride.isAccessible = true
- cacheToggleOverride.set(DESKTOP_WINDOWING_MODE, null)
+ cachedToggleOverride.isAccessible = true
+ cachedToggleOverride.set(DESKTOP_WINDOWING_MODE, null)
+
+ // Clear override cache stored in System property
+ System.clearProperty(SYSTEM_PROPERTY_OVERRIDE_KEY)
+ }
+
+ private companion object {
+ const val SYSTEM_PROPERTY_OVERRIDE_KEY = "sys.wmshell.desktopmode.dev_toggle_override"
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
index 22ab82b383a7..ab1194e66275 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
@@ -51,6 +51,7 @@ import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.notification.NotificationUtils.interpolate
import com.android.systemui.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor
import com.android.systemui.util.kotlin.Utils.Companion.sample as sampleCombine
+import com.android.systemui.util.kotlin.Utils.Companion.sampleFilter
import com.android.systemui.util.kotlin.pairwise
import com.android.systemui.util.kotlin.sample
import javax.inject.Inject
@@ -250,17 +251,13 @@ constructor(
/** Keyguard can be clipped at the top as the shade is dragged */
val topClippingBounds: Flow<Int?> by lazy {
- combineTransform(
+ repository.topClippingBounds
+ .sampleFilter(
keyguardTransitionInteractor
.transitionValue(scene = Scenes.Gone, stateWithoutSceneContainer = GONE)
- .map { it == 1f }
- .onStart { emit(false) }
- .distinctUntilChanged(),
- repository.topClippingBounds
- ) { isGone, topClippingBounds ->
- if (!isGone) {
- emit(topClippingBounds)
- }
+ .onStart { emit(0f) }
+ ) { goneValue ->
+ goneValue != 1f
}
.distinctUntilChanged()
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/NotificationPlayer.java b/packages/SystemUI/src/com/android/systemui/media/NotificationPlayer.java
index 988fe640de2d..18a04ec60d56 100644
--- a/packages/SystemUI/src/com/android/systemui/media/NotificationPlayer.java
+++ b/packages/SystemUI/src/com/android/systemui/media/NotificationPlayer.java
@@ -158,7 +158,7 @@ public class NotificationPlayer implements OnCompletionListener, OnErrorListener
}
if (mp != null) {
if (DEBUG) {
- Log.d(mTag, "mPlayer.pause+release piid:" + player.getPlayerIId());
+ Log.d(mTag, "mp.pause+release piid:" + mp.getPlayerIId());
}
mp.pause();
try {
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index a2ba1674f33b..3db99522f657 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -298,22 +298,21 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
private final String[] mNonPreemptibleInputMethods;
/**
- * See {@link #shouldEnableExperimentalConcurrentMultiUserMode(Context)} about when set to be
- * {@code true}.
+ * See {@link #shouldEnableConcurrentMultiUserMode(Context)} about when set to be {@code true}.
*/
@SharedByAllUsersField
- private final boolean mExperimentalConcurrentMultiUserModeEnabled;
+ private final boolean mConcurrentMultiUserModeEnabled;
/**
- * Returns {@code true} if experimental concurrent multi-user mode is enabled.
+ * Returns {@code true} if the concurrent multi-user mode is enabled.
*
* <p>Currently not compatible with profiles (e.g. work profile).</p>
*
* @param context {@link Context} to be used to query
* {@link PackageManager#FEATURE_AUTOMOTIVE}
- * @return {@code true} if experimental concurrent multi-user mode is enabled.
+ * @return {@code true} if the concurrent multi-user mode is enabled.
*/
- static boolean shouldEnableExperimentalConcurrentMultiUserMode(@NonNull Context context) {
+ static boolean shouldEnableConcurrentMultiUserMode(@NonNull Context context) {
return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)
&& UserManager.isVisibleBackgroundUsersEnabled()
&& context.getResources().getBoolean(android.R.bool.config_perDisplayFocusEnabled)
@@ -330,7 +329,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@UserIdInt
@BinderThread
private int resolveImeUserIdLocked(@UserIdInt int callingProcessUserId) {
- return mExperimentalConcurrentMultiUserModeEnabled ? callingProcessUserId : mCurrentUserId;
+ return mConcurrentMultiUserModeEnabled ? callingProcessUserId : mCurrentUserId;
}
final Context mContext;
@@ -973,7 +972,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
public Lifecycle(Context context) {
this(context, new InputMethodManagerService(context,
- shouldEnableExperimentalConcurrentMultiUserMode(context)));
+ shouldEnableConcurrentMultiUserMode(context)));
}
public Lifecycle(
@@ -1003,7 +1002,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
// Called on ActivityManager thread.
synchronized (ImfLock.class) {
- if (mService.mExperimentalConcurrentMultiUserModeEnabled) {
+ if (mService.mConcurrentMultiUserModeEnabled) {
// In concurrent multi-user mode, we in general do not rely on the concept of
// current user.
return;
@@ -1037,9 +1036,9 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
SecureSettingsWrapper.onUserStarting(userId);
synchronized (ImfLock.class) {
mService.getUserData(userId);
- if (mService.mExperimentalConcurrentMultiUserModeEnabled) {
+ if (mService.mConcurrentMultiUserModeEnabled) {
if (mService.mCurrentUserId != userId && mService.mSystemReady) {
- mService.experimentalInitializeVisibleBackgroundUserLocked(userId);
+ mService.initializeVisibleBackgroundUserLocked(userId);
}
}
}
@@ -1062,8 +1061,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
// We need to rebuild IMEs.
postInputMethodSettingUpdatedLocked(false /* resetDefaultEnabledIme */, userId);
updateInputMethodsFromSettingsLocked(true /* enabledChanged */, userId);
- } else if (mExperimentalConcurrentMultiUserModeEnabled) {
- experimentalInitializeVisibleBackgroundUserLocked(userId);
+ } else if (mConcurrentMultiUserModeEnabled) {
+ initializeVisibleBackgroundUserLocked(userId);
}
}
}
@@ -1090,20 +1089,19 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
}
public InputMethodManagerService(Context context,
- boolean experimentalConcurrentMultiUserModeEnabled) {
- this(context, experimentalConcurrentMultiUserModeEnabled, null, null, null);
+ boolean concurrentMultiUserModeEnabled) {
+ this(context, concurrentMultiUserModeEnabled, null, null, null);
}
@VisibleForTesting
InputMethodManagerService(
Context context,
- boolean experimentalConcurrentMultiUserModeEnabled,
+ boolean concurrentMultiUserModeEnabled,
@Nullable ServiceThread serviceThreadForTesting,
@Nullable ServiceThread ioThreadForTesting,
@Nullable IntFunction<InputMethodBindingController> bindingControllerForTesting) {
synchronized (ImfLock.class) {
- mExperimentalConcurrentMultiUserModeEnabled =
- experimentalConcurrentMultiUserModeEnabled;
+ mConcurrentMultiUserModeEnabled = concurrentMultiUserModeEnabled;
mContext = context;
mRes = context.getResources();
SecureSettingsWrapper.onStart(mContext);
@@ -1428,10 +1426,10 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
AdditionalSubtypeMapRepository::startWriterThread,
"Start AdditionalSubtypeMapRepository's writer thread");
- if (mExperimentalConcurrentMultiUserModeEnabled) {
+ if (mConcurrentMultiUserModeEnabled) {
for (int userId : mUserManagerInternal.getUserIds()) {
if (userId != mCurrentUserId) {
- experimentalInitializeVisibleBackgroundUserLocked(userId);
+ initializeVisibleBackgroundUserLocked(userId);
}
}
}
@@ -2538,7 +2536,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@SuppressWarnings("GuardedBy") Consumer<ClientState> clearClientSession = c -> {
// TODO(b/305849394): Figure out what we should do for single user IME mode.
final boolean shouldClearClientSession =
- !mExperimentalConcurrentMultiUserModeEnabled
+ !mConcurrentMultiUserModeEnabled
|| UserHandle.getUserId(c.mUid) == userId;
if (shouldClearClientSession) {
clearClientSessionLocked(c);
@@ -2840,27 +2838,25 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
}
/**
- * This is an experimental implementation used when and only when
- * {@link #mExperimentalConcurrentMultiUserModeEnabled}.
+ * This initialization logic is used when and only when {@link #mConcurrentMultiUserModeEnabled}
+ * is set to {@code true}.
*
- * <p>Never assume what this method is doing is officially supported. For the canonical and
- * desired behaviors always refer to single-user code paths such as
+ * <p>There remain several yet-to-be-implemented features. For the canonical and desired
+ * behaviors always refer to single-user code paths such as
* {@link #updateInputMethodsFromSettingsLocked(boolean, int)}.</p>
*
* <p>Here are examples of missing features.</p>
* <ul>
- * <li>Subtypes are not supported at all!</li>
* <li>Profiles are not supported.</li>
* <li>
* {@link PackageManager#COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED} is not updated.
* </li>
* <li>{@link InputMethodBindingController#getDeviceIdToShowIme()} is ignored.</li>
- * <li>{@link #mPreventImeStartupUnlessTextEditor} is ignored.</li>
* <li>and so on.</li>
* </ul>
*/
@GuardedBy("ImfLock.class")
- void experimentalInitializeVisibleBackgroundUserLocked(@UserIdInt int userId) {
+ void initializeVisibleBackgroundUserLocked(@UserIdInt int userId) {
final var settings = InputMethodSettingsRepository.get(userId);
// Until we figure out what makes most sense, we enable all the pre-installed IMEs in
@@ -3700,8 +3696,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
final long ident = Binder.clearCallingIdentity();
try {
// Verify if IMMS is in the process of switching user.
- if (!mExperimentalConcurrentMultiUserModeEnabled
- && mUserSwitchHandlerTask != null) {
+ if (!mConcurrentMultiUserModeEnabled && mUserSwitchHandlerTask != null) {
// There is already an on-going pending user switch task.
final int nextUserId = mUserSwitchHandlerTask.mToUserId;
if (userId == nextUserId) {
@@ -3756,7 +3751,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
}
// Verify if caller is a background user.
- if (!mExperimentalConcurrentMultiUserModeEnabled && userId != mCurrentUserId) {
+ if (!mConcurrentMultiUserModeEnabled && userId != mCurrentUserId) {
if (ArrayUtils.contains(
mUserManagerInternal.getProfileIds(mCurrentUserId, false),
userId)) {
@@ -5538,7 +5533,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
@GuardedBy("ImfLock.class")
private boolean switchToInputMethodLocked(String imeId, @UserIdInt int userId) {
final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
- if (mExperimentalConcurrentMultiUserModeEnabled || userId == mCurrentUserId) {
+ if (mConcurrentMultiUserModeEnabled || userId == mCurrentUserId) {
if (!settings.getMethodMap().containsKey(imeId)
|| !settings.getEnabledInputMethodList()
.contains(settings.getMethodMap().get(imeId))) {
@@ -6122,8 +6117,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
mVisibilityStateComputer.dump(pw, " ");
p.println(" mInFullscreenMode=" + userData.mInFullscreenMode);
p.println(" mSystemReady=" + mSystemReady + " mInteractive=" + mIsInteractive);
- p.println(" mExperimentalConcurrentMultiUserModeEnabled="
- + mExperimentalConcurrentMultiUserModeEnabled);
+ p.println(" mConcurrentMultiUserModeEnabled=" + mConcurrentMultiUserModeEnabled);
p.println(" ENABLE_HIDE_IME_CAPTION_BAR="
+ InputMethodService.ENABLE_HIDE_IME_CAPTION_BAR);
p.println(" mSettingsObserver=" + mSettingsObserver);
diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java
index d45ed12e5ef6..14e256f7a815 100644
--- a/services/core/java/com/android/server/wm/BackNavigationController.java
+++ b/services/core/java/com/android/server/wm/BackNavigationController.java
@@ -1335,12 +1335,16 @@ class BackNavigationController {
}
// If there is only one adaptor, attach the windowless window to top activity,
// because fixed rotation only applies on activity.
- // Note that embedded activity won't use fixed rotation.
- final Configuration openConfig = mAdaptors.length == 1
+ // Note that embedded activity won't use fixed rotation. Also, there is only one
+ // animation target for closing task.
+ final boolean chooseActivity = mAdaptors.length == 1
+ && (switchType == ACTIVITY_SWITCH || mainActivity.mDisplayContent
+ .isFixedRotationLaunchingApp(mainActivity));
+ final Configuration openConfig = chooseActivity
? mainActivity.getConfiguration() : openTask.getConfiguration();
mRequestedStartingSurfaceId = openTask.mAtmService.mTaskOrganizerController
.addWindowlessStartingSurface(openTask, mainActivity,
- mAdaptors.length == 1 ? mainActivity.getSurfaceControl()
+ chooseActivity ? mainActivity.getSurfaceControl()
: mRemoteAnimationTarget.leash, snapshot, openConfig,
new IWindowlessStartingSurfaceCallback.Stub() {
// Once the starting surface has been created in shell, it will call
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 215cf2c5c85c..791d030a6b63 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -2134,14 +2134,20 @@ public final class SystemServer implements Dumpable {
}
t.traceEnd();
- t.traceBegin("StartVpnManagerService");
- try {
- vpnManager = VpnManagerService.create(context);
- ServiceManager.addService(Context.VPN_MANAGEMENT_SERVICE, vpnManager);
- } catch (Throwable e) {
- reportWtf("starting VPN Manager Service", e);
+ if (!isWatch || !android.server.Flags.allowRemovingVpnService()) {
+ t.traceBegin("StartVpnManagerService");
+ try {
+ vpnManager = VpnManagerService.create(context);
+ ServiceManager.addService(Context.VPN_MANAGEMENT_SERVICE, vpnManager);
+ } catch (Throwable e) {
+ reportWtf("starting VPN Manager Service", e);
+ }
+ t.traceEnd();
+ } else {
+ // VPN management currently does not work in Wear, so skip starting the
+ // VPN manager SystemService.
+ Slog.i(TAG, "Not starting VpnManagerService");
}
- t.traceEnd();
t.traceBegin("StartVcnManagementService");
try {
diff --git a/services/java/com/android/server/flags.aconfig b/services/java/com/android/server/flags.aconfig
index e8aa68cf1a63..29f387117073 100644
--- a/services/java/com/android/server/flags.aconfig
+++ b/services/java/com/android/server/flags.aconfig
@@ -21,4 +21,11 @@ flag {
namespace: "wear_frameworks"
description: "Remove WearableSensingManagerService on Wear"
bug: "340929916"
+}
+
+flag {
+ name: "allow_removing_vpn_service"
+ namespace: "wear_frameworks"
+ description: "Allow removing VpnManagerService"
+ bug: "340928692"
} \ No newline at end of file
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceTestBase.java b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceTestBase.java
index 80eab112d814..17d9ef9fad34 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceTestBase.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceTestBase.java
@@ -233,7 +233,7 @@ public class InputMethodManagerServiceTestBase {
Process.THREAD_PRIORITY_FOREGROUND,
true /* allowIo */);
mInputMethodManagerService = new InputMethodManagerService(mContext,
- InputMethodManagerService.shouldEnableExperimentalConcurrentMultiUserMode(mContext),
+ InputMethodManagerService.shouldEnableConcurrentMultiUserMode(mContext),
mServiceThread, mIoThread,
unusedUserId -> mMockInputMethodBindingController);
spyOn(mInputMethodManagerService);