Loading core/java/android/view/inputmethod/InputMethodManager.java +21 −0 Original line number Diff line number Diff line Loading @@ -86,6 +86,7 @@ import android.view.WindowManager.LayoutParams.SoftInputModeFlags; import android.view.autofill.AutofillManager; import com.android.internal.annotations.GuardedBy; import com.android.internal.inputmethod.DirectBootAwareness; import com.android.internal.inputmethod.ImeTracing; import com.android.internal.inputmethod.InputBindResult; import com.android.internal.inputmethod.InputMethodDebug; Loading Loading @@ -1233,6 +1234,26 @@ public final class InputMethodManager { } } /** * Returns the list of installed input methods for the specified user. * * @param userId user ID to query * @param directBootAwareness {@code true} if caller want to query installed input methods list * on user locked state. * @return {@link List} of {@link InputMethodInfo}. * @hide */ @RequiresPermission(INTERACT_ACROSS_USERS_FULL) @NonNull public List<InputMethodInfo> getInputMethodListAsUser(@UserIdInt int userId, @DirectBootAwareness int directBootAwareness) { try { return mService.getAwareLockedInputMethodList(userId, directBootAwareness); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Returns the list of enabled input methods. * Loading core/java/com/android/internal/inputmethod/DirectBootAwareness.java 0 → 100644 +47 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.internal.inputmethod; import static java.lang.annotation.RetentionPolicy.SOURCE; import android.annotation.IntDef; import java.lang.annotation.Retention; /** * Specifies the decided filtering mode regarding IMEs' DirectBoot awareness when querying IMEs. */ @Retention(SOURCE) @IntDef({DirectBootAwareness.AUTO, DirectBootAwareness.ANY}) public @interface DirectBootAwareness { /** * The same semantics as {@link android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AUTO}, that * is, if the user to be queried is still locked, then only DirectBoot-aware IMEs will be * matched. If the user to be queried is already unlocked, then IMEs will not be filtered out * based on their DirectBoot awareness. */ int AUTO = 0; /** * The same semantics as specifying <strong>both</strong> * {@link android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE} and * {@link android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE}, that is, IME will never * be filtered out based on their DirectBoot awareness, no matter whether the user to be queried * is still locked or already unlocked. */ int ANY = 1; } core/java/com/android/internal/view/IInputMethodManager.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ interface IInputMethodManager { // TODO: Use ParceledListSlice instead List<InputMethodInfo> getInputMethodList(int userId); List<InputMethodInfo> getAwareLockedInputMethodList(int userId, int directBootAwareness); // TODO: Use ParceledListSlice instead List<InputMethodInfo> getEnabledInputMethodList(int userId); List<InputMethodSubtype> getEnabledInputMethodSubtypeList(in String imiId, Loading packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodSettingValuesWrapper.java +3 −1 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import android.view.inputmethod.InputMethodInfo; import android.view.inputmethod.InputMethodManager; import com.android.internal.annotations.GuardedBy; import com.android.internal.inputmethod.DirectBootAwareness; import java.util.ArrayList; import java.util.HashMap; Loading Loading @@ -88,7 +89,8 @@ public class InputMethodSettingValuesWrapper { public void refreshAllInputMethodAndSubtypes() { mMethodList.clear(); mMethodList.addAll(mImm.getInputMethodListAsUser(mContentResolver.getUserId())); mMethodList.addAll(mImm.getInputMethodListAsUser( mContentResolver.getUserId(), DirectBootAwareness.ANY)); } public List<InputMethodInfo> getInputMethodList() { Loading services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +46 −18 Original line number Diff line number Diff line Loading @@ -149,6 +149,7 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.compat.IPlatformCompat; import com.android.internal.content.PackageMonitor; import com.android.internal.infra.AndroidFuture; import com.android.internal.inputmethod.DirectBootAwareness; import com.android.internal.inputmethod.IInputContentUriToken; import com.android.internal.inputmethod.IInputMethodPrivilegedOperations; import com.android.internal.inputmethod.ImeTracing; Loading Loading @@ -1869,8 +1870,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub return true; } @Override public List<InputMethodInfo> getInputMethodList(@UserIdInt int userId) { private List<InputMethodInfo> getInputMethodListInternal(@UserIdInt int userId, @DirectBootAwareness int directBootAwareness) { if (UserHandle.getCallingUserId() != userId) { mContext.enforceCallingPermission( Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); Loading @@ -1883,13 +1884,24 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } final long ident = Binder.clearCallingIdentity(); try { return getInputMethodListLocked(resolvedUserIds[0]); return getInputMethodListLocked(resolvedUserIds[0], directBootAwareness); } finally { Binder.restoreCallingIdentity(ident); } } } @Override public List<InputMethodInfo> getInputMethodList(@UserIdInt int userId) { return getInputMethodListInternal(userId, DirectBootAwareness.AUTO); } @Override public List<InputMethodInfo> getAwareLockedInputMethodList(@UserIdInt int userId, @DirectBootAwareness int directBootAwareness) { return getInputMethodListInternal(userId, directBootAwareness); } @Override public List<InputMethodInfo> getEnabledInputMethodList(@UserIdInt int userId) { if (UserHandle.getCallingUserId() != userId) { Loading @@ -1912,9 +1924,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } @GuardedBy("mMethodMap") private List<InputMethodInfo> getInputMethodListLocked(@UserIdInt int userId) { private List<InputMethodInfo> getInputMethodListLocked(@UserIdInt int userId, @DirectBootAwareness int directBootAwareness) { final ArrayList<InputMethodInfo> methodList; if (userId == mSettings.getCurrentUserId()) { if (userId == mSettings.getCurrentUserId() && directBootAwareness == DirectBootAwareness.AUTO) { // Create a copy. methodList = new ArrayList<>(mMethodList); } else { Loading @@ -1924,7 +1938,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub new ArrayMap<>(); AdditionalSubtypeUtils.load(additionalSubtypeMap, userId); queryInputMethodServicesInternal(mContext, userId, additionalSubtypeMap, methodMap, methodList); methodList, directBootAwareness); } return methodList; } Loading Loading @@ -4389,17 +4403,31 @@ public class InputMethodManagerService extends IInputMethodManager.Stub static void queryInputMethodServicesInternal(Context context, @UserIdInt int userId, ArrayMap<String, List<InputMethodSubtype>> additionalSubtypeMap, ArrayMap<String, InputMethodInfo> methodMap, ArrayList<InputMethodInfo> methodList) { ArrayMap<String, InputMethodInfo> methodMap, ArrayList<InputMethodInfo> methodList, @DirectBootAwareness int directBootAwareness) { methodList.clear(); methodMap.clear(); // Note: We do not specify PackageManager.MATCH_ENCRYPTION_* flags here because the default // behavior of PackageManager is exactly what we want. It by default picks up appropriate // services depending on the unlock state for the specified user. final int directBootAwarenessFlags; switch (directBootAwareness) { case DirectBootAwareness.ANY: directBootAwarenessFlags = PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE; break; case DirectBootAwareness.AUTO: directBootAwarenessFlags = PackageManager.MATCH_DIRECT_BOOT_AUTO; break; default: directBootAwarenessFlags = PackageManager.MATCH_DIRECT_BOOT_AUTO; Slog.e(TAG, "Unknown directBootAwareness=" + directBootAwareness + ". Falling back to DirectBootAwareness.AUTO"); break; } final int flags = PackageManager.GET_META_DATA | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS | directBootAwarenessFlags; final List<ResolveInfo> services = context.getPackageManager().queryIntentServicesAsUser( new Intent(InputMethod.SERVICE_INTERFACE), PackageManager.GET_META_DATA | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, userId); new Intent(InputMethod.SERVICE_INTERFACE), flags, userId); methodList.ensureCapacity(services.size()); methodMap.ensureCapacity(services.size()); Loading Loading @@ -4448,7 +4476,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub mMyPackageMonitor.clearKnownImePackageNamesLocked(); queryInputMethodServicesInternal(mContext, mSettings.getCurrentUserId(), mAdditionalSubtypeMap, mMethodMap, mMethodList); mAdditionalSubtypeMap, mMethodMap, mMethodList, DirectBootAwareness.AUTO); // Construct the set of possible IME packages for onPackageChanged() to avoid false // negatives when the package state remains to be the same but only the component state is Loading Loading @@ -4752,7 +4780,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub private List<InputMethodInfo> getInputMethodListAsUser(@UserIdInt int userId) { synchronized (mMethodMap) { return getInputMethodListLocked(userId); return getInputMethodListLocked(userId, DirectBootAwareness.AUTO); } } Loading @@ -4777,7 +4805,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub new ArrayMap<>(); AdditionalSubtypeUtils.load(additionalSubtypeMap, userId); queryInputMethodServicesInternal(mContext, userId, additionalSubtypeMap, methodMap, methodList); methodMap, methodList, DirectBootAwareness.AUTO); return methodMap; } Loading Loading @@ -5406,7 +5434,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub mSettings.getCurrentUserId(), shellCommand.getErrPrintWriter()); for (int userId : userIds) { final List<InputMethodInfo> methods = all ? getInputMethodListLocked(userId) ? getInputMethodListLocked(userId, DirectBootAwareness.AUTO) : getEnabledInputMethodListLocked(userId); if (userIds.length > 1) { pr.print("User #"); Loading Loading @@ -5641,7 +5669,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub new ArrayMap<>(); AdditionalSubtypeUtils.load(additionalSubtypeMap, userId); queryInputMethodServicesInternal(mContext, userId, additionalSubtypeMap, methodMap, methodList); methodMap, methodList, DirectBootAwareness.AUTO); final InputMethodSettings settings = new InputMethodSettings( mContext.getResources(), mContext.getContentResolver(), methodMap, userId, false); Loading Loading
core/java/android/view/inputmethod/InputMethodManager.java +21 −0 Original line number Diff line number Diff line Loading @@ -86,6 +86,7 @@ import android.view.WindowManager.LayoutParams.SoftInputModeFlags; import android.view.autofill.AutofillManager; import com.android.internal.annotations.GuardedBy; import com.android.internal.inputmethod.DirectBootAwareness; import com.android.internal.inputmethod.ImeTracing; import com.android.internal.inputmethod.InputBindResult; import com.android.internal.inputmethod.InputMethodDebug; Loading Loading @@ -1233,6 +1234,26 @@ public final class InputMethodManager { } } /** * Returns the list of installed input methods for the specified user. * * @param userId user ID to query * @param directBootAwareness {@code true} if caller want to query installed input methods list * on user locked state. * @return {@link List} of {@link InputMethodInfo}. * @hide */ @RequiresPermission(INTERACT_ACROSS_USERS_FULL) @NonNull public List<InputMethodInfo> getInputMethodListAsUser(@UserIdInt int userId, @DirectBootAwareness int directBootAwareness) { try { return mService.getAwareLockedInputMethodList(userId, directBootAwareness); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Returns the list of enabled input methods. * Loading
core/java/com/android/internal/inputmethod/DirectBootAwareness.java 0 → 100644 +47 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.internal.inputmethod; import static java.lang.annotation.RetentionPolicy.SOURCE; import android.annotation.IntDef; import java.lang.annotation.Retention; /** * Specifies the decided filtering mode regarding IMEs' DirectBoot awareness when querying IMEs. */ @Retention(SOURCE) @IntDef({DirectBootAwareness.AUTO, DirectBootAwareness.ANY}) public @interface DirectBootAwareness { /** * The same semantics as {@link android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AUTO}, that * is, if the user to be queried is still locked, then only DirectBoot-aware IMEs will be * matched. If the user to be queried is already unlocked, then IMEs will not be filtered out * based on their DirectBoot awareness. */ int AUTO = 0; /** * The same semantics as specifying <strong>both</strong> * {@link android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE} and * {@link android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE}, that is, IME will never * be filtered out based on their DirectBoot awareness, no matter whether the user to be queried * is still locked or already unlocked. */ int ANY = 1; }
core/java/com/android/internal/view/IInputMethodManager.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ interface IInputMethodManager { // TODO: Use ParceledListSlice instead List<InputMethodInfo> getInputMethodList(int userId); List<InputMethodInfo> getAwareLockedInputMethodList(int userId, int directBootAwareness); // TODO: Use ParceledListSlice instead List<InputMethodInfo> getEnabledInputMethodList(int userId); List<InputMethodSubtype> getEnabledInputMethodSubtypeList(in String imiId, Loading
packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodSettingValuesWrapper.java +3 −1 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import android.view.inputmethod.InputMethodInfo; import android.view.inputmethod.InputMethodManager; import com.android.internal.annotations.GuardedBy; import com.android.internal.inputmethod.DirectBootAwareness; import java.util.ArrayList; import java.util.HashMap; Loading Loading @@ -88,7 +89,8 @@ public class InputMethodSettingValuesWrapper { public void refreshAllInputMethodAndSubtypes() { mMethodList.clear(); mMethodList.addAll(mImm.getInputMethodListAsUser(mContentResolver.getUserId())); mMethodList.addAll(mImm.getInputMethodListAsUser( mContentResolver.getUserId(), DirectBootAwareness.ANY)); } public List<InputMethodInfo> getInputMethodList() { Loading
services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +46 −18 Original line number Diff line number Diff line Loading @@ -149,6 +149,7 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.compat.IPlatformCompat; import com.android.internal.content.PackageMonitor; import com.android.internal.infra.AndroidFuture; import com.android.internal.inputmethod.DirectBootAwareness; import com.android.internal.inputmethod.IInputContentUriToken; import com.android.internal.inputmethod.IInputMethodPrivilegedOperations; import com.android.internal.inputmethod.ImeTracing; Loading Loading @@ -1869,8 +1870,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub return true; } @Override public List<InputMethodInfo> getInputMethodList(@UserIdInt int userId) { private List<InputMethodInfo> getInputMethodListInternal(@UserIdInt int userId, @DirectBootAwareness int directBootAwareness) { if (UserHandle.getCallingUserId() != userId) { mContext.enforceCallingPermission( Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); Loading @@ -1883,13 +1884,24 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } final long ident = Binder.clearCallingIdentity(); try { return getInputMethodListLocked(resolvedUserIds[0]); return getInputMethodListLocked(resolvedUserIds[0], directBootAwareness); } finally { Binder.restoreCallingIdentity(ident); } } } @Override public List<InputMethodInfo> getInputMethodList(@UserIdInt int userId) { return getInputMethodListInternal(userId, DirectBootAwareness.AUTO); } @Override public List<InputMethodInfo> getAwareLockedInputMethodList(@UserIdInt int userId, @DirectBootAwareness int directBootAwareness) { return getInputMethodListInternal(userId, directBootAwareness); } @Override public List<InputMethodInfo> getEnabledInputMethodList(@UserIdInt int userId) { if (UserHandle.getCallingUserId() != userId) { Loading @@ -1912,9 +1924,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } @GuardedBy("mMethodMap") private List<InputMethodInfo> getInputMethodListLocked(@UserIdInt int userId) { private List<InputMethodInfo> getInputMethodListLocked(@UserIdInt int userId, @DirectBootAwareness int directBootAwareness) { final ArrayList<InputMethodInfo> methodList; if (userId == mSettings.getCurrentUserId()) { if (userId == mSettings.getCurrentUserId() && directBootAwareness == DirectBootAwareness.AUTO) { // Create a copy. methodList = new ArrayList<>(mMethodList); } else { Loading @@ -1924,7 +1938,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub new ArrayMap<>(); AdditionalSubtypeUtils.load(additionalSubtypeMap, userId); queryInputMethodServicesInternal(mContext, userId, additionalSubtypeMap, methodMap, methodList); methodList, directBootAwareness); } return methodList; } Loading Loading @@ -4389,17 +4403,31 @@ public class InputMethodManagerService extends IInputMethodManager.Stub static void queryInputMethodServicesInternal(Context context, @UserIdInt int userId, ArrayMap<String, List<InputMethodSubtype>> additionalSubtypeMap, ArrayMap<String, InputMethodInfo> methodMap, ArrayList<InputMethodInfo> methodList) { ArrayMap<String, InputMethodInfo> methodMap, ArrayList<InputMethodInfo> methodList, @DirectBootAwareness int directBootAwareness) { methodList.clear(); methodMap.clear(); // Note: We do not specify PackageManager.MATCH_ENCRYPTION_* flags here because the default // behavior of PackageManager is exactly what we want. It by default picks up appropriate // services depending on the unlock state for the specified user. final int directBootAwarenessFlags; switch (directBootAwareness) { case DirectBootAwareness.ANY: directBootAwarenessFlags = PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE; break; case DirectBootAwareness.AUTO: directBootAwarenessFlags = PackageManager.MATCH_DIRECT_BOOT_AUTO; break; default: directBootAwarenessFlags = PackageManager.MATCH_DIRECT_BOOT_AUTO; Slog.e(TAG, "Unknown directBootAwareness=" + directBootAwareness + ". Falling back to DirectBootAwareness.AUTO"); break; } final int flags = PackageManager.GET_META_DATA | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS | directBootAwarenessFlags; final List<ResolveInfo> services = context.getPackageManager().queryIntentServicesAsUser( new Intent(InputMethod.SERVICE_INTERFACE), PackageManager.GET_META_DATA | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, userId); new Intent(InputMethod.SERVICE_INTERFACE), flags, userId); methodList.ensureCapacity(services.size()); methodMap.ensureCapacity(services.size()); Loading Loading @@ -4448,7 +4476,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub mMyPackageMonitor.clearKnownImePackageNamesLocked(); queryInputMethodServicesInternal(mContext, mSettings.getCurrentUserId(), mAdditionalSubtypeMap, mMethodMap, mMethodList); mAdditionalSubtypeMap, mMethodMap, mMethodList, DirectBootAwareness.AUTO); // Construct the set of possible IME packages for onPackageChanged() to avoid false // negatives when the package state remains to be the same but only the component state is Loading Loading @@ -4752,7 +4780,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub private List<InputMethodInfo> getInputMethodListAsUser(@UserIdInt int userId) { synchronized (mMethodMap) { return getInputMethodListLocked(userId); return getInputMethodListLocked(userId, DirectBootAwareness.AUTO); } } Loading @@ -4777,7 +4805,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub new ArrayMap<>(); AdditionalSubtypeUtils.load(additionalSubtypeMap, userId); queryInputMethodServicesInternal(mContext, userId, additionalSubtypeMap, methodMap, methodList); methodMap, methodList, DirectBootAwareness.AUTO); return methodMap; } Loading Loading @@ -5406,7 +5434,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub mSettings.getCurrentUserId(), shellCommand.getErrPrintWriter()); for (int userId : userIds) { final List<InputMethodInfo> methods = all ? getInputMethodListLocked(userId) ? getInputMethodListLocked(userId, DirectBootAwareness.AUTO) : getEnabledInputMethodListLocked(userId); if (userIds.length > 1) { pr.print("User #"); Loading Loading @@ -5641,7 +5669,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub new ArrayMap<>(); AdditionalSubtypeUtils.load(additionalSubtypeMap, userId); queryInputMethodServicesInternal(mContext, userId, additionalSubtypeMap, methodMap, methodList); methodMap, methodList, DirectBootAwareness.AUTO); final InputMethodSettings settings = new InputMethodSettings( mContext.getResources(), mContext.getContentResolver(), methodMap, userId, false); Loading