diff options
Diffstat (limited to 'android/view/textclassifier')
-rw-r--r-- | android/view/textclassifier/Log.java | 46 | ||||
-rw-r--r-- | android/view/textclassifier/SmartSelection.java | 63 | ||||
-rw-r--r-- | android/view/textclassifier/TextClassifier.java | 8 | ||||
-rw-r--r-- | android/view/textclassifier/TextClassifierConstants.java | 90 | ||||
-rw-r--r-- | android/view/textclassifier/TextClassifierImpl.java | 17 |
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; |