• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "annotator/annotator_jni_common.h"
18 
19 #include "utils/java/jni-base.h"
20 #include "utils/java/jni-helper.h"
21 
22 namespace libtextclassifier3 {
23 namespace {
24 
EntityTypesFromJObject(JNIEnv * env,const jobject & jobject)25 StatusOr<std::unordered_set<std::string>> EntityTypesFromJObject(
26     JNIEnv* env, const jobject& jobject) {
27   std::unordered_set<std::string> entity_types;
28   jobjectArray jentity_types = reinterpret_cast<jobjectArray>(jobject);
29   const int size = env->GetArrayLength(jentity_types);
30   for (int i = 0; i < size; ++i) {
31     TC3_ASSIGN_OR_RETURN(
32         ScopedLocalRef<jstring> jentity_type,
33         JniHelper::GetObjectArrayElement<jstring>(env, jentity_types, i));
34     TC3_ASSIGN_OR_RETURN(std::string entity_type,
35                          ToStlString(env, jentity_type.get()));
36     entity_types.insert(entity_type);
37   }
38   return entity_types;
39 }
40 
41 template <typename T>
FromJavaOptionsInternal(JNIEnv * env,jobject joptions,const std::string & class_name)42 StatusOr<T> FromJavaOptionsInternal(JNIEnv* env, jobject joptions,
43                                     const std::string& class_name) {
44   if (!joptions) {
45     return {Status::UNKNOWN};
46   }
47 
48   TC3_ASSIGN_OR_RETURN(ScopedLocalRef<jclass> options_class,
49                        JniHelper::FindClass(env, class_name.c_str()));
50 
51   // .getLocale()
52   TC3_ASSIGN_OR_RETURN(
53       jmethodID get_locale,
54       JniHelper::GetMethodID(env, options_class.get(), "getLocale",
55                              "()Ljava/lang/String;"));
56   TC3_ASSIGN_OR_RETURN(
57       ScopedLocalRef<jstring> locales,
58       JniHelper::CallObjectMethod<jstring>(env, joptions, get_locale));
59 
60   // .getReferenceTimeMsUtc()
61   TC3_ASSIGN_OR_RETURN(jmethodID get_reference_time_method,
62                        JniHelper::GetMethodID(env, options_class.get(),
63                                               "getReferenceTimeMsUtc", "()J"));
64   TC3_ASSIGN_OR_RETURN(
65       int64 reference_time,
66       JniHelper::CallLongMethod(env, joptions, get_reference_time_method));
67 
68   // .getReferenceTimezone()
69   TC3_ASSIGN_OR_RETURN(
70       jmethodID get_reference_timezone_method,
71       JniHelper::GetMethodID(env, options_class.get(), "getReferenceTimezone",
72                              "()Ljava/lang/String;"));
73   TC3_ASSIGN_OR_RETURN(ScopedLocalRef<jstring> reference_timezone,
74                        JniHelper::CallObjectMethod<jstring>(
75                            env, joptions, get_reference_timezone_method));
76 
77   // .getDetectedTextLanguageTags()
78   TC3_ASSIGN_OR_RETURN(jmethodID get_detected_text_language_tags_method,
79                        JniHelper::GetMethodID(env, options_class.get(),
80                                               "getDetectedTextLanguageTags",
81                                               "()Ljava/lang/String;"));
82   TC3_ASSIGN_OR_RETURN(
83       ScopedLocalRef<jstring> detected_text_language_tags,
84       JniHelper::CallObjectMethod<jstring>(
85           env, joptions, get_detected_text_language_tags_method));
86 
87   // .getAnnotationUsecase()
88   TC3_ASSIGN_OR_RETURN(jmethodID get_annotation_usecase,
89                        JniHelper::GetMethodID(env, options_class.get(),
90                                               "getAnnotationUsecase", "()I"));
91   TC3_ASSIGN_OR_RETURN(
92       int32 annotation_usecase,
93       JniHelper::CallIntMethod(env, joptions, get_annotation_usecase));
94 
95   // .getUserLocationLat()
96   TC3_ASSIGN_OR_RETURN(jmethodID get_user_location_lat,
97                        JniHelper::GetMethodID(env, options_class.get(),
98                                               "getUserLocationLat", "()D"));
99   TC3_ASSIGN_OR_RETURN(
100       double user_location_lat,
101       JniHelper::CallDoubleMethod(env, joptions, get_user_location_lat));
102 
103   // .getUserLocationLng()
104   TC3_ASSIGN_OR_RETURN(jmethodID get_user_location_lng,
105                        JniHelper::GetMethodID(env, options_class.get(),
106                                               "getUserLocationLng", "()D"));
107   TC3_ASSIGN_OR_RETURN(
108       double user_location_lng,
109       JniHelper::CallDoubleMethod(env, joptions, get_user_location_lng));
110 
111   // .getUserLocationAccuracyMeters()
112   TC3_ASSIGN_OR_RETURN(
113       jmethodID get_user_location_accuracy_meters,
114       JniHelper::GetMethodID(env, options_class.get(),
115                              "getUserLocationAccuracyMeters", "()F"));
116   TC3_ASSIGN_OR_RETURN(float user_location_accuracy_meters,
117                        JniHelper::CallFloatMethod(
118                            env, joptions, get_user_location_accuracy_meters));
119 
120   T options;
121   TC3_ASSIGN_OR_RETURN(options.locales, ToStlString(env, locales.get()));
122   TC3_ASSIGN_OR_RETURN(options.reference_timezone,
123                        ToStlString(env, reference_timezone.get()));
124   options.reference_time_ms_utc = reference_time;
125   TC3_ASSIGN_OR_RETURN(options.detected_text_language_tags,
126                        ToStlString(env, detected_text_language_tags.get()));
127   options.annotation_usecase =
128       static_cast<AnnotationUsecase>(annotation_usecase);
129   options.location_context = {user_location_lat, user_location_lng,
130                               user_location_accuracy_meters};
131   return options;
132 }
133 }  // namespace
134 
FromJavaSelectionOptions(JNIEnv * env,jobject joptions)135 StatusOr<SelectionOptions> FromJavaSelectionOptions(JNIEnv* env,
136                                                     jobject joptions) {
137   if (!joptions) {
138     // Falling back to default options in case joptions is null
139     SelectionOptions default_selection_options;
140     return default_selection_options;
141   }
142 
143   TC3_ASSIGN_OR_RETURN(
144       ScopedLocalRef<jclass> options_class,
145       JniHelper::FindClass(env, TC3_PACKAGE_PATH TC3_ANNOTATOR_CLASS_NAME_STR
146                            "$SelectionOptions"));
147 
148   // .getLocale()
149   TC3_ASSIGN_OR_RETURN(
150       jmethodID get_locales,
151       JniHelper::GetMethodID(env, options_class.get(), "getLocales",
152                              "()Ljava/lang/String;"));
153   TC3_ASSIGN_OR_RETURN(
154       ScopedLocalRef<jstring> locales,
155       JniHelper::CallObjectMethod<jstring>(env, joptions, get_locales));
156 
157   // .getAnnotationUsecase()
158   TC3_ASSIGN_OR_RETURN(jmethodID get_annotation_usecase,
159                        JniHelper::GetMethodID(env, options_class.get(),
160                                               "getAnnotationUsecase", "()I"));
161   TC3_ASSIGN_OR_RETURN(
162       int32 annotation_usecase,
163       JniHelper::CallIntMethod(env, joptions, get_annotation_usecase));
164 
165   SelectionOptions options;
166   TC3_ASSIGN_OR_RETURN(options.locales, ToStlString(env, locales.get()));
167   options.annotation_usecase =
168       static_cast<AnnotationUsecase>(annotation_usecase);
169 
170   return options;
171 }
172 
FromJavaClassificationOptions(JNIEnv * env,jobject joptions)173 StatusOr<ClassificationOptions> FromJavaClassificationOptions(
174     JNIEnv* env, jobject joptions) {
175   if (!joptions) {
176     // Falling back to default options in case joptions is null
177     ClassificationOptions default_classification_options;
178     return default_classification_options;
179   }
180 
181   TC3_ASSIGN_OR_RETURN(ClassificationOptions classifier_options,
182                        FromJavaOptionsInternal<ClassificationOptions>(
183                            env, joptions,
184                            TC3_PACKAGE_PATH TC3_ANNOTATOR_CLASS_NAME_STR
185                            "$ClassificationOptions"));
186 
187   TC3_ASSIGN_OR_RETURN(
188       ScopedLocalRef<jclass> options_class,
189       JniHelper::FindClass(env, TC3_PACKAGE_PATH TC3_ANNOTATOR_CLASS_NAME_STR
190                            "$ClassificationOptions"));
191   // .getUserFamiliarLanguageTags()
192   TC3_ASSIGN_OR_RETURN(jmethodID get_user_familiar_language_tags,
193                        JniHelper::GetMethodID(env, options_class.get(),
194                                               "getUserFamiliarLanguageTags",
195                                               "()Ljava/lang/String;"));
196   TC3_ASSIGN_OR_RETURN(ScopedLocalRef<jstring> user_familiar_language_tags,
197                        JniHelper::CallObjectMethod<jstring>(
198                            env, joptions, get_user_familiar_language_tags));
199 
200   TC3_ASSIGN_OR_RETURN(classifier_options.user_familiar_language_tags,
201                        ToStlString(env, user_familiar_language_tags.get()));
202 
203   return classifier_options;
204 }
205 
FromJavaAnnotationOptions(JNIEnv * env,jobject joptions)206 StatusOr<AnnotationOptions> FromJavaAnnotationOptions(JNIEnv* env,
207                                                       jobject joptions) {
208   if (!joptions) {
209     // Falling back to default options in case joptions is null
210     AnnotationOptions default_annotation_options;
211     return default_annotation_options;
212   }
213 
214   TC3_ASSIGN_OR_RETURN(
215       ScopedLocalRef<jclass> options_class,
216       JniHelper::FindClass(env, TC3_PACKAGE_PATH TC3_ANNOTATOR_CLASS_NAME_STR
217                            "$AnnotationOptions"));
218 
219   // .getEntityTypes()
220   TC3_ASSIGN_OR_RETURN(
221       jmethodID get_entity_types,
222       JniHelper::GetMethodID(env, options_class.get(), "getEntityTypes",
223                              "()[Ljava/lang/String;"));
224   TC3_ASSIGN_OR_RETURN(
225       ScopedLocalRef<jobject> entity_types,
226       JniHelper::CallObjectMethod<jobject>(env, joptions, get_entity_types));
227 
228   // .isSerializedEntityDataEnabled()
229   TC3_ASSIGN_OR_RETURN(
230       jmethodID is_serialized_entity_data_enabled_method,
231       JniHelper::GetMethodID(env, options_class.get(),
232                              "isSerializedEntityDataEnabled", "()Z"));
233   TC3_ASSIGN_OR_RETURN(
234       bool is_serialized_entity_data_enabled,
235       JniHelper::CallBooleanMethod(env, joptions,
236                                    is_serialized_entity_data_enabled_method));
237 
238   // .hasLocationPermission()
239   TC3_ASSIGN_OR_RETURN(jmethodID has_location_permission_method,
240                        JniHelper::GetMethodID(env, options_class.get(),
241                                               "hasLocationPermission", "()Z"));
242   TC3_ASSIGN_OR_RETURN(bool has_location_permission,
243                        JniHelper::CallBooleanMethod(
244                            env, joptions, has_location_permission_method));
245 
246   // .hasPersonalizationPermission()
247   TC3_ASSIGN_OR_RETURN(
248       jmethodID has_personalization_permission_method,
249       JniHelper::GetMethodID(env, options_class.get(),
250                              "hasPersonalizationPermission", "()Z"));
251   TC3_ASSIGN_OR_RETURN(
252       bool has_personalization_permission,
253       JniHelper::CallBooleanMethod(env, joptions,
254                                    has_personalization_permission_method));
255 
256   TC3_ASSIGN_OR_RETURN(
257       AnnotationOptions annotation_options,
258       FromJavaOptionsInternal<AnnotationOptions>(
259           env, joptions,
260           TC3_PACKAGE_PATH TC3_ANNOTATOR_CLASS_NAME_STR "$AnnotationOptions"));
261   TC3_ASSIGN_OR_RETURN(annotation_options.entity_types,
262                        EntityTypesFromJObject(env, entity_types.get()));
263   annotation_options.is_serialized_entity_data_enabled =
264       is_serialized_entity_data_enabled;
265   annotation_options.permissions.has_location_permission =
266       has_location_permission;
267   annotation_options.permissions.has_personalization_permission =
268       has_personalization_permission;
269   return annotation_options;
270 }
271 
FromJavaInputFragment(JNIEnv * env,jobject jfragment)272 StatusOr<InputFragment> FromJavaInputFragment(JNIEnv* env, jobject jfragment) {
273   if (!jfragment) {
274     return Status(StatusCode::INTERNAL, "Called with null input fragment.");
275   }
276   InputFragment fragment;
277 
278   TC3_ASSIGN_OR_RETURN(
279       ScopedLocalRef<jclass> fragment_class,
280       JniHelper::FindClass(
281           env, TC3_PACKAGE_PATH TC3_ANNOTATOR_CLASS_NAME_STR "$InputFragment"));
282 
283   // .getText()
284   TC3_ASSIGN_OR_RETURN(
285       jmethodID get_text,
286       JniHelper::GetMethodID(env, fragment_class.get(), "getText",
287                              "()Ljava/lang/String;"));
288 
289   TC3_ASSIGN_OR_RETURN(
290       ScopedLocalRef<jstring> text,
291       JniHelper::CallObjectMethod<jstring>(env, jfragment, get_text));
292 
293   TC3_ASSIGN_OR_RETURN(fragment.text, ToStlString(env, text.get()));
294 
295   // .hasDatetimeOptions()
296   TC3_ASSIGN_OR_RETURN(jmethodID has_date_time_options_method,
297                        JniHelper::GetMethodID(env, fragment_class.get(),
298                                               "hasDatetimeOptions", "()Z"));
299 
300   TC3_ASSIGN_OR_RETURN(bool has_date_time_options,
301                        JniHelper::CallBooleanMethod(
302                            env, jfragment, has_date_time_options_method));
303 
304   if (has_date_time_options) {
305     // .getReferenceTimeMsUtc()
306     TC3_ASSIGN_OR_RETURN(
307         jmethodID get_reference_time_method,
308         JniHelper::GetMethodID(env, fragment_class.get(),
309                                "getReferenceTimeMsUtc", "()J"));
310 
311     TC3_ASSIGN_OR_RETURN(
312         int64 reference_time,
313         JniHelper::CallLongMethod(env, jfragment, get_reference_time_method));
314 
315     // .getReferenceTimezone()
316     TC3_ASSIGN_OR_RETURN(
317         jmethodID get_reference_timezone_method,
318         JniHelper::GetMethodID(env, fragment_class.get(),
319                                "getReferenceTimezone", "()Ljava/lang/String;"));
320 
321     TC3_ASSIGN_OR_RETURN(ScopedLocalRef<jstring> jreference_timezone,
322                          JniHelper::CallObjectMethod<jstring>(
323                              env, jfragment, get_reference_timezone_method));
324 
325     TC3_ASSIGN_OR_RETURN(std::string reference_timezone,
326                          ToStlString(env, jreference_timezone.get()));
327 
328     fragment.datetime_options =
329         DatetimeOptions{.reference_time_ms_utc = reference_time,
330                         .reference_timezone = reference_timezone};
331   }
332 
333   return fragment;
334 }
335 }  // namespace libtextclassifier3
336