Merge "Let InputMethodPrivilegedOperationsRegistry deal with its singleton-ness"

This commit is contained in:
TreeHugger Robot
2018-09-19 16:48:54 +00:00
committed by Android (Google) Code Review
3 changed files with 50 additions and 62 deletions

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}
}
}