Loading core/java/android/inputmethodservice/AbstractInputMethodService.java +8 −0 Original line number Diff line number Diff line Loading @@ -252,4 +252,12 @@ public abstract class AbstractInputMethodService extends Service return; } /** * Called when the user took some actions that should be taken into consideration to update the * MRU list for input method rotation. * * @hide */ public void notifyUserActionIfNecessary() { } } core/java/android/inputmethodservice/InputMethodService.java +30 −1 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACK import static java.lang.annotation.RetentionPolicy.SOURCE; import android.annotation.AnyThread; import android.annotation.CallSuper; import android.annotation.DrawableRes; import android.annotation.IntDef; Loading Loading @@ -79,6 +80,7 @@ import android.widget.ImageButton; import android.widget.LinearLayout; import android.widget.TextView; import com.android.internal.annotations.GuardedBy; import com.android.internal.inputmethod.IInputContentUriToken; import com.android.internal.inputmethod.IInputMethodPrivilegedOperations; import com.android.internal.inputmethod.InputMethodPrivilegedOperations; Loading Loading @@ -402,6 +404,10 @@ public class InputMethodService extends AbstractInputMethodService { @BackDispositionMode int mBackDisposition; private Object mLock = new Object(); @GuardedBy("mLock") private boolean mNotifyUserActionSent; /** * {@code true} when the previous IME had non-empty inset at the bottom of the screen and we * have not shown our own window yet. In this situation, the previous inset continues to be Loading Loading @@ -594,7 +600,7 @@ public class InputMethodService extends AbstractInputMethodService { @MainThread @Override public void changeInputMethodSubtype(InputMethodSubtype subtype) { onCurrentInputMethodSubtypeChanged(subtype); dispatchOnCurrentInputMethodSubtypeChanged(subtype); } } Loading Loading @@ -2792,6 +2798,13 @@ public class InputMethodService extends AbstractInputMethodService { } } private void dispatchOnCurrentInputMethodSubtypeChanged(InputMethodSubtype newSubtype) { synchronized (mLock) { mNotifyUserActionSent = false; } onCurrentInputMethodSubtypeChanged(newSubtype); } // TODO: Handle the subtype change event /** * Called when the subtype was changed. Loading Loading @@ -2847,6 +2860,22 @@ public class InputMethodService extends AbstractInputMethodService { exposeContentInternal(inputContentInfo, getCurrentInputEditorInfo()); } /** * {@inheritDoc} * @hide */ @AnyThread @Override public final void notifyUserActionIfNecessary() { synchronized (mLock) { if (mNotifyUserActionSent) { return; } mPrivOps.notifyUserActionAsync(); mNotifyUserActionSent = true; } } /** * Allow the receiver of {@link InputContentInfo} to obtain a temporary read-only access * permission to the content. Loading core/java/android/view/inputmethod/InputMethodManager.java +6 −73 Original line number Diff line number Diff line Loading @@ -353,28 +353,6 @@ public final class InputMethodManager { int mCursorCandStart; int mCursorCandEnd; /** * Represents an invalid action notification sequence number. * {@link com.android.server.InputMethodManagerService} always issues a positive integer for * action notification sequence numbers. Thus {@code -1} is guaranteed to be different from any * valid sequence number. */ private static final int NOT_AN_ACTION_NOTIFICATION_SEQUENCE_NUMBER = -1; /** * The next sequence number that is to be sent to * {@link com.android.server.InputMethodManagerService} via * {@link IInputMethodManager#notifyUserAction(int)} at once when a user action is observed. */ private int mNextUserActionNotificationSequenceNumber = NOT_AN_ACTION_NOTIFICATION_SEQUENCE_NUMBER; /** * The last sequence number that is already sent to * {@link com.android.server.InputMethodManagerService}. */ private int mLastSentUserActionNotificationSequenceNumber = NOT_AN_ACTION_NOTIFICATION_SEQUENCE_NUMBER; /** * The instance that has previously been sent to the input method. */ Loading Loading @@ -421,7 +399,6 @@ public final class InputMethodManager { static final int MSG_SEND_INPUT_EVENT = 5; static final int MSG_TIMEOUT_INPUT_EVENT = 6; static final int MSG_FLUSH_INPUT_EVENT = 7; static final int MSG_SET_USER_ACTION_NOTIFICATION_SEQUENCE_NUMBER = 9; static final int MSG_REPORT_FULLSCREEN_MODE = 10; private static boolean isAutofillUIShowing(View servedView) { Loading Loading @@ -558,12 +535,6 @@ public final class InputMethodManager { finishedInputEvent(msg.arg1, false, false); return; } case MSG_SET_USER_ACTION_NOTIFICATION_SEQUENCE_NUMBER: { synchronized (mH) { mNextUserActionNotificationSequenceNumber = msg.arg1; } return; } case MSG_REPORT_FULLSCREEN_MODE: { final boolean fullscreen = msg.arg1 != 0; InputConnection ic = null; Loading Loading @@ -605,11 +576,6 @@ public final class InputMethodManager { closeConnection(); } @Override protected void onUserAction() { mParentInputMethodManager.notifyUserAction(); } @Override public String toString() { return "ControlledInputConnectionWrapper{" Loading Loading @@ -656,12 +622,6 @@ public final class InputMethodManager { mH.obtainMessage(MSG_SET_ACTIVE, active ? 1 : 0, fullscreen ? 1 : 0).sendToTarget(); } @Override public void setUserActionNotificationSequenceNumber(int sequenceNumber) { mH.obtainMessage(MSG_SET_USER_ACTION_NOTIFICATION_SEQUENCE_NUMBER, sequenceNumber, 0) .sendToTarget(); } @Override public void reportFullscreenMode(boolean fullscreen) { mH.obtainMessage(MSG_REPORT_FULLSCREEN_MODE, fullscreen ? 1 : 0, 0) Loading Loading @@ -1355,8 +1315,6 @@ public final class InputMethodManager { mBindSequence = res.sequence; mCurMethod = res.method; mCurId = res.id; mNextUserActionNotificationSequenceNumber = res.userActionNotificationSequenceNumber; } else if (res.channel != null && res.channel != mCurChannel) { res.channel.dispose(); } Loading Loading @@ -2190,37 +2148,16 @@ public final class InputMethodManager { /** * Notify that a user took some action with this input method. * * @deprecated Just kept to avoid possible app compat issue. * @hide */ @Deprecated @UnsupportedAppUsage(trackingBug = 114740982, maxTargetSdk = Build.VERSION_CODES.P) public void notifyUserAction() { synchronized (mH) { if (mLastSentUserActionNotificationSequenceNumber == mNextUserActionNotificationSequenceNumber) { if (DEBUG) { Log.w(TAG, "Ignoring notifyUserAction as it has already been sent." + " mLastSentUserActionNotificationSequenceNumber: " + mLastSentUserActionNotificationSequenceNumber + " mNextUserActionNotificationSequenceNumber: " + mNextUserActionNotificationSequenceNumber); } return; } try { if (DEBUG) { Log.w(TAG, "notifyUserAction: " + " mLastSentUserActionNotificationSequenceNumber: " + mLastSentUserActionNotificationSequenceNumber + " mNextUserActionNotificationSequenceNumber: " + mNextUserActionNotificationSequenceNumber); } mService.notifyUserAction(mNextUserActionNotificationSequenceNumber); mLastSentUserActionNotificationSequenceNumber = mNextUserActionNotificationSequenceNumber; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } Log.w(TAG, "notifyUserAction() is a hidden method, which is now just a stub method" + " that does nothing. Leave comments in b.android.com/114740982 if your " + " application still depends on the previous behavior of this method."); } /** Loading Loading @@ -2421,10 +2358,6 @@ public final class InputMethodManager { + " mCursorSelEnd=" + mCursorSelEnd + " mCursorCandStart=" + mCursorCandStart + " mCursorCandEnd=" + mCursorCandEnd); p.println(" mNextUserActionNotificationSequenceNumber=" + mNextUserActionNotificationSequenceNumber + " mLastSentUserActionNotificationSequenceNumber=" + mLastSentUserActionNotificationSequenceNumber); } /** Loading core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -39,4 +39,6 @@ interface IInputMethodPrivilegedOperations { boolean switchToPreviousInputMethod(); boolean switchToNextInputMethod(boolean onlyCurrentIme); boolean shouldOfferSwitchingToNextInputMethod(); oneway void notifyUserActionAsync(); } core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java +16 −0 Original line number Diff line number Diff line Loading @@ -346,4 +346,20 @@ public final class InputMethodPrivilegedOperations { throw e.rethrowFromSystemServer(); } } /** * Calls {@link IInputMethodPrivilegedOperations#notifyUserActionAsync()} */ @AnyThread public void notifyUserActionAsync() { final IInputMethodPrivilegedOperations ops = mOps.getAndWarnIfNull(); if (ops == null) { return; } try { ops.notifyUserActionAsync(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } } Loading
core/java/android/inputmethodservice/AbstractInputMethodService.java +8 −0 Original line number Diff line number Diff line Loading @@ -252,4 +252,12 @@ public abstract class AbstractInputMethodService extends Service return; } /** * Called when the user took some actions that should be taken into consideration to update the * MRU list for input method rotation. * * @hide */ public void notifyUserActionIfNecessary() { } }
core/java/android/inputmethodservice/InputMethodService.java +30 −1 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACK import static java.lang.annotation.RetentionPolicy.SOURCE; import android.annotation.AnyThread; import android.annotation.CallSuper; import android.annotation.DrawableRes; import android.annotation.IntDef; Loading Loading @@ -79,6 +80,7 @@ import android.widget.ImageButton; import android.widget.LinearLayout; import android.widget.TextView; import com.android.internal.annotations.GuardedBy; import com.android.internal.inputmethod.IInputContentUriToken; import com.android.internal.inputmethod.IInputMethodPrivilegedOperations; import com.android.internal.inputmethod.InputMethodPrivilegedOperations; Loading Loading @@ -402,6 +404,10 @@ public class InputMethodService extends AbstractInputMethodService { @BackDispositionMode int mBackDisposition; private Object mLock = new Object(); @GuardedBy("mLock") private boolean mNotifyUserActionSent; /** * {@code true} when the previous IME had non-empty inset at the bottom of the screen and we * have not shown our own window yet. In this situation, the previous inset continues to be Loading Loading @@ -594,7 +600,7 @@ public class InputMethodService extends AbstractInputMethodService { @MainThread @Override public void changeInputMethodSubtype(InputMethodSubtype subtype) { onCurrentInputMethodSubtypeChanged(subtype); dispatchOnCurrentInputMethodSubtypeChanged(subtype); } } Loading Loading @@ -2792,6 +2798,13 @@ public class InputMethodService extends AbstractInputMethodService { } } private void dispatchOnCurrentInputMethodSubtypeChanged(InputMethodSubtype newSubtype) { synchronized (mLock) { mNotifyUserActionSent = false; } onCurrentInputMethodSubtypeChanged(newSubtype); } // TODO: Handle the subtype change event /** * Called when the subtype was changed. Loading Loading @@ -2847,6 +2860,22 @@ public class InputMethodService extends AbstractInputMethodService { exposeContentInternal(inputContentInfo, getCurrentInputEditorInfo()); } /** * {@inheritDoc} * @hide */ @AnyThread @Override public final void notifyUserActionIfNecessary() { synchronized (mLock) { if (mNotifyUserActionSent) { return; } mPrivOps.notifyUserActionAsync(); mNotifyUserActionSent = true; } } /** * Allow the receiver of {@link InputContentInfo} to obtain a temporary read-only access * permission to the content. Loading
core/java/android/view/inputmethod/InputMethodManager.java +6 −73 Original line number Diff line number Diff line Loading @@ -353,28 +353,6 @@ public final class InputMethodManager { int mCursorCandStart; int mCursorCandEnd; /** * Represents an invalid action notification sequence number. * {@link com.android.server.InputMethodManagerService} always issues a positive integer for * action notification sequence numbers. Thus {@code -1} is guaranteed to be different from any * valid sequence number. */ private static final int NOT_AN_ACTION_NOTIFICATION_SEQUENCE_NUMBER = -1; /** * The next sequence number that is to be sent to * {@link com.android.server.InputMethodManagerService} via * {@link IInputMethodManager#notifyUserAction(int)} at once when a user action is observed. */ private int mNextUserActionNotificationSequenceNumber = NOT_AN_ACTION_NOTIFICATION_SEQUENCE_NUMBER; /** * The last sequence number that is already sent to * {@link com.android.server.InputMethodManagerService}. */ private int mLastSentUserActionNotificationSequenceNumber = NOT_AN_ACTION_NOTIFICATION_SEQUENCE_NUMBER; /** * The instance that has previously been sent to the input method. */ Loading Loading @@ -421,7 +399,6 @@ public final class InputMethodManager { static final int MSG_SEND_INPUT_EVENT = 5; static final int MSG_TIMEOUT_INPUT_EVENT = 6; static final int MSG_FLUSH_INPUT_EVENT = 7; static final int MSG_SET_USER_ACTION_NOTIFICATION_SEQUENCE_NUMBER = 9; static final int MSG_REPORT_FULLSCREEN_MODE = 10; private static boolean isAutofillUIShowing(View servedView) { Loading Loading @@ -558,12 +535,6 @@ public final class InputMethodManager { finishedInputEvent(msg.arg1, false, false); return; } case MSG_SET_USER_ACTION_NOTIFICATION_SEQUENCE_NUMBER: { synchronized (mH) { mNextUserActionNotificationSequenceNumber = msg.arg1; } return; } case MSG_REPORT_FULLSCREEN_MODE: { final boolean fullscreen = msg.arg1 != 0; InputConnection ic = null; Loading Loading @@ -605,11 +576,6 @@ public final class InputMethodManager { closeConnection(); } @Override protected void onUserAction() { mParentInputMethodManager.notifyUserAction(); } @Override public String toString() { return "ControlledInputConnectionWrapper{" Loading Loading @@ -656,12 +622,6 @@ public final class InputMethodManager { mH.obtainMessage(MSG_SET_ACTIVE, active ? 1 : 0, fullscreen ? 1 : 0).sendToTarget(); } @Override public void setUserActionNotificationSequenceNumber(int sequenceNumber) { mH.obtainMessage(MSG_SET_USER_ACTION_NOTIFICATION_SEQUENCE_NUMBER, sequenceNumber, 0) .sendToTarget(); } @Override public void reportFullscreenMode(boolean fullscreen) { mH.obtainMessage(MSG_REPORT_FULLSCREEN_MODE, fullscreen ? 1 : 0, 0) Loading Loading @@ -1355,8 +1315,6 @@ public final class InputMethodManager { mBindSequence = res.sequence; mCurMethod = res.method; mCurId = res.id; mNextUserActionNotificationSequenceNumber = res.userActionNotificationSequenceNumber; } else if (res.channel != null && res.channel != mCurChannel) { res.channel.dispose(); } Loading Loading @@ -2190,37 +2148,16 @@ public final class InputMethodManager { /** * Notify that a user took some action with this input method. * * @deprecated Just kept to avoid possible app compat issue. * @hide */ @Deprecated @UnsupportedAppUsage(trackingBug = 114740982, maxTargetSdk = Build.VERSION_CODES.P) public void notifyUserAction() { synchronized (mH) { if (mLastSentUserActionNotificationSequenceNumber == mNextUserActionNotificationSequenceNumber) { if (DEBUG) { Log.w(TAG, "Ignoring notifyUserAction as it has already been sent." + " mLastSentUserActionNotificationSequenceNumber: " + mLastSentUserActionNotificationSequenceNumber + " mNextUserActionNotificationSequenceNumber: " + mNextUserActionNotificationSequenceNumber); } return; } try { if (DEBUG) { Log.w(TAG, "notifyUserAction: " + " mLastSentUserActionNotificationSequenceNumber: " + mLastSentUserActionNotificationSequenceNumber + " mNextUserActionNotificationSequenceNumber: " + mNextUserActionNotificationSequenceNumber); } mService.notifyUserAction(mNextUserActionNotificationSequenceNumber); mLastSentUserActionNotificationSequenceNumber = mNextUserActionNotificationSequenceNumber; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } Log.w(TAG, "notifyUserAction() is a hidden method, which is now just a stub method" + " that does nothing. Leave comments in b.android.com/114740982 if your " + " application still depends on the previous behavior of this method."); } /** Loading Loading @@ -2421,10 +2358,6 @@ public final class InputMethodManager { + " mCursorSelEnd=" + mCursorSelEnd + " mCursorCandStart=" + mCursorCandStart + " mCursorCandEnd=" + mCursorCandEnd); p.println(" mNextUserActionNotificationSequenceNumber=" + mNextUserActionNotificationSequenceNumber + " mLastSentUserActionNotificationSequenceNumber=" + mLastSentUserActionNotificationSequenceNumber); } /** Loading
core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -39,4 +39,6 @@ interface IInputMethodPrivilegedOperations { boolean switchToPreviousInputMethod(); boolean switchToNextInputMethod(boolean onlyCurrentIme); boolean shouldOfferSwitchingToNextInputMethod(); oneway void notifyUserActionAsync(); }
core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java +16 −0 Original line number Diff line number Diff line Loading @@ -346,4 +346,20 @@ public final class InputMethodPrivilegedOperations { throw e.rethrowFromSystemServer(); } } /** * Calls {@link IInputMethodPrivilegedOperations#notifyUserActionAsync()} */ @AnyThread public void notifyUserActionAsync() { final IInputMethodPrivilegedOperations ops = mOps.getAndWarnIfNull(); if (ops == null) { return; } try { ops.notifyUserActionAsync(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } }