Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cbd74f55 authored by Yohei Yukawa's avatar Yohei Yukawa
Browse files

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
      8130073e
 [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
parent 24ceab6c
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -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")
+17 −0
Original line number Diff line number Diff line
@@ -376,6 +376,23 @@ final class SecureSettingsWrapper {
        putOrGet(userId, readerWriter);
    }

    /**
     * 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}.
     *