From 29f6c4bfa8e4a9463d696578a1196b6d3ca88075 Mon Sep 17 00:00:00 2001 From: Steve Elliott Date: Mon, 19 Oct 2020 13:21:35 -0400 Subject: [PATCH] Re-enable IME image inserting for RemoteInputView The prior implementation was not calling InputContentInfo#requestPermission, resulting in the Uri for the image from the IME not being accessible by SysUI. This is because when using the InputConnectionCompat utils from AndroidX, the caller needs to explicitly invoke that method, which we were not doing. In general, it is preferred that SystemUI does not depend on the support lib when possible, so this change re-implements the IME image insertion handing using the built-in mechanism, which also automatically handles granting the appropriate URI permissions for SystemUI. Bug: 163595585 Test: manual, atest Change-Id: I473a03f3e5a1d756eb4b083d52bd992839911c66 --- .../statusbar/policy/RemoteInputView.java | 76 ++++++++++--------- 1 file changed, 42 insertions(+), 34 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java index 9c3395f9332d1..c84589a9e142d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java @@ -18,11 +18,13 @@ package com.android.systemui.statusbar.policy; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; +import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.Notification; import android.app.PendingIntent; import android.app.RemoteInput; +import android.content.ClipData; import android.content.ClipDescription; import android.content.Context; import android.content.Intent; @@ -43,6 +45,7 @@ import android.util.Log; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.MotionEvent; +import android.view.OnReceiveContentCallback; import android.view.View; import android.view.ViewAnimationUtils; import android.view.ViewGroup; @@ -57,9 +60,6 @@ import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.TextView; -import androidx.core.view.inputmethod.InputConnectionCompat; -import androidx.core.view.inputmethod.InputContentInfoCompat; - import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto; import com.android.internal.statusbar.IStatusBarService; @@ -73,7 +73,9 @@ import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewW import com.android.systemui.statusbar.notification.stack.StackStateAnimator; import com.android.systemui.statusbar.phone.LightBarController; +import java.util.Collections; import java.util.HashMap; +import java.util.Set; import java.util.function.Consumer; /** @@ -313,6 +315,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene mRemoteInputs = remoteInputs; mRemoteInput = remoteInput; mEditText.setHint(mRemoteInput.getLabel()); + mEditText.mSupportedMimeTypes = remoteInput.getAllowedDataTypes(); mEntry.editedSuggestionInfo = editedSuggestionInfo; if (editedSuggestionInfo != null) { @@ -571,6 +574,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene boolean mShowImeOnInputConnection; private LightBarController mLightBarController; UserHandle mUser; + private Set mSupportedMimeTypes; public RemoteEditText(Context context, AttributeSet attrs) { super(context, attrs); @@ -578,6 +582,40 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene mLightBarController = Dependency.get(LightBarController.class); } + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + setOnReceiveContentCallback(new OnReceiveContentCallback() { + @Override + public boolean onReceiveContent(@NonNull View view, @NonNull Payload payload) { + ClipData clip = payload.getClip(); + if (clip.getItemCount() == 0) { + return false; + } + Uri contentUri = clip.getItemAt(0).getUri(); + ClipDescription description = clip.getDescription(); + String mimeType = null; + if (description.getMimeTypeCount() > 0) { + mimeType = description.getMimeType(0); + } + if (mimeType != null) { + Intent dataIntent = mRemoteInputView + .prepareRemoteInputFromData(mimeType, contentUri); + mRemoteInputView.sendRemoteInput(dataIntent); + } + return true; + } + + @NonNull + @Override + public Set getSupportedMimeTypes(@NonNull View view) { + return mSupportedMimeTypes != null + ? mSupportedMimeTypes + : Collections.emptySet(); + } + }); + } + private void defocusIfNeeded(boolean animate) { if (mRemoteInputView != null && mRemoteInputView.mEntry.getRow().isChangingPosition() || isTemporarilyDetached()) { @@ -670,36 +708,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene @Override public InputConnection onCreateInputConnection(EditorInfo outAttrs) { - // TODO: Pass RemoteInput data types to allow image insertion. - // String[] allowedDataTypes = mRemoteInputView.mRemoteInput.getAllowedDataTypes() - // .toArray(new String[0]); - // EditorInfoCompat.setContentMimeTypes(outAttrs, allowedDataTypes); - final InputConnection inputConnection = super.onCreateInputConnection(outAttrs); - - final InputConnectionCompat.OnCommitContentListener callback = - new InputConnectionCompat.OnCommitContentListener() { - @Override - public boolean onCommitContent( - InputContentInfoCompat inputContentInfoCompat, int i, - Bundle bundle) { - Uri contentUri = inputContentInfoCompat.getContentUri(); - ClipDescription description = inputContentInfoCompat.getDescription(); - String mimeType = null; - if (description != null && description.getMimeTypeCount() > 0) { - mimeType = description.getMimeType(0); - } - if (mimeType != null) { - Intent dataIntent = mRemoteInputView.prepareRemoteInputFromData( - mimeType, contentUri); - mRemoteInputView.sendRemoteInput(dataIntent); - } - return true; - } - }; - - InputConnection ic = inputConnection == null ? null : - InputConnectionCompat.createWrapper(inputConnection, outAttrs, callback); - + final InputConnection ic = super.onCreateInputConnection(outAttrs); Context userContext = null; try { userContext = mContext.createPackageContextAsUser( @@ -747,7 +756,6 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene } else { setBackground(null); } - } } }