Merge "Add getInputMethodList API for locked user state"

This commit is contained in:
Wilson Wu
2021-12-29 02:00:02 +00:00
committed by Android (Google) Code Review
5 changed files with 118 additions and 19 deletions

View File

@@ -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;
@@ -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.
*

View File

@@ -0,0 +1,47 @@
/*
* 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;
}

View File

@@ -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,

View File

@@ -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;
@@ -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() {

View File

@@ -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;
@@ -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);
@@ -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) {
@@ -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 {
@@ -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;
}
@@ -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());
@@ -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
@@ -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);
}
}
@@ -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;
}
@@ -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 #");
@@ -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);