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 android.annotation.Nullable; 20 import android.provider.DeviceConfig; 21 22 import com.android.internal.annotations.VisibleForTesting; 23 import com.android.internal.util.IndentingPrintWriter; 24 25 import java.util.Optional; 26 27 /** 28 * TextClassifier specific settings. 29 * 30 * <p>Currently, this class does not guarantee co-diverted flags are updated atomically. 31 * 32 * <pre> 33 * adb shell cmd device_config put textclassifier system_textclassifier_enabled true 34 * </pre> 35 * 36 * @see android.provider.DeviceConfig#NAMESPACE_TEXTCLASSIFIER 37 * @hide 38 */ 39 // TODO: Rename to TextClassifierSettings. 40 public final class TextClassificationConstants { 41 /** Whether the smart linkify feature is enabled. */ 42 private static final String SMART_LINKIFY_ENABLED = "smart_linkify_enabled"; 43 44 /** Whether SystemTextClassifier is enabled. */ 45 static final String SYSTEM_TEXT_CLASSIFIER_ENABLED = "system_textclassifier_enabled"; 46 47 /** Whether TextClassifierImpl is enabled. */ 48 @VisibleForTesting 49 static final String LOCAL_TEXT_CLASSIFIER_ENABLED = "local_textclassifier_enabled"; 50 51 /** Enable smart selection without a visible UI changes. */ 52 private static final String MODEL_DARK_LAUNCH_ENABLED = "model_dark_launch_enabled"; 53 54 /** Whether the smart selection feature is enabled. */ 55 private static final String SMART_SELECTION_ENABLED = "smart_selection_enabled"; 56 57 /** Whether the smart text share feature is enabled. */ 58 private static final String SMART_TEXT_SHARE_ENABLED = "smart_text_share_enabled"; 59 60 /** Whether animation for smart selection is enabled. */ 61 private static final String SMART_SELECT_ANIMATION_ENABLED = "smart_select_animation_enabled"; 62 63 /** Max length of text that generateLinks can accept. */ 64 @VisibleForTesting 65 static final String GENERATE_LINKS_MAX_TEXT_LENGTH = "generate_links_max_text_length"; 66 67 /** 68 * The TextClassifierService which would like to use. Example of setting the package: 69 * 70 * <pre> 71 * adb shell cmd device_config put textclassifier textclassifier_service_package_override \ 72 * com.android.textclassifier 73 * </pre> 74 */ 75 @VisibleForTesting 76 static final String TEXT_CLASSIFIER_SERVICE_PACKAGE_OVERRIDE = 77 "textclassifier_service_package_override"; 78 79 /** 80 * The timeout value in seconds used by {@link SystemTextClassifier} for each TextClassifier API 81 * calls. 82 */ 83 @VisibleForTesting 84 static final String SYSTEM_TEXT_CLASSIFIER_API_TIMEOUT_IN_SECOND = 85 "system_textclassifier_api_timeout_in_second"; 86 87 /** 88 * The maximum amount of characters before and after the selected text that is passed to the 89 * TextClassifier for the smart selection. e.g. If this value is 100, then 100 characters before 90 * the selection and 100 characters after the selection will be passed to the TextClassifier. 91 */ 92 private static final String SMART_SELECTION_TRIM_DELTA = "smart_selection_trim_delta"; 93 94 private static final String DEFAULT_TEXT_CLASSIFIER_SERVICE_PACKAGE_OVERRIDE = null; 95 private static final boolean LOCAL_TEXT_CLASSIFIER_ENABLED_DEFAULT = true; 96 private static final boolean SYSTEM_TEXT_CLASSIFIER_ENABLED_DEFAULT = true; 97 private static final boolean MODEL_DARK_LAUNCH_ENABLED_DEFAULT = false; 98 private static final boolean SMART_SELECTION_ENABLED_DEFAULT = true; 99 private static final boolean SMART_TEXT_SHARE_ENABLED_DEFAULT = true; 100 private static final boolean SMART_LINKIFY_ENABLED_DEFAULT = true; 101 private static final boolean SMART_SELECT_ANIMATION_ENABLED_DEFAULT = true; 102 private static final int GENERATE_LINKS_MAX_TEXT_LENGTH_DEFAULT = 100 * 1000; 103 private static final long SYSTEM_TEXT_CLASSIFIER_API_TIMEOUT_IN_SECOND_DEFAULT = 60; 104 private static final int SMART_SELECTION_TRIM_DELTA_DEFAULT = 120; 105 106 private static final Object sLock = new Object(); 107 private static volatile boolean sMemoizedValuesInitialized; 108 private static boolean sLocalTextClassifierEnabled; 109 private static boolean sSystemTextClassifierEnabled; 110 private static boolean sModelDarkLaunchEnabled; 111 private static boolean sSmartSelectionEnabled; 112 private static boolean sSmartTextShareEnabled; 113 private static boolean sSmartLinkifyEnabled; 114 private static boolean sSmartSelectAnimationEnabled; 115 private static int sGenerateLinksMaxTextLength; 116 private static long sSystemTextClassifierApiTimeoutInSecond; 117 private static int sSmartSelectionTrimDelta; 118 119 /** 120 * For DeviceConfig values where we don't care if they change at runtime, fetch them once and 121 * memoize their values. 122 */ ensureMemoizedValues()123 private static void ensureMemoizedValues() { 124 if (sMemoizedValuesInitialized) { 125 return; 126 } 127 synchronized (sLock) { 128 if (sMemoizedValuesInitialized) { 129 return; 130 } 131 132 // Read all namespace properties so we get a single snapshot (values 133 // fetched aren't updated in the interim). 134 DeviceConfig.Properties properties = 135 DeviceConfig.getProperties(DeviceConfig.NAMESPACE_TEXTCLASSIFIER); 136 sLocalTextClassifierEnabled = 137 properties.getBoolean( 138 LOCAL_TEXT_CLASSIFIER_ENABLED, 139 LOCAL_TEXT_CLASSIFIER_ENABLED_DEFAULT); 140 sModelDarkLaunchEnabled = 141 properties.getBoolean( 142 MODEL_DARK_LAUNCH_ENABLED, 143 MODEL_DARK_LAUNCH_ENABLED_DEFAULT); 144 sSmartSelectionEnabled = 145 properties.getBoolean( 146 SMART_SELECTION_ENABLED, 147 SMART_SELECTION_ENABLED_DEFAULT); 148 sSmartTextShareEnabled = 149 properties.getBoolean( 150 SMART_TEXT_SHARE_ENABLED, 151 SMART_TEXT_SHARE_ENABLED_DEFAULT); 152 sSmartLinkifyEnabled = 153 properties.getBoolean( 154 SMART_LINKIFY_ENABLED, 155 SMART_LINKIFY_ENABLED_DEFAULT); 156 sSmartSelectAnimationEnabled = 157 properties.getBoolean( 158 SMART_SELECT_ANIMATION_ENABLED, 159 SMART_SELECT_ANIMATION_ENABLED_DEFAULT); 160 sGenerateLinksMaxTextLength = 161 properties.getInt( 162 GENERATE_LINKS_MAX_TEXT_LENGTH, 163 GENERATE_LINKS_MAX_TEXT_LENGTH_DEFAULT); 164 sSystemTextClassifierApiTimeoutInSecond = 165 properties.getLong( 166 SYSTEM_TEXT_CLASSIFIER_API_TIMEOUT_IN_SECOND, 167 SYSTEM_TEXT_CLASSIFIER_API_TIMEOUT_IN_SECOND_DEFAULT); 168 sSmartSelectionTrimDelta = 169 properties.getInt( 170 SMART_SELECTION_TRIM_DELTA, 171 SMART_SELECTION_TRIM_DELTA_DEFAULT); 172 173 sMemoizedValuesInitialized = true; 174 } 175 } 176 177 @VisibleForTesting resetMemoizedValues()178 public static void resetMemoizedValues() { 179 sMemoizedValuesInitialized = false; 180 } 181 182 @Nullable getTextClassifierServicePackageOverride()183 public String getTextClassifierServicePackageOverride() { 184 // Don't memoize this value because we want to be able to receive config 185 // updates at runtime. 186 return DeviceConfig.getString( 187 DeviceConfig.NAMESPACE_TEXTCLASSIFIER, 188 TEXT_CLASSIFIER_SERVICE_PACKAGE_OVERRIDE, 189 DEFAULT_TEXT_CLASSIFIER_SERVICE_PACKAGE_OVERRIDE); 190 } 191 isLocalTextClassifierEnabled()192 public boolean isLocalTextClassifierEnabled() { 193 ensureMemoizedValues(); 194 return sLocalTextClassifierEnabled; 195 } 196 isSystemTextClassifierEnabled()197 public boolean isSystemTextClassifierEnabled() { 198 // Don't memoize this value because we want to be able to receive config 199 // updates at runtime. 200 return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_TEXTCLASSIFIER, 201 SYSTEM_TEXT_CLASSIFIER_ENABLED, 202 SYSTEM_TEXT_CLASSIFIER_ENABLED_DEFAULT); 203 } 204 isModelDarkLaunchEnabled()205 public boolean isModelDarkLaunchEnabled() { 206 ensureMemoizedValues(); 207 return sModelDarkLaunchEnabled; 208 } 209 isSmartSelectionEnabled()210 public boolean isSmartSelectionEnabled() { 211 ensureMemoizedValues(); 212 return sSmartSelectionEnabled; 213 } 214 isSmartTextShareEnabled()215 public boolean isSmartTextShareEnabled() { 216 ensureMemoizedValues(); 217 return sSmartTextShareEnabled; 218 } 219 isSmartLinkifyEnabled()220 public boolean isSmartLinkifyEnabled() { 221 ensureMemoizedValues(); 222 return sSmartLinkifyEnabled; 223 } 224 isSmartSelectionAnimationEnabled()225 public boolean isSmartSelectionAnimationEnabled() { 226 ensureMemoizedValues(); 227 return sSmartSelectAnimationEnabled; 228 } 229 getGenerateLinksMaxTextLength()230 public int getGenerateLinksMaxTextLength() { 231 ensureMemoizedValues(); 232 return sGenerateLinksMaxTextLength; 233 } 234 getSystemTextClassifierApiTimeoutInSecond()235 public long getSystemTextClassifierApiTimeoutInSecond() { 236 ensureMemoizedValues(); 237 return sSystemTextClassifierApiTimeoutInSecond; 238 } 239 getSmartSelectionTrimDelta()240 public int getSmartSelectionTrimDelta() { 241 ensureMemoizedValues(); 242 return sSmartSelectionTrimDelta; 243 } 244 dump(IndentingPrintWriter pw)245 void dump(IndentingPrintWriter pw) { 246 pw.println("TextClassificationConstants:"); 247 pw.increaseIndent(); 248 pw.print(GENERATE_LINKS_MAX_TEXT_LENGTH, getGenerateLinksMaxTextLength()).println(); 249 pw.print(LOCAL_TEXT_CLASSIFIER_ENABLED, isLocalTextClassifierEnabled()).println(); 250 pw.print(MODEL_DARK_LAUNCH_ENABLED, isModelDarkLaunchEnabled()).println(); 251 pw.print(SMART_LINKIFY_ENABLED, isSmartLinkifyEnabled()).println(); 252 pw.print(SMART_SELECT_ANIMATION_ENABLED, isSmartSelectionAnimationEnabled()).println(); 253 pw.print(SMART_SELECTION_ENABLED, isSmartSelectionEnabled()).println(); 254 pw.print(SMART_TEXT_SHARE_ENABLED, isSmartTextShareEnabled()).println(); 255 pw.print(SYSTEM_TEXT_CLASSIFIER_ENABLED, isSystemTextClassifierEnabled()).println(); 256 pw.print( 257 TEXT_CLASSIFIER_SERVICE_PACKAGE_OVERRIDE, 258 getTextClassifierServicePackageOverride()) 259 .println(); 260 pw.print( 261 SYSTEM_TEXT_CLASSIFIER_API_TIMEOUT_IN_SECOND, 262 getSystemTextClassifierApiTimeoutInSecond()) 263 .println(); 264 pw.print(SMART_SELECTION_TRIM_DELTA, getSmartSelectionTrimDelta()).println(); 265 pw.decreaseIndent(); 266 } 267 } 268