diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter
index 3a336880ef306..b8e32aa31564f 100644
--- a/ci/licenses_golden/licenses_flutter
+++ b/ci/licenses_golden/licenses_flutter
@@ -3091,6 +3091,7 @@ ORIGIN: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/syst
ORIGIN: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/systemchannels/NavigationChannel.java + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/systemchannels/PlatformChannel.java + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/systemchannels/PlatformViewsChannel.java + ../../../flutter/LICENSE
+ORIGIN: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/systemchannels/ProcessTextChannel.java + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/systemchannels/RestorationChannel.java + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/systemchannels/SpellCheckChannel.java + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/systemchannels/SystemChannel.java + ../../../flutter/LICENSE
@@ -3133,6 +3134,7 @@ ORIGIN: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/Platf
ORIGIN: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/SingleViewPresentation.java + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/VirtualDisplayController.java + ../../../flutter/LICENSE
+ORIGIN: ../../../flutter/shell/platform/android/io/flutter/plugin/text/ProcessTextPlugin.java + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/android/io/flutter/util/HandlerCompat.java + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/android/io/flutter/util/PathUtils.java + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/android/io/flutter/util/Preconditions.java + ../../../flutter/LICENSE
@@ -5861,6 +5863,7 @@ FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/system
FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/systemchannels/NavigationChannel.java
FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/systemchannels/PlatformChannel.java
FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/systemchannels/PlatformViewsChannel.java
+FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/systemchannels/ProcessTextChannel.java
FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/systemchannels/RestorationChannel.java
FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/systemchannels/SettingsChannel.java
FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/systemchannels/SpellCheckChannel.java
@@ -5908,6 +5911,7 @@ FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/Platfor
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/SingleViewPresentation.java
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/SurfaceTexturePlatformViewRenderTarget.java
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/VirtualDisplayController.java
+FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/text/ProcessTextPlugin.java
FILE: ../../../flutter/shell/platform/android/io/flutter/util/HandlerCompat.java
FILE: ../../../flutter/shell/platform/android/io/flutter/util/PathUtils.java
FILE: ../../../flutter/shell/platform/android/io/flutter/util/Preconditions.java
diff --git a/shell/platform/android/AndroidManifest.xml b/shell/platform/android/AndroidManifest.xml
index 5fbd0d8553c2b..97c77ee7ef57f 100644
--- a/shell/platform/android/AndroidManifest.xml
+++ b/shell/platform/android/AndroidManifest.xml
@@ -24,4 +24,12 @@
+
+
+
+
+
+
+
+
diff --git a/shell/platform/android/BUILD.gn b/shell/platform/android/BUILD.gn
index 06e4c9de02985..1f1068db7e703 100644
--- a/shell/platform/android/BUILD.gn
+++ b/shell/platform/android/BUILD.gn
@@ -265,6 +265,7 @@ android_java_sources = [
"io/flutter/embedding/engine/systemchannels/NavigationChannel.java",
"io/flutter/embedding/engine/systemchannels/PlatformChannel.java",
"io/flutter/embedding/engine/systemchannels/PlatformViewsChannel.java",
+ "io/flutter/embedding/engine/systemchannels/ProcessTextChannel.java",
"io/flutter/embedding/engine/systemchannels/RestorationChannel.java",
"io/flutter/embedding/engine/systemchannels/SettingsChannel.java",
"io/flutter/embedding/engine/systemchannels/SpellCheckChannel.java",
@@ -312,6 +313,7 @@ android_java_sources = [
"io/flutter/plugin/platform/SingleViewPresentation.java",
"io/flutter/plugin/platform/SurfaceTexturePlatformViewRenderTarget.java",
"io/flutter/plugin/platform/VirtualDisplayController.java",
+ "io/flutter/plugin/text/ProcessTextPlugin.java",
"io/flutter/util/HandlerCompat.java",
"io/flutter/util/PathUtils.java",
"io/flutter/util/Preconditions.java",
diff --git a/shell/platform/android/io/flutter/embedding/engine/FlutterEngine.java b/shell/platform/android/io/flutter/embedding/engine/FlutterEngine.java
index 2bfa379f39c1e..cb00ec42b363c 100644
--- a/shell/platform/android/io/flutter/embedding/engine/FlutterEngine.java
+++ b/shell/platform/android/io/flutter/embedding/engine/FlutterEngine.java
@@ -31,6 +31,7 @@
import io.flutter.embedding.engine.systemchannels.MouseCursorChannel;
import io.flutter.embedding.engine.systemchannels.NavigationChannel;
import io.flutter.embedding.engine.systemchannels.PlatformChannel;
+import io.flutter.embedding.engine.systemchannels.ProcessTextChannel;
import io.flutter.embedding.engine.systemchannels.RestorationChannel;
import io.flutter.embedding.engine.systemchannels.SettingsChannel;
import io.flutter.embedding.engine.systemchannels.SpellCheckChannel;
@@ -38,6 +39,7 @@
import io.flutter.embedding.engine.systemchannels.TextInputChannel;
import io.flutter.plugin.localization.LocalizationPlugin;
import io.flutter.plugin.platform.PlatformViewsController;
+import io.flutter.plugin.text.ProcessTextPlugin;
import io.flutter.util.ViewUtils;
import java.util.HashSet;
import java.util.List;
@@ -95,6 +97,7 @@ public class FlutterEngine implements ViewUtils.DisplayUpdater {
@NonNull private final NavigationChannel navigationChannel;
@NonNull private final RestorationChannel restorationChannel;
@NonNull private final PlatformChannel platformChannel;
+ @NonNull private final ProcessTextChannel processTextChannel;
@NonNull private final SettingsChannel settingsChannel;
@NonNull private final SpellCheckChannel spellCheckChannel;
@NonNull private final SystemChannel systemChannel;
@@ -329,6 +332,7 @@ public FlutterEngine(
mouseCursorChannel = new MouseCursorChannel(dartExecutor);
navigationChannel = new NavigationChannel(dartExecutor);
platformChannel = new PlatformChannel(dartExecutor);
+ processTextChannel = new ProcessTextChannel(dartExecutor, context.getPackageManager());
restorationChannel = new RestorationChannel(dartExecutor, waitForRestorationData);
settingsChannel = new SettingsChannel(dartExecutor);
spellCheckChannel = new SpellCheckChannel(dartExecutor);
@@ -384,6 +388,9 @@ public FlutterEngine(
}
ViewUtils.calculateMaximumDisplayMetrics(context, this);
+
+ ProcessTextPlugin processTextPlugin = new ProcessTextPlugin(this.getProcessTextChannel());
+ this.pluginRegistry.add(processTextPlugin);
}
private void attachToJni() {
@@ -545,6 +552,12 @@ public PlatformChannel getPlatformChannel() {
return platformChannel;
}
+ /** System channel that sends text processing requests from Flutter to Android. */
+ @NonNull
+ public ProcessTextChannel getProcessTextChannel() {
+ return processTextChannel;
+ }
+
/**
* System channel to exchange restoration data between framework and engine.
*
diff --git a/shell/platform/android/io/flutter/embedding/engine/systemchannels/ProcessTextChannel.java b/shell/platform/android/io/flutter/embedding/engine/systemchannels/ProcessTextChannel.java
new file mode 100644
index 0000000000000..f1d12bc681111
--- /dev/null
+++ b/shell/platform/android/io/flutter/embedding/engine/systemchannels/ProcessTextChannel.java
@@ -0,0 +1,122 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package io.flutter.embedding.engine.systemchannels;
+
+import android.content.pm.PackageManager;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import io.flutter.embedding.engine.dart.DartExecutor;
+import io.flutter.plugin.common.MethodCall;
+import io.flutter.plugin.common.MethodChannel;
+import io.flutter.plugin.common.StandardMethodCodec;
+import java.util.ArrayList;
+import java.util.Map;
+
+/**
+ * {@link ProcessTextChannel} is a platform channel that is used by the framework to initiate text
+ * processing feature in the embedding and for the embedding to send back the results.
+ *
+ *
When the framework needs to query the list of text processing actions (for instance to expose
+ * them in the selected text context menu), it will send to the embedding the message {@code
+ * ProcessText.queryTextActions}. In response, the {@link io.flutter.plugin.text.ProcessTextPlugin}
+ * will return a map of all activities that can process text. The map keys are generated IDs and the
+ * values are the activities labels. On the first request, the {@link
+ * io.flutter.plugin.text.ProcessTextPlugin} will make a call to Android's package manager to query
+ * all activities that can be performed for the {@code Intent.ACTION_PROCESS_TEXT} intent.
+ *
+ *
When a text processing action has to be executed, the framework will send to the embedding the
+ * message {@code ProcessText.processTextAction} with the {@code int id} of the choosen text action
+ * and the {@code String} of text to process as arguments. In response, the {@link
+ * io.flutter.plugin.text.ProcessTextPlugin} will make a call to the Android application activity to
+ * start the activity exposing the text action. The {@link io.flutter.plugin.text.ProcessTextPlugin}
+ * will return the processed text if there is one, or null if the activity did not return a
+ * transformed text.
+ *
+ *
{@link io.flutter.plugin.text.ProcessTextPlugin} implements {@link ProcessTextMethodHandler}
+ * that parses incoming messages from Flutter.
+ */
+public class ProcessTextChannel {
+ private static final String TAG = "ProcessTextChannel";
+ private static final String CHANNEL_NAME = "flutter/processtext";
+ private static final String METHOD_QUERY_TEXT_ACTIONS = "ProcessText.queryTextActions";
+ private static final String METHOD_PROCESS_TEXT_ACTION = "ProcessText.processTextAction";
+
+ public final MethodChannel channel;
+ public final PackageManager packageManager;
+ private ProcessTextMethodHandler processTextMethodHandler;
+
+ @NonNull
+ public final MethodChannel.MethodCallHandler parsingMethodHandler =
+ new MethodChannel.MethodCallHandler() {
+ @Override
+ public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
+ if (processTextMethodHandler == null) {
+ return;
+ }
+ String method = call.method;
+ Object args = call.arguments;
+ switch (method) {
+ case METHOD_QUERY_TEXT_ACTIONS:
+ try {
+ Map actions = processTextMethodHandler.queryTextActions();
+ result.success(actions);
+ } catch (IllegalStateException exception) {
+ result.error("error", exception.getMessage(), null);
+ }
+ break;
+ case METHOD_PROCESS_TEXT_ACTION:
+ try {
+ final ArrayList