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.util.KeyValueListParser;
21 import android.util.Slog;
22 
23 import java.util.Arrays;
24 import java.util.Collections;
25 import java.util.List;
26 import java.util.StringJoiner;
27 
28 /**
29  * TextClassifier specific settings.
30  * This is encoded as a key=value list, separated by commas. Ex:
31  *
32  * <pre>
33  * smart_linkify_enabled                    (boolean)
34  * system_textclassifier_enabled            (boolean)
35  * model_dark_launch_enabled                (boolean)
36  * smart_selection_enabled                  (boolean)
37  * smart_text_share_enabled                 (boolean)
38  * smart_linkify_enabled                    (boolean)
39  * smart_select_animation_enabled           (boolean)
40  * suggest_selection_max_range_length       (int)
41  * classify_text_max_range_length           (int)
42  * generate_links_max_text_length           (int)
43  * generate_links_log_sample_rate           (int)
44  * entity_list_default                      (String[])
45  * entity_list_not_editable                 (String[])
46  * entity_list_editable                     (String[])
47  * </pre>
48  *
49  * <p>
50  * Type: string
51  * see also android.provider.Settings.Global.TEXT_CLASSIFIER_CONSTANTS
52  *
53  * Example of setting the values for testing.
54  * adb shell settings put global text_classifier_constants \
55  *      model_dark_launch_enabled=true,smart_selection_enabled=true,\
56  *      entity_list_default=phone:address
57  * @hide
58  */
59 public final class TextClassificationConstants {
60 
61     private static final String LOG_TAG = "TextClassificationConstants";
62 
63     private static final String LOCAL_TEXT_CLASSIFIER_ENABLED =
64             "local_textclassifier_enabled";
65     private static final String SYSTEM_TEXT_CLASSIFIER_ENABLED =
66             "system_textclassifier_enabled";
67     private static final String MODEL_DARK_LAUNCH_ENABLED =
68             "model_dark_launch_enabled";
69     private static final String SMART_SELECTION_ENABLED =
70             "smart_selection_enabled";
71     private static final String SMART_TEXT_SHARE_ENABLED =
72             "smart_text_share_enabled";
73     private static final String SMART_LINKIFY_ENABLED =
74             "smart_linkify_enabled";
75     private static final String SMART_SELECT_ANIMATION_ENABLED =
76             "smart_select_animation_enabled";
77     private static final String SUGGEST_SELECTION_MAX_RANGE_LENGTH =
78             "suggest_selection_max_range_length";
79     private static final String CLASSIFY_TEXT_MAX_RANGE_LENGTH =
80             "classify_text_max_range_length";
81     private static final String GENERATE_LINKS_MAX_TEXT_LENGTH =
82             "generate_links_max_text_length";
83     private static final String GENERATE_LINKS_LOG_SAMPLE_RATE =
84             "generate_links_log_sample_rate";
85     private static final String ENTITY_LIST_DEFAULT =
86             "entity_list_default";
87     private static final String ENTITY_LIST_NOT_EDITABLE =
88             "entity_list_not_editable";
89     private static final String ENTITY_LIST_EDITABLE =
90             "entity_list_editable";
91 
92     private static final boolean LOCAL_TEXT_CLASSIFIER_ENABLED_DEFAULT = true;
93     private static final boolean SYSTEM_TEXT_CLASSIFIER_ENABLED_DEFAULT = true;
94     private static final boolean MODEL_DARK_LAUNCH_ENABLED_DEFAULT = false;
95     private static final boolean SMART_SELECTION_ENABLED_DEFAULT = true;
96     private static final boolean SMART_TEXT_SHARE_ENABLED_DEFAULT = true;
97     private static final boolean SMART_LINKIFY_ENABLED_DEFAULT = true;
98     private static final boolean SMART_SELECT_ANIMATION_ENABLED_DEFAULT = true;
99     private static final int SUGGEST_SELECTION_MAX_RANGE_LENGTH_DEFAULT = 10 * 1000;
100     private static final int CLASSIFY_TEXT_MAX_RANGE_LENGTH_DEFAULT = 10 * 1000;
101     private static final int GENERATE_LINKS_MAX_TEXT_LENGTH_DEFAULT = 100 * 1000;
102     private static final int GENERATE_LINKS_LOG_SAMPLE_RATE_DEFAULT = 100;
103     private static final String ENTITY_LIST_DELIMITER = ":";
104     private static final String ENTITY_LIST_DEFAULT_VALUE = new StringJoiner(ENTITY_LIST_DELIMITER)
105             .add(TextClassifier.TYPE_ADDRESS)
106             .add(TextClassifier.TYPE_EMAIL)
107             .add(TextClassifier.TYPE_PHONE)
108             .add(TextClassifier.TYPE_URL)
109             .add(TextClassifier.TYPE_DATE)
110             .add(TextClassifier.TYPE_DATE_TIME)
111             .add(TextClassifier.TYPE_FLIGHT_NUMBER).toString();
112 
113     private final boolean mSystemTextClassifierEnabled;
114     private final boolean mLocalTextClassifierEnabled;
115     private final boolean mModelDarkLaunchEnabled;
116     private final boolean mSmartSelectionEnabled;
117     private final boolean mSmartTextShareEnabled;
118     private final boolean mSmartLinkifyEnabled;
119     private final boolean mSmartSelectionAnimationEnabled;
120     private final int mSuggestSelectionMaxRangeLength;
121     private final int mClassifyTextMaxRangeLength;
122     private final int mGenerateLinksMaxTextLength;
123     private final int mGenerateLinksLogSampleRate;
124     private final List<String> mEntityListDefault;
125     private final List<String> mEntityListNotEditable;
126     private final List<String> mEntityListEditable;
127 
TextClassificationConstants(@ullable String settings)128     private TextClassificationConstants(@Nullable String settings) {
129         final KeyValueListParser parser = new KeyValueListParser(',');
130         try {
131             parser.setString(settings);
132         } catch (IllegalArgumentException e) {
133             // Failed to parse the settings string, log this and move on with defaults.
134             Slog.e(LOG_TAG, "Bad TextClassifier settings: " + settings);
135         }
136         mSystemTextClassifierEnabled = parser.getBoolean(
137                 SYSTEM_TEXT_CLASSIFIER_ENABLED,
138                 SYSTEM_TEXT_CLASSIFIER_ENABLED_DEFAULT);
139         mLocalTextClassifierEnabled = parser.getBoolean(
140                 LOCAL_TEXT_CLASSIFIER_ENABLED,
141                 LOCAL_TEXT_CLASSIFIER_ENABLED_DEFAULT);
142         mModelDarkLaunchEnabled = parser.getBoolean(
143                 MODEL_DARK_LAUNCH_ENABLED,
144                 MODEL_DARK_LAUNCH_ENABLED_DEFAULT);
145         mSmartSelectionEnabled = parser.getBoolean(
146                 SMART_SELECTION_ENABLED,
147                 SMART_SELECTION_ENABLED_DEFAULT);
148         mSmartTextShareEnabled = parser.getBoolean(
149                 SMART_TEXT_SHARE_ENABLED,
150                 SMART_TEXT_SHARE_ENABLED_DEFAULT);
151         mSmartLinkifyEnabled = parser.getBoolean(
152                 SMART_LINKIFY_ENABLED,
153                 SMART_LINKIFY_ENABLED_DEFAULT);
154         mSmartSelectionAnimationEnabled = parser.getBoolean(
155                 SMART_SELECT_ANIMATION_ENABLED,
156                 SMART_SELECT_ANIMATION_ENABLED_DEFAULT);
157         mSuggestSelectionMaxRangeLength = parser.getInt(
158                 SUGGEST_SELECTION_MAX_RANGE_LENGTH,
159                 SUGGEST_SELECTION_MAX_RANGE_LENGTH_DEFAULT);
160         mClassifyTextMaxRangeLength = parser.getInt(
161                 CLASSIFY_TEXT_MAX_RANGE_LENGTH,
162                 CLASSIFY_TEXT_MAX_RANGE_LENGTH_DEFAULT);
163         mGenerateLinksMaxTextLength = parser.getInt(
164                 GENERATE_LINKS_MAX_TEXT_LENGTH,
165                 GENERATE_LINKS_MAX_TEXT_LENGTH_DEFAULT);
166         mGenerateLinksLogSampleRate = parser.getInt(
167                 GENERATE_LINKS_LOG_SAMPLE_RATE,
168                 GENERATE_LINKS_LOG_SAMPLE_RATE_DEFAULT);
169         mEntityListDefault = parseEntityList(parser.getString(
170                 ENTITY_LIST_DEFAULT,
171                 ENTITY_LIST_DEFAULT_VALUE));
172         mEntityListNotEditable = parseEntityList(parser.getString(
173                 ENTITY_LIST_NOT_EDITABLE,
174                 ENTITY_LIST_DEFAULT_VALUE));
175         mEntityListEditable = parseEntityList(parser.getString(
176                 ENTITY_LIST_EDITABLE,
177                 ENTITY_LIST_DEFAULT_VALUE));
178     }
179 
180     /** Load from a settings string. */
loadFromString(String settings)181     public static TextClassificationConstants loadFromString(String settings) {
182         return new TextClassificationConstants(settings);
183     }
184 
isLocalTextClassifierEnabled()185     public boolean isLocalTextClassifierEnabled() {
186         return mLocalTextClassifierEnabled;
187     }
188 
isSystemTextClassifierEnabled()189     public boolean isSystemTextClassifierEnabled() {
190         return mSystemTextClassifierEnabled;
191     }
192 
isModelDarkLaunchEnabled()193     public boolean isModelDarkLaunchEnabled() {
194         return mModelDarkLaunchEnabled;
195     }
196 
isSmartSelectionEnabled()197     public boolean isSmartSelectionEnabled() {
198         return mSmartSelectionEnabled;
199     }
200 
isSmartTextShareEnabled()201     public boolean isSmartTextShareEnabled() {
202         return mSmartTextShareEnabled;
203     }
204 
isSmartLinkifyEnabled()205     public boolean isSmartLinkifyEnabled() {
206         return mSmartLinkifyEnabled;
207     }
208 
isSmartSelectionAnimationEnabled()209     public boolean isSmartSelectionAnimationEnabled() {
210         return mSmartSelectionAnimationEnabled;
211     }
212 
getSuggestSelectionMaxRangeLength()213     public int getSuggestSelectionMaxRangeLength() {
214         return mSuggestSelectionMaxRangeLength;
215     }
216 
getClassifyTextMaxRangeLength()217     public int getClassifyTextMaxRangeLength() {
218         return mClassifyTextMaxRangeLength;
219     }
220 
getGenerateLinksMaxTextLength()221     public int getGenerateLinksMaxTextLength() {
222         return mGenerateLinksMaxTextLength;
223     }
224 
getGenerateLinksLogSampleRate()225     public int getGenerateLinksLogSampleRate() {
226         return mGenerateLinksLogSampleRate;
227     }
228 
getEntityListDefault()229     public List<String> getEntityListDefault() {
230         return mEntityListDefault;
231     }
232 
getEntityListNotEditable()233     public List<String> getEntityListNotEditable() {
234         return mEntityListNotEditable;
235     }
236 
getEntityListEditable()237     public List<String> getEntityListEditable() {
238         return mEntityListEditable;
239     }
240 
parseEntityList(String listStr)241     private static List<String> parseEntityList(String listStr) {
242         return Collections.unmodifiableList(Arrays.asList(listStr.split(ENTITY_LIST_DELIMITER)));
243     }
244 }
245