blob: a6f636f4cc8b0312731b4b515d0333bccc6076b3 [file] [log] [blame]
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "annotator/annotator_jni_common.h"
#include "annotator/knowledge/knowledge-engine-types.h"
#include "utils/java/jni-base.h"
#include "utils/java/jni-helper.h"
namespace libtextclassifier3 {
namespace {
StatusOr<std::unordered_set<std::string>> EntityTypesFromJObject(
JNIEnv* env, const jobject& jobject) {
std::unordered_set<std::string> entity_types;
jobjectArray jentity_types = reinterpret_cast<jobjectArray>(jobject);
TC3_ASSIGN_OR_RETURN(const int size,
JniHelper::GetArrayLength(env, jentity_types));
for (int i = 0; i < size; ++i) {
TC3_ASSIGN_OR_RETURN(
ScopedLocalRef<jstring> jentity_type,
JniHelper::GetObjectArrayElement<jstring>(env, jentity_types, i));
TC3_ASSIGN_OR_RETURN(std::string entity_type,
JStringToUtf8String(env, jentity_type.get()));
entity_types.insert(entity_type);
}
return entity_types;
}
template <typename T>
StatusOr<T> FromJavaOptionsInternal(JNIEnv* env, jobject joptions,
const std::string& class_name) {
if (!joptions) {
return {Status::UNKNOWN};
}
TC3_ASSIGN_OR_RETURN(ScopedLocalRef<jclass> options_class,
JniHelper::FindClass(env, class_name.c_str()));
// .getLocale()
TC3_ASSIGN_OR_RETURN(
jmethodID get_locale,
JniHelper::GetMethodID(env, options_class.get(), "getLocale",
"()Ljava/lang/String;"));
TC3_ASSIGN_OR_RETURN(
ScopedLocalRef<jstring> locales,
JniHelper::CallObjectMethod<jstring>(env, joptions, get_locale));
// .getReferenceTimeMsUtc()
TC3_ASSIGN_OR_RETURN(jmethodID get_reference_time_method,
JniHelper::GetMethodID(env, options_class.get(),
"getReferenceTimeMsUtc", "()J"));
TC3_ASSIGN_OR_RETURN(
int64 reference_time,
JniHelper::CallLongMethod(env, joptions, get_reference_time_method));
// .getReferenceTimezone()
TC3_ASSIGN_OR_RETURN(
jmethodID get_reference_timezone_method,
JniHelper::GetMethodID(env, options_class.get(), "getReferenceTimezone",
"()Ljava/lang/String;"));
TC3_ASSIGN_OR_RETURN(ScopedLocalRef<jstring> reference_timezone,
JniHelper::CallObjectMethod<jstring>(
env, joptions, get_reference_timezone_method));
// .getDetectedTextLanguageTags()
TC3_ASSIGN_OR_RETURN(jmethodID get_detected_text_language_tags_method,
JniHelper::GetMethodID(env, options_class.get(),
"getDetectedTextLanguageTags",
"()Ljava/lang/String;"));
TC3_ASSIGN_OR_RETURN(
ScopedLocalRef<jstring> detected_text_language_tags,
JniHelper::CallObjectMethod<jstring>(
env, joptions, get_detected_text_language_tags_method));
// .getAnnotationUsecase()
TC3_ASSIGN_OR_RETURN(jmethodID get_annotation_usecase,
JniHelper::GetMethodID(env, options_class.get(),
"getAnnotationUsecase", "()I"));
TC3_ASSIGN_OR_RETURN(
int32 annotation_usecase,
JniHelper::CallIntMethod(env, joptions, get_annotation_usecase));
// .getUserLocationLat()
TC3_ASSIGN_OR_RETURN(jmethodID get_user_location_lat,
JniHelper::GetMethodID(env, options_class.get(),
"getUserLocationLat", "()D"));
TC3_ASSIGN_OR_RETURN(
double user_location_lat,
JniHelper::CallDoubleMethod(env, joptions, get_user_location_lat));
// .getUserLocationLng()
TC3_ASSIGN_OR_RETURN(jmethodID get_user_location_lng,
JniHelper::GetMethodID(env, options_class.get(),
"getUserLocationLng", "()D"));
TC3_ASSIGN_OR_RETURN(
double user_location_lng,
JniHelper::CallDoubleMethod(env, joptions, get_user_location_lng));
// .getUserLocationAccuracyMeters()
TC3_ASSIGN_OR_RETURN(
jmethodID get_user_location_accuracy_meters,
JniHelper::GetMethodID(env, options_class.get(),
"getUserLocationAccuracyMeters", "()F"));
TC3_ASSIGN_OR_RETURN(float user_location_accuracy_meters,
JniHelper::CallFloatMethod(
env, joptions, get_user_location_accuracy_meters));
// .getUsePodNer()
TC3_ASSIGN_OR_RETURN(
jmethodID get_use_pod_ner,
JniHelper::GetMethodID(env, options_class.get(), "getUsePodNer", "()Z"));
TC3_ASSIGN_OR_RETURN(bool use_pod_ner, JniHelper::CallBooleanMethod(
env, joptions, get_use_pod_ner));
// .getUseVocabAnnotator()
TC3_ASSIGN_OR_RETURN(jmethodID get_use_vocab_annotator,
JniHelper::GetMethodID(env, options_class.get(),
"getUseVocabAnnotator", "()Z"));
TC3_ASSIGN_OR_RETURN(
bool use_vocab_annotator,
JniHelper::CallBooleanMethod(env, joptions, get_use_vocab_annotator));
T options;
TC3_ASSIGN_OR_RETURN(options.locales,
JStringToUtf8String(env, locales.get()));
TC3_ASSIGN_OR_RETURN(options.reference_timezone,
JStringToUtf8String(env, reference_timezone.get()));
options.reference_time_ms_utc = reference_time;
TC3_ASSIGN_OR_RETURN(
options.detected_text_language_tags,
JStringToUtf8String(env, detected_text_language_tags.get()));
options.annotation_usecase =
static_cast<AnnotationUsecase>(annotation_usecase);
options.location_context = {user_location_lat, user_location_lng,
user_location_accuracy_meters};
options.use_pod_ner = use_pod_ner;
options.use_vocab_annotator = use_vocab_annotator;
return options;
}
} // namespace
StatusOr<SelectionOptions> FromJavaSelectionOptions(JNIEnv* env,
jobject joptions) {
if (!joptions) {
// Falling back to default options in case joptions is null
SelectionOptions default_selection_options;
return default_selection_options;
}
TC3_ASSIGN_OR_RETURN(
ScopedLocalRef<jclass> options_class,
JniHelper::FindClass(env, TC3_PACKAGE_PATH TC3_ANNOTATOR_CLASS_NAME_STR
"$SelectionOptions"));
// .getLocale()
TC3_ASSIGN_OR_RETURN(
jmethodID get_locales,
JniHelper::GetMethodID(env, options_class.get(), "getLocales",
"()Ljava/lang/String;"));
TC3_ASSIGN_OR_RETURN(
ScopedLocalRef<jstring> locales,
JniHelper::CallObjectMethod<jstring>(env, joptions, get_locales));
// .getDetectedTextLanguageTags()
TC3_ASSIGN_OR_RETURN(jmethodID get_detected_text_language_tags_method,
JniHelper::GetMethodID(env, options_class.get(),
"getDetectedTextLanguageTags",
"()Ljava/lang/String;"));
TC3_ASSIGN_OR_RETURN(
ScopedLocalRef<jstring> detected_text_language_tags,
JniHelper::CallObjectMethod<jstring>(
env, joptions, get_detected_text_language_tags_method));
// .getAnnotationUsecase()
TC3_ASSIGN_OR_RETURN(jmethodID get_annotation_usecase,
JniHelper::GetMethodID(env, options_class.get(),
"getAnnotationUsecase", "()I"));
TC3_ASSIGN_OR_RETURN(
int32 annotation_usecase,
JniHelper::CallIntMethod(env, joptions, get_annotation_usecase));
// .getUserLocationLat()
TC3_ASSIGN_OR_RETURN(jmethodID get_user_location_lat,
JniHelper::GetMethodID(env, options_class.get(),
"getUserLocationLat", "()D"));
TC3_ASSIGN_OR_RETURN(
double user_location_lat,
JniHelper::CallDoubleMethod(env, joptions, get_user_location_lat));
// .getUserLocationLng()
TC3_ASSIGN_OR_RETURN(jmethodID get_user_location_lng,
JniHelper::GetMethodID(env, options_class.get(),
"getUserLocationLng", "()D"));
TC3_ASSIGN_OR_RETURN(
double user_location_lng,
JniHelper::CallDoubleMethod(env, joptions, get_user_location_lng));
// .getUserLocationAccuracyMeters()
TC3_ASSIGN_OR_RETURN(
jmethodID get_user_location_accuracy_meters,
JniHelper::GetMethodID(env, options_class.get(),
"getUserLocationAccuracyMeters", "()F"));
TC3_ASSIGN_OR_RETURN(float user_location_accuracy_meters,
JniHelper::CallFloatMethod(
env, joptions, get_user_location_accuracy_meters));
// .getUsePodNer()
TC3_ASSIGN_OR_RETURN(
jmethodID get_use_pod_ner,
JniHelper::GetMethodID(env, options_class.get(), "getUsePodNer", "()Z"));
TC3_ASSIGN_OR_RETURN(bool use_pod_ner, JniHelper::CallBooleanMethod(
env, joptions, get_use_pod_ner));
SelectionOptions options;
TC3_ASSIGN_OR_RETURN(options.locales,
JStringToUtf8String(env, locales.get()));
options.annotation_usecase =
static_cast<AnnotationUsecase>(annotation_usecase);
TC3_ASSIGN_OR_RETURN(
options.detected_text_language_tags,
JStringToUtf8String(env, detected_text_language_tags.get()));
options.location_context = {user_location_lat, user_location_lng,
user_location_accuracy_meters};
options.use_pod_ner = use_pod_ner;
return options;
}
StatusOr<ClassificationOptions> FromJavaClassificationOptions(
JNIEnv* env, jobject joptions) {
if (!joptions) {
// Falling back to default options in case joptions is null
ClassificationOptions default_classification_options;
return default_classification_options;
}
TC3_ASSIGN_OR_RETURN(ClassificationOptions classifier_options,
FromJavaOptionsInternal<ClassificationOptions>(
env, joptions,
TC3_PACKAGE_PATH TC3_ANNOTATOR_CLASS_NAME_STR
"$ClassificationOptions"));
TC3_ASSIGN_OR_RETURN(
ScopedLocalRef<jclass> options_class,
JniHelper::FindClass(env, TC3_PACKAGE_PATH TC3_ANNOTATOR_CLASS_NAME_STR
"$ClassificationOptions"));
// .getUserFamiliarLanguageTags()
TC3_ASSIGN_OR_RETURN(jmethodID get_user_familiar_language_tags,
JniHelper::GetMethodID(env, options_class.get(),
"getUserFamiliarLanguageTags",
"()Ljava/lang/String;"));
TC3_ASSIGN_OR_RETURN(ScopedLocalRef<jstring> user_familiar_language_tags,
JniHelper::CallObjectMethod<jstring>(
env, joptions, get_user_familiar_language_tags));
TC3_ASSIGN_OR_RETURN(
classifier_options.user_familiar_language_tags,
JStringToUtf8String(env, user_familiar_language_tags.get()));
// .getTriggerDictionaryOnBeginnerWords()
TC3_ASSIGN_OR_RETURN(
jmethodID get_trigger_dictionary_on_beginner_words,
JniHelper::GetMethodID(env, options_class.get(),
"getTriggerDictionaryOnBeginnerWords", "()Z"));
TC3_ASSIGN_OR_RETURN(
classifier_options.trigger_dictionary_on_beginner_words,
JniHelper::CallBooleanMethod(env, joptions,
get_trigger_dictionary_on_beginner_words));
return classifier_options;
}
StatusOr<AnnotationOptions> FromJavaAnnotationOptions(JNIEnv* env,
jobject joptions) {
if (!joptions) {
// Falling back to default options in case joptions is null
AnnotationOptions default_annotation_options;
return default_annotation_options;
}
TC3_ASSIGN_OR_RETURN(
ScopedLocalRef<jclass> options_class,
JniHelper::FindClass(env, TC3_PACKAGE_PATH TC3_ANNOTATOR_CLASS_NAME_STR
"$AnnotationOptions"));
// .getEntityTypes()
TC3_ASSIGN_OR_RETURN(
jmethodID get_entity_types,
JniHelper::GetMethodID(env, options_class.get(), "getEntityTypes",
"()[Ljava/lang/String;"));
TC3_ASSIGN_OR_RETURN(
ScopedLocalRef<jobject> entity_types,
JniHelper::CallObjectMethod<jobject>(env, joptions, get_entity_types));
// .isSerializedEntityDataEnabled()
TC3_ASSIGN_OR_RETURN(
jmethodID is_serialized_entity_data_enabled_method,
JniHelper::GetMethodID(env, options_class.get(),
"isSerializedEntityDataEnabled", "()Z"));
TC3_ASSIGN_OR_RETURN(
bool is_serialized_entity_data_enabled,
JniHelper::CallBooleanMethod(env, joptions,
is_serialized_entity_data_enabled_method));
// .hasLocationPermission()
TC3_ASSIGN_OR_RETURN(jmethodID has_location_permission_method,
JniHelper::GetMethodID(env, options_class.get(),
"hasLocationPermission", "()Z"));
TC3_ASSIGN_OR_RETURN(bool has_location_permission,
JniHelper::CallBooleanMethod(
env, joptions, has_location_permission_method));
// .hasPersonalizationPermission()
TC3_ASSIGN_OR_RETURN(
jmethodID has_personalization_permission_method,
JniHelper::GetMethodID(env, options_class.get(),
"hasPersonalizationPermission", "()Z"));
TC3_ASSIGN_OR_RETURN(
bool has_personalization_permission,
JniHelper::CallBooleanMethod(env, joptions,
has_personalization_permission_method));
// .getAnnotateMode()
TC3_ASSIGN_OR_RETURN(jmethodID get_annotate_mode,
JniHelper::GetMethodID(env, options_class.get(),
"getAnnotateMode", "()I"));
TC3_ASSIGN_OR_RETURN(
int32 annotate_mode,
JniHelper::CallIntMethod(env, joptions, get_annotate_mode));
TC3_ASSIGN_OR_RETURN(
AnnotationOptions annotation_options,
FromJavaOptionsInternal<AnnotationOptions>(
env, joptions,
TC3_PACKAGE_PATH TC3_ANNOTATOR_CLASS_NAME_STR "$AnnotationOptions"));
TC3_ASSIGN_OR_RETURN(annotation_options.entity_types,
EntityTypesFromJObject(env, entity_types.get()));
annotation_options.is_serialized_entity_data_enabled =
is_serialized_entity_data_enabled;
annotation_options.permissions.has_location_permission =
has_location_permission;
annotation_options.permissions.has_personalization_permission =
has_personalization_permission;
annotation_options.annotate_mode = static_cast<AnnotateMode>(annotate_mode);
// .getTriggerDictionaryOnBeginnerWords()
TC3_ASSIGN_OR_RETURN(
jmethodID get_trigger_dictionary_on_beginner_words,
JniHelper::GetMethodID(env, options_class.get(),
"getTriggerDictionaryOnBeginnerWords", "()Z"));
TC3_ASSIGN_OR_RETURN(
annotation_options.trigger_dictionary_on_beginner_words,
JniHelper::CallBooleanMethod(env, joptions,
get_trigger_dictionary_on_beginner_words));
return annotation_options;
}
StatusOr<InputFragment> FromJavaInputFragment(JNIEnv* env, jobject jfragment) {
if (!jfragment) {
return Status(StatusCode::INTERNAL, "Called with null input fragment.");
}
InputFragment fragment;
TC3_ASSIGN_OR_RETURN(
ScopedLocalRef<jclass> fragment_class,
JniHelper::FindClass(
env, TC3_PACKAGE_PATH TC3_ANNOTATOR_CLASS_NAME_STR "$InputFragment"));
// .getText()
TC3_ASSIGN_OR_RETURN(
jmethodID get_text,
JniHelper::GetMethodID(env, fragment_class.get(), "getText",
"()Ljava/lang/String;"));
TC3_ASSIGN_OR_RETURN(
ScopedLocalRef<jstring> text,
JniHelper::CallObjectMethod<jstring>(env, jfragment, get_text));
TC3_ASSIGN_OR_RETURN(fragment.text, JStringToUtf8String(env, text.get()));
// .hasDatetimeOptions()
TC3_ASSIGN_OR_RETURN(jmethodID has_date_time_options_method,
JniHelper::GetMethodID(env, fragment_class.get(),
"hasDatetimeOptions", "()Z"));
TC3_ASSIGN_OR_RETURN(bool has_date_time_options,
JniHelper::CallBooleanMethod(
env, jfragment, has_date_time_options_method));
if (has_date_time_options) {
// .getReferenceTimeMsUtc()
TC3_ASSIGN_OR_RETURN(
jmethodID get_reference_time_method,
JniHelper::GetMethodID(env, fragment_class.get(),
"getReferenceTimeMsUtc", "()J"));
TC3_ASSIGN_OR_RETURN(
int64 reference_time,
JniHelper::CallLongMethod(env, jfragment, get_reference_time_method));
// .getReferenceTimezone()
TC3_ASSIGN_OR_RETURN(
jmethodID get_reference_timezone_method,
JniHelper::GetMethodID(env, fragment_class.get(),
"getReferenceTimezone", "()Ljava/lang/String;"));
TC3_ASSIGN_OR_RETURN(ScopedLocalRef<jstring> jreference_timezone,
JniHelper::CallObjectMethod<jstring>(
env, jfragment, get_reference_timezone_method));
TC3_ASSIGN_OR_RETURN(std::string reference_timezone,
JStringToUtf8String(env, jreference_timezone.get()));
fragment.datetime_options =
DatetimeOptions{.reference_time_ms_utc = reference_time,
.reference_timezone = reference_timezone};
}
// .getBoundingBoxHeight()
TC3_ASSIGN_OR_RETURN(jmethodID get_bounding_box_height,
JniHelper::GetMethodID(env, fragment_class.get(),
"getBoundingBoxHeight", "()F"));
TC3_ASSIGN_OR_RETURN(
float bounding_box_height,
JniHelper::CallFloatMethod(env, jfragment, get_bounding_box_height));
fragment.bounding_box_height = bounding_box_height;
// .getBoundingBoxTop()
TC3_ASSIGN_OR_RETURN(jmethodID get_bounding_box_top,
JniHelper::GetMethodID(env, fragment_class.get(),
"getBoundingBoxTop", "()F"));
TC3_ASSIGN_OR_RETURN(
float bounding_box_top,
JniHelper::CallFloatMethod(env, jfragment, get_bounding_box_top));
fragment.bounding_box_top = bounding_box_top;
return fragment;
}
} // namespace libtextclassifier3