summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Yohei Yukawa <yukawa@google.com> 2024-07-29 12:41:22 -0700
committer Yohei Yukawa <yukawa@google.com> 2024-07-29 12:41:22 -0700
commitcbd74f55e9849e4812696c275727fba7b35b2e13 (patch)
tree58d2400df9b577aa7be232ffcdc736240a5e5ba9
parent24ceab6ca8b4c371604a95c3c18aa1cbeed585d2 (diff)
Handle onUserStopped to lock the user storage again
This CL addresses an unintentional developer-observable behavior change introduced in my previous CL [1], with which querying IMEs for background users started relying on always on-memory InputMethodSettingsRepository rather than dynamically querying available IMEs. The issue I had been completely unaware of was that user storage could be locked again upon stopping the user. Here is the correct user state transition diagram, and the user stroage is unlocked only from onUserUnlocking to onUserStopped. +--------------------------------------------------------------+ | | +-> onUserStarting ---> onUserUnlocking --+--> onUserStopped --+ | | +-------------------------------+ With this CL InputMethodManagerService starts taking the avobe rule into account to correctly reset relevant data repositories, that are SecureSettingsWrapper and InputMethodSettingsRepository. The the corresponding CTS change [2] about how to programmatically verify this scenario. [1]: Ic0dd655fbd86b8ccce2b3298b4c70359a468f9ec 8130073e978ab0a826ecfab9bee1254551023a32 [2]: Ifa2225070bf8223f8964cf063c86889e312c5e9a Fix: 356037588 Test: atest CtsInputMethodInstallTestCases:UserUnlockTest Test: manually verified as follows 1. Build aosp_cf_x86_64_only_phone-trunk_staging-userdebug and start it 2. make -j SoftKeyboard 3. adb shell pm create-user test_user 4. adb shell am start-user 10 && adb shell dumpsys user --user 10 -> Verify "State: RUNNING_UNLOCKED" 5. adb install --user 10 \ -r $OUT/system/app/SoftKeyboard/SoftKeyboard.apk 6. adb shell ime list -a -s --user 10 -> Verify SoftKeyboard is included 7. adb shell am stop-user 10 && adb shell dumpsys user --user 10 -> Verify "State: -1" 9. adb shell ime list -a -s --user 10 -> Verify SoftKeyboard is no longer included Flag: EXEMPT bug fix Change-Id: I3199ab9d081edf7254f093cd0ed5f322a5604916
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodManagerService.java15
-rw-r--r--services/core/java/com/android/server/inputmethod/SecureSettingsWrapper.java17
2 files changed, 32 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 3ce4343ae808..9b74bcbda4f4 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -1126,6 +1126,21 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
}
});
}
+
+ @Override
+ public void onUserStopped(@NonNull TargetUser user) {
+ final int userId = user.getUserIdentifier();
+ // Called on ActivityManager thread.
+ SecureSettingsWrapper.onUserStopped(userId);
+ mService.mIoHandler.post(() -> {
+ final var additionalSubtypeMap = AdditionalSubtypeMapRepository.get(userId);
+ final var settings = InputMethodManagerService.queryInputMethodServicesInternal(
+ mService.mContext, userId, additionalSubtypeMap,
+ DirectBootAwareness.AUTO).getMethodMap();
+ InputMethodSettingsRepository.put(userId,
+ InputMethodSettings.create(settings, userId));
+ });
+ }
}
@GuardedBy("ImfLock.class")
diff --git a/services/core/java/com/android/server/inputmethod/SecureSettingsWrapper.java b/services/core/java/com/android/server/inputmethod/SecureSettingsWrapper.java
index c208a5b209e5..476888ebf26d 100644
--- a/services/core/java/com/android/server/inputmethod/SecureSettingsWrapper.java
+++ b/services/core/java/com/android/server/inputmethod/SecureSettingsWrapper.java
@@ -377,6 +377,23 @@ final class SecureSettingsWrapper {
}
/**
+ * Called when a user is stopped, which changes the user storage to the locked state again.
+ *
+ * @param userId the ID of the user whose storage is being locked again.
+ */
+ @AnyThread
+ static void onUserStopped(@UserIdInt int userId) {
+ final LockedUserImpl lockedUserImpl = new LockedUserImpl(userId, sContentResolver);
+ synchronized (sMutationLock) {
+ final ReaderWriter current = sUserMap.get(userId);
+ if (current == null || current instanceof LockedUserImpl) {
+ return;
+ }
+ sUserMap = sUserMap.cloneWithPutOrSelf(userId, lockedUserImpl);
+ }
+ }
+
+ /**
* Put the given string {@code value} to {@code key}.
*
* @param key a secure settings key.