Merge "Notify the registered AutofillCallback for inline." into rvc-dev am: f755f9c1a5

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/11818505

Change-Id: Iecf0eaccc63c3c187c161957301d1d24f97c16c6
This commit is contained in:
Joanne Chung
2020-06-18 14:57:33 +00:00
committed by Automerger Merge Worker
4 changed files with 96 additions and 29 deletions

View File

@@ -45,6 +45,8 @@ final class AutofillInlineSessionController {
private final Object mLock; private final Object mLock;
@NonNull @NonNull
private final Handler mHandler; private final Handler mHandler;
@NonNull
private final InlineFillUi.InlineUiEventCallback mUiCallback;
@Nullable @Nullable
@GuardedBy("mLock") @GuardedBy("mLock")
@@ -54,12 +56,14 @@ final class AutofillInlineSessionController {
private InlineFillUi mInlineFillUi; private InlineFillUi mInlineFillUi;
AutofillInlineSessionController(InputMethodManagerInternal inputMethodManagerInternal, AutofillInlineSessionController(InputMethodManagerInternal inputMethodManagerInternal,
int userId, ComponentName componentName, Handler handler, Object lock) { int userId, ComponentName componentName, Handler handler, Object lock,
InlineFillUi.InlineUiEventCallback callback) {
mInputMethodManagerInternal = inputMethodManagerInternal; mInputMethodManagerInternal = inputMethodManagerInternal;
mUserId = userId; mUserId = userId;
mComponentName = componentName; mComponentName = componentName;
mHandler = handler; mHandler = handler;
mLock = lock; mLock = lock;
mUiCallback = callback;
} }
@@ -82,7 +86,8 @@ final class AutofillInlineSessionController {
// TODO(b/151123764): consider reusing the same AutofillInlineSession object for the // TODO(b/151123764): consider reusing the same AutofillInlineSession object for the
// same field. // same field.
mSession = new AutofillInlineSuggestionsRequestSession(mInputMethodManagerInternal, mUserId, mSession = new AutofillInlineSuggestionsRequestSession(mInputMethodManagerInternal, mUserId,
mComponentName, mHandler, mLock, autofillId, requestConsumer, uiExtras); mComponentName, mHandler, mLock, autofillId, requestConsumer, uiExtras,
mUiCallback);
mSession.onCreateInlineSuggestionsRequestLocked(); mSession.onCreateInlineSuggestionsRequestLocked();
} }

View File

@@ -29,6 +29,7 @@ import android.os.Handler;
import android.os.RemoteException; import android.os.RemoteException;
import android.util.Slog; import android.util.Slog;
import android.view.autofill.AutofillId; import android.view.autofill.AutofillId;
import android.view.inputmethod.InlineSuggestion;
import android.view.inputmethod.InlineSuggestionsRequest; import android.view.inputmethod.InlineSuggestionsRequest;
import android.view.inputmethod.InlineSuggestionsResponse; import android.view.inputmethod.InlineSuggestionsResponse;
@@ -40,6 +41,7 @@ import com.android.server.autofill.ui.InlineFillUi;
import com.android.server.inputmethod.InputMethodManagerInternal; import com.android.server.inputmethod.InputMethodManagerInternal;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.function.Consumer; import java.util.function.Consumer;
@@ -65,6 +67,8 @@ final class AutofillInlineSuggestionsRequestSession {
private final Handler mHandler; private final Handler mHandler;
@NonNull @NonNull
private final Bundle mUiExtras; private final Bundle mUiExtras;
@NonNull
private final InlineFillUi.InlineUiEventCallback mUiCallback;
@GuardedBy("mLock") @GuardedBy("mLock")
@NonNull @NonNull
@@ -97,18 +101,22 @@ final class AutofillInlineSuggestionsRequestSession {
@GuardedBy("mLock") @GuardedBy("mLock")
private boolean mDestroyed = false; private boolean mDestroyed = false;
@GuardedBy("mLock")
private boolean mPreviousHasNonPinSuggestionShow;
AutofillInlineSuggestionsRequestSession( AutofillInlineSuggestionsRequestSession(
@NonNull InputMethodManagerInternal inputMethodManagerInternal, int userId, @NonNull InputMethodManagerInternal inputMethodManagerInternal, int userId,
@NonNull ComponentName componentName, @NonNull Handler handler, @NonNull Object lock, @NonNull ComponentName componentName, @NonNull Handler handler, @NonNull Object lock,
@NonNull AutofillId autofillId, @NonNull AutofillId autofillId,
@NonNull Consumer<InlineSuggestionsRequest> requestConsumer, @NonNull Bundle uiExtras) { @NonNull Consumer<InlineSuggestionsRequest> requestConsumer, @NonNull Bundle uiExtras,
@NonNull InlineFillUi.InlineUiEventCallback callback) {
mInputMethodManagerInternal = inputMethodManagerInternal; mInputMethodManagerInternal = inputMethodManagerInternal;
mUserId = userId; mUserId = userId;
mComponentName = componentName; mComponentName = componentName;
mHandler = handler; mHandler = handler;
mLock = lock; mLock = lock;
mUiExtras = uiExtras; mUiExtras = uiExtras;
mUiCallback = callback;
mAutofillId = autofillId; mAutofillId = autofillId;
mImeRequestConsumer = requestConsumer; mImeRequestConsumer = requestConsumer;
@@ -217,6 +225,7 @@ final class AutofillInlineSuggestionsRequestSession {
// No-op if both the previous response and current response are empty. // No-op if both the previous response and current response are empty.
return; return;
} }
maybeNotifyFillUiEventLocked(response.getInlineSuggestions());
updateResponseToImeUncheckLocked(response); updateResponseToImeUncheckLocked(response);
mPreviousResponseIsNotEmpty = !isEmptyResponse; mPreviousResponseIsNotEmpty = !isEmptyResponse;
} }
@@ -238,6 +247,38 @@ final class AutofillInlineSuggestionsRequestSession {
} }
} }
@GuardedBy("mLock")
private void maybeNotifyFillUiEventLocked(@NonNull List<InlineSuggestion> suggestions) {
if (mDestroyed) {
return;
}
boolean hasSuggestionToShow = false;
for (int i = 0; i < suggestions.size(); i++) {
InlineSuggestion suggestion = suggestions.get(i);
// It is possible we don't have any match result but we still have pinned
// suggestions. Only notify we have non-pinned suggestions to show
if (!suggestion.getInfo().isPinned()) {
hasSuggestionToShow = true;
break;
}
}
if (sDebug) {
Slog.d(TAG, "maybeNotifyFillUiEventLoked(): hasSuggestionToShow=" + hasSuggestionToShow
+ ", mPreviousHasNonPinSuggestionShow=" + mPreviousHasNonPinSuggestionShow);
}
// Use mPreviousHasNonPinSuggestionShow to save previous status, if the display status
// change, we can notify the event.
if (hasSuggestionToShow && !mPreviousHasNonPinSuggestionShow) {
// From no suggestion to has suggestions to show
mUiCallback.notifyInlineUiShown(mAutofillId);
} else if (!hasSuggestionToShow && mPreviousHasNonPinSuggestionShow) {
// From has suggestions to no suggestions to show
mUiCallback.notifyInlineUiHidden(mAutofillId);
}
// Update the latest status
mPreviousHasNonPinSuggestionShow = hasSuggestionToShow;
}
/** /**
* Handles the {@code request} and {@code callback} received from the IME. * Handles the {@code request} and {@code callback} received from the IME.
* *

View File

@@ -843,7 +843,18 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
setClientLocked(client); setClientLocked(client);
mInlineSessionController = new AutofillInlineSessionController(inputMethodManagerInternal, mInlineSessionController = new AutofillInlineSessionController(inputMethodManagerInternal,
userId, componentName, handler, mLock); userId, componentName, handler, mLock,
new InlineFillUi.InlineUiEventCallback() {
@Override
public void notifyInlineUiShown(AutofillId autofillId) {
notifyFillUiShown(autofillId);
}
@Override
public void notifyInlineUiHidden(AutofillId autofillId) {
notifyFillUiHidden(autofillId);
}
});
mMetricsLogger.write(newLogMaker(MetricsEvent.AUTOFILL_SESSION_STARTED) mMetricsLogger.write(newLogMaker(MetricsEvent.AUTOFILL_SESSION_STARTED)
.addTaggedData(MetricsEvent.FIELD_AUTOFILL_FLAGS, flags)); .addTaggedData(MetricsEvent.FIELD_AUTOFILL_FLAGS, flags));
@@ -1329,6 +1340,26 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
this, intentSender, intent)); this, intentSender, intent));
} }
private void notifyFillUiHidden(@NonNull AutofillId autofillId) {
synchronized (mLock) {
try {
mClient.notifyFillUiHidden(this.id, autofillId);
} catch (RemoteException e) {
Slog.e(TAG, "Error sending fill UI hidden notification", e);
}
}
}
private void notifyFillUiShown(@NonNull AutofillId autofillId) {
synchronized (mLock) {
try {
mClient.notifyFillUiShown(this.id, autofillId);
} catch (RemoteException e) {
Slog.e(TAG, "Error sending fill UI shown notification", e);
}
}
}
private void doStartIntentSender(IntentSender intentSender, Intent intent) { private void doStartIntentSender(IntentSender intentSender, Intent intent) {
try { try {
synchronized (mLock) { synchronized (mLock) {
@@ -2769,11 +2800,6 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
// TODO(b/156099633): remove this once framework gets out of business of resending // TODO(b/156099633): remove this once framework gets out of business of resending
// inline suggestions when IME visibility changes. // inline suggestions when IME visibility changes.
mInlineSessionController.hideInlineSuggestionsUiLocked(viewState.id); mInlineSessionController.hideInlineSuggestionsUiLocked(viewState.id);
try {
mClient.notifyFillUiHidden(this.id, viewState.id);
} catch (RemoteException e) {
Slog.e(TAG, "Error requesting to hide fill UI", e);
}
viewState.resetState(ViewState.STATE_CHANGED); viewState.resetState(ViewState.STATE_CHANGED);
return; return;
} else if ((viewState.id.equals(this.mCurrentViewId)) } else if ((viewState.id.equals(this.mCurrentViewId))
@@ -2800,11 +2826,6 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
// TODO: we should be able to replace this with controller#filterInlineFillUiLocked // TODO: we should be able to replace this with controller#filterInlineFillUiLocked
// to accomplish filtering for augmented autofill. // to accomplish filtering for augmented autofill.
mInlineSessionController.hideInlineSuggestionsUiLocked(mCurrentViewId); mInlineSessionController.hideInlineSuggestionsUiLocked(mCurrentViewId);
try {
mClient.notifyFillUiHidden(this.id, mCurrentViewId);
} catch (RemoteException e) {
Slog.e(TAG, "Error sending fill UI hidden notification", e);
}
} }
} }
@@ -2890,11 +2911,6 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
if (requestShowInlineSuggestionsLocked(response, filterText)) { if (requestShowInlineSuggestionsLocked(response, filterText)) {
final ViewState currentView = mViewStates.get(mCurrentViewId); final ViewState currentView = mViewStates.get(mCurrentViewId);
currentView.setState(ViewState.STATE_INLINE_SHOWN); currentView.setState(ViewState.STATE_INLINE_SHOWN);
try {
mClient.notifyFillUiShown(this.id, mCurrentViewId);
} catch (RemoteException e) {
Slog.e(TAG, "Error sending fill UI shown notification", e);
}
//TODO(b/137800469): Fix it to log showed only when IME asks for inflation, //TODO(b/137800469): Fix it to log showed only when IME asks for inflation,
// rather than here where framework sends back the response. // rather than here where framework sends back the response.
mService.logDatasetShown(id, mClientState); mService.logDatasetShown(id, mClientState);
@@ -2965,11 +2981,6 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
synchronized (mLock) { synchronized (mLock) {
mInlineSessionController.hideInlineSuggestionsUiLocked( mInlineSessionController.hideInlineSuggestionsUiLocked(
focusedId); focusedId);
try {
mClient.notifyFillUiHidden(this.id, focusedId);
} catch (RemoteException e) {
Slog.e(TAG, "Error sending fill UI hidden notification", e);
}
} }
}, remoteRenderService); }, remoteRenderService);
return mInlineSessionController.setInlineFillUiLocked(inlineFillUi); return mInlineSessionController.setInlineFillUiLocked(inlineFillUi);
@@ -3484,11 +3495,6 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
} }
if (mCurrentViewId != null) { if (mCurrentViewId != null) {
mInlineSessionController.hideInlineSuggestionsUiLocked(mCurrentViewId); mInlineSessionController.hideInlineSuggestionsUiLocked(mCurrentViewId);
try {
mClient.notifyFillUiHidden(this.id, mCurrentViewId);
} catch (RemoteException e) {
Slog.e(TAG, "Error sending fill UI hidden notification", e);
}
} }
autoFillApp(dataset); autoFillApp(dataset);
return; return;

View File

@@ -297,4 +297,19 @@ public final class InlineFillUi {
*/ */
void startIntentSender(@NonNull IntentSender intentSender, @NonNull Intent intent); void startIntentSender(@NonNull IntentSender intentSender, @NonNull Intent intent);
} }
/**
* Callback for inline suggestion Ui related events.
*/
public interface InlineUiEventCallback {
/**
* Callback to notify inline ui is shown.
*/
void notifyInlineUiShown(@NonNull AutofillId autofillId);
/**
* Callback to notify inline ui is hidden.
*/
void notifyInlineUiHidden(@NonNull AutofillId autofillId);
}
} }