For Wear devices download textclassifier manifest on charger
Moving cl/569239296 to main

Test: make && make dist

Change-Id: I41020f4bded9e278edaf7f2842df7b8152289ea0
diff --git a/java/src/com/android/textclassifier/DefaultTextClassifierService.java b/java/src/com/android/textclassifier/DefaultTextClassifierService.java
index d57af5e..d34f860 100644
--- a/java/src/com/android/textclassifier/DefaultTextClassifierService.java
+++ b/java/src/com/android/textclassifier/DefaultTextClassifierService.java
@@ -316,7 +316,7 @@
 
     @Override
     public TextClassifierSettings createTextClassifierSettings() {
-      return new TextClassifierSettings();
+      return new TextClassifierSettings(getContext());
     }
 
     @Override
diff --git a/java/src/com/android/textclassifier/common/TextClassifierSettings.java b/java/src/com/android/textclassifier/common/TextClassifierSettings.java
index d0ea917..6de8fe2 100644
--- a/java/src/com/android/textclassifier/common/TextClassifierSettings.java
+++ b/java/src/com/android/textclassifier/common/TextClassifierSettings.java
@@ -18,6 +18,8 @@
 
 import static java.util.concurrent.TimeUnit.HOURS;
 
+import android.content.Context;
+import android.content.pm.PackageManager;
 import android.provider.DeviceConfig;
 import android.provider.DeviceConfig.Properties;
 import android.text.TextUtils;
@@ -55,15 +57,20 @@
 
   /** Whether the user language profile feature is enabled. */
   private static final String USER_LANGUAGE_PROFILE_ENABLED = "user_language_profile_enabled";
+
   /** Max length of text that suggestSelection can accept. */
   @VisibleForTesting
   static final String SUGGEST_SELECTION_MAX_RANGE_LENGTH = "suggest_selection_max_range_length";
+
   /** Max length of text that classifyText can accept. */
   private static final String CLASSIFY_TEXT_MAX_RANGE_LENGTH = "classify_text_max_range_length";
+
   /** Max length of text that generateLinks can accept. */
   private static final String GENERATE_LINKS_MAX_TEXT_LENGTH = "generate_links_max_text_length";
+
   /** Sampling rate for generateLinks logging. */
   private static final String GENERATE_LINKS_LOG_SAMPLE_RATE = "generate_links_log_sample_rate";
+
   /**
    * Extra count that is added to some languages, e.g. system languages, when deducing the frequent
    * languages in {@link
@@ -75,52 +82,65 @@
    * hint is not given.
    */
   @VisibleForTesting static final String ENTITY_LIST_DEFAULT = "entity_list_default";
+
   /**
    * A colon(:) separated string that specifies the default entities types for generateLinks when
    * the text is in a not editable UI widget.
    */
   private static final String ENTITY_LIST_NOT_EDITABLE = "entity_list_not_editable";
+
   /**
    * A colon(:) separated string that specifies the default entities types for generateLinks when
    * the text is in an editable UI widget.
    */
   private static final String ENTITY_LIST_EDITABLE = "entity_list_editable";
+
   /**
    * A colon(:) separated string that specifies the default action types for
    * suggestConversationActions when the suggestions are used in an app.
    */
   private static final String IN_APP_CONVERSATION_ACTION_TYPES_DEFAULT =
       "in_app_conversation_action_types_default";
+
   /**
    * A colon(:) separated string that specifies the default action types for
    * suggestConversationActions when the suggestions are used in a notification.
    */
   private static final String NOTIFICATION_CONVERSATION_ACTION_TYPES_DEFAULT =
       "notification_conversation_action_types_default";
+
   /** Threshold to accept a suggested language from LangID model. */
   @VisibleForTesting static final String LANG_ID_THRESHOLD_OVERRIDE = "lang_id_threshold_override";
+
   /** Whether to enable {@link com.android.textclassifier.intent.TemplateIntentFactory}. */
   @VisibleForTesting
   static final String TEMPLATE_INTENT_FACTORY_ENABLED = "template_intent_factory_enabled";
+
   /** Whether to enable "translate" action in classifyText. */
   private static final String TRANSLATE_IN_CLASSIFICATION_ENABLED =
       "translate_in_classification_enabled";
+
   /**
    * Whether to detect the languages of the text in request by using langId for the native model.
    */
   private static final String DETECT_LANGUAGES_FROM_TEXT_ENABLED =
       "detect_languages_from_text_enabled";
+
   /** Whether to use models downloaded by config updater. */
   private static final String CONFIG_UPDATER_MODEL_ENABLED = "config_updater_model_enabled";
+
   /** Whether to enable model downloading with ModelDownloadManager */
   @VisibleForTesting
   public static final String MODEL_DOWNLOAD_MANAGER_ENABLED = "model_download_manager_enabled";
+
   /** Type of network to download model manifest. A String value of androidx.work.NetworkType. */
   private static final String MANIFEST_DOWNLOAD_REQUIRED_NETWORK_TYPE =
       "manifest_download_required_network_type";
+
   /** Max attempts allowed for a single ModelDownloader downloading task. */
   @VisibleForTesting
   static final String MODEL_DOWNLOAD_WORKER_MAX_ATTEMPTS = "model_download_worker_max_attempts";
+
   /** Max attempts allowed for a certain manifest url. */
   @VisibleForTesting
   public static final String MANIFEST_DOWNLOAD_MAX_ATTEMPTS = "manifest_download_max_attempts";
@@ -181,6 +201,7 @@
    * @see {@code TextClassifierImpl#detectLanguages(String, int, int)} for reference.
    */
   @VisibleForTesting static final String LANG_ID_CONTEXT_SETTINGS = "lang_id_context_settings";
+
   /** Default threshold to translate the language of the context the user selects */
   private static final String TRANSLATE_ACTION_THRESHOLD = "translate_action_threshold";
 
@@ -216,6 +237,7 @@
           ConversationAction.TYPE_VIEW_MAP,
           TYPE_ADD_CONTACT,
           TYPE_COPY);
+
   /**
    * < 0 : Not set. Use value from LangId model. 0 - 1: Override value in LangId model.
    *
@@ -236,6 +258,7 @@
   private static final int MANIFEST_DOWNLOAD_MAX_ATTEMPTS_DEFAULT = 3;
   private static final long MODEL_DOWNLOAD_BACKOFF_DELAY_IN_MILLIS_DEFAULT = HOURS.toMillis(1);
   private static final boolean MANIFEST_DOWNLOAD_REQUIRES_DEVICE_IDLE_DEFAULT = false;
+  private static final boolean MANIFEST_DOWNLOAD_REQUIRES_CHARGING_WEAR_DEFAULT = true;
   private static final boolean MANIFEST_DOWNLOAD_REQUIRES_CHARGING_DEFAULT = false;
   private static final boolean MULTI_LANGUAGE_SUPPORT_ENABLED_DEFAULT = false;
   private static final int MULTI_LANGUAGE_MODELS_LIMIT_DEFAULT = 2;
@@ -247,6 +270,7 @@
   private static final String MANIFEST_URL_DEFAULT = "";
   private static final String TESTING_LOCALE_LIST_OVERRIDE_DEFAULT = "";
   private static final float[] LANG_ID_CONTEXT_SETTINGS_DEFAULT = new float[] {20f, 1.0f, 0.4f};
+
   /**
    * Sampling rate for API logging. For example, 100 means there is a 0.01 chance that the API call
    * is the logged.
@@ -327,14 +351,18 @@
       };
 
   private final IDeviceConfig deviceConfig;
+  private final boolean isWear;
 
-  public TextClassifierSettings() {
-    this(DEFAULT_DEVICE_CONFIG);
+  public TextClassifierSettings(Context context) {
+    this(
+        DEFAULT_DEVICE_CONFIG,
+        context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH));
   }
 
   @VisibleForTesting
-  public TextClassifierSettings(IDeviceConfig deviceConfig) {
+  public TextClassifierSettings(IDeviceConfig deviceConfig, boolean isWear) {
     this.deviceConfig = deviceConfig;
+    this.isWear = isWear;
   }
 
   public int getSuggestSelectionMaxRangeLength() {
@@ -461,7 +489,9 @@
     return deviceConfig.getBoolean(
         NAMESPACE,
         MANIFEST_DOWNLOAD_REQUIRES_CHARGING,
-        MANIFEST_DOWNLOAD_REQUIRES_CHARGING_DEFAULT);
+        isWear
+            ? MANIFEST_DOWNLOAD_REQUIRES_CHARGING_WEAR_DEFAULT
+            : MANIFEST_DOWNLOAD_REQUIRES_CHARGING_DEFAULT);
   }
 
   /* Gets a list of models urls that should not be used. Usually used for a quick rollback.  */
@@ -496,6 +526,7 @@
     return deviceConfig.getInt(
         NAMESPACE, MULTI_ANNOTATOR_CACHE_SIZE, MULTI_ANNOTATOR_CACHE_SIZE_DEFAULT);
   }
+
   /**
    * Gets all language variants and associated manifest url configured for a specific ModelType.
    *
diff --git a/java/src/com/android/textclassifier/downloader/DownloadedModelManagerImpl.java b/java/src/com/android/textclassifier/downloader/DownloadedModelManagerImpl.java
index 9bdfb5e..8e60c15 100644
--- a/java/src/com/android/textclassifier/downloader/DownloadedModelManagerImpl.java
+++ b/java/src/com/android/textclassifier/downloader/DownloadedModelManagerImpl.java
@@ -77,7 +77,8 @@
                 .build();
         File modelDownloaderDir = new File(context.getFilesDir(), DOWNLOAD_SUB_DIR_NAME);
         instance =
-            new DownloadedModelManagerImpl(db, modelDownloaderDir, new TextClassifierSettings());
+            new DownloadedModelManagerImpl(
+                db, modelDownloaderDir, new TextClassifierSettings(context));
       }
       return instance;
     }
diff --git a/java/src/com/android/textclassifier/downloader/ModelDownloadWorker.java b/java/src/com/android/textclassifier/downloader/ModelDownloadWorker.java
index ff04aea..a71cdef 100644
--- a/java/src/com/android/textclassifier/downloader/ModelDownloadWorker.java
+++ b/java/src/com/android/textclassifier/downloader/ModelDownloadWorker.java
@@ -78,7 +78,7 @@
     this.executorService = TextClassifierServiceExecutors.getDownloaderExecutor();
     this.downloader = new ModelDownloaderImpl(context, executorService);
     this.downloadedModelManager = DownloadedModelManagerImpl.getInstance(context);
-    this.settings = new TextClassifierSettings();
+    this.settings = new TextClassifierSettings(context);
     this.pendingDownloads = new ArrayMap<>();
     this.manifestsToDownload = null;
 
@@ -359,6 +359,7 @@
       return manfiestDownloadFuture;
     }
   }
+
   // Download a model and register it into Model table.
   private ListenableFuture<Void> downloadModel(ModelManifest.Model modelInfo) {
     String modelUrl = modelInfo.getUrl();
diff --git a/java/tests/instrumentation/src/com/android/textclassifier/DefaultTextClassifierServiceTest.java b/java/tests/instrumentation/src/com/android/textclassifier/DefaultTextClassifierServiceTest.java
index ddab8bd..ff99126 100644
--- a/java/tests/instrumentation/src/com/android/textclassifier/DefaultTextClassifierServiceTest.java
+++ b/java/tests/instrumentation/src/com/android/textclassifier/DefaultTextClassifierServiceTest.java
@@ -279,7 +279,7 @@
 
     @Override
     public TextClassifierSettings createTextClassifierSettings() {
-      return new TextClassifierSettings();
+      return new TextClassifierSettings(getContext());
     }
 
     @Override
diff --git a/java/tests/instrumentation/src/com/android/textclassifier/ModelFileManagerImplTest.java b/java/tests/instrumentation/src/com/android/textclassifier/ModelFileManagerImplTest.java
index 0e40515..f465bf3 100644
--- a/java/tests/instrumentation/src/com/android/textclassifier/ModelFileManagerImplTest.java
+++ b/java/tests/instrumentation/src/com/android/textclassifier/ModelFileManagerImplTest.java
@@ -83,7 +83,7 @@
         new File(ApplicationProvider.getApplicationContext().getCacheDir(), "rootTestDir");
     rootTestDir.mkdirs();
     Context context = ApplicationProvider.getApplicationContext();
-    settings = new TextClassifierSettings(deviceConfig);
+    settings = new TextClassifierSettings(deviceConfig, /* isWear= */ false);
     modelDownloadManager =
         new ModelDownloadManager(
             context,
@@ -135,7 +135,7 @@
 
     ModelFile bestModelFile =
         modelFileManager.findBestModelFile(
-            MODEL_TYPE, /* localePreferences= */ null, /*detectedLocales=*/ null);
+            MODEL_TYPE, /* localePreferences= */ null, /* detectedLocales= */ null);
     assertThat(bestModelFile).isEqualTo(newerModelFile);
   }
 
@@ -149,7 +149,7 @@
 
     ModelFile bestModelFile =
         modelFileManager.findBestModelFile(
-            MODEL_TYPE, new LocaleList(DEFAULT_LOCALE), /*detectedLocales=*/ null);
+            MODEL_TYPE, new LocaleList(DEFAULT_LOCALE), /* detectedLocales= */ null);
     assertThat(bestModelFile).isEqualTo(languageDependentModelFile);
   }
 
@@ -162,7 +162,7 @@
 
     ModelFile bestModelFile =
         modelFileManager.findBestModelFile(
-            MODEL_TYPE, new LocaleList(DEFAULT_LOCALE), /*detectedLocales=*/ null);
+            MODEL_TYPE, new LocaleList(DEFAULT_LOCALE), /* detectedLocales= */ null);
     assertThat(bestModelFile).isEqualTo(languageIndependentModelFile);
   }
 
@@ -175,7 +175,7 @@
 
     ModelFile bestModelFile =
         modelFileManager.findBestModelFile(
-            MODEL_TYPE, new LocaleList(DEFAULT_LOCALE), /*detectedLocales=*/ null);
+            MODEL_TYPE, new LocaleList(DEFAULT_LOCALE), /* detectedLocales= */ null);
     assertThat(bestModelFile).isEqualTo(matchButOlderModel);
   }
 
@@ -189,7 +189,7 @@
 
     ModelFile bestModelFile =
         modelFileManager.findBestModelFile(
-            MODEL_TYPE, LocaleList.forLanguageTags("zh-hk"), /*detectedLocales=*/ null);
+            MODEL_TYPE, LocaleList.forLanguageTags("zh-hk"), /* detectedLocales= */ null);
     assertThat(bestModelFile).isEqualTo(languageDependentModelFile);
   }
 
@@ -203,7 +203,7 @@
 
     ModelFile bestModelFile =
         modelFileManager.findBestModelFile(
-            MODEL_TYPE, LocaleList.forLanguageTags("zh"), /*detectedLocales=*/ null);
+            MODEL_TYPE, LocaleList.forLanguageTags("zh"), /* detectedLocales= */ null);
     assertThat(bestModelFile).isEqualTo(languageDependentModelFile);
   }
 
@@ -217,7 +217,7 @@
 
     ModelFile bestModelFile =
         modelFileManager.findBestModelFile(
-            MODEL_TYPE, LocaleList.forLanguageTags("zh"), /*detectedLocales=*/ null);
+            MODEL_TYPE, LocaleList.forLanguageTags("zh"), /* detectedLocales= */ null);
     assertThat(bestModelFile).isEqualTo(languageIndependentModelFile);
   }
 
@@ -250,7 +250,7 @@
         modelFileManager.findBestModelFile(
             MODEL_TYPE,
             new LocaleList(Locale.forLanguageTag("en"), Locale.forLanguageTag("zh-hk")),
-            /*detectedLocales=*/ null);
+            /* detectedLocales= */ null);
     assertThat(bestModelFile).isEqualTo(languageIndependentModelFile);
   }
 
diff --git a/java/tests/instrumentation/src/com/android/textclassifier/TextClassifierImplTest.java b/java/tests/instrumentation/src/com/android/textclassifier/TextClassifierImplTest.java
index 89d405a..8a4487d 100644
--- a/java/tests/instrumentation/src/com/android/textclassifier/TextClassifierImplTest.java
+++ b/java/tests/instrumentation/src/com/android/textclassifier/TextClassifierImplTest.java
@@ -93,7 +93,7 @@
             .setAppLabel(FakeContextBuilder.DEFAULT_COMPONENT.getPackageName(), "Test app")
             .build();
     this.deviceConfig = new TestingDeviceConfig();
-    this.settings = new TextClassifierSettings(deviceConfig);
+    this.settings = new TextClassifierSettings(deviceConfig, /* isWear= */ false);
     this.annotatorModelCache = new LruCache<>(2);
     this.classifier =
         new TextClassifierImpl(context, settings, modelFileManager, annotatorModelCache);
@@ -177,7 +177,7 @@
     String suggested = "http://www.android.com";
     int startIndex = text.indexOf(suggested);
     TextSelection.Request request =
-        new TextSelection.Request.Builder(text, startIndex, /*endIndex=*/ startIndex + 1)
+        new TextSelection.Request.Builder(text, startIndex, /* endIndex= */ startIndex + 1)
             .setIncludeTextClassification(true)
             .build();
 
@@ -194,7 +194,7 @@
   public void testSuggestSelection_notIncludeTextClassification() throws IOException {
     String text = "Visit http://www.android.com for more information";
     TextSelection.Request request =
-        new TextSelection.Request.Builder(text, /*startIndex=*/ 0, /*endIndex=*/ 4)
+        new TextSelection.Request.Builder(text, /* startIndex= */ 0, /* endIndex= */ 4)
             .setIncludeTextClassification(false)
             .build();
 
diff --git a/java/tests/instrumentation/src/com/android/textclassifier/common/TextClassifierSettingsTest.java b/java/tests/instrumentation/src/com/android/textclassifier/common/TextClassifierSettingsTest.java
index 17aef84..2f936e4 100644
--- a/java/tests/instrumentation/src/com/android/textclassifier/common/TextClassifierSettingsTest.java
+++ b/java/tests/instrumentation/src/com/android/textclassifier/common/TextClassifierSettingsTest.java
@@ -139,7 +139,7 @@
   private static void assertSettings(
       Map<String, String> keyValueMap, Consumer<TextClassifierSettings> settingsConsumer) {
     TestingDeviceConfig deviceConfig = new TestingDeviceConfig();
-    TextClassifierSettings settings = new TextClassifierSettings(deviceConfig);
+    TextClassifierSettings settings = new TextClassifierSettings(deviceConfig, /* isWear= */ false);
     for (String key : keyValueMap.keySet()) {
       deviceConfig.setConfig(key, keyValueMap.get(key));
     }
diff --git a/java/tests/instrumentation/src/com/android/textclassifier/downloader/DownloadedModelManagerImplTest.java b/java/tests/instrumentation/src/com/android/textclassifier/downloader/DownloadedModelManagerImplTest.java
index 5ff4d89..7adbf6d 100644
--- a/java/tests/instrumentation/src/com/android/textclassifier/downloader/DownloadedModelManagerImplTest.java
+++ b/java/tests/instrumentation/src/com/android/textclassifier/downloader/DownloadedModelManagerImplTest.java
@@ -52,7 +52,7 @@
     modelDownloaderDir = new File(context.getFilesDir(), "test_dir");
     modelDownloaderDir.mkdirs();
     deviceConfig = new TestingDeviceConfig();
-    settings = new TextClassifierSettings(deviceConfig);
+    settings = new TextClassifierSettings(deviceConfig, /* isWear= */ false);
     db = Room.inMemoryDatabaseBuilder(context, DownloadedModelDatabase.class).build();
     downloadedModelManagerImpl =
         DownloadedModelManagerImpl.getInstanceForTesting(db, modelDownloaderDir, settings);
diff --git a/java/tests/instrumentation/src/com/android/textclassifier/downloader/LocaleUtilsTest.java b/java/tests/instrumentation/src/com/android/textclassifier/downloader/LocaleUtilsTest.java
index a553c51..1350868 100644
--- a/java/tests/instrumentation/src/com/android/textclassifier/downloader/LocaleUtilsTest.java
+++ b/java/tests/instrumentation/src/com/android/textclassifier/downloader/LocaleUtilsTest.java
@@ -39,7 +39,7 @@
   @Before
   public void setUp() {
     deviceConfig = new TestingDeviceConfig();
-    settings = new TextClassifierSettings(deviceConfig);
+    settings = new TextClassifierSettings(deviceConfig, /* isWear= */ false);
   }
 
   @Test
diff --git a/java/tests/instrumentation/src/com/android/textclassifier/downloader/ModelDownloadManagerTest.java b/java/tests/instrumentation/src/com/android/textclassifier/downloader/ModelDownloadManagerTest.java
index 9e11c09..6128100 100644
--- a/java/tests/instrumentation/src/com/android/textclassifier/downloader/ModelDownloadManagerTest.java
+++ b/java/tests/instrumentation/src/com/android/textclassifier/downloader/ModelDownloadManagerTest.java
@@ -83,7 +83,7 @@
             ModelDownloadWorker.class,
             () -> workManager,
             downloadedModelManager,
-            new TextClassifierSettings(deviceConfig),
+            new TextClassifierSettings(deviceConfig, /* isWear= */ false),
             MoreExecutors.newDirectExecutorService());
     this.downloadManagerWithBadWorkManager =
         new ModelDownloadManager(
@@ -93,7 +93,7 @@
               throw new IllegalStateException("WorkManager may fail!");
             },
             downloadedModelManager,
-            new TextClassifierSettings(deviceConfig),
+            new TextClassifierSettings(deviceConfig, /* isWear= */ false),
             MoreExecutors.newDirectExecutorService());
 
     setDefaultLocalesRule.set(DEFAULT_LOCALE_LIST);
diff --git a/java/tests/instrumentation/src/com/android/textclassifier/downloader/ModelDownloadWorkerTest.java b/java/tests/instrumentation/src/com/android/textclassifier/downloader/ModelDownloadWorkerTest.java
index 3646934..7f50f83 100644
--- a/java/tests/instrumentation/src/com/android/textclassifier/downloader/ModelDownloadWorkerTest.java
+++ b/java/tests/instrumentation/src/com/android/textclassifier/downloader/ModelDownloadWorkerTest.java
@@ -157,7 +157,7 @@
 
     Context context = ApplicationProvider.getApplicationContext();
     this.deviceConfig = new TestingDeviceConfig();
-    this.settings = new TextClassifierSettings(deviceConfig);
+    this.settings = new TextClassifierSettings(deviceConfig, /* isWear= */ false);
     this.modelDownloaderDir = new File(context.getCacheDir(), "downloaded");
     this.modelDownloaderDir.mkdirs();
     this.modelFile = new File(modelDownloaderDir, "test.model");