Merge "Add getInputMethodList API for locked user state"
This commit is contained in:
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user