Loading core/java/android/view/textclassifier/ExtrasUtils.java +2 −1 Original line number Diff line number Diff line Loading @@ -94,7 +94,8 @@ public final class ExtrasUtils { if (actionIntents != null) { final int size = actionIntents.size(); for (int i = 0; i < size; i++) { if (intentAction.equals(actionIntents.get(i).getAction())) { final Intent intent = actionIntents.get(i); if (intent != null && intentAction.equals(intent.getAction())) { return classification.getActions().get(i); } } Loading core/java/android/view/textclassifier/TextClassification.java +4 −3 Original line number Diff line number Diff line Loading @@ -54,6 +54,7 @@ import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Objects; /** * Information for generating a widget to handle classified text. Loading Loading @@ -276,8 +277,8 @@ public final class TextClassification implements Parcelable { @Override public String toString() { return String.format(Locale.US, "TextClassification {text=%s, entities=%s, actions=%s, id=%s}", mText, mEntityConfidence, mActions, mId); "TextClassification {text=%s, entities=%s, actions=%s, id=%s, extras=%s}", mText, mEntityConfidence, mActions, mId, mExtras); } /** Loading Loading @@ -532,7 +533,7 @@ public final class TextClassification implements Parcelable { private Bundle buildExtras() { final Bundle extras = mExtras == null ? new Bundle() : mExtras.deepCopy(); if (!mActionIntents.isEmpty()) { if (mActionIntents.stream().anyMatch(Objects::nonNull)) { ExtrasUtils.putActionsIntents(extras, mActionIntents); } if (mForeignLanguageExtra != null) { Loading core/java/android/view/textclassifier/TextClassifierImpl.java +42 −22 Original line number Diff line number Diff line Loading @@ -240,9 +240,7 @@ public final class TextClassifierImpl implements TextClassifier { refTime.getZone().getId(), localesString), mContext, // TODO: Pass the locale list once it is supported in // native side. LocaleList.getDefault().get(0).toLanguageTag() getResourceLocaleString() ); if (results.length > 0) { return createClassificationResult( Loading Loading @@ -403,8 +401,7 @@ public final class TextClassifierImpl implements TextClassifier { nativeConversation, null, mContext, // TODO: Pass the locale list once it is supported in native side. LocaleList.getDefault().get(0).toLanguageTag()); getResourceLocaleString()); return createConversationActionResult(request, nativeSuggestions); } catch (Throwable t) { // Avoid throwing from this method. Log the error. Loading Loading @@ -456,10 +453,9 @@ public final class TextClassifierImpl implements TextClassifier { TextLanguage textLanguage = detectLanguage(request); int localeHypothesisCount = textLanguage.getLocaleHypothesisCount(); List<String> languageTags = new ArrayList<>(); // TODO: Reconsider this and probably make the score threshold configurable. for (int i = 0; i < localeHypothesisCount; i++) { ULocale locale = textLanguage.getLocale(i); if (textLanguage.getConfidenceScore(locale) < 0.5) { if (textLanguage.getConfidenceScore(locale) < getForeignLanguageThreshold()) { break; } languageTags.add(locale.toLanguageTag()); Loading Loading @@ -587,15 +583,10 @@ public final class TextClassifierImpl implements TextClassifier { } } final float foreignTextThreshold = mSettings.getLangIdThresholdOverride() >= 0 ? mSettings.getLangIdThresholdOverride() : 0.5f /* TODO: Load this from the langId model. */; final Bundle foreignLanguageBundle = detectForeignLanguage(classifiedText, foreignTextThreshold); final Bundle foreignLanguageBundle = detectForeignLanguage(classifiedText); builder.setForeignLanguageExtra(foreignLanguageBundle); boolean isPrimaryAction = true; final ArrayList<Intent> sourceIntents = new ArrayList<>(); List<LabeledIntent> labeledIntents = mIntentFactory.create( mContext, classifiedText, Loading Loading @@ -626,16 +617,20 @@ public final class TextClassifierImpl implements TextClassifier { /** * Returns a bundle with the language and confidence score if it finds the text to be * in a foreign language. Otherwise returns null. * in a foreign language. Otherwise returns null. This algorithm defines what the system thinks * is a foreign language. */ // TODO: Revisit this algorithm. // TODO: Consider making this public API. @Nullable private Bundle detectForeignLanguage(String text, float threshold) { private Bundle detectForeignLanguage(String text) { try { final float threshold = getForeignLanguageThreshold(); if (threshold > 1) { Log.v(LOG_TAG, "Foreign language detection disabled."); return null; } // TODO: Revisit this algorithm. try { final LangIdModel langId = getLangIdImpl(); final LangIdModel.LanguageResult[] langResults = langId.detectLanguages(text); if (langResults.length <= 0) { Loading @@ -651,8 +646,8 @@ public final class TextClassifierImpl implements TextClassifier { if (highestScoringResult.getScore() < threshold) { return null; } // TODO: Remove Log.d(LOG_TAG, String.format("Language detected: <%s:%s>", Log.v(LOG_TAG, String.format("Language detected: <%s:%s>", highestScoringResult.getLanguage(), highestScoringResult.getScore())); final Locale detected = new Locale(highestScoringResult.getLanguage()); Loading @@ -671,6 +666,18 @@ public final class TextClassifierImpl implements TextClassifier { return null; } private float getForeignLanguageThreshold() { try { return mSettings.getLangIdThresholdOverride() >= 0 ? mSettings.getLangIdThresholdOverride() : getLangIdImpl().getTranslateThreshold(); } catch (FileNotFoundException e) { final float defaultThreshold = 0.5f; Log.v(LOG_TAG, "Using default foreign language threshold: " + defaultThreshold); return defaultThreshold; } } @Override public void dump(@NonNull IndentingPrintWriter printWriter) { synchronized (mLock) { Loading Loading @@ -718,6 +725,19 @@ public final class TextClassifierImpl implements TextClassifier { } } /** * Returns the locale string for the current resources configuration. */ private String getResourceLocaleString() { // TODO: Pass the locale list once it is supported in native side. try { return mContext.getResources().getConfiguration().getLocales().get(0).toLanguageTag(); } catch (NullPointerException e) { // NPE is unexpected. Erring on the side of caution. return LocaleList.getDefault().get(0).toLanguageTag(); } } /** * Helper class to store the information from which RemoteActions are built. */ Loading core/tests/coretests/src/android/view/textclassifier/TextClassificationTest.java +3 −2 Original line number Diff line number Diff line Loading @@ -93,8 +93,8 @@ public class TextClassificationTest { final String id = "id"; final TextClassification reference = new TextClassification.Builder() .setText(text) .addAction(remoteAction0) .addAction(remoteAction1) .addAction(remoteAction0) // Action intent not included. .addAction(remoteAction1) // Action intent not included. .setEntityType(TextClassifier.TYPE_ADDRESS, 0.3f) .setEntityType(TextClassifier.TYPE_PHONE, 0.7f) .setId(id) Loading Loading @@ -132,6 +132,7 @@ public class TextClassificationTest { // Extras assertEquals(BUNDLE_VALUE, result.getExtras().getString(BUNDLE_KEY)); assertNull(ExtrasUtils.getActionsIntents(result)); } @Test Loading Loading
core/java/android/view/textclassifier/ExtrasUtils.java +2 −1 Original line number Diff line number Diff line Loading @@ -94,7 +94,8 @@ public final class ExtrasUtils { if (actionIntents != null) { final int size = actionIntents.size(); for (int i = 0; i < size; i++) { if (intentAction.equals(actionIntents.get(i).getAction())) { final Intent intent = actionIntents.get(i); if (intent != null && intentAction.equals(intent.getAction())) { return classification.getActions().get(i); } } Loading
core/java/android/view/textclassifier/TextClassification.java +4 −3 Original line number Diff line number Diff line Loading @@ -54,6 +54,7 @@ import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Objects; /** * Information for generating a widget to handle classified text. Loading Loading @@ -276,8 +277,8 @@ public final class TextClassification implements Parcelable { @Override public String toString() { return String.format(Locale.US, "TextClassification {text=%s, entities=%s, actions=%s, id=%s}", mText, mEntityConfidence, mActions, mId); "TextClassification {text=%s, entities=%s, actions=%s, id=%s, extras=%s}", mText, mEntityConfidence, mActions, mId, mExtras); } /** Loading Loading @@ -532,7 +533,7 @@ public final class TextClassification implements Parcelable { private Bundle buildExtras() { final Bundle extras = mExtras == null ? new Bundle() : mExtras.deepCopy(); if (!mActionIntents.isEmpty()) { if (mActionIntents.stream().anyMatch(Objects::nonNull)) { ExtrasUtils.putActionsIntents(extras, mActionIntents); } if (mForeignLanguageExtra != null) { Loading
core/java/android/view/textclassifier/TextClassifierImpl.java +42 −22 Original line number Diff line number Diff line Loading @@ -240,9 +240,7 @@ public final class TextClassifierImpl implements TextClassifier { refTime.getZone().getId(), localesString), mContext, // TODO: Pass the locale list once it is supported in // native side. LocaleList.getDefault().get(0).toLanguageTag() getResourceLocaleString() ); if (results.length > 0) { return createClassificationResult( Loading Loading @@ -403,8 +401,7 @@ public final class TextClassifierImpl implements TextClassifier { nativeConversation, null, mContext, // TODO: Pass the locale list once it is supported in native side. LocaleList.getDefault().get(0).toLanguageTag()); getResourceLocaleString()); return createConversationActionResult(request, nativeSuggestions); } catch (Throwable t) { // Avoid throwing from this method. Log the error. Loading Loading @@ -456,10 +453,9 @@ public final class TextClassifierImpl implements TextClassifier { TextLanguage textLanguage = detectLanguage(request); int localeHypothesisCount = textLanguage.getLocaleHypothesisCount(); List<String> languageTags = new ArrayList<>(); // TODO: Reconsider this and probably make the score threshold configurable. for (int i = 0; i < localeHypothesisCount; i++) { ULocale locale = textLanguage.getLocale(i); if (textLanguage.getConfidenceScore(locale) < 0.5) { if (textLanguage.getConfidenceScore(locale) < getForeignLanguageThreshold()) { break; } languageTags.add(locale.toLanguageTag()); Loading Loading @@ -587,15 +583,10 @@ public final class TextClassifierImpl implements TextClassifier { } } final float foreignTextThreshold = mSettings.getLangIdThresholdOverride() >= 0 ? mSettings.getLangIdThresholdOverride() : 0.5f /* TODO: Load this from the langId model. */; final Bundle foreignLanguageBundle = detectForeignLanguage(classifiedText, foreignTextThreshold); final Bundle foreignLanguageBundle = detectForeignLanguage(classifiedText); builder.setForeignLanguageExtra(foreignLanguageBundle); boolean isPrimaryAction = true; final ArrayList<Intent> sourceIntents = new ArrayList<>(); List<LabeledIntent> labeledIntents = mIntentFactory.create( mContext, classifiedText, Loading Loading @@ -626,16 +617,20 @@ public final class TextClassifierImpl implements TextClassifier { /** * Returns a bundle with the language and confidence score if it finds the text to be * in a foreign language. Otherwise returns null. * in a foreign language. Otherwise returns null. This algorithm defines what the system thinks * is a foreign language. */ // TODO: Revisit this algorithm. // TODO: Consider making this public API. @Nullable private Bundle detectForeignLanguage(String text, float threshold) { private Bundle detectForeignLanguage(String text) { try { final float threshold = getForeignLanguageThreshold(); if (threshold > 1) { Log.v(LOG_TAG, "Foreign language detection disabled."); return null; } // TODO: Revisit this algorithm. try { final LangIdModel langId = getLangIdImpl(); final LangIdModel.LanguageResult[] langResults = langId.detectLanguages(text); if (langResults.length <= 0) { Loading @@ -651,8 +646,8 @@ public final class TextClassifierImpl implements TextClassifier { if (highestScoringResult.getScore() < threshold) { return null; } // TODO: Remove Log.d(LOG_TAG, String.format("Language detected: <%s:%s>", Log.v(LOG_TAG, String.format("Language detected: <%s:%s>", highestScoringResult.getLanguage(), highestScoringResult.getScore())); final Locale detected = new Locale(highestScoringResult.getLanguage()); Loading @@ -671,6 +666,18 @@ public final class TextClassifierImpl implements TextClassifier { return null; } private float getForeignLanguageThreshold() { try { return mSettings.getLangIdThresholdOverride() >= 0 ? mSettings.getLangIdThresholdOverride() : getLangIdImpl().getTranslateThreshold(); } catch (FileNotFoundException e) { final float defaultThreshold = 0.5f; Log.v(LOG_TAG, "Using default foreign language threshold: " + defaultThreshold); return defaultThreshold; } } @Override public void dump(@NonNull IndentingPrintWriter printWriter) { synchronized (mLock) { Loading Loading @@ -718,6 +725,19 @@ public final class TextClassifierImpl implements TextClassifier { } } /** * Returns the locale string for the current resources configuration. */ private String getResourceLocaleString() { // TODO: Pass the locale list once it is supported in native side. try { return mContext.getResources().getConfiguration().getLocales().get(0).toLanguageTag(); } catch (NullPointerException e) { // NPE is unexpected. Erring on the side of caution. return LocaleList.getDefault().get(0).toLanguageTag(); } } /** * Helper class to store the information from which RemoteActions are built. */ Loading
core/tests/coretests/src/android/view/textclassifier/TextClassificationTest.java +3 −2 Original line number Diff line number Diff line Loading @@ -93,8 +93,8 @@ public class TextClassificationTest { final String id = "id"; final TextClassification reference = new TextClassification.Builder() .setText(text) .addAction(remoteAction0) .addAction(remoteAction1) .addAction(remoteAction0) // Action intent not included. .addAction(remoteAction1) // Action intent not included. .setEntityType(TextClassifier.TYPE_ADDRESS, 0.3f) .setEntityType(TextClassifier.TYPE_PHONE, 0.7f) .setId(id) Loading Loading @@ -132,6 +132,7 @@ public class TextClassificationTest { // Extras assertEquals(BUNDLE_VALUE, result.getExtras().getString(BUNDLE_KEY)); assertNull(ExtrasUtils.getActionsIntents(result)); } @Test Loading