diff options
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); |