diff options
author | Tony Mak <tonymak@google.com> | 2019-08-13 20:02:00 +0100 |
---|---|---|
committer | Tony Mak <tonymak@google.com> | 2019-09-02 11:28:55 +0100 |
commit | 608b1ae3ec66e3ecf5716614fc98de6318e35cc0 (patch) | |
tree | 3abc2576780304f27c97be3707b23972c935b2ea /jni | |
parent | 482594b2ec66deccf820718e411af73743cb1fe0 (diff) | |
download | libtextclassifier-608b1ae3ec66e3ecf5716614fc98de6318e35cc0.tar.gz |
Check-in initial version of TextClassifierService in external/libtc
1. Move existing native codes to native folder.
2. Move existing jni java codes to jni.
3. Copy TextClassifierService java codes to java
Three build targets are introduced:
1. TextClassifierServiceLibNoManifest:All the java codes without
AndroidManifest, will be used by ExtServices.
2. TextClassifierServiceLib: All the java codes with AndroidManifest,
used by our test and our own APK.
3. TextClassifierService: Our standalone TCS APK, mostly for our own
testing.
Test: atest TextClassifierServiceTest
Test: Install the apk, try smart selection.
Bug: 135110855
Change-Id: I17173769bc20cc36d6d16bd8ea511ecbaac4bb5d
Diffstat (limited to 'jni')
-rw-r--r-- | jni/Android.bp | 19 | ||||
-rw-r--r-- | jni/com/google/android/textclassifier/ActionsSuggestionsModel.java | 265 | ||||
-rw-r--r-- | jni/com/google/android/textclassifier/AnnotatorModel.java | 591 | ||||
-rw-r--r-- | jni/com/google/android/textclassifier/LangIdModel.java | 119 | ||||
-rw-r--r-- | jni/com/google/android/textclassifier/NamedVariant.java | 115 | ||||
-rw-r--r-- | jni/com/google/android/textclassifier/RemoteActionTemplate.java | 91 |
6 files changed, 1200 insertions, 0 deletions
diff --git a/jni/Android.bp b/jni/Android.bp new file mode 100644 index 0000000..569368e --- /dev/null +++ b/jni/Android.bp @@ -0,0 +1,19 @@ +// Copyright (C) 2019 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. + +java_library_static { + name: "libtextclassifier-java", + sdk_version: "core_current", + srcs: ["**/*.java"], +}
\ No newline at end of file diff --git a/jni/com/google/android/textclassifier/ActionsSuggestionsModel.java b/jni/com/google/android/textclassifier/ActionsSuggestionsModel.java new file mode 100644 index 0000000..9132b1f --- /dev/null +++ b/jni/com/google/android/textclassifier/ActionsSuggestionsModel.java @@ -0,0 +1,265 @@ +/* + * 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. + */ + +package com.google.android.textclassifier; + +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * Java wrapper for ActionsSuggestions native library interface. This library is used to suggest + * actions and replies in a given conversation. + * + * @hide + */ +public final class ActionsSuggestionsModel implements AutoCloseable { + private final AtomicBoolean isClosed = new AtomicBoolean(false); + + static { + System.loadLibrary("textclassifier"); + } + + private long actionsModelPtr; + + /** + * Creates a new instance of Actions predictor, using the provided model image, given as a file + * descriptor. + */ + public ActionsSuggestionsModel(int fileDescriptor, byte[] serializedPreconditions) { + actionsModelPtr = nativeNewActionsModel(fileDescriptor, serializedPreconditions); + if (actionsModelPtr == 0L) { + throw new IllegalArgumentException("Couldn't initialize actions model from file descriptor."); + } + } + + public ActionsSuggestionsModel(int fileDescriptor) { + this(fileDescriptor, /* serializedPreconditions= */ null); + } + + /** + * Creates a new instance of Actions predictor, using the provided model image, given as a file + * path. + */ + public ActionsSuggestionsModel(String path, byte[] serializedPreconditions) { + actionsModelPtr = nativeNewActionsModelFromPath(path, serializedPreconditions); + if (actionsModelPtr == 0L) { + throw new IllegalArgumentException("Couldn't initialize actions model from given file."); + } + } + + public ActionsSuggestionsModel(String path) { + this(path, /* serializedPreconditions= */ null); + } + + /** Suggests actions / replies to the given conversation. */ + public ActionSuggestion[] suggestActions( + Conversation conversation, ActionSuggestionOptions options, AnnotatorModel annotator) { + return nativeSuggestActions( + actionsModelPtr, + conversation, + options, + (annotator != null ? annotator.getNativeAnnotator() : 0), + /* appContext= */ null, + /* deviceLocales= */ null, + /* generateAndroidIntents= */ false); + } + + public ActionSuggestion[] suggestActionsWithIntents( + Conversation conversation, + ActionSuggestionOptions options, + Object appContext, + String deviceLocales, + AnnotatorModel annotator) { + return nativeSuggestActions( + actionsModelPtr, + conversation, + options, + (annotator != null ? annotator.getNativeAnnotator() : 0), + appContext, + deviceLocales, + /* generateAndroidIntents= */ true); + } + + /** Frees up the allocated memory. */ + @Override + public void close() { + if (isClosed.compareAndSet(false, true)) { + nativeCloseActionsModel(actionsModelPtr); + actionsModelPtr = 0L; + } + } + + @Override + protected void finalize() throws Throwable { + try { + close(); + } finally { + super.finalize(); + } + } + + /** Returns a comma separated list of locales supported by the model as BCP 47 tags. */ + public static String getLocales(int fd) { + return nativeGetLocales(fd); + } + + /** Returns the version of the model. */ + public static int getVersion(int fd) { + return nativeGetVersion(fd); + } + + /** Returns the name of the model. */ + public static String getName(int fd) { + return nativeGetName(fd); + } + + /** Action suggestion that contains a response text and the type of the response. */ + public static final class ActionSuggestion { + private final String responseText; + private final String actionType; + private final float score; + private final NamedVariant[] entityData; + private final byte[] serializedEntityData; + private final RemoteActionTemplate[] remoteActionTemplates; + + public ActionSuggestion( + String responseText, + String actionType, + float score, + NamedVariant[] entityData, + byte[] serializedEntityData, + RemoteActionTemplate[] remoteActionTemplates) { + this.responseText = responseText; + this.actionType = actionType; + this.score = score; + this.entityData = entityData; + this.serializedEntityData = serializedEntityData; + this.remoteActionTemplates = remoteActionTemplates; + } + + public String getResponseText() { + return responseText; + } + + public String getActionType() { + return actionType; + } + + /** Confidence score between 0 and 1 */ + public float getScore() { + return score; + } + + public NamedVariant[] getEntityData() { + return entityData; + } + + public byte[] getSerializedEntityData() { + return serializedEntityData; + } + + public RemoteActionTemplate[] getRemoteActionTemplates() { + return remoteActionTemplates; + } + } + + /** Represents a single message in the conversation. */ + public static final class ConversationMessage { + private final int userId; + private final String text; + private final long referenceTimeMsUtc; + private final String referenceTimezone; + private final String detectedTextLanguageTags; + + public ConversationMessage( + int userId, + String text, + long referenceTimeMsUtc, + String referenceTimezone, + String detectedTextLanguageTags) { + this.userId = userId; + this.text = text; + this.referenceTimeMsUtc = referenceTimeMsUtc; + this.referenceTimezone = referenceTimezone; + this.detectedTextLanguageTags = detectedTextLanguageTags; + } + + /** The identifier of the sender */ + public int getUserId() { + return userId; + } + + public String getText() { + return text; + } + + /** + * Return the reference time of the message, for example, it could be compose time or send time. + * {@code 0} means unspecified. + */ + public long getReferenceTimeMsUtc() { + return referenceTimeMsUtc; + } + + public String getReferenceTimezone() { + return referenceTimezone; + } + + /** Returns a comma separated list of BCP 47 language tags. */ + public String getDetectedTextLanguageTags() { + return detectedTextLanguageTags; + } + } + + /** Represents conversation between multiple users. */ + public static final class Conversation { + public final ConversationMessage[] conversationMessages; + + public Conversation(ConversationMessage[] conversationMessages) { + this.conversationMessages = conversationMessages; + } + + public ConversationMessage[] getConversationMessages() { + return conversationMessages; + } + } + + /** Represents options for the SuggestActions call. */ + public static final class ActionSuggestionOptions { + public ActionSuggestionOptions() {} + } + + private static native long nativeNewActionsModel(int fd, byte[] serializedPreconditions); + + private static native long nativeNewActionsModelFromPath( + String path, byte[] preconditionsOverwrite); + + private static native String nativeGetLocales(int fd); + + private static native int nativeGetVersion(int fd); + + private static native String nativeGetName(int fd); + + private native ActionSuggestion[] nativeSuggestActions( + long context, + Conversation conversation, + ActionSuggestionOptions options, + long annotatorPtr, + Object appContext, + String deviceLocales, + boolean generateAndroidIntents); + + private native void nativeCloseActionsModel(long ptr); +} diff --git a/jni/com/google/android/textclassifier/AnnotatorModel.java b/jni/com/google/android/textclassifier/AnnotatorModel.java new file mode 100644 index 0000000..5f99f74 --- /dev/null +++ b/jni/com/google/android/textclassifier/AnnotatorModel.java @@ -0,0 +1,591 @@ +/* + * 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. + */ + +package com.google.android.textclassifier; + +import java.util.Collection; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * Java wrapper for Annotator native library interface. This library is used for detecting entities + * in text. + * + * @hide + */ +public final class AnnotatorModel implements AutoCloseable { + private final AtomicBoolean isClosed = new AtomicBoolean(false); + + static { + System.loadLibrary("textclassifier"); + } + + // Keep these in sync with the constants defined in AOSP. + static final String TYPE_UNKNOWN = ""; + static final String TYPE_OTHER = "other"; + static final String TYPE_EMAIL = "email"; + static final String TYPE_PHONE = "phone"; + static final String TYPE_ADDRESS = "address"; + static final String TYPE_URL = "url"; + static final String TYPE_DATE = "date"; + static final String TYPE_DATE_TIME = "datetime"; + static final String TYPE_FLIGHT_NUMBER = "flight"; + + private long annotatorPtr; + + /** Enumeration for specifying the usecase of the annotations. */ + public static enum AnnotationUsecase { + /** Results are optimized for Smart{Select,Share,Linkify}. */ + SMART(0), + + /** + * Results are optimized for using TextClassifier as an infrastructure that annotates as much as + * possible. + */ + RAW(1); + + private final int value; + + AnnotationUsecase(int value) { + this.value = value; + } + + public int getValue() { + return value; + } + }; + + /** + * Creates a new instance of SmartSelect predictor, using the provided model image, given as a + * file descriptor. + */ + public AnnotatorModel(int fileDescriptor) { + annotatorPtr = nativeNewAnnotator(fileDescriptor); + if (annotatorPtr == 0L) { + throw new IllegalArgumentException("Couldn't initialize TC from file descriptor."); + } + } + + /** + * Creates a new instance of SmartSelect predictor, using the provided model image, given as a + * file path. + */ + public AnnotatorModel(String path) { + annotatorPtr = nativeNewAnnotatorFromPath(path); + if (annotatorPtr == 0L) { + throw new IllegalArgumentException("Couldn't initialize TC from given file."); + } + } + + /** Initializes the knowledge engine, passing the given serialized config to it. */ + public void initializeKnowledgeEngine(byte[] serializedConfig) { + if (!nativeInitializeKnowledgeEngine(annotatorPtr, serializedConfig)) { + throw new IllegalArgumentException("Couldn't initialize the KG engine"); + } + } + + /** Initializes the contact engine, passing the given serialized config to it. */ + public void initializeContactEngine(byte[] serializedConfig) { + if (!nativeInitializeContactEngine(annotatorPtr, serializedConfig)) { + throw new IllegalArgumentException("Couldn't initialize the contact engine"); + } + } + + /** Initializes the installed app engine, passing the given serialized config to it. */ + public void initializeInstalledAppEngine(byte[] serializedConfig) { + if (!nativeInitializeInstalledAppEngine(annotatorPtr, serializedConfig)) { + throw new IllegalArgumentException("Couldn't initialize the installed app engine"); + } + } + + /** + * Given a string context and current selection, computes the selection suggestion. + * + * <p>The begin and end are character indices into the context UTF8 string. selectionBegin is the + * character index where the selection begins, and selectionEnd is the index of one character past + * the selection span. + * + * <p>The return value is an array of two ints: suggested selection beginning and end, with the + * same semantics as the input selectionBeginning and selectionEnd. + */ + public int[] suggestSelection( + String context, int selectionBegin, int selectionEnd, SelectionOptions options) { + return nativeSuggestSelection(annotatorPtr, context, selectionBegin, selectionEnd, options); + } + + /** + * Given a string context and current selection, classifies the type of the selected text. + * + * <p>The begin and end params are character indices in the context string. + * + * <p>Returns an array of ClassificationResult objects with the probability scores for different + * collections. + */ + public ClassificationResult[] classifyText( + String context, int selectionBegin, int selectionEnd, ClassificationOptions options) { + return classifyText( + context, + selectionBegin, + selectionEnd, + options, + /*appContext=*/ null, + /*deviceLocales=*/ null); + } + + public ClassificationResult[] classifyText( + String context, + int selectionBegin, + int selectionEnd, + ClassificationOptions options, + Object appContext, + String deviceLocales) { + return nativeClassifyText( + annotatorPtr, context, selectionBegin, selectionEnd, options, appContext, deviceLocales); + } + + /** + * Annotates given input text. The annotations should cover the whole input context except for + * whitespaces, and are sorted by their position in the context string. + */ + public AnnotatedSpan[] annotate(String text, AnnotationOptions options) { + return nativeAnnotate(annotatorPtr, text, options); + } + + /** + * Looks up a knowledge entity by its identifier. Returns null if the entity is not found or on + * error. + */ + public byte[] lookUpKnowledgeEntity(String id) { + return nativeLookUpKnowledgeEntity(annotatorPtr, id); + } + + /** Frees up the allocated memory. */ + @Override + public void close() { + if (isClosed.compareAndSet(false, true)) { + nativeCloseAnnotator(annotatorPtr); + annotatorPtr = 0L; + } + } + + @Override + protected void finalize() throws Throwable { + try { + close(); + } finally { + super.finalize(); + } + } + + /** Returns a comma separated list of locales supported by the model as BCP 47 tags. */ + public static String getLocales(int fd) { + return nativeGetLocales(fd); + } + + /** Returns the version of the model. */ + public static int getVersion(int fd) { + return nativeGetVersion(fd); + } + + /** Returns the name of the model. */ + public static String getName(int fd) { + return nativeGetName(fd); + } + + /** Information about a parsed time/date. */ + public static final class DatetimeResult { + + public static final int GRANULARITY_YEAR = 0; + public static final int GRANULARITY_MONTH = 1; + public static final int GRANULARITY_WEEK = 2; + public static final int GRANULARITY_DAY = 3; + public static final int GRANULARITY_HOUR = 4; + public static final int GRANULARITY_MINUTE = 5; + public static final int GRANULARITY_SECOND = 6; + + private final long timeMsUtc; + private final int granularity; + + public DatetimeResult(long timeMsUtc, int granularity) { + this.timeMsUtc = timeMsUtc; + this.granularity = granularity; + } + + public long getTimeMsUtc() { + return timeMsUtc; + } + + public int getGranularity() { + return granularity; + } + } + + /** Classification result for classifyText method. */ + public static final class ClassificationResult { + private final String collection; + private final float score; + private final DatetimeResult datetimeResult; + private final byte[] serializedKnowledgeResult; + private final String contactName; + private final String contactGivenName; + private final String contactNickname; + private final String contactEmailAddress; + private final String contactPhoneNumber; + private final String contactId; + private final String appName; + private final String appPackageName; + private final NamedVariant[] entityData; + private final byte[] serializedEntityData; + private final RemoteActionTemplate[] remoteActionTemplates; + private final long durationMs; + private final long numericValue; + + public ClassificationResult( + String collection, + float score, + DatetimeResult datetimeResult, + byte[] serializedKnowledgeResult, + String contactName, + String contactGivenName, + String contactNickname, + String contactEmailAddress, + String contactPhoneNumber, + String contactId, + String appName, + String appPackageName, + NamedVariant[] entityData, + byte[] serializedEntityData, + RemoteActionTemplate[] remoteActionTemplates, + long durationMs, + long numericValue) { + this.collection = collection; + this.score = score; + this.datetimeResult = datetimeResult; + this.serializedKnowledgeResult = serializedKnowledgeResult; + this.contactName = contactName; + this.contactGivenName = contactGivenName; + this.contactNickname = contactNickname; + this.contactEmailAddress = contactEmailAddress; + this.contactPhoneNumber = contactPhoneNumber; + this.contactId = contactId; + this.appName = appName; + this.appPackageName = appPackageName; + this.entityData = entityData; + this.serializedEntityData = serializedEntityData; + this.remoteActionTemplates = remoteActionTemplates; + this.durationMs = durationMs; + this.numericValue = numericValue; + } + + /** Returns the classified entity type. */ + public String getCollection() { + return collection; + } + + /** Confidence score between 0 and 1. */ + public float getScore() { + return score; + } + + public DatetimeResult getDatetimeResult() { + return datetimeResult; + } + + public byte[] getSerializedKnowledgeResult() { + return serializedKnowledgeResult; + } + + public String getContactName() { + return contactName; + } + + public String getContactGivenName() { + return contactGivenName; + } + + public String getContactNickname() { + return contactNickname; + } + + public String getContactEmailAddress() { + return contactEmailAddress; + } + + public String getContactPhoneNumber() { + return contactPhoneNumber; + } + + public String getContactId() { + return contactId; + } + + public String getAppName() { + return appName; + } + + public String getAppPackageName() { + return appPackageName; + } + + public NamedVariant[] getEntityData() { + return entityData; + } + + public byte[] getSerializedEntityData() { + return serializedEntityData; + } + + public RemoteActionTemplate[] getRemoteActionTemplates() { + return remoteActionTemplates; + } + + public long getDurationMs() { + return durationMs; + } + + public long getNumericValue() { + return numericValue; + } + } + + /** Represents a result of Annotate call. */ + public static final class AnnotatedSpan { + private final int startIndex; + private final int endIndex; + private final ClassificationResult[] classification; + + AnnotatedSpan(int startIndex, int endIndex, ClassificationResult[] classification) { + this.startIndex = startIndex; + this.endIndex = endIndex; + this.classification = classification; + } + + public int getStartIndex() { + return startIndex; + } + + public int getEndIndex() { + return endIndex; + } + + public ClassificationResult[] getClassification() { + return classification; + } + } + + /** Represents options for the suggestSelection call. */ + public static final class SelectionOptions { + private final String locales; + private final String detectedTextLanguageTags; + private final int annotationUsecase; + + public SelectionOptions( + String locales, String detectedTextLanguageTags, int annotationUsecase) { + this.locales = locales; + this.detectedTextLanguageTags = detectedTextLanguageTags; + this.annotationUsecase = annotationUsecase; + } + + public SelectionOptions(String locales, String detectedTextLanguageTags) { + this(locales, detectedTextLanguageTags, AnnotationUsecase.SMART.getValue()); + } + + public String getLocales() { + return locales; + } + + /** Returns a comma separated list of BCP 47 language tags. */ + public String getDetectedTextLanguageTags() { + return detectedTextLanguageTags; + } + + public int getAnnotationUsecase() { + return annotationUsecase; + } + } + + /** Represents options for the classifyText call. */ + public static final class ClassificationOptions { + private final long referenceTimeMsUtc; + private final String referenceTimezone; + private final String locales; + private final String detectedTextLanguageTags; + private final int annotationUsecase; + + public ClassificationOptions( + long referenceTimeMsUtc, + String referenceTimezone, + String locales, + String detectedTextLanguageTags, + int annotationUsecase) { + this.referenceTimeMsUtc = referenceTimeMsUtc; + this.referenceTimezone = referenceTimezone; + this.locales = locales; + this.detectedTextLanguageTags = detectedTextLanguageTags; + this.annotationUsecase = annotationUsecase; + } + + public ClassificationOptions( + long referenceTimeMsUtc, + String referenceTimezone, + String locales, + String detectedTextLanguageTags) { + this( + referenceTimeMsUtc, + referenceTimezone, + locales, + detectedTextLanguageTags, + AnnotationUsecase.SMART.getValue()); + } + + public long getReferenceTimeMsUtc() { + return referenceTimeMsUtc; + } + + public String getReferenceTimezone() { + return referenceTimezone; + } + + public String getLocale() { + return locales; + } + + /** Returns a comma separated list of BCP 47 language tags. */ + public String getDetectedTextLanguageTags() { + return detectedTextLanguageTags; + } + + public int getAnnotationUsecase() { + return annotationUsecase; + } + } + + /** Represents options for the annotate call. */ + public static final class AnnotationOptions { + private final long referenceTimeMsUtc; + private final String referenceTimezone; + private final String locales; + private final String detectedTextLanguageTags; + private final String[] entityTypes; + private final int annotationUsecase; + private final boolean isSerializedEntityDataEnabled; + + public AnnotationOptions( + long referenceTimeMsUtc, + String referenceTimezone, + String locales, + String detectedTextLanguageTags, + Collection<String> entityTypes, + int annotationUsecase, + boolean isSerializedEntityDataEnabled) { + this.referenceTimeMsUtc = referenceTimeMsUtc; + this.referenceTimezone = referenceTimezone; + this.locales = locales; + this.detectedTextLanguageTags = detectedTextLanguageTags; + this.entityTypes = entityTypes == null ? new String[0] : entityTypes.toArray(new String[0]); + this.annotationUsecase = annotationUsecase; + this.isSerializedEntityDataEnabled = isSerializedEntityDataEnabled; + } + + public AnnotationOptions( + long referenceTimeMsUtc, + String referenceTimezone, + String locales, + String detectedTextLanguageTags) { + this( + referenceTimeMsUtc, + referenceTimezone, + locales, + detectedTextLanguageTags, + null, + AnnotationUsecase.SMART.getValue(), + /* isSerializedEntityDataEnabled */ false); + } + + public long getReferenceTimeMsUtc() { + return referenceTimeMsUtc; + } + + public String getReferenceTimezone() { + return referenceTimezone; + } + + public String getLocale() { + return locales; + } + + /** Returns a comma separated list of BCP 47 language tags. */ + public String getDetectedTextLanguageTags() { + return detectedTextLanguageTags; + } + + public String[] getEntityTypes() { + return entityTypes; + } + + public int getAnnotationUsecase() { + return annotationUsecase; + } + + public boolean isSerializedEntityDataEnabled() { + return isSerializedEntityDataEnabled; + } + } + + /** + * Retrieves the pointer to the native object. Note: Need to keep the AnnotatorModel alive as long + * as the pointer is used. + */ + long getNativeAnnotator() { + return nativeGetNativeModelPtr(annotatorPtr); + } + + private static native long nativeNewAnnotator(int fd); + + private static native long nativeNewAnnotatorFromPath(String path); + + private static native String nativeGetLocales(int fd); + + private static native int nativeGetVersion(int fd); + + private static native String nativeGetName(int fd); + + private native long nativeGetNativeModelPtr(long context); + + private native boolean nativeInitializeKnowledgeEngine(long context, byte[] serializedConfig); + + private native boolean nativeInitializeContactEngine(long context, byte[] serializedConfig); + + private native boolean nativeInitializeInstalledAppEngine(long context, byte[] serializedConfig); + + private native int[] nativeSuggestSelection( + long context, String text, int selectionBegin, int selectionEnd, SelectionOptions options); + + private native ClassificationResult[] nativeClassifyText( + long context, + String text, + int selectionBegin, + int selectionEnd, + ClassificationOptions options, + Object appContext, + String deviceLocales); + + private native AnnotatedSpan[] nativeAnnotate( + long context, String text, AnnotationOptions options); + + private native byte[] nativeLookUpKnowledgeEntity(long context, String id); + + private native void nativeCloseAnnotator(long context); +} diff --git a/jni/com/google/android/textclassifier/LangIdModel.java b/jni/com/google/android/textclassifier/LangIdModel.java new file mode 100644 index 0000000..d3e166f --- /dev/null +++ b/jni/com/google/android/textclassifier/LangIdModel.java @@ -0,0 +1,119 @@ +/* + * 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. + */ + +package com.google.android.textclassifier; + +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * Java wrapper for LangId native library interface. This class is used to detect languages in text. + * + * @hide + */ +public final class LangIdModel implements AutoCloseable { + private final AtomicBoolean isClosed = new AtomicBoolean(false); + + static { + System.loadLibrary("textclassifier"); + } + + private long modelPtr; + + /** Creates a new instance of LangId predictor, using the provided model image. */ + public LangIdModel(int fd) { + modelPtr = nativeNew(fd); + if (modelPtr == 0L) { + throw new IllegalArgumentException("Couldn't initialize LangId from given file descriptor."); + } + } + + /** Creates a new instance of LangId predictor, using the provided model image. */ + public LangIdModel(String modelPath) { + modelPtr = nativeNewFromPath(modelPath); + if (modelPtr == 0L) { + throw new IllegalArgumentException("Couldn't initialize LangId from given file."); + } + } + + /** Detects the languages for given text. */ + public LanguageResult[] detectLanguages(String text) { + return nativeDetectLanguages(modelPtr, text); + } + + /** Frees up the allocated memory. */ + @Override + public void close() { + if (isClosed.compareAndSet(false, true)) { + nativeClose(modelPtr); + modelPtr = 0L; + } + } + + @Override + protected void finalize() throws Throwable { + try { + close(); + } finally { + super.finalize(); + } + } + + /** Result for detectLanguages method. */ + public static final class LanguageResult { + final String mLanguage; + final float mScore; + + LanguageResult(String language, float score) { + mLanguage = language; + mScore = score; + } + + public final String getLanguage() { + return mLanguage; + } + + public final float getScore() { + return mScore; + } + } + + /** Returns the version of the LangId model used. */ + public int getVersion() { + return nativeGetVersion(modelPtr); + } + + public float getLangIdThreshold() { + return nativeGetLangIdThreshold(modelPtr); + } + + public static int getVersion(int fd) { + return nativeGetVersionFromFd(fd); + } + + private static native long nativeNew(int fd); + + private static native long nativeNewFromPath(String path); + + private native LanguageResult[] nativeDetectLanguages(long nativePtr, String text); + + private native void nativeClose(long nativePtr); + + private native int nativeGetVersion(long nativePtr); + + private static native int nativeGetVersionFromFd(int fd); + + private native float nativeGetLangIdThreshold(long nativePtr); +} diff --git a/jni/com/google/android/textclassifier/NamedVariant.java b/jni/com/google/android/textclassifier/NamedVariant.java new file mode 100644 index 0000000..d04bb11 --- /dev/null +++ b/jni/com/google/android/textclassifier/NamedVariant.java @@ -0,0 +1,115 @@ +/* + * 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. + */ + +package com.google.android.textclassifier; + +/** + * Represents a union of different basic types. + * + * @hide + */ +public final class NamedVariant { + public static final int TYPE_EMPTY = 0; + public static final int TYPE_INT = 1; + public static final int TYPE_LONG = 2; + public static final int TYPE_FLOAT = 3; + public static final int TYPE_DOUBLE = 4; + public static final int TYPE_BOOL = 5; + public static final int TYPE_STRING = 6; + + public NamedVariant(String name, int value) { + this.name = name; + this.intValue = value; + this.type = TYPE_INT; + } + + public NamedVariant(String name, long value) { + this.name = name; + this.longValue = value; + this.type = TYPE_LONG; + } + + public NamedVariant(String name, float value) { + this.name = name; + this.floatValue = value; + this.type = TYPE_FLOAT; + } + + public NamedVariant(String name, double value) { + this.name = name; + this.doubleValue = value; + this.type = TYPE_DOUBLE; + } + + public NamedVariant(String name, boolean value) { + this.name = name; + this.boolValue = value; + this.type = TYPE_BOOL; + } + + public NamedVariant(String name, String value) { + this.name = name; + this.stringValue = value; + this.type = TYPE_STRING; + } + + public String getName() { + return name; + } + + public int getType() { + return type; + } + + public int getInt() { + assert (type == TYPE_INT); + return intValue; + } + + public long getLong() { + assert (type == TYPE_LONG); + return longValue; + } + + public float getFloat() { + assert (type == TYPE_FLOAT); + return floatValue; + } + + public double getDouble() { + assert (type == TYPE_DOUBLE); + return doubleValue; + } + + public boolean getBool() { + assert (type == TYPE_BOOL); + return boolValue; + } + + public String getString() { + assert (type == TYPE_STRING); + return stringValue; + } + + private final String name; + private final int type; + private int intValue; + private long longValue; + private float floatValue; + private double doubleValue; + private boolean boolValue; + private String stringValue; +} diff --git a/jni/com/google/android/textclassifier/RemoteActionTemplate.java b/jni/com/google/android/textclassifier/RemoteActionTemplate.java new file mode 100644 index 0000000..308d809 --- /dev/null +++ b/jni/com/google/android/textclassifier/RemoteActionTemplate.java @@ -0,0 +1,91 @@ +/* + * 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. + */ + +package com.google.android.textclassifier; + +/** + * Represents a template for an Android RemoteAction. + * + * @hide + */ +public final class RemoteActionTemplate { + /** Title shown for the action (see: RemoteAction.getTitle). */ + public final String titleWithoutEntity; + + /** Title with entity for the action. */ + public final String titleWithEntity; + + /** Description shown for the action (see: RemoteAction.getContentDescription). */ + public final String description; + + /** + * Description shown for the action (see: RemoteAction.getContentDescription) when app name is + * available. Caller is expected to replace the placeholder by the name of the app that is going + * to handle the action. + */ + public final String descriptionWithAppName; + + /** The action to set on the Intent (see: Intent.setAction). */ + public final String action; + + /** The data to set on the Intent (see: Intent.setData). */ + public final String data; + + /** The type to set on the Intent (see: Intent.setType). */ + public final String type; + + /** Flags for launching the Intent (see: Intent.setFlags). */ + public final Integer flags; + + /** Categories to set on the Intent (see: Intent.addCategory). */ + public final String[] category; + + /** Explicit application package to set on the Intent (see: Intent.setPackage). */ + public final String packageName; + + /** The list of all the extras to add to the Intent. */ + public final NamedVariant[] extras; + + /** Private request code to use for the Intent. */ + public final Integer requestCode; + + public RemoteActionTemplate( + String titleWithoutEntity, + String titleWithEntity, + String description, + String descriptionWithAppName, + String action, + String data, + String type, + Integer flags, + String[] category, + String packageName, + NamedVariant[] extras, + Integer requestCode) { + this.titleWithoutEntity = titleWithoutEntity; + this.titleWithEntity = titleWithEntity; + this.description = description; + this.descriptionWithAppName = descriptionWithAppName; + this.action = action; + this.data = data; + this.type = type; + this.flags = flags; + this.category = category; + this.packageName = packageName; + this.extras = extras; + this.requestCode = requestCode; + } +} |