Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 0552ef7

Browse files
authored
Undo custom serialization of spell check results on Android (#34647)
1 parent bf951ee commit 0552ef7

File tree

3 files changed

+51
-27
lines changed

3 files changed

+51
-27
lines changed

shell/platform/android/io/flutter/embedding/engine/systemchannels/SpellCheckChannel.java

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,10 @@
88
import androidx.annotation.Nullable;
99
import io.flutter.Log;
1010
import io.flutter.embedding.engine.dart.DartExecutor;
11-
import io.flutter.plugin.common.JSONMethodCodec;
1211
import io.flutter.plugin.common.MethodCall;
1312
import io.flutter.plugin.common.MethodChannel;
14-
import org.json.JSONArray;
15-
import org.json.JSONException;
13+
import io.flutter.plugin.common.StandardMethodCodec;
14+
import java.util.ArrayList;
1615

1716
/**
1817
* {@link SpellCheckChannel} is a platform channel that is used by the framework to initiate spell
@@ -26,9 +25,8 @@
2625
*
2726
* <p>Once the spell check results are received by the {@link
2827
* io.flutter.plugin.editing.SpellCheckPlugin}, it will send back to the framework the {@code
29-
* ArrayList<String>} of encoded spell check results (see {@link
30-
* io.flutter.plugin.editing.SpellCheckPlugin#onGetSentenceSuggestions} for details). For example,
31-
* the argument may look like: {@code {"7.11.world\nword\nold"}}. The {@link
28+
* ArrayList<HashMap<String,Object>>} of spell check results (see {@link
29+
* io.flutter.plugin.editing.SpellCheckPlugin#onGetSentenceSuggestions} for details). The {@link
3230
* io.flutter.plugin.editing.SpellCheckPlugin} only handles one request to fetch spell check results
3331
* at a time; see {@link io.flutter.plugin.editing.SpellCheckPlugin#initiateSpellCheck} for details.
3432
*
@@ -59,11 +57,11 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result
5957
switch (method) {
6058
case "SpellCheck.initiateSpellCheck":
6159
try {
62-
final JSONArray argumentList = (JSONArray) args;
63-
String locale = argumentList.getString(0);
64-
String text = argumentList.getString(1);
60+
final ArrayList<String> argumentList = (ArrayList<String>) args;
61+
String locale = argumentList.get(0);
62+
String text = argumentList.get(1);
6563
spellCheckMethodHandler.initiateSpellCheck(locale, text, result);
66-
} catch (JSONException exception) {
64+
} catch (IllegalStateException exception) {
6765
result.error("error", exception.getMessage(), null);
6866
}
6967
break;
@@ -75,7 +73,7 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result
7573
};
7674

7775
public SpellCheckChannel(@NonNull DartExecutor dartExecutor) {
78-
channel = new MethodChannel(dartExecutor, "flutter/spellcheck", JSONMethodCodec.INSTANCE);
76+
channel = new MethodChannel(dartExecutor, "flutter/spellcheck", StandardMethodCodec.INSTANCE);
7977
channel.setMethodCallHandler(parsingMethodHandler);
8078
}
8179

shell/platform/android/io/flutter/plugin/editing/SpellCheckPlugin.java

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import io.flutter.plugin.common.MethodChannel;
1616
import io.flutter.plugin.localization.LocalizationPlugin;
1717
import java.util.ArrayList;
18+
import java.util.HashMap;
1819
import java.util.Locale;
1920

2021
/**
@@ -34,6 +35,10 @@ public class SpellCheckPlugin
3435
private final TextServicesManager mTextServicesManager;
3536
private SpellCheckerSession mSpellCheckerSession;
3637

38+
public static final String START_INDEX_KEY = "startIndex";
39+
public static final String END_INDEX_KEY = "endIndex";
40+
public static final String SUGGESTIONS_KEY = "suggestions";
41+
3742
@VisibleForTesting MethodChannel.Result pendingResult;
3843

3944
// The maximum number of suggestions that the Android spell check service is allowed to provide
@@ -105,19 +110,28 @@ public void performSpellCheck(@NonNull String locale, @NonNull String text) {
105110
* Callback for Android spell check API that decomposes results and send results through the
106111
* {@link SpellCheckChannel}.
107112
*
108-
* <p>Spell check results will be encoded as a string representing the span of that result, with
109-
* the format "start_index.end_index.suggestion_1/nsuggestion_2/nsuggestion_3", where there may be
110-
* up to 5 suggestions.
113+
* <p>Spell check results are encoded as dictionaries with a format that looks like
114+
*
115+
* <pre>{@code
116+
* {
117+
* startIndex: 0,
118+
* endIndex: 5,
119+
* suggestions: [hello, ...]
120+
* }
121+
* }</pre>
122+
*
123+
* where there may be up to 5 suggestions.
111124
*/
112125
@Override
113126
public void onGetSentenceSuggestions(SentenceSuggestionsInfo[] results) {
114127
if (results.length == 0) {
115-
pendingResult.success(new ArrayList<String>());
128+
pendingResult.success(new ArrayList<HashMap<String, Object>>());
116129
pendingResult = null;
117130
return;
118131
}
119132

120-
ArrayList<String> spellCheckerSuggestionSpans = new ArrayList<String>();
133+
ArrayList<HashMap<String, Object>> spellCheckerSuggestionSpans =
134+
new ArrayList<HashMap<String, Object>>();
121135
SentenceSuggestionsInfo spellCheckResults = results[0];
122136

123137
for (int i = 0; i < spellCheckResults.getSuggestionsCount(); i++) {
@@ -128,19 +142,20 @@ public void onGetSentenceSuggestions(SentenceSuggestionsInfo[] results) {
128142
continue;
129143
}
130144

131-
String spellCheckerSuggestionSpan = "";
145+
HashMap<String, Object> spellCheckerSuggestionSpan = new HashMap<String, Object>();
132146
int start = spellCheckResults.getOffsetAt(i);
133-
int end = start + spellCheckResults.getLengthAt(i) - 1;
147+
int end = start + spellCheckResults.getLengthAt(i);
134148

135-
spellCheckerSuggestionSpan += String.valueOf(start) + ".";
136-
spellCheckerSuggestionSpan += String.valueOf(end) + ".";
149+
spellCheckerSuggestionSpan.put(START_INDEX_KEY, start);
150+
spellCheckerSuggestionSpan.put(END_INDEX_KEY, end);
137151

152+
ArrayList<String> suggestions = new ArrayList<String>();
138153
for (int j = 0; j < suggestionsCount; j++) {
139-
spellCheckerSuggestionSpan += suggestionsInfo.getSuggestionAt(j) + "\n";
154+
suggestions.add(suggestionsInfo.getSuggestionAt(j));
140155
}
141156

142-
spellCheckerSuggestionSpans.add(
143-
spellCheckerSuggestionSpan.substring(0, spellCheckerSuggestionSpan.length() - 1));
157+
spellCheckerSuggestionSpan.put(SUGGESTIONS_KEY, suggestions);
158+
spellCheckerSuggestionSpans.add(spellCheckerSuggestionSpan);
144159
}
145160

146161
pendingResult.success(spellCheckerSuggestionSpans);

shell/platform/android/test/io/flutter/plugin/editing/SpellCheckPluginTest.java

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,13 @@
2121
import io.flutter.embedding.engine.dart.DartExecutor;
2222
import io.flutter.embedding.engine.systemchannels.SpellCheckChannel;
2323
import io.flutter.plugin.common.BinaryMessenger;
24-
import io.flutter.plugin.common.JSONMethodCodec;
2524
import io.flutter.plugin.common.MethodCall;
2625
import io.flutter.plugin.common.MethodChannel;
26+
import io.flutter.plugin.common.StandardMethodCodec;
2727
import java.nio.ByteBuffer;
2828
import java.util.ArrayList;
2929
import java.util.Arrays;
30+
import java.util.HashMap;
3031
import java.util.Locale;
3132
import org.junit.Test;
3233
import org.junit.runner.RunWith;
@@ -38,7 +39,7 @@ public class SpellCheckPluginTest {
3839
private static void sendToBinaryMessageHandler(
3940
BinaryMessenger.BinaryMessageHandler binaryMessageHandler, String method, Object args) {
4041
MethodCall methodCall = new MethodCall(method, args);
41-
ByteBuffer encodedMethodCall = JSONMethodCodec.INSTANCE.encodeMethodCall(methodCall);
42+
ByteBuffer encodedMethodCall = StandardMethodCodec.INSTANCE.encodeMethodCall(methodCall);
4243
binaryMessageHandler.onMessage(
4344
(ByteBuffer) encodedMethodCall.flip(), mock(BinaryMessenger.BinaryReply.class));
4445
}
@@ -185,7 +186,7 @@ public void onGetSentenceSuggestionsResultsWithSuccessAndNoResultsProperly() {
185186

186187
spellCheckPlugin.onGetSentenceSuggestions(new SentenceSuggestionsInfo[] {});
187188

188-
verify(mockResult).success(new ArrayList<String>());
189+
verify(mockResult).success(new ArrayList<HashMap<String, Object>>());
189190
}
190191

191192
@Test
@@ -209,6 +210,16 @@ public void onGetSentenceSuggestionsResultsWithSuccessAndResultsProperly() {
209210
new int[] {5})
210211
});
211212

212-
verify(mockResult).success(new ArrayList<String>(Arrays.asList("7.11.world\nword\nold")));
213+
ArrayList<HashMap<String, Object>> expectedResults = new ArrayList<HashMap<String, Object>>();
214+
HashMap<String, Object> expectedResult = new HashMap<String, Object>();
215+
216+
expectedResult.put(SpellCheckPlugin.START_INDEX_KEY, 7);
217+
expectedResult.put(SpellCheckPlugin.END_INDEX_KEY, 12);
218+
expectedResult.put(
219+
SpellCheckPlugin.SUGGESTIONS_KEY,
220+
new ArrayList<String>(Arrays.asList("world", "word", "old")));
221+
expectedResults.add(expectedResult);
222+
223+
verify(mockResult).success(expectedResults);
213224
}
214225
}

0 commit comments

Comments
 (0)