Skip to content

Commit d3e26fa

Browse files
authored
Merge branch 'flutter-ml:develop' into develop
2 parents 28fb6a9 + 3654338 commit d3e26fa

File tree

8 files changed

+203
-112
lines changed

8 files changed

+203
-112
lines changed

.github/workflows/inactive-issues.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
issues: write
1212
pull-requests: write
1313
steps:
14-
- uses: actions/stale@v9
14+
- uses: actions/stale@v10
1515
with:
1616
days-before-issue-stale: 30
1717
days-before-issue-close: 14
Lines changed: 71 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,9 @@
11
package com.google_mlkit_commons;
22

3-
import com.google.android.gms.tasks.Task;
4-
import com.google.android.gms.tasks.Tasks;
53
import com.google.mlkit.common.model.DownloadConditions;
64
import com.google.mlkit.common.model.RemoteModel;
75
import com.google.mlkit.common.model.RemoteModelManager;
86

9-
import java.util.concurrent.Callable;
10-
import java.util.concurrent.ExecutionException;
11-
import java.util.concurrent.ExecutorService;
12-
import java.util.concurrent.Executors;
13-
import java.util.concurrent.Future;
14-
157
import io.flutter.plugin.common.MethodCall;
168
import io.flutter.plugin.common.MethodChannel;
179

@@ -20,13 +12,22 @@ public class GenericModelManager {
2012
private static final String DELETE = "delete";
2113
private static final String CHECK = "check";
2214

23-
public RemoteModelManager remoteModelManager = RemoteModelManager.getInstance();
15+
public interface CheckModelIsDownloadedCallback {
16+
void onCheckResult(Boolean isDownloaded);
17+
18+
void onError(Exception e);
19+
}
2420

25-
//To avoid downloading models in the main thread as they are around 20MB and may crash the app.
26-
private final ExecutorService executorService = Executors.newCachedThreadPool();
21+
public RemoteModelManager remoteModelManager = RemoteModelManager.getInstance();
2722

2823
public void manageModel(final RemoteModel model, final MethodCall call, final MethodChannel.Result result) {
2924
String task = call.argument("task");
25+
26+
if (task == null) {
27+
result.notImplemented();
28+
return;
29+
}
30+
3031
switch (task) {
3132
case DOWNLOAD:
3233
boolean isWifiReqRequired = call.argument("wifi");
@@ -41,52 +42,77 @@ public void manageModel(final RemoteModel model, final MethodCall call, final Me
4142
deleteModel(model, result);
4243
break;
4344
case CHECK:
44-
Boolean downloaded = isModelDownloaded(model);
45-
if (downloaded != null) result.success(downloaded);
46-
else result.error("error", null, null);
45+
isModelDownloaded(
46+
model,
47+
new CheckModelIsDownloadedCallback() {
48+
@Override
49+
public void onCheckResult(Boolean isDownloaded) {
50+
result.success(isDownloaded);
51+
}
52+
53+
@Override
54+
public void onError(Exception e) {
55+
result.error("error", e.toString(), null);
56+
}
57+
}
58+
);
4759
break;
4860
default:
4961
result.notImplemented();
5062
}
5163
}
5264

5365
public void downloadModel(RemoteModel remoteModel, DownloadConditions downloadConditions, final MethodChannel.Result result) {
54-
if (isModelDownloaded(remoteModel)) {
55-
result.success("success");
56-
return;
57-
}
58-
remoteModelManager.download(remoteModel, downloadConditions).addOnSuccessListener(aVoid -> result.success("success")).addOnFailureListener(e -> result.error("error", e.toString(), null));
59-
}
66+
isModelDownloaded(
67+
remoteModel,
68+
new CheckModelIsDownloadedCallback() {
69+
@Override
70+
public void onCheckResult(Boolean isDownloaded) {
71+
if (isDownloaded) {
72+
result.success("success");
73+
return;
74+
}
6075

61-
public void deleteModel(RemoteModel remoteModel, final MethodChannel.Result result) {
62-
if (!isModelDownloaded(remoteModel)) {
63-
result.success("success");
64-
return;
65-
}
66-
remoteModelManager.deleteDownloadedModel(remoteModel).addOnSuccessListener(aVoid -> result.success("success")).addOnFailureListener(e -> result.error("error", e.toString(), null));
67-
}
76+
remoteModelManager.download(remoteModel, downloadConditions)
77+
.addOnSuccessListener(aVoid -> result.success("success"))
78+
.addOnFailureListener(e -> result.error("error", e.toString(), null));
79+
}
6880

69-
public Boolean isModelDownloaded(RemoteModel model) {
70-
IsModelDownloaded myCallable = new IsModelDownloaded(remoteModelManager.isModelDownloaded(model));
71-
Future<Boolean> taskResult = executorService.submit(myCallable);
72-
try {
73-
return taskResult.get();
74-
} catch (InterruptedException | ExecutionException e) {
75-
e.printStackTrace();
76-
}
77-
return null;
81+
@Override
82+
public void onError(Exception e) {
83+
result.error("error", e.toString(), null);
84+
}
85+
}
86+
);
7887
}
79-
}
8088

81-
class IsModelDownloaded implements Callable<Boolean> {
82-
final Task<Boolean> booleanTask;
89+
public void deleteModel(RemoteModel remoteModel, final MethodChannel.Result result) {
90+
isModelDownloaded(remoteModel, new CheckModelIsDownloadedCallback() {
91+
@Override
92+
public void onCheckResult(Boolean isDownloaded) {
93+
if (!isDownloaded) {
94+
result.success("success");
95+
return;
96+
}
97+
remoteModelManager.deleteDownloadedModel(remoteModel)
98+
.addOnSuccessListener(aVoid -> result.success("success"))
99+
.addOnFailureListener(e -> result.error("error", e.toString(), null));
100+
}
83101

84-
public IsModelDownloaded(Task<Boolean> booleanTask) {
85-
this.booleanTask = booleanTask;
102+
@Override
103+
public void onError(Exception e) {
104+
result.error("error", e.toString(), null);
105+
}
106+
});
86107
}
87108

88-
@Override
89-
public Boolean call() throws Exception {
90-
return Tasks.await(booleanTask);
109+
public void isModelDownloaded(RemoteModel model, CheckModelIsDownloadedCallback callback) {
110+
try {
111+
remoteModelManager.isModelDownloaded(model)
112+
.addOnFailureListener(callback::onError)
113+
.addOnSuccessListener(callback::onCheckResult);
114+
} catch (Exception e) {
115+
callback.onError(e);
116+
}
91117
}
92-
}
118+
}

packages/google_mlkit_digital_ink_recognition/android/src/main/java/com/google_mlkit_digital_ink_recognition/DigitalInkRecognizer.java

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,33 @@ private void handleDetection(MethodCall call, final MethodChannel.Result result)
5454
DigitalInkRecognitionModel model = getModel(tag, result);
5555
if (model == null)
5656
return;
57-
if (!genericModelManager.isModelDownloaded(model)) {
58-
result.error("Model Error", "Model has not been downloaded yet ", null);
59-
return;
60-
}
6157

58+
genericModelManager.isModelDownloaded(
59+
model,
60+
new GenericModelManager.CheckModelIsDownloadedCallback() {
61+
@Override
62+
public void onCheckResult(Boolean isDownloaded) {
63+
if (!isDownloaded) {
64+
result.error("Model Error", "Model has not been downloaded yet ", null);
65+
return;
66+
}
67+
68+
handleInkDetectionIfModelDownloaded(call, result, model);
69+
}
70+
71+
@Override
72+
public void onError(Exception e) {
73+
result.error("Model download check failed", e.toString(), e);
74+
}
75+
}
76+
);
77+
}
78+
79+
private void handleInkDetectionIfModelDownloaded(
80+
MethodCall call,
81+
final MethodChannel.Result result,
82+
DigitalInkRecognitionModel model
83+
) {
6284
String id = call.argument("id");
6385
com.google.mlkit.vision.digitalink.recognition.DigitalInkRecognizer recognizer = instances.get(id);
6486
if (recognizer == null) {
@@ -164,4 +186,4 @@ private DigitalInkRecognitionModel getModel(String tag, final MethodChannel.Resu
164186
}
165187
return DigitalInkRecognitionModel.builder(modelIdentifier).build();
166188
}
167-
}
189+
}

packages/google_mlkit_entity_extraction/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
## 0.15.2
2+
* Update dependencies
3+
14
## 0.15.1
25

36
* Increase android sdk compile version to 35

packages/google_mlkit_entity_extraction/android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,6 @@ android {
3636
}
3737

3838
dependencies {
39-
implementation("com.google.mlkit:entity-extraction:16.0.0-beta5")
39+
implementation("com.google.mlkit:entity-extraction:16.0.0-beta6")
4040
}
4141
}

packages/google_mlkit_entity_extraction/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: google_mlkit_entity_extraction
22
description: "A Flutter plugin to use Google's ML Kit Entity Extractor API to recognize specific entities within static text."
3-
version: 0.15.1
3+
version: 0.15.2
44
homepage: https://github.com/flutter-ml/google_ml_kit_flutter
55
repository: https://github.com/flutter-ml/google_ml_kit_flutter/tree/master/packages/google_mlkit_entity_extraction
66

packages/google_mlkit_image_labeling/android/src/main/java/com/google_mlkit_image_labeling/ImageLabelDetector.java

Lines changed: 41 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,43 @@ private void handleDetection(MethodCall call, final MethodChannel.Result result)
7979
CustomImageLabelerOptions labelerOptions = getLocalOptions(options);
8080
imageLabeler = ImageLabeling.getClient(labelerOptions);
8181
} else if (type.equals("remote")) {
82-
CustomImageLabelerOptions labelerOptions = getRemoteOptions(options);
83-
if (labelerOptions == null) {
84-
result.error("Error Model has not been downloaded yet", "Model has not been downloaded yet", "Model has not been downloaded yet");
85-
return;
86-
}
87-
imageLabeler = ImageLabeling.getClient(labelerOptions);
82+
float confidenceThreshold = (float) (double) options.get("confidenceThreshold");
83+
int maxCount = (int) options.get("maxCount");
84+
String name = (String) options.get("modelName");
85+
86+
FirebaseModelSource firebaseModelSource = new FirebaseModelSource.Builder(name).build();
87+
CustomRemoteModel remoteModel = new CustomRemoteModel.Builder(firebaseModelSource).build();
88+
89+
genericModelManager.isModelDownloaded(
90+
remoteModel,
91+
new GenericModelManager.CheckModelIsDownloadedCallback() {
92+
@Override
93+
public void onCheckResult(Boolean isDownloaded) {
94+
if (!isDownloaded) {
95+
result.error("Error Model has not been downloaded yet", "Model has not been downloaded yet", "Model has not been downloaded yet");
96+
return;
97+
}
98+
99+
startImageLabelDetector(
100+
ImageLabeling.getClient(
101+
new CustomImageLabelerOptions.Builder(remoteModel)
102+
.setConfidenceThreshold(confidenceThreshold)
103+
.setMaxResultCount(maxCount)
104+
.build()
105+
),
106+
inputImage,
107+
result
108+
);
109+
}
110+
111+
@Override
112+
public void onError(Exception e) {
113+
result.error("Model download check failed", e.getMessage(), e);
114+
}
115+
}
116+
);
117+
118+
return;
88119
} else {
89120
String error = "Invalid model type: " + type;
90121
result.error(type, error, error);
@@ -93,6 +124,10 @@ private void handleDetection(MethodCall call, final MethodChannel.Result result)
93124
instances.put(id, imageLabeler);
94125
}
95126

127+
startImageLabelDetector(imageLabeler, inputImage, result);
128+
}
129+
130+
private void startImageLabelDetector(ImageLabeler imageLabeler, InputImage inputImage, MethodChannel.Result result) {
96131
imageLabeler.process(inputImage)
97132
.addOnSuccessListener(imageLabels -> {
98133
List<Map<String, Object>> labels = new ArrayList<>(imageLabels.size());
@@ -131,24 +166,6 @@ private CustomImageLabelerOptions getLocalOptions(Map<String, Object> labelerOpt
131166
.build();
132167
}
133168

134-
//Options for labeler to work with custom model.
135-
private CustomImageLabelerOptions getRemoteOptions(Map<String, Object> labelerOptions) {
136-
float confidenceThreshold = (float) (double) labelerOptions.get("confidenceThreshold");
137-
int maxCount = (int) labelerOptions.get("maxCount");
138-
String name = (String) labelerOptions.get("modelName");
139-
140-
FirebaseModelSource firebaseModelSource = new FirebaseModelSource.Builder(name).build();
141-
CustomRemoteModel remoteModel = new CustomRemoteModel.Builder(firebaseModelSource).build();
142-
if (!genericModelManager.isModelDownloaded(remoteModel)) {
143-
return null;
144-
}
145-
146-
return new CustomImageLabelerOptions.Builder(remoteModel)
147-
.setConfidenceThreshold(confidenceThreshold)
148-
.setMaxResultCount(maxCount)
149-
.build();
150-
}
151-
152169
private void closeDetector(MethodCall call) {
153170
String id = call.argument("id");
154171
ImageLabeler imageLabeler = instances.get(id);

0 commit comments

Comments
 (0)