Loading core/java/android/view/textclassifier/ActionsSuggestionsHelper.java +1 −1 Original line number Diff line number Diff line Loading @@ -143,7 +143,7 @@ public final class ActionsSuggestionsHelper { // intent for each action type. LabeledIntent.TitleChooser titleChooser = ActionsSuggestionsHelper.createTitleChooser(nativeSuggestion.getActionType()); return labeledIntents.get(0).resolve(context, titleChooser); return labeledIntents.get(0).resolve(context, titleChooser, null); } /** Loading core/java/android/view/textclassifier/ExtrasUtils.java +84 −7 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package android.view.textclassifier; import android.annotation.Nullable; import android.app.RemoteAction; import android.content.Intent; import android.icu.util.ULocale; import android.os.Bundle; import java.util.ArrayList; Loading @@ -27,6 +28,7 @@ import java.util.ArrayList; * Utility class for inserting and retrieving data in TextClassifier request/response extras. * @hide */ // TODO: Make this a TestApi for CTS testing. public final class ExtrasUtils { private static final String ENTITIES_EXTRAS = "entities-extras"; Loading @@ -37,6 +39,7 @@ public final class ExtrasUtils { private static final String SCORE = "score"; private static final String MODEL_VERSION = "model-version"; private static final String MODEL_NAME = "model-name"; private static final String TEXT_LANGUAGES = "text-languages"; private ExtrasUtils() {} Loading @@ -56,6 +59,8 @@ public final class ExtrasUtils { /** * Stores {@code extra} as foreign language information in TextClassifier response object's * extras {@code container}. * * @see #getForeignLanguageExtra(TextClassification) */ static void putForeignLanguageExtra(Bundle container, Bundle extra) { container.putParcelable(FOREIGN_LANGUAGE, extra); Loading @@ -64,12 +69,67 @@ public final class ExtrasUtils { /** * Returns foreign language detection information contained in the TextClassification object. * responses. * * @see #putForeignLanguageExtra(Bundle, Bundle) */ @Nullable public static Bundle getForeignLanguageExtra(TextClassification classification) { public static Bundle getForeignLanguageExtra(@Nullable TextClassification classification) { if (classification == null) { return null; } return classification.getExtras().getBundle(FOREIGN_LANGUAGE); } /** * @see #getTopLanguage(Intent) */ static void putTopLanguageScores(Bundle container, EntityConfidence languageScores) { final int maxSize = Math.min(3, languageScores.getEntities().size()); final String[] languages = languageScores.getEntities().subList(0, maxSize) .toArray(new String[0]); final float[] scores = new float[languages.length]; for (int i = 0; i < languages.length; i++) { scores[i] = languageScores.getConfidenceScore(languages[i]); } container.putStringArray(ENTITY_TYPE, languages); container.putFloatArray(SCORE, scores); } /** * @see #putTopLanguageScores(Bundle, EntityConfidence) */ @Nullable public static ULocale getTopLanguage(@Nullable Intent intent) { if (intent == null) { return null; } final Bundle tcBundle = intent.getBundleExtra(TextClassifier.EXTRA_FROM_TEXT_CLASSIFIER); if (tcBundle == null) { return null; } final Bundle textLanguagesExtra = tcBundle.getBundle(TEXT_LANGUAGES); if (textLanguagesExtra == null) { return null; } final String[] languages = textLanguagesExtra.getStringArray(ENTITY_TYPE); final float[] scores = textLanguagesExtra.getFloatArray(SCORE); if (languages == null || scores == null || languages.length == 0 || languages.length != scores.length) { return null; } int highestScoringIndex = 0; for (int i = 1; i < languages.length; i++) { if (scores[highestScoringIndex] < scores[i]) { highestScoringIndex = i; } } return ULocale.forLanguageTag(languages[highestScoringIndex]); } public static void putTextLanguagesExtra(Bundle container, Bundle extra) { container.putBundle(TEXT_LANGUAGES, extra); } /** * Stores {@code actionIntents} information in TextClassifier response object's extras * {@code container}. Loading Loading @@ -122,7 +182,10 @@ public final class ExtrasUtils { * Returns {@code actionIntents} information contained in the TextClassification object. */ @Nullable public static ArrayList<Intent> getActionsIntents(TextClassification classification) { public static ArrayList<Intent> getActionsIntents(@Nullable TextClassification classification) { if (classification == null) { return null; } return classification.getExtras().getParcelableArrayList(ACTIONS_INTENTS); } Loading @@ -131,7 +194,11 @@ public final class ExtrasUtils { * action string, {@code intentAction}. */ @Nullable public static RemoteAction findAction(TextClassification classification, String intentAction) { public static RemoteAction findAction( @Nullable TextClassification classification, @Nullable String intentAction) { if (classification == null || intentAction == null) { return null; } final ArrayList<Intent> actionIntents = getActionsIntents(classification); if (actionIntents != null) { final int size = actionIntents.size(); Loading @@ -149,7 +216,7 @@ public final class ExtrasUtils { * Returns the first "translate" action found in the {@code classification} object. */ @Nullable public static RemoteAction findTranslateAction(TextClassification classification) { public static RemoteAction findTranslateAction(@Nullable TextClassification classification) { return findAction(classification, Intent.ACTION_TRANSLATE); } Loading @@ -157,7 +224,10 @@ public final class ExtrasUtils { * Returns the entity type contained in the {@code extra}. */ @Nullable public static String getEntityType(Bundle extra) { public static String getEntityType(@Nullable Bundle extra) { if (extra == null) { return null; } return extra.getString(ENTITY_TYPE); } Loading @@ -166,14 +236,21 @@ public final class ExtrasUtils { */ @Nullable public static float getScore(Bundle extra) { return extra.getFloat(SCORE, -1); final int defaultValue = -1; if (extra == null) { return defaultValue; } return extra.getFloat(SCORE, defaultValue); } /** * Returns the model name contained in the {@code extra}. */ @Nullable public static String getModelName(Bundle extra) { public static String getModelName(@Nullable Bundle extra) { if (extra == null) { return null; } return extra.getString(MODEL_NAME); } } core/java/android/view/textclassifier/TextClassificationConstants.java +69 −14 Original line number Diff line number Diff line Loading @@ -50,6 +50,7 @@ import java.util.StringJoiner; * template_intent_factory_enabled (boolean) * translate_in_classification_enabled (boolean) * detect_languages_from_text_enabled (boolean) * lang_id_context_settings (float[]) * </pre> * * <p> Loading @@ -59,11 +60,13 @@ import java.util.StringJoiner; * Example of setting the values for testing. * adb shell settings put global text_classifier_constants \ * model_dark_launch_enabled=true,smart_selection_enabled=true, \ * entity_list_default=phone:address * entity_list_default=phone:address, \ * lang_id_context_settings=20:1.0:0.4 * @hide */ public final class TextClassificationConstants { private static final String LOG_TAG = "TextClassificationConstants"; private static final String LOG_TAG = TextClassifier.DEFAULT_LOG_TAG; /** * Whether the smart linkify feature is enabled. Loading Loading @@ -148,7 +151,6 @@ public final class TextClassificationConstants { * Whether to enable {@link android.view.textclassifier.TemplateIntentFactory}. */ private static final String TEMPLATE_INTENT_FACTORY_ENABLED = "template_intent_factory_enabled"; /** * Whether to enable "translate" action in classifyText. */ Loading @@ -160,6 +162,20 @@ public final class TextClassificationConstants { */ private static final String DETECT_LANGUAGES_FROM_TEXT_ENABLED = "detect_languages_from_text_enabled"; /** * A colon(:) separated string that specifies the configuration to use when including * surrounding context text in language detection queries. * <p> * Format= minimumTextSize<int>:penalizeRatio<float>:textScoreRatio<float> * <p> * e.g. 20:1.0:0.4 * <p> * Accept all text lengths with minimumTextSize=0 * <p> * Reject all text less than minimumTextSize with penalizeRatio=0 * @see {@code TextClassifierImpl#detectLanguages(String, int, int)} for reference. */ private static final String LANG_ID_CONTEXT_SETTINGS = "lang_id_context_settings"; private static final boolean LOCAL_TEXT_CLASSIFIER_ENABLED_DEFAULT = true; private static final boolean SYSTEM_TEXT_CLASSIFIER_ENABLED_DEFAULT = true; Loading Loading @@ -205,6 +221,8 @@ public final class TextClassificationConstants { private static final boolean TEMPLATE_INTENT_FACTORY_ENABLED_DEFAULT = true; private static final boolean TRANSLATE_IN_CLASSIFICATION_ENABLED_DEFAULT = true; private static final boolean DETECT_LANGUAGES_FROM_TEXT_ENABLED_DEFAULT = true; private static final String LANG_ID_CONTEXT_SETTINGS_DEFAULT = new StringJoiner(STRING_LIST_DELIMITER).add("20").add("1.0").add("0.4").toString(); private final boolean mSystemTextClassifierEnabled; private final boolean mLocalTextClassifierEnabled; Loading @@ -226,6 +244,7 @@ public final class TextClassificationConstants { private final boolean mTemplateIntentFactoryEnabled; private final boolean mTranslateInClassificationEnabled; private final boolean mDetectLanguagesFromTextEnabled; private final float[] mLangIdContextSettings; private TextClassificationConstants(@Nullable String settings) { ConfigParser configParser = new ConfigParser(settings); Loading Loading @@ -273,7 +292,8 @@ public final class TextClassificationConstants { configParser.getInt( GENERATE_LINKS_LOG_SAMPLE_RATE, GENERATE_LINKS_LOG_SAMPLE_RATE_DEFAULT); mEntityListDefault = parseStringList(configParser.getString( mEntityListDefault = parseStringList( configParser.getString( ENTITY_LIST_DEFAULT, ENTITY_LIST_DEFAULT_VALUE)); mEntityListNotEditable = parseStringList( Loading @@ -296,13 +316,22 @@ public final class TextClassificationConstants { configParser.getFloat( LANG_ID_THRESHOLD_OVERRIDE, LANG_ID_THRESHOLD_OVERRIDE_DEFAULT); mTemplateIntentFactoryEnabled = configParser.getBoolean( mTemplateIntentFactoryEnabled = configParser.getBoolean( TEMPLATE_INTENT_FACTORY_ENABLED, TEMPLATE_INTENT_FACTORY_ENABLED_DEFAULT); mTranslateInClassificationEnabled = configParser.getBoolean( TRANSLATE_IN_CLASSIFICATION_ENABLED, TRANSLATE_IN_CLASSIFICATION_ENABLED_DEFAULT); mDetectLanguagesFromTextEnabled = configParser.getBoolean( DETECT_LANGUAGES_FROM_TEXT_ENABLED, DETECT_LANGUAGES_FROM_TEXT_ENABLED_DEFAULT); mTranslateInClassificationEnabled = configParser.getBoolean( TRANSLATE_IN_CLASSIFICATION_ENABLED, TRANSLATE_IN_CLASSIFICATION_ENABLED_DEFAULT); mDetectLanguagesFromTextEnabled = configParser.getBoolean( DETECT_LANGUAGES_FROM_TEXT_ENABLED, DETECT_LANGUAGES_FROM_TEXT_ENABLED_DEFAULT); mLangIdContextSettings = parseFloatArray( configParser, LANG_ID_CONTEXT_SETTINGS, LANG_ID_CONTEXT_SETTINGS_DEFAULT); } /** Load from a settings string. */ Loading Loading @@ -390,10 +419,35 @@ public final class TextClassificationConstants { return mDetectLanguagesFromTextEnabled; } public float[] getLangIdContextSettings() { return mLangIdContextSettings; } private static List<String> parseStringList(String listStr) { return Collections.unmodifiableList(Arrays.asList(listStr.split(STRING_LIST_DELIMITER))); } private static float[] parseFloatArray( ConfigParser configParser, String key, String defaultStr) { final String str = configParser.getString(key, defaultStr); final String[] defaultSplit = defaultStr.split(STRING_LIST_DELIMITER); String[] split = str.split(STRING_LIST_DELIMITER); if (split.length != defaultSplit.length) { Log.v(LOG_TAG, "Error parsing " + key + " flag. Using defaults."); split = defaultSplit; } final float[] result = new float[split.length]; for (int i = 0; i < split.length; i++) { try { result[i] = Float.parseFloat(split[i]); } catch (NumberFormatException e) { Log.v(LOG_TAG, "Error parsing part of " + key + " flag. Using defaults."); result[i] = Float.parseFloat(defaultSplit[i]); } } return result; } void dump(IndentingPrintWriter pw) { pw.println("TextClassificationConstants:"); pw.increaseIndent(); Loading @@ -418,6 +472,7 @@ public final class TextClassificationConstants { pw.printPair("isTemplateIntentFactoryEnabled", mTemplateIntentFactoryEnabled); pw.printPair("isTranslateInClassificationEnabled", mTranslateInClassificationEnabled); pw.printPair("isDetectLanguageFromTextEnabled", mDetectLanguagesFromTextEnabled); pw.printPair("getLangIdContextSettings", Arrays.toString(mLangIdContextSettings)); pw.decreaseIndent(); pw.println(); } Loading core/java/android/view/textclassifier/TextClassifier.java +47 −1 Original line number Diff line number Diff line Loading @@ -33,11 +33,13 @@ import android.text.util.Linkify; import android.text.util.Linkify.LinkifyMask; import android.util.ArrayMap; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.Preconditions; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.text.BreakIterator; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; Loading Loading @@ -644,11 +646,14 @@ public interface TextClassifier { * <li>Provides validation of input parameters to TextClassifier methods * </ul> * * Intended to be used only in this package. * Intended to be used only for TextClassifier purposes. * @hide */ final class Utils { @GuardedBy("WORD_ITERATOR") private static final BreakIterator WORD_ITERATOR = BreakIterator.getWordInstance(); /** * @throws IllegalArgumentException if text is null; startIndex is negative; * endIndex is greater than text.length() or is not greater than startIndex; Loading @@ -665,6 +670,47 @@ public interface TextClassifier { Preconditions.checkArgumentInRange(text.length(), 0, maxLength, "text.length()"); } /** * Returns the substring of {@code text} that contains at least text from index * {@code start} <i>(inclusive)</i> to index {@code end} <i><(exclusive)/i> with the goal of * returning text that is at least {@code minimumLength}. If {@code text} is not long * enough, this will return {@code text}. This method returns text at word boundaries. * * @param text the source text * @param start the start index of text that must be included * @param end the end index of text that must be included * @param minimumLength minimum length of text to return if {@code text} is long enough */ public static String getSubString( String text, int start, int end, int minimumLength) { Preconditions.checkArgument(start >= 0); Preconditions.checkArgument(end <= text.length()); Preconditions.checkArgument(start <= end); if (text.length() < minimumLength) { return text; } final int length = end - start; if (length >= minimumLength) { return text.substring(start, end); } final int offset = (minimumLength - length) / 2; int iterStart = Math.max(0, Math.min(start - offset, text.length() - minimumLength)); int iterEnd = Math.min(text.length(), iterStart + minimumLength); synchronized (WORD_ITERATOR) { WORD_ITERATOR.setText(text); iterStart = WORD_ITERATOR.isBoundary(iterStart) ? iterStart : Math.max(0, WORD_ITERATOR.preceding(iterStart)); iterEnd = WORD_ITERATOR.isBoundary(iterEnd) ? iterEnd : Math.max(iterEnd, WORD_ITERATOR.following(iterEnd)); WORD_ITERATOR.setText(""); return text.substring(iterStart, iterEnd); } } /** * Generates links using legacy {@link Linkify}. */ Loading core/java/android/view/textclassifier/TextClassifierImpl.java +142 −43 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
core/java/android/view/textclassifier/ActionsSuggestionsHelper.java +1 −1 Original line number Diff line number Diff line Loading @@ -143,7 +143,7 @@ public final class ActionsSuggestionsHelper { // intent for each action type. LabeledIntent.TitleChooser titleChooser = ActionsSuggestionsHelper.createTitleChooser(nativeSuggestion.getActionType()); return labeledIntents.get(0).resolve(context, titleChooser); return labeledIntents.get(0).resolve(context, titleChooser, null); } /** Loading
core/java/android/view/textclassifier/ExtrasUtils.java +84 −7 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package android.view.textclassifier; import android.annotation.Nullable; import android.app.RemoteAction; import android.content.Intent; import android.icu.util.ULocale; import android.os.Bundle; import java.util.ArrayList; Loading @@ -27,6 +28,7 @@ import java.util.ArrayList; * Utility class for inserting and retrieving data in TextClassifier request/response extras. * @hide */ // TODO: Make this a TestApi for CTS testing. public final class ExtrasUtils { private static final String ENTITIES_EXTRAS = "entities-extras"; Loading @@ -37,6 +39,7 @@ public final class ExtrasUtils { private static final String SCORE = "score"; private static final String MODEL_VERSION = "model-version"; private static final String MODEL_NAME = "model-name"; private static final String TEXT_LANGUAGES = "text-languages"; private ExtrasUtils() {} Loading @@ -56,6 +59,8 @@ public final class ExtrasUtils { /** * Stores {@code extra} as foreign language information in TextClassifier response object's * extras {@code container}. * * @see #getForeignLanguageExtra(TextClassification) */ static void putForeignLanguageExtra(Bundle container, Bundle extra) { container.putParcelable(FOREIGN_LANGUAGE, extra); Loading @@ -64,12 +69,67 @@ public final class ExtrasUtils { /** * Returns foreign language detection information contained in the TextClassification object. * responses. * * @see #putForeignLanguageExtra(Bundle, Bundle) */ @Nullable public static Bundle getForeignLanguageExtra(TextClassification classification) { public static Bundle getForeignLanguageExtra(@Nullable TextClassification classification) { if (classification == null) { return null; } return classification.getExtras().getBundle(FOREIGN_LANGUAGE); } /** * @see #getTopLanguage(Intent) */ static void putTopLanguageScores(Bundle container, EntityConfidence languageScores) { final int maxSize = Math.min(3, languageScores.getEntities().size()); final String[] languages = languageScores.getEntities().subList(0, maxSize) .toArray(new String[0]); final float[] scores = new float[languages.length]; for (int i = 0; i < languages.length; i++) { scores[i] = languageScores.getConfidenceScore(languages[i]); } container.putStringArray(ENTITY_TYPE, languages); container.putFloatArray(SCORE, scores); } /** * @see #putTopLanguageScores(Bundle, EntityConfidence) */ @Nullable public static ULocale getTopLanguage(@Nullable Intent intent) { if (intent == null) { return null; } final Bundle tcBundle = intent.getBundleExtra(TextClassifier.EXTRA_FROM_TEXT_CLASSIFIER); if (tcBundle == null) { return null; } final Bundle textLanguagesExtra = tcBundle.getBundle(TEXT_LANGUAGES); if (textLanguagesExtra == null) { return null; } final String[] languages = textLanguagesExtra.getStringArray(ENTITY_TYPE); final float[] scores = textLanguagesExtra.getFloatArray(SCORE); if (languages == null || scores == null || languages.length == 0 || languages.length != scores.length) { return null; } int highestScoringIndex = 0; for (int i = 1; i < languages.length; i++) { if (scores[highestScoringIndex] < scores[i]) { highestScoringIndex = i; } } return ULocale.forLanguageTag(languages[highestScoringIndex]); } public static void putTextLanguagesExtra(Bundle container, Bundle extra) { container.putBundle(TEXT_LANGUAGES, extra); } /** * Stores {@code actionIntents} information in TextClassifier response object's extras * {@code container}. Loading Loading @@ -122,7 +182,10 @@ public final class ExtrasUtils { * Returns {@code actionIntents} information contained in the TextClassification object. */ @Nullable public static ArrayList<Intent> getActionsIntents(TextClassification classification) { public static ArrayList<Intent> getActionsIntents(@Nullable TextClassification classification) { if (classification == null) { return null; } return classification.getExtras().getParcelableArrayList(ACTIONS_INTENTS); } Loading @@ -131,7 +194,11 @@ public final class ExtrasUtils { * action string, {@code intentAction}. */ @Nullable public static RemoteAction findAction(TextClassification classification, String intentAction) { public static RemoteAction findAction( @Nullable TextClassification classification, @Nullable String intentAction) { if (classification == null || intentAction == null) { return null; } final ArrayList<Intent> actionIntents = getActionsIntents(classification); if (actionIntents != null) { final int size = actionIntents.size(); Loading @@ -149,7 +216,7 @@ public final class ExtrasUtils { * Returns the first "translate" action found in the {@code classification} object. */ @Nullable public static RemoteAction findTranslateAction(TextClassification classification) { public static RemoteAction findTranslateAction(@Nullable TextClassification classification) { return findAction(classification, Intent.ACTION_TRANSLATE); } Loading @@ -157,7 +224,10 @@ public final class ExtrasUtils { * Returns the entity type contained in the {@code extra}. */ @Nullable public static String getEntityType(Bundle extra) { public static String getEntityType(@Nullable Bundle extra) { if (extra == null) { return null; } return extra.getString(ENTITY_TYPE); } Loading @@ -166,14 +236,21 @@ public final class ExtrasUtils { */ @Nullable public static float getScore(Bundle extra) { return extra.getFloat(SCORE, -1); final int defaultValue = -1; if (extra == null) { return defaultValue; } return extra.getFloat(SCORE, defaultValue); } /** * Returns the model name contained in the {@code extra}. */ @Nullable public static String getModelName(Bundle extra) { public static String getModelName(@Nullable Bundle extra) { if (extra == null) { return null; } return extra.getString(MODEL_NAME); } }
core/java/android/view/textclassifier/TextClassificationConstants.java +69 −14 Original line number Diff line number Diff line Loading @@ -50,6 +50,7 @@ import java.util.StringJoiner; * template_intent_factory_enabled (boolean) * translate_in_classification_enabled (boolean) * detect_languages_from_text_enabled (boolean) * lang_id_context_settings (float[]) * </pre> * * <p> Loading @@ -59,11 +60,13 @@ import java.util.StringJoiner; * Example of setting the values for testing. * adb shell settings put global text_classifier_constants \ * model_dark_launch_enabled=true,smart_selection_enabled=true, \ * entity_list_default=phone:address * entity_list_default=phone:address, \ * lang_id_context_settings=20:1.0:0.4 * @hide */ public final class TextClassificationConstants { private static final String LOG_TAG = "TextClassificationConstants"; private static final String LOG_TAG = TextClassifier.DEFAULT_LOG_TAG; /** * Whether the smart linkify feature is enabled. Loading Loading @@ -148,7 +151,6 @@ public final class TextClassificationConstants { * Whether to enable {@link android.view.textclassifier.TemplateIntentFactory}. */ private static final String TEMPLATE_INTENT_FACTORY_ENABLED = "template_intent_factory_enabled"; /** * Whether to enable "translate" action in classifyText. */ Loading @@ -160,6 +162,20 @@ public final class TextClassificationConstants { */ private static final String DETECT_LANGUAGES_FROM_TEXT_ENABLED = "detect_languages_from_text_enabled"; /** * A colon(:) separated string that specifies the configuration to use when including * surrounding context text in language detection queries. * <p> * Format= minimumTextSize<int>:penalizeRatio<float>:textScoreRatio<float> * <p> * e.g. 20:1.0:0.4 * <p> * Accept all text lengths with minimumTextSize=0 * <p> * Reject all text less than minimumTextSize with penalizeRatio=0 * @see {@code TextClassifierImpl#detectLanguages(String, int, int)} for reference. */ private static final String LANG_ID_CONTEXT_SETTINGS = "lang_id_context_settings"; private static final boolean LOCAL_TEXT_CLASSIFIER_ENABLED_DEFAULT = true; private static final boolean SYSTEM_TEXT_CLASSIFIER_ENABLED_DEFAULT = true; Loading Loading @@ -205,6 +221,8 @@ public final class TextClassificationConstants { private static final boolean TEMPLATE_INTENT_FACTORY_ENABLED_DEFAULT = true; private static final boolean TRANSLATE_IN_CLASSIFICATION_ENABLED_DEFAULT = true; private static final boolean DETECT_LANGUAGES_FROM_TEXT_ENABLED_DEFAULT = true; private static final String LANG_ID_CONTEXT_SETTINGS_DEFAULT = new StringJoiner(STRING_LIST_DELIMITER).add("20").add("1.0").add("0.4").toString(); private final boolean mSystemTextClassifierEnabled; private final boolean mLocalTextClassifierEnabled; Loading @@ -226,6 +244,7 @@ public final class TextClassificationConstants { private final boolean mTemplateIntentFactoryEnabled; private final boolean mTranslateInClassificationEnabled; private final boolean mDetectLanguagesFromTextEnabled; private final float[] mLangIdContextSettings; private TextClassificationConstants(@Nullable String settings) { ConfigParser configParser = new ConfigParser(settings); Loading Loading @@ -273,7 +292,8 @@ public final class TextClassificationConstants { configParser.getInt( GENERATE_LINKS_LOG_SAMPLE_RATE, GENERATE_LINKS_LOG_SAMPLE_RATE_DEFAULT); mEntityListDefault = parseStringList(configParser.getString( mEntityListDefault = parseStringList( configParser.getString( ENTITY_LIST_DEFAULT, ENTITY_LIST_DEFAULT_VALUE)); mEntityListNotEditable = parseStringList( Loading @@ -296,13 +316,22 @@ public final class TextClassificationConstants { configParser.getFloat( LANG_ID_THRESHOLD_OVERRIDE, LANG_ID_THRESHOLD_OVERRIDE_DEFAULT); mTemplateIntentFactoryEnabled = configParser.getBoolean( mTemplateIntentFactoryEnabled = configParser.getBoolean( TEMPLATE_INTENT_FACTORY_ENABLED, TEMPLATE_INTENT_FACTORY_ENABLED_DEFAULT); mTranslateInClassificationEnabled = configParser.getBoolean( TRANSLATE_IN_CLASSIFICATION_ENABLED, TRANSLATE_IN_CLASSIFICATION_ENABLED_DEFAULT); mDetectLanguagesFromTextEnabled = configParser.getBoolean( DETECT_LANGUAGES_FROM_TEXT_ENABLED, DETECT_LANGUAGES_FROM_TEXT_ENABLED_DEFAULT); mTranslateInClassificationEnabled = configParser.getBoolean( TRANSLATE_IN_CLASSIFICATION_ENABLED, TRANSLATE_IN_CLASSIFICATION_ENABLED_DEFAULT); mDetectLanguagesFromTextEnabled = configParser.getBoolean( DETECT_LANGUAGES_FROM_TEXT_ENABLED, DETECT_LANGUAGES_FROM_TEXT_ENABLED_DEFAULT); mLangIdContextSettings = parseFloatArray( configParser, LANG_ID_CONTEXT_SETTINGS, LANG_ID_CONTEXT_SETTINGS_DEFAULT); } /** Load from a settings string. */ Loading Loading @@ -390,10 +419,35 @@ public final class TextClassificationConstants { return mDetectLanguagesFromTextEnabled; } public float[] getLangIdContextSettings() { return mLangIdContextSettings; } private static List<String> parseStringList(String listStr) { return Collections.unmodifiableList(Arrays.asList(listStr.split(STRING_LIST_DELIMITER))); } private static float[] parseFloatArray( ConfigParser configParser, String key, String defaultStr) { final String str = configParser.getString(key, defaultStr); final String[] defaultSplit = defaultStr.split(STRING_LIST_DELIMITER); String[] split = str.split(STRING_LIST_DELIMITER); if (split.length != defaultSplit.length) { Log.v(LOG_TAG, "Error parsing " + key + " flag. Using defaults."); split = defaultSplit; } final float[] result = new float[split.length]; for (int i = 0; i < split.length; i++) { try { result[i] = Float.parseFloat(split[i]); } catch (NumberFormatException e) { Log.v(LOG_TAG, "Error parsing part of " + key + " flag. Using defaults."); result[i] = Float.parseFloat(defaultSplit[i]); } } return result; } void dump(IndentingPrintWriter pw) { pw.println("TextClassificationConstants:"); pw.increaseIndent(); Loading @@ -418,6 +472,7 @@ public final class TextClassificationConstants { pw.printPair("isTemplateIntentFactoryEnabled", mTemplateIntentFactoryEnabled); pw.printPair("isTranslateInClassificationEnabled", mTranslateInClassificationEnabled); pw.printPair("isDetectLanguageFromTextEnabled", mDetectLanguagesFromTextEnabled); pw.printPair("getLangIdContextSettings", Arrays.toString(mLangIdContextSettings)); pw.decreaseIndent(); pw.println(); } Loading
core/java/android/view/textclassifier/TextClassifier.java +47 −1 Original line number Diff line number Diff line Loading @@ -33,11 +33,13 @@ import android.text.util.Linkify; import android.text.util.Linkify.LinkifyMask; import android.util.ArrayMap; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.Preconditions; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.text.BreakIterator; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; Loading Loading @@ -644,11 +646,14 @@ public interface TextClassifier { * <li>Provides validation of input parameters to TextClassifier methods * </ul> * * Intended to be used only in this package. * Intended to be used only for TextClassifier purposes. * @hide */ final class Utils { @GuardedBy("WORD_ITERATOR") private static final BreakIterator WORD_ITERATOR = BreakIterator.getWordInstance(); /** * @throws IllegalArgumentException if text is null; startIndex is negative; * endIndex is greater than text.length() or is not greater than startIndex; Loading @@ -665,6 +670,47 @@ public interface TextClassifier { Preconditions.checkArgumentInRange(text.length(), 0, maxLength, "text.length()"); } /** * Returns the substring of {@code text} that contains at least text from index * {@code start} <i>(inclusive)</i> to index {@code end} <i><(exclusive)/i> with the goal of * returning text that is at least {@code minimumLength}. If {@code text} is not long * enough, this will return {@code text}. This method returns text at word boundaries. * * @param text the source text * @param start the start index of text that must be included * @param end the end index of text that must be included * @param minimumLength minimum length of text to return if {@code text} is long enough */ public static String getSubString( String text, int start, int end, int minimumLength) { Preconditions.checkArgument(start >= 0); Preconditions.checkArgument(end <= text.length()); Preconditions.checkArgument(start <= end); if (text.length() < minimumLength) { return text; } final int length = end - start; if (length >= minimumLength) { return text.substring(start, end); } final int offset = (minimumLength - length) / 2; int iterStart = Math.max(0, Math.min(start - offset, text.length() - minimumLength)); int iterEnd = Math.min(text.length(), iterStart + minimumLength); synchronized (WORD_ITERATOR) { WORD_ITERATOR.setText(text); iterStart = WORD_ITERATOR.isBoundary(iterStart) ? iterStart : Math.max(0, WORD_ITERATOR.preceding(iterStart)); iterEnd = WORD_ITERATOR.isBoundary(iterEnd) ? iterEnd : Math.max(iterEnd, WORD_ITERATOR.following(iterEnd)); WORD_ITERATOR.setText(""); return text.substring(iterStart, iterEnd); } } /** * Generates links using legacy {@link Linkify}. */ Loading
core/java/android/view/textclassifier/TextClassifierImpl.java +142 −43 File changed.Preview size limit exceeded, changes collapsed. Show changes