Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 42c5a166 authored by satok's avatar satok
Browse files

Fix internal variables and equals in SuggestionSpan

Bug: 4443922

- Instantiating other package's class for the name is complicated, so we changed the internal value for the notification target class from Class to String.
- Implement equals

Change-Id: Iaf7682be777f0027d33c9a3be4609ac01b6950ad
parent 2a3c67c0
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -19386,7 +19386,6 @@ package android.text.style {
    method public int describeContents();
    method public int getFlags();
    method public java.lang.String getLocale();
    method public java.lang.Class<?> getNotificationTargetClass();
    method public int getSpanTypeId();
    method public java.lang.String[] getSuggestions();
    method public void writeToParcel(android.os.Parcel, int);
+26 −28
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@ import android.os.Parcelable;
import android.os.SystemClock;
import android.text.ParcelableSpan;
import android.text.TextUtils;
import android.util.Log;

import java.util.Arrays;
import java.util.Locale;
@@ -31,8 +30,6 @@ import java.util.Locale;
 * Holds suggestion candidates of words under this span.
 */
public class SuggestionSpan implements ParcelableSpan {
    private static final String TAG = SuggestionSpan.class.getSimpleName();

    /**
     * Flag for indicating that the input is verbatim. TextView refers to this flag to determine
     * how it displays a word with SuggestionSpan.
@@ -56,7 +53,7 @@ public class SuggestionSpan implements ParcelableSpan {
    private final int mFlags;
    private final String[] mSuggestions;
    private final String mLocaleString;
    private final Class<?> mNotificationTargetClass;
    private final String mNotificationTargetClassName;
    private final int mHashCode;

    /*
@@ -100,25 +97,20 @@ public class SuggestionSpan implements ParcelableSpan {
        } else {
            mLocaleString = locale.toString();
        }
        mNotificationTargetClass = notificationTargetClass;
        if (notificationTargetClass != null) {
            mNotificationTargetClassName = notificationTargetClass.getCanonicalName();
        } else {
            mNotificationTargetClassName = "";
        }
        mHashCode = hashCodeInternal(
                mFlags, mSuggestions, mLocaleString, mNotificationTargetClass);
                mFlags, mSuggestions, mLocaleString, mNotificationTargetClassName);
    }

    public SuggestionSpan(Parcel src) {
        mSuggestions = src.readStringArray();
        mFlags = src.readInt();
        mLocaleString = src.readString();
        Class<?> tempClass = null;
        try {
            final String className = src.readString();
            if (!TextUtils.isEmpty(className)) {
                tempClass = Class.forName(className);
            }
        } catch (ClassNotFoundException e) {
            Log.i(TAG, "Invalid class name was created.");
        }
        mNotificationTargetClass = tempClass;
        mNotificationTargetClassName = src.readString();
        mHashCode = src.readInt();
    }

@@ -137,13 +129,16 @@ public class SuggestionSpan implements ParcelableSpan {
    }

    /**
     * @return The class to notify. The class of the original IME package will receive
     * @return The name of the class to notify. The class of the original IME package will receive
     * a notification when the user selects one of the suggestions. The notification will include
     * the original string, the suggested replacement string as well as the hashCode of this span.
     * The class will get notified by an intent that has those information.
     * This is an internal API because only the framework should know the class name.
     *
     * @hide
     */
    public Class<?> getNotificationTargetClass() {
        return mNotificationTargetClass;
    public String getNotificationTargetClassName() {
        return mNotificationTargetClassName;
    }

    public int getFlags() {
@@ -160,9 +155,7 @@ public class SuggestionSpan implements ParcelableSpan {
        dest.writeStringArray(mSuggestions);
        dest.writeInt(mFlags);
        dest.writeString(mLocaleString);
        dest.writeString(mNotificationTargetClass != null
                ? mNotificationTargetClass.getCanonicalName()
                : "");
        dest.writeString(mNotificationTargetClassName);
        dest.writeInt(mHashCode);
    }

@@ -171,18 +164,23 @@ public class SuggestionSpan implements ParcelableSpan {
        return TextUtils.SUGGESTION_SPAN;
    }

    @Override
    public boolean equals(Object o) {
        if (o instanceof SuggestionSpan) {
            return ((SuggestionSpan)o).hashCode() == mHashCode;
        }
        return false;
    }

    @Override
    public int hashCode() {
        return mHashCode;
    }

    private static int hashCodeInternal(int flags, String[] suggestions,String locale,
            Class<?> notificationTargetClass) {
        final String cls = notificationTargetClass != null
                ? notificationTargetClass.getCanonicalName()
                : "";
        return Arrays.hashCode(
                new Object[] {SystemClock.uptimeMillis(), flags, suggestions, locale, cls});
            String notificationTargetClassName) {
        return Arrays.hashCode(new Object[] {SystemClock.uptimeMillis(), flags, suggestions, locale,
                notificationTargetClassName});
    }

    public static final Parcelable.Creator<SuggestionSpan> CREATOR =
+21 −3
Original line number Diff line number Diff line
@@ -1021,8 +1021,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
            final InputMethodInfo currentImi = mMethodMap.get(mCurMethodId);
            for (int i = 0; i < spans.length; ++i) {
                SuggestionSpan ss = spans[i];
                if (ss.getNotificationTargetClass() != null) {
                if (!TextUtils.isEmpty(ss.getNotificationTargetClassName())) {
                    mSecureSuggestionSpans.put(ss, currentImi);
                    final InputMethodInfo targetImi = mSecureSuggestionSpans.get(ss);
                }
            }
        }
@@ -1035,11 +1036,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
            if (targetImi != null) {
                final String[] suggestions = span.getSuggestions();
                if (index < 0 || index >= suggestions.length) return false;
                final Class<?> c = span.getNotificationTargetClass();
                final String className = span.getNotificationTargetClassName();
                final Intent intent = new Intent();
                // Ensures that only a class in the original IME package will receive the
                // notification.
                intent.setClassName(targetImi.getPackageName(), c.getCanonicalName());
                intent.setClassName(targetImi.getPackageName(), className);
                intent.setAction(SuggestionSpan.ACTION_SUGGESTION_PICKED);
                intent.putExtra(SuggestionSpan.SUGGESTION_SPAN_PICKED_BEFORE, originalString);
                intent.putExtra(SuggestionSpan.SUGGESTION_SPAN_PICKED_AFTER, suggestions[index]);
@@ -1145,6 +1146,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
        }
    }

    @Override
    public boolean showSoftInput(IInputMethodClient client, int flags,
            ResultReceiver resultReceiver) {
        int uid = Binder.getCallingUid();
@@ -1210,6 +1212,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
        return res;
    }

    @Override
    public boolean hideSoftInput(IInputMethodClient client, int flags,
            ResultReceiver resultReceiver) {
        int uid = Binder.getCallingUid();
@@ -1272,6 +1275,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
        return res;
    }

    @Override
    public void windowGainedFocus(IInputMethodClient client, IBinder windowToken,
            boolean viewHasFocus, boolean isTextEditor, int softInputMode,
            boolean first, int windowFlags) {
@@ -1373,6 +1377,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
        }
    }

    @Override
    public void showInputMethodPickerFromClient(IInputMethodClient client) {
        synchronized (mMethodMap) {
            if (mCurClient == null || client == null
@@ -1387,10 +1392,12 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
        }
    }

    @Override
    public void setInputMethod(IBinder token, String id) {
        setInputMethodWithSubtypeId(token, id, NOT_A_SUBTYPE_ID);
    }

    @Override
    public void setInputMethodAndSubtype(IBinder token, String id, InputMethodSubtype subtype) {
        synchronized (mMethodMap) {
            if (subtype != null) {
@@ -1402,6 +1409,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
        }
    }

    @Override
    public void showInputMethodAndSubtypeEnablerFromClient(
            IInputMethodClient client, String inputMethodId) {
        synchronized (mMethodMap) {
@@ -1524,6 +1532,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
        }
    }

    @Override
    public void hideMySoftInput(IBinder token, int flags) {
        synchronized (mMethodMap) {
            if (token == null || mCurToken != token) {
@@ -1540,6 +1549,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
        }
    }

    @Override
    public void showMySoftInput(IBinder token, int flags) {
        synchronized (mMethodMap) {
            if (token == null || mCurToken != token) {
@@ -1576,6 +1586,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
        }
    }

    @Override
    public boolean handleMessage(Message msg) {
        HandlerCaller.SomeArgs args;
        switch (msg.what) {
@@ -1919,6 +1930,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
            }

            AlertDialog.OnClickListener adocl = new AlertDialog.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    hideInputMethodMenu();
                }
@@ -1930,6 +1942,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
            mDialogBuilder = new AlertDialog.Builder(context)
                    .setTitle(com.android.internal.R.string.select_input_method)
                    .setOnCancelListener(new OnCancelListener() {
                        @Override
                        public void onCancel(DialogInterface dialog) {
                            hideInputMethodMenu();
                        }
@@ -1940,6 +1953,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub

            mDialogBuilder.setSingleChoiceItems(mItems, checkedItem,
                    new AlertDialog.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            synchronized (mMethodMap) {
                                if (mIms == null || mIms.length <= which
@@ -1964,6 +1978,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
                mDialogBuilder.setPositiveButton(
                        com.android.internal.R.string.configure_input_methods,
                        new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int whichButton) {
                                showConfigureInputMethods();
                            }
@@ -1999,6 +2014,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub

    // ----------------------------------------------------------------------

    @Override
    public boolean setInputMethodEnabled(String id, boolean enabled) {
        synchronized (mMethodMap) {
            if (mContext.checkCallingOrSelfPermission(
@@ -2329,6 +2345,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
    /**
     * @return Return the current subtype of this input method.
     */
    @Override
    public InputMethodSubtype getCurrentInputMethodSubtype() {
        boolean subtypeIsSelected = false;
        try {
@@ -2411,6 +2428,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
        }
    }

    @Override
    public boolean setCurrentInputMethodSubtype(InputMethodSubtype subtype) {
        synchronized (mMethodMap) {
            if (subtype != null && mCurMethodId != null) {