Merge "Let InputMethodPrivilegedOperationsRegistry deal with its singleton-ness"
This commit is contained in:
committed by
Android (Google) Code Review
commit
bd5fed399f
@@ -85,6 +85,7 @@ import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.inputmethod.IInputContentUriToken;
|
||||
import com.android.internal.inputmethod.IInputMethodPrivilegedOperations;
|
||||
import com.android.internal.inputmethod.InputMethodPrivilegedOperations;
|
||||
import com.android.internal.inputmethod.InputMethodPrivilegedOperationsRegistry;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
@@ -465,7 +466,7 @@ public class InputMethodService extends AbstractInputMethodService {
|
||||
public final void initializeInternal(IBinder token, int displayId,
|
||||
IInputMethodPrivilegedOperations privilegedOperations) {
|
||||
mPrivOps.set(privilegedOperations);
|
||||
mImm.registerInputMethodPrivOps(token, mPrivOps);
|
||||
InputMethodPrivilegedOperationsRegistry.put(token, mPrivOps);
|
||||
updateInputMethodDisplay(displayId);
|
||||
attachToken(token);
|
||||
}
|
||||
@@ -1031,7 +1032,7 @@ public class InputMethodService extends AbstractInputMethodService {
|
||||
if (mToken != null) {
|
||||
// This is completely optional, but allows us to show more explicit error messages
|
||||
// when IME developers are doing something unsupported.
|
||||
mImm.unregisterInputMethodPrivOps(mToken);
|
||||
InputMethodPrivilegedOperationsRegistry.remove(mToken);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,6 @@ import android.view.ViewRootImpl;
|
||||
import android.view.WindowManager.LayoutParams.SoftInputModeFlags;
|
||||
import android.view.autofill.AutofillManager;
|
||||
|
||||
import com.android.internal.inputmethod.InputMethodPrivilegedOperations;
|
||||
import com.android.internal.inputmethod.InputMethodPrivilegedOperationsRegistry;
|
||||
import com.android.internal.os.SomeArgs;
|
||||
import com.android.internal.view.IInputConnectionWrapper;
|
||||
@@ -387,9 +386,6 @@ public final class InputMethodManager {
|
||||
final Pool<PendingEvent> mPendingEventPool = new SimplePool<>(20);
|
||||
final SparseArray<PendingEvent> mPendingEvents = new SparseArray<>(20);
|
||||
|
||||
private final InputMethodPrivilegedOperationsRegistry mPrivOpsRegistry =
|
||||
new InputMethodPrivilegedOperationsRegistry();
|
||||
|
||||
// -----------------------------------------------------------
|
||||
|
||||
static final int MSG_DUMP = 1;
|
||||
@@ -741,7 +737,7 @@ public final class InputMethodManager {
|
||||
*/
|
||||
@Deprecated
|
||||
public void showStatusIcon(IBinder imeToken, String packageName, @DrawableRes int iconId) {
|
||||
mPrivOpsRegistry.get(imeToken).updateStatusIcon(packageName, iconId);
|
||||
InputMethodPrivilegedOperationsRegistry.get(imeToken).updateStatusIcon(packageName, iconId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -751,7 +747,7 @@ public final class InputMethodManager {
|
||||
*/
|
||||
@Deprecated
|
||||
public void hideStatusIcon(IBinder imeToken) {
|
||||
mPrivOpsRegistry.get(imeToken).updateStatusIcon(null, 0);
|
||||
InputMethodPrivilegedOperationsRegistry.get(imeToken).updateStatusIcon(null, 0);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@@ -1792,7 +1788,7 @@ public final class InputMethodManager {
|
||||
public void setInputMethod(IBinder token, String id) {
|
||||
if (token == null) {
|
||||
// Note: null token is allowed for callers that have WRITE_SECURE_SETTINGS permission.
|
||||
// Thus we cannot always rely on mPrivOpsRegistry unfortunately.
|
||||
// Thus we cannot always rely on InputMethodPrivilegedOperationsRegistry unfortunately.
|
||||
// TODO(Bug 114488811): Consider deprecating null token rule.
|
||||
try {
|
||||
mService.setInputMethod(token, id);
|
||||
@@ -1801,7 +1797,7 @@ public final class InputMethodManager {
|
||||
}
|
||||
return;
|
||||
}
|
||||
mPrivOpsRegistry.get(token).setInputMethod(id);
|
||||
InputMethodPrivilegedOperationsRegistry.get(token).setInputMethod(id);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1821,7 +1817,7 @@ public final class InputMethodManager {
|
||||
public void setInputMethodAndSubtype(IBinder token, String id, InputMethodSubtype subtype) {
|
||||
if (token == null) {
|
||||
// Note: null token is allowed for callers that have WRITE_SECURE_SETTINGS permission.
|
||||
// Thus we cannot always rely on mPrivOpsRegistry unfortunately.
|
||||
// Thus we cannot always rely on InputMethodPrivilegedOperationsRegistry unfortunately.
|
||||
// TODO(Bug 114488811): Consider deprecating null token rule.
|
||||
try {
|
||||
mService.setInputMethodAndSubtype(token, id, subtype);
|
||||
@@ -1830,7 +1826,7 @@ public final class InputMethodManager {
|
||||
}
|
||||
return;
|
||||
}
|
||||
mPrivOpsRegistry.get(token).setInputMethodAndSubtype(id, subtype);
|
||||
InputMethodPrivilegedOperationsRegistry.get(token).setInputMethodAndSubtype(id, subtype);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1850,7 +1846,7 @@ public final class InputMethodManager {
|
||||
*/
|
||||
@Deprecated
|
||||
public void hideSoftInputFromInputMethod(IBinder token, int flags) {
|
||||
mPrivOpsRegistry.get(token).hideMySoftInput(flags);
|
||||
InputMethodPrivilegedOperationsRegistry.get(token).hideMySoftInput(flags);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1871,7 +1867,7 @@ public final class InputMethodManager {
|
||||
*/
|
||||
@Deprecated
|
||||
public void showSoftInputFromInputMethod(IBinder token, int flags) {
|
||||
mPrivOpsRegistry.get(token).showMySoftInput(flags);
|
||||
InputMethodPrivilegedOperationsRegistry.get(token).showMySoftInput(flags);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2231,7 +2227,7 @@ public final class InputMethodManager {
|
||||
public boolean switchToLastInputMethod(IBinder imeToken) {
|
||||
if (imeToken == null) {
|
||||
// Note: null token is allowed for callers that have WRITE_SECURE_SETTINGS permission.
|
||||
// Thus we cannot always rely on mPrivOpsRegistry unfortunately.
|
||||
// Thus we cannot always rely on InputMethodPrivilegedOperationsRegistry unfortunately.
|
||||
// TODO(Bug 114488811): Consider deprecating null token rule.
|
||||
try {
|
||||
return mService.switchToPreviousInputMethod(imeToken);
|
||||
@@ -2239,7 +2235,7 @@ public final class InputMethodManager {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
return mPrivOpsRegistry.get(imeToken).switchToPreviousInputMethod();
|
||||
return InputMethodPrivilegedOperationsRegistry.get(imeToken).switchToPreviousInputMethod();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2259,7 +2255,7 @@ public final class InputMethodManager {
|
||||
public boolean switchToNextInputMethod(IBinder imeToken, boolean onlyCurrentIme) {
|
||||
if (imeToken == null) {
|
||||
// Note: null token is allowed for callers that have WRITE_SECURE_SETTINGS permission.
|
||||
// Thus we cannot always rely on mPrivOpsRegistry unfortunately.
|
||||
// Thus we cannot always rely on InputMethodPrivilegedOperationsRegistry unfortunately.
|
||||
// TODO(Bug 114488811): Consider deprecating null token rule.
|
||||
try {
|
||||
return mService.switchToNextInputMethod(imeToken, onlyCurrentIme);
|
||||
@@ -2267,7 +2263,8 @@ public final class InputMethodManager {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
return mPrivOpsRegistry.get(imeToken).switchToNextInputMethod(onlyCurrentIme);
|
||||
return InputMethodPrivilegedOperationsRegistry.get(imeToken)
|
||||
.switchToNextInputMethod(onlyCurrentIme);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2286,7 +2283,8 @@ public final class InputMethodManager {
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean shouldOfferSwitchingToNextInputMethod(IBinder imeToken) {
|
||||
return mPrivOpsRegistry.get(imeToken).shouldOfferSwitchingToNextInputMethod();
|
||||
return InputMethodPrivilegedOperationsRegistry.get(imeToken)
|
||||
.shouldOfferSwitchingToNextInputMethod();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2422,34 +2420,4 @@ public final class InputMethodManager {
|
||||
sb.append(",temporaryDetach=" + view.isTemporarilyDetached());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by {@link InputMethodService} so that API calls to deprecated ones defined in this
|
||||
* class can be forwarded to {@link InputMethodPrivilegedOperations}.
|
||||
*
|
||||
* <p>Note: this method does not hold strong references to {@code token} and {@code ops}. The
|
||||
* registry entry will be automatically cleared after {@code token} is garbage collected.</p>
|
||||
*
|
||||
* @param token IME token that is associated with {@code ops}
|
||||
* @param ops {@link InputMethodPrivilegedOperations} that is associated with {@code token}
|
||||
* @hide
|
||||
*/
|
||||
public void registerInputMethodPrivOps(IBinder token, InputMethodPrivilegedOperations ops) {
|
||||
mPrivOpsRegistry.put(token, ops);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from {@link InputMethodService#onDestroy()} to make sure that deprecated IME APIs
|
||||
* defined in this class can no longer access to {@link InputMethodPrivilegedOperations}.
|
||||
*
|
||||
* <p>Note: Calling this method is optional, but at least gives more explict error message in
|
||||
* logcat when IME developers are doing something unsupported (e.g. trying to call IME APIs
|
||||
* after {@link InputMethodService#onDestroy()}).</p>
|
||||
*
|
||||
* @param token IME token to be removed.
|
||||
* @hide
|
||||
*/
|
||||
public void unregisterInputMethodPrivOps(IBinder token) {
|
||||
mPrivOpsRegistry.remove(token);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,12 +29,19 @@ import java.util.WeakHashMap;
|
||||
/**
|
||||
* A weak-reference-based mapper from IME token to {@link InputMethodPrivilegedOperations} that is
|
||||
* used only to support deprecated IME APIs in {@link android.view.inputmethod.InputMethodManager}.
|
||||
*
|
||||
* <p>This class is designed to be used as a per-process global registry.</p>
|
||||
*/
|
||||
public final class InputMethodPrivilegedOperationsRegistry {
|
||||
private final Object mLock = new Object();
|
||||
@GuardedBy("mLock")
|
||||
private final WeakHashMap<IBinder, WeakReference<InputMethodPrivilegedOperations>>
|
||||
mRegistry = new WeakHashMap<>();
|
||||
private InputMethodPrivilegedOperationsRegistry() {
|
||||
// Not intended to be instantiated.
|
||||
}
|
||||
|
||||
private static final Object sLock = new Object();
|
||||
|
||||
@Nullable
|
||||
@GuardedBy("sLock")
|
||||
private static WeakHashMap<IBinder, WeakReference<InputMethodPrivilegedOperations>> sRegistry;
|
||||
|
||||
@Nullable
|
||||
private static InputMethodPrivilegedOperations sNop;
|
||||
@@ -62,10 +69,13 @@ public final class InputMethodPrivilegedOperationsRegistry {
|
||||
* @param ops {@link InputMethodPrivilegedOperations} to be associated with the given IME token
|
||||
*/
|
||||
@AnyThread
|
||||
public void put(IBinder token, InputMethodPrivilegedOperations ops) {
|
||||
synchronized (mLock) {
|
||||
public static void put(IBinder token, InputMethodPrivilegedOperations ops) {
|
||||
synchronized (sLock) {
|
||||
if (sRegistry == null) {
|
||||
sRegistry = new WeakHashMap<>();
|
||||
}
|
||||
final WeakReference<InputMethodPrivilegedOperations> previousOps =
|
||||
mRegistry.put(token, new WeakReference<>(ops));
|
||||
sRegistry.put(token, new WeakReference<>(ops));
|
||||
if (previousOps != null) {
|
||||
throw new IllegalStateException(previousOps.get() + " is already registered for "
|
||||
+ " this token=" + token + " newOps=" + ops);
|
||||
@@ -84,9 +94,12 @@ public final class InputMethodPrivilegedOperationsRegistry {
|
||||
*/
|
||||
@NonNull
|
||||
@AnyThread
|
||||
public InputMethodPrivilegedOperations get(IBinder token) {
|
||||
synchronized (mLock) {
|
||||
final WeakReference<InputMethodPrivilegedOperations> wrapperRef = mRegistry.get(token);
|
||||
public static InputMethodPrivilegedOperations get(IBinder token) {
|
||||
synchronized (sLock) {
|
||||
if (sRegistry == null) {
|
||||
return getNopOps();
|
||||
}
|
||||
final WeakReference<InputMethodPrivilegedOperations> wrapperRef = sRegistry.get(token);
|
||||
if (wrapperRef == null) {
|
||||
return getNopOps();
|
||||
}
|
||||
@@ -108,9 +121,15 @@ public final class InputMethodPrivilegedOperationsRegistry {
|
||||
* @param token IME token to be removed.
|
||||
*/
|
||||
@AnyThread
|
||||
public void remove(IBinder token) {
|
||||
synchronized (mLock) {
|
||||
mRegistry.remove(token);
|
||||
public static void remove(IBinder token) {
|
||||
synchronized (sLock) {
|
||||
if (sRegistry == null) {
|
||||
return;
|
||||
}
|
||||
sRegistry.remove(token);
|
||||
if (sRegistry.isEmpty()) {
|
||||
sRegistry = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user