Optionally schedule a delayed deletion of suggestions in sample keyboard
Test: manual Bug: 157515522 Change-Id: Ia5517e8caff538fcc21bf69f15370a3bb2aea5de
This commit is contained in:
@@ -102,6 +102,9 @@ public class AutofillImeService extends InputMethodService {
|
|||||||
Toast.LENGTH_SHORT).show();
|
Toast.LENGTH_SHORT).show();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private ResponseState mResponseState = ResponseState.RESET;
|
||||||
|
private Runnable mDelayedDeletion;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateInputView() {
|
public View onCreateInputView() {
|
||||||
mInputView = (InputView) LayoutInflater.from(this).inflate(R.layout.input_view, null);
|
mInputView = (InputView) LayoutInflater.from(this).inflate(R.layout.input_view, null);
|
||||||
@@ -122,21 +125,51 @@ public class AutofillImeService extends InputMethodService {
|
|||||||
if(mKeyboard != null) {
|
if(mKeyboard != null) {
|
||||||
mKeyboard.reset();
|
mKeyboard.reset();
|
||||||
}
|
}
|
||||||
if (mInputView != null) {
|
if (mResponseState == ResponseState.FINISH_INPUT) {
|
||||||
|
mResponseState = ResponseState.START_INPUT;
|
||||||
|
} else {
|
||||||
|
mResponseState = ResponseState.RESET;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFinishInput() {
|
||||||
|
super.onFinishInput();
|
||||||
|
if (mResponseState == ResponseState.RECEIVE_RESPONSE) {
|
||||||
|
mResponseState = ResponseState.FINISH_INPUT;
|
||||||
|
} else {
|
||||||
|
mResponseState = ResponseState.RESET;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cancelDelayedDeletion(String msg) {
|
||||||
|
if(mDelayedDeletion != null) {
|
||||||
|
Log.d(TAG, msg + " canceling delayed deletion");
|
||||||
|
mHandler.removeCallbacks(mDelayedDeletion);
|
||||||
|
mDelayedDeletion = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void scheduleDelayedDeletion() {
|
||||||
|
if (mInputView != null && mDelayedDeletion == null) {
|
||||||
// We delay the deletion of the suggestions from previous input connection, to avoid
|
// We delay the deletion of the suggestions from previous input connection, to avoid
|
||||||
// the flicker caused by deleting them and immediately showing new suggestions for
|
// the flicker caused by deleting them and immediately showing new suggestions for
|
||||||
// the current input connection.
|
// the current input connection.
|
||||||
Log.d(TAG, "onStartInput scheduling a delayed deletion of inline suggestions");
|
Log.d(TAG, "Scheduling a delayed deletion of inline suggestions");
|
||||||
mDelayedDeletion = () -> {
|
mDelayedDeletion = () -> {
|
||||||
Log.d(TAG, "onStartInput deleting inline suggestions");
|
Log.d(TAG, "Executing scheduled deleting inline suggestions");
|
||||||
mDelayedDeletion = null;
|
mDelayedDeletion = null;
|
||||||
updateInlineSuggestionStrip(Collections.emptyList());
|
clearInlineSuggestionStrip();
|
||||||
};
|
};
|
||||||
mHandler.postDelayed(mDelayedDeletion, 200);
|
mHandler.postDelayed(mDelayedDeletion, 200);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Runnable mDelayedDeletion;
|
private void clearInlineSuggestionStrip() {
|
||||||
|
if (mInputView != null) {
|
||||||
|
updateInlineSuggestionStrip(Collections.emptyList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStartInputView(EditorInfo info, boolean restarting) {
|
public void onStartInputView(EditorInfo info, boolean restarting) {
|
||||||
@@ -153,7 +186,7 @@ public class AutofillImeService extends InputMethodService {
|
|||||||
// called. If the framework is changed to not resend, then we need to cache the
|
// called. If the framework is changed to not resend, then we need to cache the
|
||||||
// inline suggestion views locally and re-attach them when the IME is shown again by
|
// inline suggestion views locally and re-attach them when the IME is shown again by
|
||||||
// onStartInputView.
|
// onStartInputView.
|
||||||
updateInlineSuggestionStrip(Collections.emptyList());
|
clearInlineSuggestionStrip();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,22 +260,29 @@ public class AutofillImeService extends InputMethodService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onInlineSuggestionsResponse(InlineSuggestionsResponse response) {
|
public boolean onInlineSuggestionsResponse(InlineSuggestionsResponse response) {
|
||||||
Log.d(TAG, "onInlineSuggestionsResponse() called");
|
Log.d(TAG,
|
||||||
if(mDelayedDeletion != null) {
|
"onInlineSuggestionsResponse() called: " + response.getInlineSuggestions().size());
|
||||||
Log.d(TAG, "onInlineSuggestionsResponse unscheduling delayed deletion");
|
cancelDelayedDeletion("onInlineSuggestionsResponse");
|
||||||
mHandler.removeCallbacks(mDelayedDeletion);
|
final List<InlineSuggestion> inlineSuggestions = response.getInlineSuggestions();
|
||||||
}
|
mResponseState = ResponseState.RECEIVE_RESPONSE;
|
||||||
onInlineSuggestionsResponseInternal(response);
|
mHandler.post(() -> {
|
||||||
|
if (mResponseState == ResponseState.START_INPUT && inlineSuggestions.isEmpty()) {
|
||||||
|
scheduleDelayedDeletion();
|
||||||
|
} else {
|
||||||
|
inflateThenShowSuggestions(inlineSuggestions);
|
||||||
|
}
|
||||||
|
mResponseState = ResponseState.RESET;
|
||||||
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateInlineSuggestionStrip(List<SuggestionItem> suggestionItems) {
|
private void updateInlineSuggestionStrip(List<SuggestionItem> suggestionItems) {
|
||||||
|
Log.d(TAG, "Actually updating the suggestion strip: " + suggestionItems.size());
|
||||||
mPinnedSuggestionsStart.removeAllViews();
|
mPinnedSuggestionsStart.removeAllViews();
|
||||||
mScrollableSuggestions.removeAllViews();
|
mScrollableSuggestions.removeAllViews();
|
||||||
mPinnedSuggestionsEnd.removeAllViews();
|
mPinnedSuggestionsEnd.removeAllViews();
|
||||||
|
|
||||||
final int size = suggestionItems.size();
|
if (suggestionItems.isEmpty()) {
|
||||||
if (size <= 0) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,8 +291,7 @@ public class AutofillImeService extends InputMethodService {
|
|||||||
getColor(R.color.suggestion_strip_background));
|
getColor(R.color.suggestion_strip_background));
|
||||||
mSuggestionStrip.setVisibility(View.VISIBLE);
|
mSuggestionStrip.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
for (int i = 0; i < size; i++) {
|
for (SuggestionItem suggestionItem : suggestionItems) {
|
||||||
final SuggestionItem suggestionItem = suggestionItems.get(i);
|
|
||||||
if (suggestionItem == null) {
|
if (suggestionItem == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -292,18 +331,8 @@ public class AutofillImeService extends InputMethodService {
|
|||||||
handler.postDelayed(mMoveScrollableSuggestionsDown, MOVE_SUGGESTIONS_DOWN_TIMEOUT);
|
handler.postDelayed(mMoveScrollableSuggestionsDown, MOVE_SUGGESTIONS_DOWN_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onInlineSuggestionsResponseInternal(InlineSuggestionsResponse response) {
|
private void inflateThenShowSuggestions( List<InlineSuggestion> inlineSuggestions) {
|
||||||
Log.d(TAG, "onInlineSuggestionsResponseInternal() called. Suggestion="
|
|
||||||
+ response.getInlineSuggestions().size());
|
|
||||||
|
|
||||||
final List<InlineSuggestion> inlineSuggestions = response.getInlineSuggestions();
|
|
||||||
|
|
||||||
final int totalSuggestionsCount = inlineSuggestions.size();
|
final int totalSuggestionsCount = inlineSuggestions.size();
|
||||||
if (totalSuggestionsCount <= 0) {
|
|
||||||
updateInlineSuggestionStrip(Collections.emptyList());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Map<Integer, SuggestionItem> suggestionMap = Collections.synchronizedMap((
|
final Map<Integer, SuggestionItem> suggestionMap = Collections.synchronizedMap((
|
||||||
new TreeMap<>()));
|
new TreeMap<>()));
|
||||||
final ExecutorService executor = Executors.newSingleThreadExecutor();
|
final ExecutorService executor = Executors.newSingleThreadExecutor();
|
||||||
@@ -355,4 +384,11 @@ public class AutofillImeService extends InputMethodService {
|
|||||||
mIsPinned = isPinned;
|
mIsPinned = isPinned;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum ResponseState {
|
||||||
|
RESET,
|
||||||
|
RECEIVE_RESPONSE,
|
||||||
|
FINISH_INPUT,
|
||||||
|
START_INPUT,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user