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

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

Fix IME list corruption upon IMM#setAdditionalInputMethodSubtypes

This is a follow up CL to my previous CL [1], which introduced a
tricky bug where InputMethodManagerService may look to forget certain
IMEs when an IME calls IMM#setAdditionalInputMethodSubtypes() API.

The issue is that when an IME X calls

  InputMethodManagerService#setAdditionalInputMethodSubtypes(),

IMMS stops recogning IMEs that are not visible from IME X. This
happens because InputMethodSettings for the calling user will be
replaced with

  packageManager.queryIntentServices(
    new Intent(InputMethod.SERVICE_INTERFACE),
    PackageManager.GET_META_DATA
    | PackageManager.MATCH_DIRECT_BOOT_AUTO
    | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS);

where package visibility filtering will be applied with IME X's
identity rather than system_server's identity.

With this commit we start calling packageManager#queryIntentServices()
with system_server's identity as it used to be before my commit [1].

See also the corresponding regression test [2].

 [1]: If7d9dc5636f1bf04f02a18c84d55681914e82014
      43198777
 [2]: I25245a48088c8dd75affc1e68e174a8f8af0d189

Bug: 343108534
Fix: 335281466
Fix: 339928613
Fix: 340806169
Fix: 342105635
Fix: 339912139
Test: atest CtsInputMethodTestCases:InputMethodSubtypeEndToEndTest
Change-Id: I3ea4e233202f8b77b8162a743f1ffedff9abb4af
parent 6203f2d0
Loading
Loading
Loading
Loading
+15 −9
Original line number Diff line number Diff line
@@ -4098,21 +4098,21 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
            if (additionalSubtypeMap != newAdditionalSubtypeMap) {
                AdditionalSubtypeMapRepository.putAndSave(userId, newAdditionalSubtypeMap,
                        settings.getMethodMap());
                final InputMethodSettings newSettings = queryInputMethodServicesInternal(mContext,
                        userId, AdditionalSubtypeMapRepository.get(userId),
                final long ident = Binder.clearCallingIdentity();
                try {
                    final InputMethodSettings newSettings = queryInputMethodServicesInternal(
                            mContext, userId, AdditionalSubtypeMapRepository.get(userId),
                            DirectBootAwareness.AUTO);
                    InputMethodSettingsRepository.put(userId, newSettings);
                    if (isCurrentUser) {
                    final long ident = Binder.clearCallingIdentity();
                    try {
                        postInputMethodSettingUpdatedLocked(false /* resetDefaultEnabledIme */);
                    }
                } finally {
                    Binder.restoreCallingIdentity(ident);
                }
            }
        }
    }
    }

    @Override
    public void setExplicitlyEnabledInputMethodSubtypes(String imeId,
@@ -4969,6 +4969,12 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
        final int flags = PackageManager.GET_META_DATA
                | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
                | directBootAwarenessFlags;

        // Beware that package visibility filtering will be enforced based on the effective calling
        // identity (Binder.getCallingUid()), but our use case always expect Binder.getCallingUid()
        // to return Process.SYSTEM_UID here. The actual filtering is implemented separately with
        // canCallerAccessInputMethod().
        // TODO(b/343108534): Use PackageManagerInternal#queryIntentServices() to pass SYSTEM_UID.
        final List<ResolveInfo> services = userAwareContext.getPackageManager().queryIntentServices(
                new Intent(InputMethod.SERVICE_INTERFACE),
                PackageManager.ResolveInfoFlags.of(flags));