1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.autofill.ui; 18 19 import static com.android.server.autofill.Helper.sDebug; 20 21 import android.annotation.NonNull; 22 import android.annotation.Nullable; 23 import android.content.IntentSender; 24 import android.os.IBinder; 25 import android.service.autofill.IInlineSuggestionUiCallback; 26 import android.service.autofill.InlinePresentation; 27 import android.util.Slog; 28 29 import com.android.server.LocalServices; 30 import com.android.server.autofill.Helper; 31 import com.android.server.autofill.RemoteInlineSuggestionRenderService; 32 import com.android.server.inputmethod.InputMethodManagerInternal; 33 34 import java.util.function.Consumer; 35 36 /** 37 * Wraps the parameters needed to create a new inline suggestion view in the remote renderer 38 * service, and handles the callback from the events on the created remote view. 39 */ 40 final class RemoteInlineSuggestionViewConnector { 41 private static final String TAG = RemoteInlineSuggestionViewConnector.class.getSimpleName(); 42 43 @Nullable private final RemoteInlineSuggestionRenderService mRemoteRenderService; 44 @NonNull private final InlinePresentation mInlinePresentation; 45 @Nullable private final IBinder mHostInputToken; 46 private final int mDisplayId; 47 private final int mUserId; 48 private final int mSessionId; 49 50 @NonNull private final Runnable mOnAutofillCallback; 51 @NonNull private final Runnable mOnErrorCallback; 52 @NonNull private final Runnable mOnInflateCallback; 53 @NonNull private final Consumer<IntentSender> mStartIntentSenderFromClientApp; 54 RemoteInlineSuggestionViewConnector( @onNull InlineFillUi.InlineFillUiInfo inlineFillUiInfo, @NonNull InlinePresentation inlinePresentation, @NonNull Runnable onAutofillCallback, @NonNull InlineFillUi.InlineSuggestionUiCallback uiCallback)55 RemoteInlineSuggestionViewConnector( 56 @NonNull InlineFillUi.InlineFillUiInfo inlineFillUiInfo, 57 @NonNull InlinePresentation inlinePresentation, 58 @NonNull Runnable onAutofillCallback, 59 @NonNull InlineFillUi.InlineSuggestionUiCallback uiCallback) { 60 mRemoteRenderService = inlineFillUiInfo.mRemoteRenderService; 61 mInlinePresentation = inlinePresentation; 62 mHostInputToken = inlineFillUiInfo.mInlineRequest.getHostInputToken(); 63 mDisplayId = inlineFillUiInfo.mInlineRequest.getHostDisplayId(); 64 mUserId = inlineFillUiInfo.mUserId; 65 mSessionId = inlineFillUiInfo.mSessionId; 66 67 mOnAutofillCallback = onAutofillCallback; 68 mOnErrorCallback = uiCallback::onError; 69 mOnInflateCallback = uiCallback::onInflate; 70 mStartIntentSenderFromClientApp = uiCallback::startIntentSender; 71 } 72 73 /** 74 * Calls the remote renderer service to create a new inline suggestion view. 75 * 76 * @return true if the call is made to the remote renderer service, false otherwise. 77 */ renderSuggestion( int width, int height, @NonNull IInlineSuggestionUiCallback callback)78 public boolean renderSuggestion( 79 int width, int height, @NonNull IInlineSuggestionUiCallback callback) { 80 if (Helper.sanitizeSlice(mInlinePresentation.getSlice()) == null) { 81 if (sDebug) Slog.d(TAG, "Skipped rendering inline suggestion."); 82 return false; 83 } 84 if (mRemoteRenderService != null) { 85 if (sDebug) Slog.d(TAG, "Request to recreate the UI"); 86 mRemoteRenderService.renderSuggestion(callback, mInlinePresentation, width, height, 87 mHostInputToken, mDisplayId, mUserId, mSessionId); 88 return true; 89 } 90 return false; 91 } 92 93 /** 94 * Handles the callback for the event of remote view being clicked. 95 */ onClick()96 public void onClick() { 97 mOnAutofillCallback.run(); 98 } 99 100 /** 101 * Handles the callback for the remote error when creating or interacting with the view. 102 */ onError()103 public void onError() { 104 mOnErrorCallback.run(); 105 } 106 onRender()107 public void onRender() { 108 mOnInflateCallback.run(); 109 } 110 111 /** 112 * Handles the callback for transferring the touch event on the remote view to the IME 113 * process. 114 */ onTransferTouchFocusToImeWindow(IBinder sourceInputToken, int displayId)115 public void onTransferTouchFocusToImeWindow(IBinder sourceInputToken, int displayId) { 116 final InputMethodManagerInternal inputMethodManagerInternal = 117 LocalServices.getService(InputMethodManagerInternal.class); 118 if (!inputMethodManagerInternal.transferTouchFocusToImeWindow(sourceInputToken, 119 displayId)) { 120 Slog.e(TAG, "Cannot transfer touch focus from suggestion to IME"); 121 mOnErrorCallback.run(); 122 } 123 } 124 125 /** 126 * Handles starting an intent sender from the client app's process. 127 */ onStartIntentSender(IntentSender intentSender)128 public void onStartIntentSender(IntentSender intentSender) { 129 mStartIntentSenderFromClientApp.accept(intentSender); 130 } 131 } 132