1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.view.textclassifier; 18 19 import com.android.internal.util.IndentingPrintWriter; 20 21 import java.util.Arrays; 22 import java.util.List; 23 import java.util.function.Supplier; 24 25 /** 26 * TextClassifier specific settings. 27 * This is encoded as a key=value list, separated by commas. 28 * <p> 29 * Example of setting the values for testing. 30 * <p> 31 * <pre> 32 * adb shell settings put global text_classifier_constants \ 33 * model_dark_launch_enabled=true,smart_selection_enabled=true, \ 34 * entity_list_default=phone:address, \ 35 * lang_id_context_settings=20:1.0:0.4 36 * </pre> 37 * <p> 38 * Settings are also available in device config. These take precedence over those in settings 39 * global. 40 * <p> 41 * <pre> 42 * adb shell cmd device_config put textclassifier system_textclassifier_enabled true 43 * </pre> 44 * 45 * @see android.provider.Settings.Global.TEXT_CLASSIFIER_CONSTANTS 46 * @see android.provider.DeviceConfig.NAMESPACE_TEXTCLASSIFIER 47 * @hide 48 */ 49 // TODO: Rename to TextClassifierSettings. 50 public final class TextClassificationConstants { 51 52 /** 53 * Whether the smart linkify feature is enabled. 54 */ 55 private static final String SMART_LINKIFY_ENABLED = "smart_linkify_enabled"; 56 /** 57 * Whether SystemTextClassifier is enabled. 58 */ 59 private static final String SYSTEM_TEXT_CLASSIFIER_ENABLED = "system_textclassifier_enabled"; 60 /** 61 * Whether TextClassifierImpl is enabled. 62 */ 63 private static final String LOCAL_TEXT_CLASSIFIER_ENABLED = "local_textclassifier_enabled"; 64 /** 65 * Enable smart selection without a visible UI changes. 66 */ 67 private static final String MODEL_DARK_LAUNCH_ENABLED = "model_dark_launch_enabled"; 68 69 /** 70 * Whether the smart selection feature is enabled. 71 */ 72 private static final String SMART_SELECTION_ENABLED = "smart_selection_enabled"; 73 /** 74 * Whether the smart text share feature is enabled. 75 */ 76 private static final String SMART_TEXT_SHARE_ENABLED = "smart_text_share_enabled"; 77 /** 78 * Whether animation for smart selection is enabled. 79 */ 80 private static final String SMART_SELECT_ANIMATION_ENABLED = 81 "smart_select_animation_enabled"; 82 /** 83 * Max length of text that suggestSelection can accept. 84 */ 85 private static final String SUGGEST_SELECTION_MAX_RANGE_LENGTH = 86 "suggest_selection_max_range_length"; 87 /** 88 * Max length of text that classifyText can accept. 89 */ 90 private static final String CLASSIFY_TEXT_MAX_RANGE_LENGTH = "classify_text_max_range_length"; 91 /** 92 * Max length of text that generateLinks can accept. 93 */ 94 private static final String GENERATE_LINKS_MAX_TEXT_LENGTH = "generate_links_max_text_length"; 95 /** 96 * Sampling rate for generateLinks logging. 97 */ 98 private static final String GENERATE_LINKS_LOG_SAMPLE_RATE = 99 "generate_links_log_sample_rate"; 100 /** 101 * A colon(:) separated string that specifies the default entities types for 102 * generateLinks when hint is not given. 103 */ 104 private static final String ENTITY_LIST_DEFAULT = "entity_list_default"; 105 /** 106 * A colon(:) separated string that specifies the default entities types for 107 * generateLinks when the text is in a not editable UI widget. 108 */ 109 private static final String ENTITY_LIST_NOT_EDITABLE = "entity_list_not_editable"; 110 /** 111 * A colon(:) separated string that specifies the default entities types for 112 * generateLinks when the text is in an editable UI widget. 113 */ 114 private static final String ENTITY_LIST_EDITABLE = "entity_list_editable"; 115 /** 116 * A colon(:) separated string that specifies the default action types for 117 * suggestConversationActions when the suggestions are used in an app. 118 */ 119 private static final String IN_APP_CONVERSATION_ACTION_TYPES_DEFAULT = 120 "in_app_conversation_action_types_default"; 121 /** 122 * A colon(:) separated string that specifies the default action types for 123 * suggestConversationActions when the suggestions are used in a notification. 124 */ 125 private static final String NOTIFICATION_CONVERSATION_ACTION_TYPES_DEFAULT = 126 "notification_conversation_action_types_default"; 127 /** 128 * Threshold to accept a suggested language from LangID model. 129 */ 130 private static final String LANG_ID_THRESHOLD_OVERRIDE = "lang_id_threshold_override"; 131 /** 132 * Whether to enable {@link android.view.textclassifier.TemplateIntentFactory}. 133 */ 134 private static final String TEMPLATE_INTENT_FACTORY_ENABLED = "template_intent_factory_enabled"; 135 /** 136 * Whether to enable "translate" action in classifyText. 137 */ 138 private static final String TRANSLATE_IN_CLASSIFICATION_ENABLED = 139 "translate_in_classification_enabled"; 140 /** 141 * Whether to detect the languages of the text in request by using langId for the native 142 * model. 143 */ 144 private static final String DETECT_LANGUAGES_FROM_TEXT_ENABLED = 145 "detect_languages_from_text_enabled"; 146 /** 147 * A colon(:) separated string that specifies the configuration to use when including 148 * surrounding context text in language detection queries. 149 * <p> 150 * Format= minimumTextSize<int>:penalizeRatio<float>:textScoreRatio<float> 151 * <p> 152 * e.g. 20:1.0:0.4 153 * <p> 154 * Accept all text lengths with minimumTextSize=0 155 * <p> 156 * Reject all text less than minimumTextSize with penalizeRatio=0 157 * @see {@code TextClassifierImpl#detectLanguages(String, int, int)} for reference. 158 */ 159 private static final String LANG_ID_CONTEXT_SETTINGS = "lang_id_context_settings"; 160 161 private static final boolean LOCAL_TEXT_CLASSIFIER_ENABLED_DEFAULT = true; 162 private static final boolean SYSTEM_TEXT_CLASSIFIER_ENABLED_DEFAULT = true; 163 private static final boolean MODEL_DARK_LAUNCH_ENABLED_DEFAULT = false; 164 private static final boolean SMART_SELECTION_ENABLED_DEFAULT = true; 165 private static final boolean SMART_TEXT_SHARE_ENABLED_DEFAULT = true; 166 private static final boolean SMART_LINKIFY_ENABLED_DEFAULT = true; 167 private static final boolean SMART_SELECT_ANIMATION_ENABLED_DEFAULT = true; 168 private static final int SUGGEST_SELECTION_MAX_RANGE_LENGTH_DEFAULT = 10 * 1000; 169 private static final int CLASSIFY_TEXT_MAX_RANGE_LENGTH_DEFAULT = 10 * 1000; 170 private static final int GENERATE_LINKS_MAX_TEXT_LENGTH_DEFAULT = 100 * 1000; 171 private static final int GENERATE_LINKS_LOG_SAMPLE_RATE_DEFAULT = 100; 172 private static final List<String> ENTITY_LIST_DEFAULT_VALUE = Arrays.asList( 173 TextClassifier.TYPE_ADDRESS, 174 TextClassifier.TYPE_EMAIL, 175 TextClassifier.TYPE_PHONE, 176 TextClassifier.TYPE_URL, 177 TextClassifier.TYPE_DATE, 178 TextClassifier.TYPE_DATE_TIME, 179 TextClassifier.TYPE_FLIGHT_NUMBER); 180 private static final List<String> CONVERSATION_ACTIONS_TYPES_DEFAULT_VALUES = Arrays.asList( 181 ConversationAction.TYPE_TEXT_REPLY, 182 ConversationAction.TYPE_CREATE_REMINDER, 183 ConversationAction.TYPE_CALL_PHONE, 184 ConversationAction.TYPE_OPEN_URL, 185 ConversationAction.TYPE_SEND_EMAIL, 186 ConversationAction.TYPE_SEND_SMS, 187 ConversationAction.TYPE_TRACK_FLIGHT, 188 ConversationAction.TYPE_VIEW_CALENDAR, 189 ConversationAction.TYPE_VIEW_MAP, 190 ConversationAction.TYPE_ADD_CONTACT, 191 ConversationAction.TYPE_COPY); 192 /** 193 * < 0 : Not set. Use value from LangId model. 194 * 0 - 1: Override value in LangId model. 195 * 196 * @see EntityConfidence 197 */ 198 private static final float LANG_ID_THRESHOLD_OVERRIDE_DEFAULT = -1f; 199 private static final boolean TEMPLATE_INTENT_FACTORY_ENABLED_DEFAULT = true; 200 private static final boolean TRANSLATE_IN_CLASSIFICATION_ENABLED_DEFAULT = true; 201 private static final boolean DETECT_LANGUAGES_FROM_TEXT_ENABLED_DEFAULT = true; 202 private static final float[] LANG_ID_CONTEXT_SETTINGS_DEFAULT = new float[] {20f, 1.0f, 0.4f}; 203 204 private final ConfigParser mConfigParser; 205 TextClassificationConstants(Supplier<String> legacySettingsSupplier)206 public TextClassificationConstants(Supplier<String> legacySettingsSupplier) { 207 mConfigParser = new ConfigParser(legacySettingsSupplier); 208 } 209 isLocalTextClassifierEnabled()210 public boolean isLocalTextClassifierEnabled() { 211 return mConfigParser.getBoolean( 212 LOCAL_TEXT_CLASSIFIER_ENABLED, 213 LOCAL_TEXT_CLASSIFIER_ENABLED_DEFAULT); 214 } 215 isSystemTextClassifierEnabled()216 public boolean isSystemTextClassifierEnabled() { 217 return mConfigParser.getBoolean( 218 SYSTEM_TEXT_CLASSIFIER_ENABLED, 219 SYSTEM_TEXT_CLASSIFIER_ENABLED_DEFAULT); 220 } 221 isModelDarkLaunchEnabled()222 public boolean isModelDarkLaunchEnabled() { 223 return mConfigParser.getBoolean( 224 MODEL_DARK_LAUNCH_ENABLED, 225 MODEL_DARK_LAUNCH_ENABLED_DEFAULT); 226 } 227 isSmartSelectionEnabled()228 public boolean isSmartSelectionEnabled() { 229 return mConfigParser.getBoolean( 230 SMART_SELECTION_ENABLED, 231 SMART_SELECTION_ENABLED_DEFAULT); 232 } 233 isSmartTextShareEnabled()234 public boolean isSmartTextShareEnabled() { 235 return mConfigParser.getBoolean( 236 SMART_TEXT_SHARE_ENABLED, 237 SMART_TEXT_SHARE_ENABLED_DEFAULT); 238 } 239 isSmartLinkifyEnabled()240 public boolean isSmartLinkifyEnabled() { 241 return mConfigParser.getBoolean( 242 SMART_LINKIFY_ENABLED, 243 SMART_LINKIFY_ENABLED_DEFAULT); 244 } 245 isSmartSelectionAnimationEnabled()246 public boolean isSmartSelectionAnimationEnabled() { 247 return mConfigParser.getBoolean( 248 SMART_SELECT_ANIMATION_ENABLED, 249 SMART_SELECT_ANIMATION_ENABLED_DEFAULT); 250 } 251 getSuggestSelectionMaxRangeLength()252 public int getSuggestSelectionMaxRangeLength() { 253 return mConfigParser.getInt( 254 SUGGEST_SELECTION_MAX_RANGE_LENGTH, 255 SUGGEST_SELECTION_MAX_RANGE_LENGTH_DEFAULT); 256 } 257 getClassifyTextMaxRangeLength()258 public int getClassifyTextMaxRangeLength() { 259 return mConfigParser.getInt( 260 CLASSIFY_TEXT_MAX_RANGE_LENGTH, 261 CLASSIFY_TEXT_MAX_RANGE_LENGTH_DEFAULT); 262 } 263 getGenerateLinksMaxTextLength()264 public int getGenerateLinksMaxTextLength() { 265 return mConfigParser.getInt( 266 GENERATE_LINKS_MAX_TEXT_LENGTH, 267 GENERATE_LINKS_MAX_TEXT_LENGTH_DEFAULT); 268 } 269 getGenerateLinksLogSampleRate()270 public int getGenerateLinksLogSampleRate() { 271 return mConfigParser.getInt( 272 GENERATE_LINKS_LOG_SAMPLE_RATE, 273 GENERATE_LINKS_LOG_SAMPLE_RATE_DEFAULT); 274 } 275 getEntityListDefault()276 public List<String> getEntityListDefault() { 277 return mConfigParser.getStringList( 278 ENTITY_LIST_DEFAULT, 279 ENTITY_LIST_DEFAULT_VALUE); 280 } 281 getEntityListNotEditable()282 public List<String> getEntityListNotEditable() { 283 return mConfigParser.getStringList( 284 ENTITY_LIST_NOT_EDITABLE, 285 ENTITY_LIST_DEFAULT_VALUE); 286 } 287 getEntityListEditable()288 public List<String> getEntityListEditable() { 289 return mConfigParser.getStringList( 290 ENTITY_LIST_EDITABLE, 291 ENTITY_LIST_DEFAULT_VALUE); 292 } 293 getInAppConversationActionTypes()294 public List<String> getInAppConversationActionTypes() { 295 return mConfigParser.getStringList( 296 IN_APP_CONVERSATION_ACTION_TYPES_DEFAULT, 297 CONVERSATION_ACTIONS_TYPES_DEFAULT_VALUES); 298 } 299 getNotificationConversationActionTypes()300 public List<String> getNotificationConversationActionTypes() { 301 return mConfigParser.getStringList( 302 NOTIFICATION_CONVERSATION_ACTION_TYPES_DEFAULT, 303 CONVERSATION_ACTIONS_TYPES_DEFAULT_VALUES); 304 } 305 getLangIdThresholdOverride()306 public float getLangIdThresholdOverride() { 307 return mConfigParser.getFloat( 308 LANG_ID_THRESHOLD_OVERRIDE, 309 LANG_ID_THRESHOLD_OVERRIDE_DEFAULT); 310 } 311 isTemplateIntentFactoryEnabled()312 public boolean isTemplateIntentFactoryEnabled() { 313 return mConfigParser.getBoolean( 314 TEMPLATE_INTENT_FACTORY_ENABLED, 315 TEMPLATE_INTENT_FACTORY_ENABLED_DEFAULT); 316 } 317 isTranslateInClassificationEnabled()318 public boolean isTranslateInClassificationEnabled() { 319 return mConfigParser.getBoolean( 320 TRANSLATE_IN_CLASSIFICATION_ENABLED, 321 TRANSLATE_IN_CLASSIFICATION_ENABLED_DEFAULT); 322 } 323 isDetectLanguagesFromTextEnabled()324 public boolean isDetectLanguagesFromTextEnabled() { 325 return mConfigParser.getBoolean( 326 DETECT_LANGUAGES_FROM_TEXT_ENABLED, 327 DETECT_LANGUAGES_FROM_TEXT_ENABLED_DEFAULT); 328 } 329 getLangIdContextSettings()330 public float[] getLangIdContextSettings() { 331 return mConfigParser.getFloatArray( 332 LANG_ID_CONTEXT_SETTINGS, 333 LANG_ID_CONTEXT_SETTINGS_DEFAULT); 334 } 335 dump(IndentingPrintWriter pw)336 void dump(IndentingPrintWriter pw) { 337 pw.println("TextClassificationConstants:"); 338 pw.increaseIndent(); 339 pw.printPair("classify_text_max_range_length", getClassifyTextMaxRangeLength()) 340 .println(); 341 pw.printPair("detect_language_from_text_enabled", isDetectLanguagesFromTextEnabled()) 342 .println(); 343 pw.printPair("entity_list_default", getEntityListDefault()) 344 .println(); 345 pw.printPair("entity_list_editable", getEntityListEditable()) 346 .println(); 347 pw.printPair("entity_list_not_editable", getEntityListNotEditable()) 348 .println(); 349 pw.printPair("generate_links_log_sample_rate", getGenerateLinksLogSampleRate()) 350 .println(); 351 pw.printPair("generate_links_max_text_length", getGenerateLinksMaxTextLength()) 352 .println(); 353 pw.printPair("in_app_conversation_action_types_default", getInAppConversationActionTypes()) 354 .println(); 355 pw.printPair("lang_id_context_settings", Arrays.toString(getLangIdContextSettings())) 356 .println(); 357 pw.printPair("lang_id_threshold_override", getLangIdThresholdOverride()) 358 .println(); 359 pw.printPair("local_textclassifier_enabled", isLocalTextClassifierEnabled()) 360 .println(); 361 pw.printPair("model_dark_launch_enabled", isModelDarkLaunchEnabled()) 362 .println(); 363 pw.printPair("notification_conversation_action_types_default", 364 getNotificationConversationActionTypes()).println(); 365 pw.printPair("smart_linkify_enabled", isSmartLinkifyEnabled()) 366 .println(); 367 pw.printPair("smart_select_animation_enabled", isSmartSelectionAnimationEnabled()) 368 .println(); 369 pw.printPair("smart_selection_enabled", isSmartSelectionEnabled()) 370 .println(); 371 pw.printPair("smart_text_share_enabled", isSmartTextShareEnabled()) 372 .println(); 373 pw.printPair("suggest_selection_max_range_length", getSuggestSelectionMaxRangeLength()) 374 .println(); 375 pw.printPair("system_textclassifier_enabled", isSystemTextClassifierEnabled()) 376 .println(); 377 pw.printPair("template_intent_factory_enabled", isTemplateIntentFactoryEnabled()) 378 .println(); 379 pw.printPair("translate_in_classification_enabled", isTranslateInClassificationEnabled()) 380 .println(); 381 pw.decreaseIndent(); 382 } 383 }