summaryrefslogtreecommitdiff
path: root/android/view/textclassifier
diff options
context:
space:
mode:
Diffstat (limited to 'android/view/textclassifier')
-rw-r--r--android/view/textclassifier/Log.java46
-rw-r--r--android/view/textclassifier/SmartSelection.java63
-rw-r--r--android/view/textclassifier/TextClassifier.java8
-rw-r--r--android/view/textclassifier/TextClassifierConstants.java90
-rw-r--r--android/view/textclassifier/TextClassifierImpl.java17
5 files changed, 221 insertions, 3 deletions
diff --git a/android/view/textclassifier/Log.java b/android/view/textclassifier/Log.java
new file mode 100644
index 00000000..83ca15df
--- /dev/null
+++ b/android/view/textclassifier/Log.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2017 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 android.view.textclassifier;
+
+import android.util.Slog;
+
+/**
+ * Logging for android.view.textclassifier package.
+ */
+final class Log {
+
+ /**
+ * true: Enables full logging.
+ * false: Limits logging to debug level.
+ */
+ private static final boolean ENABLE_FULL_LOGGING = false;
+
+ private Log() {}
+
+ public static void d(String tag, String msg) {
+ Slog.d(tag, msg);
+ }
+
+ public static void e(String tag, String msg, Throwable tr) {
+ if (ENABLE_FULL_LOGGING) {
+ Slog.e(tag, msg, tr);
+ } else {
+ final String trString = (tr != null) ? tr.getClass().getSimpleName() : "??";
+ Slog.d(tag, String.format("%s (%s)", msg, trString));
+ }
+ }
+}
diff --git a/android/view/textclassifier/SmartSelection.java b/android/view/textclassifier/SmartSelection.java
index f0e83d1f..2c93a19b 100644
--- a/android/view/textclassifier/SmartSelection.java
+++ b/android/view/textclassifier/SmartSelection.java
@@ -16,6 +16,8 @@
package android.view.textclassifier;
+import android.content.res.AssetFileDescriptor;
+
/**
* Java wrapper for SmartSelection native library interface.
* This library is used for detecting entities in text.
@@ -42,6 +44,26 @@ final class SmartSelection {
}
/**
+ * Creates a new instance of SmartSelect predictor, using the provided model image, given as a
+ * file path.
+ */
+ SmartSelection(String path) {
+ mCtx = nativeNewFromPath(path);
+ }
+
+ /**
+ * Creates a new instance of SmartSelect predictor, using the provided model image, given as an
+ * AssetFileDescriptor.
+ */
+ SmartSelection(AssetFileDescriptor afd) {
+ mCtx = nativeNewFromAssetFileDescriptor(afd, afd.getStartOffset(), afd.getLength());
+ if (mCtx == 0L) {
+ throw new IllegalArgumentException(
+ "Couldn't initialize TC from given AssetFileDescriptor");
+ }
+ }
+
+ /**
* Given a string context and current selection, computes the SmartSelection suggestion.
*
* The begin and end are character indices into the context UTF8 string. selectionBegin is the
@@ -69,6 +91,15 @@ final class SmartSelection {
}
/**
+ * Annotates given input text. Every word of the input is a part of some annotation.
+ * The annotations are sorted by their position in the context string.
+ * The annotations do not overlap.
+ */
+ public AnnotatedSpan[] annotate(String text) {
+ return nativeAnnotate(mCtx, text);
+ }
+
+ /**
* Frees up the allocated memory.
*/
public void close() {
@@ -91,12 +122,19 @@ final class SmartSelection {
private static native long nativeNew(int fd);
+ private static native long nativeNewFromPath(String path);
+
+ private static native long nativeNewFromAssetFileDescriptor(AssetFileDescriptor afd,
+ long offset, long size);
+
private static native int[] nativeSuggest(
long context, String text, int selectionBegin, int selectionEnd);
private static native ClassificationResult[] nativeClassifyText(
long context, String text, int selectionBegin, int selectionEnd, int hintFlags);
+ private static native AnnotatedSpan[] nativeAnnotate(long context, String text);
+
private static native void nativeClose(long context);
private static native String nativeGetLanguage(int fd);
@@ -114,4 +152,29 @@ final class SmartSelection {
mScore = score;
}
}
+
+ /** Represents a result of Annotate call. */
+ public static final class AnnotatedSpan {
+ final int mStartIndex;
+ final int mEndIndex;
+ final ClassificationResult[] mClassification;
+
+ AnnotatedSpan(int startIndex, int endIndex, ClassificationResult[] classification) {
+ mStartIndex = startIndex;
+ mEndIndex = endIndex;
+ mClassification = classification;
+ }
+
+ public int getStartIndex() {
+ return mStartIndex;
+ }
+
+ public int getEndIndex() {
+ return mEndIndex;
+ }
+
+ public ClassificationResult[] getClassification() {
+ return mClassification;
+ }
+ }
}
diff --git a/android/view/textclassifier/TextClassifier.java b/android/view/textclassifier/TextClassifier.java
index bb1e693f..c3601d9d 100644
--- a/android/view/textclassifier/TextClassifier.java
+++ b/android/view/textclassifier/TextClassifier.java
@@ -152,4 +152,12 @@ public interface TextClassifier {
*/
@WorkerThread
default void logEvent(String source, String event) {}
+
+ /**
+ * Returns this TextClassifier's settings.
+ * @hide
+ */
+ default TextClassifierConstants getSettings() {
+ return TextClassifierConstants.DEFAULT;
+ }
}
diff --git a/android/view/textclassifier/TextClassifierConstants.java b/android/view/textclassifier/TextClassifierConstants.java
new file mode 100644
index 00000000..51e6168e
--- /dev/null
+++ b/android/view/textclassifier/TextClassifierConstants.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2017 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 android.view.textclassifier;
+
+import android.annotation.Nullable;
+import android.util.KeyValueListParser;
+import android.util.Slog;
+
+/**
+ * TextClassifier specific settings.
+ * This is encoded as a key=value list, separated by commas. Ex:
+ *
+ * <pre>
+ * smart_selection_dark_launch (boolean)
+ * smart_selection_enabled_for_edit_text (boolean)
+ * </pre>
+ *
+ * <p>
+ * Type: string
+ * see also android.provider.Settings.Global.TEXT_CLASSIFIER_CONSTANTS
+ *
+ * Example of setting the values for testing.
+ * adb shell settings put global text_classifier_constants smart_selection_dark_launch=true,smart_selection_enabled_for_edit_text=true
+ * @hide
+ */
+public final class TextClassifierConstants {
+
+ private static final String LOG_TAG = "TextClassifierConstants";
+
+ private static final String SMART_SELECTION_DARK_LAUNCH =
+ "smart_selection_dark_launch";
+ private static final String SMART_SELECTION_ENABLED_FOR_EDIT_TEXT =
+ "smart_selection_enabled_for_edit_text";
+
+ private static final boolean SMART_SELECTION_DARK_LAUNCH_DEFAULT = false;
+ private static final boolean SMART_SELECTION_ENABLED_FOR_EDIT_TEXT_DEFAULT = true;
+
+ /** Default settings. */
+ static final TextClassifierConstants DEFAULT = new TextClassifierConstants();
+
+ private final boolean mDarkLaunch;
+ private final boolean mSuggestSelectionEnabledForEditableText;
+
+ private TextClassifierConstants() {
+ mDarkLaunch = SMART_SELECTION_DARK_LAUNCH_DEFAULT;
+ mSuggestSelectionEnabledForEditableText = SMART_SELECTION_ENABLED_FOR_EDIT_TEXT_DEFAULT;
+ }
+
+ private TextClassifierConstants(@Nullable String settings) {
+ final KeyValueListParser parser = new KeyValueListParser(',');
+ try {
+ parser.setString(settings);
+ } catch (IllegalArgumentException e) {
+ // Failed to parse the settings string, log this and move on with defaults.
+ Slog.e(LOG_TAG, "Bad TextClassifier settings: " + settings);
+ }
+ mDarkLaunch = parser.getBoolean(
+ SMART_SELECTION_DARK_LAUNCH,
+ SMART_SELECTION_DARK_LAUNCH_DEFAULT);
+ mSuggestSelectionEnabledForEditableText = parser.getBoolean(
+ SMART_SELECTION_ENABLED_FOR_EDIT_TEXT,
+ SMART_SELECTION_ENABLED_FOR_EDIT_TEXT_DEFAULT);
+ }
+
+ static TextClassifierConstants loadFromString(String settings) {
+ return new TextClassifierConstants(settings);
+ }
+
+ public boolean isDarkLaunch() {
+ return mDarkLaunch;
+ }
+
+ public boolean isSuggestSelectionEnabledForEditableText() {
+ return mSuggestSelectionEnabledForEditableText;
+ }
+}
diff --git a/android/view/textclassifier/TextClassifierImpl.java b/android/view/textclassifier/TextClassifierImpl.java
index 2aa81a2c..1c07be4b 100644
--- a/android/view/textclassifier/TextClassifierImpl.java
+++ b/android/view/textclassifier/TextClassifierImpl.java
@@ -24,18 +24,17 @@ import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable;
-import android.icu.text.BreakIterator;
import android.net.Uri;
import android.os.LocaleList;
import android.os.ParcelFileDescriptor;
import android.provider.Browser;
import android.provider.ContactsContract;
+import android.provider.Settings;
import android.text.Spannable;
import android.text.TextUtils;
import android.text.method.WordIterator;
import android.text.style.ClickableSpan;
import android.text.util.Linkify;
-import android.util.Log;
import android.util.Patterns;
import android.view.View;
import android.widget.TextViewMetrics;
@@ -47,6 +46,7 @@ import com.android.internal.util.Preconditions;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
+import java.text.BreakIterator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -91,6 +91,8 @@ final class TextClassifierImpl implements TextClassifier {
@GuardedBy("mSmartSelectionLock") // Do not access outside this lock.
private SmartSelection mSmartSelection;
+ private TextClassifierConstants mSettings;
+
TextClassifierImpl(Context context) {
mContext = Preconditions.checkNotNull(context);
}
@@ -160,7 +162,7 @@ final class TextClassifierImpl implements TextClassifier {
}
} catch (Throwable t) {
// Avoid throwing from this method. Log the error.
- Log.e(LOG_TAG, "Error getting assist info.", t);
+ Log.e(LOG_TAG, "Error getting text classification info.", t);
}
// Getting here means something went wrong, return a NO_OP result.
return TextClassifier.NO_OP.classifyText(
@@ -189,6 +191,15 @@ final class TextClassifierImpl implements TextClassifier {
}
}
+ @Override
+ public TextClassifierConstants getSettings() {
+ if (mSettings == null) {
+ mSettings = TextClassifierConstants.loadFromString(Settings.Global.getString(
+ mContext.getContentResolver(), Settings.Global.TEXT_CLASSIFIER_CONSTANTS));
+ }
+ return mSettings;
+ }
+
private SmartSelection getSmartSelection(LocaleList localeList) throws FileNotFoundException {
synchronized (mSmartSelectionLock) {
localeList = localeList == null ? LocaleList.getEmptyLocaleList() : localeList;