|
| 1 | +// Copyright 2013 The Flutter Authors. All rights reserved. |
| 2 | +// Use of this source code is governed by a BSD-style license that can be |
| 3 | +// found in the LICENSE file. |
| 4 | + |
| 5 | +package io.flutter.embedding.engine.systemchannels; |
| 6 | + |
| 7 | +import android.content.pm.PackageManager; |
| 8 | +import androidx.annotation.NonNull; |
| 9 | +import androidx.annotation.Nullable; |
| 10 | +import io.flutter.embedding.engine.dart.DartExecutor; |
| 11 | +import io.flutter.plugin.common.MethodCall; |
| 12 | +import io.flutter.plugin.common.MethodChannel; |
| 13 | +import io.flutter.plugin.common.StandardMethodCodec; |
| 14 | +import java.util.ArrayList; |
| 15 | +import java.util.Map; |
| 16 | + |
| 17 | +/** |
| 18 | + * {@link ProcessTextChannel} is a platform channel that is used by the framework to initiate text |
| 19 | + * processing feature in the embedding and for the embedding to send back the results. |
| 20 | + * |
| 21 | + * <p>When the framework needs to query the list of text processing actions (for instance to expose |
| 22 | + * them in the selected text context menu), it will send to the embedding the message {@code |
| 23 | + * ProcessText.queryTextActions}. In response, the {@link io.flutter.plugin.text.ProcessTextPlugin} |
| 24 | + * will return a map of all activities that can process text. The map keys are generated IDs and the |
| 25 | + * values are the activities labels. On the first request, the {@link |
| 26 | + * io.flutter.plugin.text.ProcessTextPlugin} will make a call to Android's package manager to query |
| 27 | + * all activities that can be performed for the {@code Intent.ACTION_PROCESS_TEXT} intent. |
| 28 | + * |
| 29 | + * <p>When a text processing action has to be executed, the framework will send to the embedding the |
| 30 | + * message {@code ProcessText.processTextAction} with the {@code int id} of the choosen text action |
| 31 | + * and the {@code String} of text to process as arguments. In response, the {@link |
| 32 | + * io.flutter.plugin.text.ProcessTextPlugin} will make a call to the Android application activity to |
| 33 | + * start the activity exposing the text action. The {@link io.flutter.plugin.text.ProcessTextPlugin} |
| 34 | + * will return the processed text if there is one, or null if the activity did not return a |
| 35 | + * transformed text. |
| 36 | + * |
| 37 | + * <p>{@link io.flutter.plugin.text.ProcessTextPlugin} implements {@link ProcessTextMethodHandler} |
| 38 | + * that parses incoming messages from Flutter. |
| 39 | + */ |
| 40 | +public class ProcessTextChannel { |
| 41 | + private static final String TAG = "ProcessTextChannel"; |
| 42 | + private static final String CHANNEL_NAME = "flutter/processtext"; |
| 43 | + private static final String METHOD_QUERY_TEXT_ACTIONS = "ProcessText.queryTextActions"; |
| 44 | + private static final String METHOD_PROCESS_TEXT_ACTION = "ProcessText.processTextAction"; |
| 45 | + |
| 46 | + public final MethodChannel channel; |
| 47 | + public final PackageManager packageManager; |
| 48 | + private ProcessTextMethodHandler processTextMethodHandler; |
| 49 | + |
| 50 | + @NonNull |
| 51 | + public final MethodChannel.MethodCallHandler parsingMethodHandler = |
| 52 | + new MethodChannel.MethodCallHandler() { |
| 53 | + @Override |
| 54 | + public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { |
| 55 | + if (processTextMethodHandler == null) { |
| 56 | + return; |
| 57 | + } |
| 58 | + String method = call.method; |
| 59 | + Object args = call.arguments; |
| 60 | + switch (method) { |
| 61 | + case METHOD_QUERY_TEXT_ACTIONS: |
| 62 | + try { |
| 63 | + Map<String, String> actions = processTextMethodHandler.queryTextActions(); |
| 64 | + result.success(actions); |
| 65 | + } catch (IllegalStateException exception) { |
| 66 | + result.error("error", exception.getMessage(), null); |
| 67 | + } |
| 68 | + break; |
| 69 | + case METHOD_PROCESS_TEXT_ACTION: |
| 70 | + try { |
| 71 | + final ArrayList<Object> argumentList = (ArrayList<Object>) args; |
| 72 | + String id = (String) (argumentList.get(0)); |
| 73 | + String text = (String) (argumentList.get(1)); |
| 74 | + boolean readOnly = (boolean) (argumentList.get(2)); |
| 75 | + processTextMethodHandler.processTextAction(id, text, readOnly, result); |
| 76 | + } catch (IllegalStateException exception) { |
| 77 | + result.error("error", exception.getMessage(), null); |
| 78 | + } |
| 79 | + break; |
| 80 | + default: |
| 81 | + result.notImplemented(); |
| 82 | + break; |
| 83 | + } |
| 84 | + } |
| 85 | + }; |
| 86 | + |
| 87 | + public ProcessTextChannel( |
| 88 | + @NonNull DartExecutor dartExecutor, @NonNull PackageManager packageManager) { |
| 89 | + this.packageManager = packageManager; |
| 90 | + channel = new MethodChannel(dartExecutor, CHANNEL_NAME, StandardMethodCodec.INSTANCE); |
| 91 | + channel.setMethodCallHandler(parsingMethodHandler); |
| 92 | + } |
| 93 | + |
| 94 | + /** |
| 95 | + * Sets the {@link ProcessTextMethodHandler} which receives all requests to the text processing |
| 96 | + * feature sent through this channel. |
| 97 | + */ |
| 98 | + public void setMethodHandler(@Nullable ProcessTextMethodHandler processTextMethodHandler) { |
| 99 | + this.processTextMethodHandler = processTextMethodHandler; |
| 100 | + } |
| 101 | + |
| 102 | + public interface ProcessTextMethodHandler { |
| 103 | + /** Requests the map of text actions. Each text action has a unique id and a localized label. */ |
| 104 | + Map<String, String> queryTextActions(); |
| 105 | + |
| 106 | + /** |
| 107 | + * Requests to run a text action on a given input text. |
| 108 | + * |
| 109 | + * @param id The ID of the text action returned by {@code ProcessText.queryTextActions}. |
| 110 | + * @param input The text to be processed. |
| 111 | + * @param readOnly Indicates to the activity if the processed text will be used as read-only. |
| 112 | + * see |
| 113 | + * https://developer.android.com/reference/android/content/Intent#EXTRA_PROCESS_TEXT_READONLY |
| 114 | + * @param result The method channel result instance used to reply. |
| 115 | + */ |
| 116 | + void processTextAction( |
| 117 | + @NonNull String id, |
| 118 | + @NonNull String input, |
| 119 | + @NonNull boolean readOnly, |
| 120 | + @NonNull MethodChannel.Result result); |
| 121 | + } |
| 122 | +} |
0 commit comments