Merge "Allow language change to take effect in T9 search without relaunching Dialer."
diff --git a/java/com/android/dialer/app/DialtactsActivity.java b/java/com/android/dialer/app/DialtactsActivity.java
index 66e02b4..65965f4 100644
--- a/java/com/android/dialer/app/DialtactsActivity.java
+++ b/java/com/android/dialer/app/DialtactsActivity.java
@@ -100,6 +100,7 @@
 import com.android.dialer.common.LogUtil;
 import com.android.dialer.common.UiUtil;
 import com.android.dialer.common.concurrent.ThreadUtil;
+import com.android.dialer.compat.CompatUtils;
 import com.android.dialer.configprovider.ConfigProviderBindings;
 import com.android.dialer.constants.ActivityRequestCodes;
 import com.android.dialer.contactsfragment.ContactsFragment;
@@ -187,6 +188,7 @@
   private static final String KEY_SEARCH_QUERY = "search_query";
   private static final String KEY_DIALPAD_QUERY = "dialpad_query";
   private static final String KEY_FIRST_LAUNCH = "first_launch";
+  private static final String KEY_SAVED_LANGUAGE_CODE = "saved_language_code";
   private static final String KEY_WAS_CONFIGURATION_CHANGE = "was_configuration_change";
   private static final String KEY_IS_DIALPAD_SHOWN = "is_dialpad_shown";
   private static final String KEY_FAB_VISIBLE = "fab_visible";
@@ -262,6 +264,7 @@
   private DragDropController dragDropController;
   private ActionBarController actionBarController;
   private FloatingActionButtonController floatingActionButtonController;
+  private String savedLanguageCode;
   private boolean wasConfigurationChange;
   private long timeTabSelected;
 
@@ -451,6 +454,7 @@
       inDialpadSearch = savedInstanceState.getBoolean(KEY_IN_DIALPAD_SEARCH_UI);
       inNewSearch = savedInstanceState.getBoolean(KEY_IN_NEW_SEARCH_UI);
       firstLaunch = savedInstanceState.getBoolean(KEY_FIRST_LAUNCH);
+      savedLanguageCode = savedInstanceState.getString(KEY_SAVED_LANGUAGE_CODE);
       wasConfigurationChange = savedInstanceState.getBoolean(KEY_WAS_CONFIGURATION_CHANGE);
       isDialpadShown = savedInstanceState.getBoolean(KEY_IS_DIALPAD_SHOWN);
       floatingActionButtonController.setVisible(savedInstanceState.getBoolean(KEY_FAB_VISIBLE));
@@ -563,9 +567,16 @@
     }
 
     prepareVoiceSearchButton();
-    if (!wasConfigurationChange) {
-      dialerDatabaseHelper.startSmartDialUpdateThread();
+
+    // Start the thread that updates the smart dial database if
+    // (1) the activity is not recreated with a new configuration, or
+    // (2) the activity is recreated with a new configuration but the change is a language change.
+    boolean isLanguageChanged =
+        !CompatUtils.getLocale(this).getISO3Language().equals(savedLanguageCode);
+    if (!wasConfigurationChange || isLanguageChanged) {
+      dialerDatabaseHelper.startSmartDialUpdateThread(/* forceUpdate = */ isLanguageChanged);
     }
+
     if (isDialpadShown) {
       floatingActionButtonController.scaleOut();
     } else {
@@ -668,6 +679,7 @@
     super.onSaveInstanceState(outState);
     outState.putString(KEY_SEARCH_QUERY, searchQuery);
     outState.putString(KEY_DIALPAD_QUERY, dialpadQuery);
+    outState.putString(KEY_SAVED_LANGUAGE_CODE, CompatUtils.getLocale(this).getISO3Language());
     outState.putBoolean(KEY_IN_REGULAR_SEARCH_UI, inRegularSearch);
     outState.putBoolean(KEY_IN_DIALPAD_SEARCH_UI, inDialpadSearch);
     outState.putBoolean(KEY_IN_NEW_SEARCH_UI, inNewSearch);
diff --git a/java/com/android/dialer/database/DialerDatabaseHelper.java b/java/com/android/dialer/database/DialerDatabaseHelper.java
index d12b4e8..bc70fa4 100644
--- a/java/com/android/dialer/database/DialerDatabaseHelper.java
+++ b/java/com/android/dialer/database/DialerDatabaseHelper.java
@@ -331,14 +331,18 @@
     editor.apply();
   }
 
-  /** Starts the database upgrade process in the background. */
-  public void startSmartDialUpdateThread() {
+  /**
+   * Starts the database upgrade process in the background.
+   *
+   * @see #updateSmartDialDatabase(boolean) for the usage of {@code forceUpdate}.
+   */
+  public void startSmartDialUpdateThread(boolean forceUpdate) {
     if (PermissionsUtil.hasContactsReadPermissions(context)) {
       DialerExecutorComponent.get(context)
           .dialerExecutorFactory()
           .createNonUiTaskBuilder(new UpdateSmartDialWorker())
           .build()
-          .executeParallel(null);
+          .executeParallel(forceUpdate);
     }
   }
 
@@ -599,9 +603,11 @@
    * contacts since last update, and updates the records in smartdial database and prefix database
    * accordingly. It also queries the deleted contact database to remove newly deleted contacts
    * since last update.
+   *
+   * @param forceUpdate If set to true, update the database by reloading all contacts.
    */
   @WorkerThread
-  public synchronized void updateSmartDialDatabase() {
+  public synchronized void updateSmartDialDatabase(boolean forceUpdate) {
     LogUtil.enterBlock("DialerDatabaseHelper.updateSmartDialDatabase");
 
     final SQLiteDatabase db = getWritableDatabase();
@@ -613,7 +619,8 @@
     final SharedPreferences databaseLastUpdateSharedPref =
         context.getSharedPreferences(DATABASE_LAST_CREATED_SHARED_PREF, Context.MODE_PRIVATE);
     final String lastUpdateMillis =
-        String.valueOf(databaseLastUpdateSharedPref.getLong(LAST_UPDATED_MILLIS, 0));
+        String.valueOf(
+            forceUpdate ? 0 : databaseLastUpdateSharedPref.getLong(LAST_UPDATED_MILLIS, 0));
 
     LogUtil.v(
         "DialerDatabaseHelper.updateSmartDialDatabase", "last updated at " + lastUpdateMillis);
@@ -1235,12 +1242,12 @@
     }
   }
 
-  private class UpdateSmartDialWorker implements Worker<Void, Void> {
+  private class UpdateSmartDialWorker implements Worker<Boolean, Void> {
 
     @Nullable
     @Override
-    public Void doInBackground(@Nullable Void input) throws Throwable {
-      updateSmartDialDatabase();
+    public Void doInBackground(Boolean forceUpdate) throws Throwable {
+      updateSmartDialDatabase(forceUpdate);
       return null;
     }
   }