Show SIM account preference in Contacts Storage Settings when default
account is set as SIM account.

Test: atest SettingsRoboTests:com.android.settings.applications.contacts.ContactsStorageSettingsTest
atest SettingsRoboTests:com.android.settings.applications.contacts.ContactsStoragePreferenceControllerTest
Bug: 368641291
Flag: com.android.settings.flags.enable_contacts_default_account_in_settings

Change-Id: I2f80e63a807f5a060c2ef6f05e3e413c6a689e1f
diff --git a/src/com/android/settings/applications/contacts/ContactsStoragePreferenceController.java b/src/com/android/settings/applications/contacts/ContactsStoragePreferenceController.java
index dd22781..e4343e5 100644
--- a/src/com/android/settings/applications/contacts/ContactsStoragePreferenceController.java
+++ b/src/com/android/settings/applications/contacts/ContactsStoragePreferenceController.java
@@ -71,7 +71,12 @@
                     == DefaultAccountAndState.DEFAULT_ACCOUNT_STATE_LOCAL) {
                 return mContext.getResources().getString(
                         R.string.contacts_storage_local_account_summary);
-            } else if (currentDefaultAccount != null) {
+            } else if (currentDefaultAccountState
+                    == DefaultAccountAndState.DEFAULT_ACCOUNT_STATE_SIM) {
+                return mContext.getResources().getString(
+                        R.string.sim_card_label);
+            } else if (currentDefaultAccountState
+                    == DefaultAccountAndState.DEFAULT_ACCOUNT_STATE_CLOUD) {
                 String accountTypeLabel = (String) mAuthenticatorHelper.getLabelForType(mContext,
                         currentDefaultAccount.type);
                 // If there's no account type, or the account type is the same as the
diff --git a/src/com/android/settings/applications/contacts/ContactsStorageSettings.java b/src/com/android/settings/applications/contacts/ContactsStorageSettings.java
index 3d449cf..8e71d08 100644
--- a/src/com/android/settings/applications/contacts/ContactsStorageSettings.java
+++ b/src/com/android/settings/applications/contacts/ContactsStorageSettings.java
@@ -28,7 +28,9 @@
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.provider.ContactsContract.RawContacts.DefaultAccount.DefaultAccountAndState;
+import android.util.Log;
 import android.widget.Toast;
+
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.UiThread;
@@ -79,10 +81,16 @@
         for (String preferenceKey : mAccountMap.keySet()) {
             if (selectedPreferenceKey.equals(preferenceKey)) {
                 try {
+                    DefaultAccountAndState currentDefaultAccount = mAccountMap.get(preferenceKey);
                     DefaultAccount.setDefaultAccountForNewContacts(getContentResolver(),
-                            mAccountMap.get(preferenceKey));
+                            currentDefaultAccount);
                     selectedPref.setChecked(true);
+                    if (currentDefaultAccount.getState()
+                            == DefaultAccountAndState.DEFAULT_ACCOUNT_STATE_CLOUD) {
+                        startMoveLocalAndSimContactsActivity();
+                    }
                 } catch (RuntimeException e) {
+                    Log.e(TAG, "Error setting the default account " + e);
                     Toast.makeText(getContext(),
                             R.string.contacts_storage_set_default_account_error_message,
                             Toast.LENGTH_SHORT).show();
@@ -123,9 +131,14 @@
         // when creating eligible account preferences.
         mAccountMap.clear();
         final PreferenceScreen screen = getPreferenceScreen();
+        // If the default account is SIM, we should show in the page, otherwise don't show.
+        SelectorWithWidgetPreference simAccountPreference = buildSimAccountPreference();
+        if (simAccountPreference != null) {
+            getPreferenceScreen().addPreference(simAccountPreference);
+        }
         List<Account> accounts = DefaultAccount.getEligibleCloudAccounts(getContentResolver());
         for (int i = 0; i < accounts.size(); i++) {
-            screen.addPreference(buildAccountPreference(accounts.get(i), /*order=*/i));
+            screen.addPreference(buildCloudAccountPreference(accounts.get(i), /*order=*/i));
         }
         // If there's no eligible account types, the "Add Account" preference should
         // not be shown to the users.
@@ -156,7 +169,7 @@
         if (mAccountMap.containsKey(preferenceKey)) {
             preference = getPreferenceScreen().findPreference(preferenceKey);
         } else if (preferenceKey != null && currentDefaultAccount != null) {
-            preference = buildAccountPreference(currentDefaultAccount, mAccountMap.size());
+            preference = buildCloudAccountPreference(currentDefaultAccount, mAccountMap.size());
             getPreferenceScreen().addPreference(preference);
         }
         if (preference != null) {
@@ -165,7 +178,7 @@
     }
 
     //TODO: Add preference category on account preferences.
-    private SelectorWithWidgetPreference buildAccountPreference(Account account, int order) {
+    private SelectorWithWidgetPreference buildCloudAccountPreference(Account account, int order) {
         SelectorWithWidgetPreference preference = new SelectorWithWidgetPreference(
                 getPrefContext());
         DefaultAccountAndState accountAndState = DefaultAccountAndState.ofCloud(account);
@@ -180,6 +193,26 @@
         return preference;
     }
 
+    @Nullable
+    private SelectorWithWidgetPreference buildSimAccountPreference() {
+        DefaultAccountAndState currentDefaultAccountAndState =
+                DefaultAccount.getDefaultAccountForNewContacts(getContentResolver());
+        if (currentDefaultAccountAndState.getState()
+                == DefaultAccountAndState.DEFAULT_ACCOUNT_STATE_SIM) {
+            String preferenceKey = getAccountHashCode(currentDefaultAccountAndState);
+            SelectorWithWidgetPreference preference = new SelectorWithWidgetPreference(
+                    getPrefContext());
+            preference.setTitle(R.string.sim_card_label);
+            preference.setIcon(R.drawable.ic_sim_card);
+            preference.setSummary(R.string.sim_card_label);
+            preference.setKey(preferenceKey);
+            preference.setOnClickListener(this);
+            mAccountMap.put(preferenceKey, currentDefaultAccountAndState);
+            return preference;
+        }
+        return null;
+    }
+
     private RestrictedPreference buildAddAccountPreference(boolean noAccountBeenAdded) {
         RestrictedPreference preference = new RestrictedPreference(getPrefContext());
         preference.setKey(PREF_KEY_ADD_ACCOUNT);
@@ -194,7 +227,17 @@
         return preference;
     }
 
-    private @Nullable String getAccountHashCode(DefaultAccountAndState currentDefaultAccountAndState) {
+    private void startMoveLocalAndSimContactsActivity() {
+        Intent intent = new Intent()
+                .setAction(DefaultAccount.ACTION_MOVE_CONTACTS_TO_DEFAULT_ACCOUNT)
+                .setPackage("com.android.providers.contacts")
+                .addFlags(FLAG_ACTIVITY_NEW_TASK);
+        getContext().startActivity(intent);
+    }
+
+    @Nullable
+    private String getAccountHashCode(
+            DefaultAccountAndState currentDefaultAccountAndState) {
         Account currentDefaultAccount = currentDefaultAccountAndState.getAccount();
         if (currentDefaultAccount != null && (currentDefaultAccountAndState.getState()
                 == DefaultAccountAndState.DEFAULT_ACCOUNT_STATE_CLOUD
diff --git a/tests/robotests/src/com/android/settings/applications/contacts/ContactsStoragePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/contacts/ContactsStoragePreferenceControllerTest.java
index 45600c2..f954b22 100644
--- a/tests/robotests/src/com/android/settings/applications/contacts/ContactsStoragePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/contacts/ContactsStoragePreferenceControllerTest.java
@@ -179,6 +179,24 @@
     }
 
     @Test
+    public void getSummary_simAccountIsSetAsDefault_shouldReturnSimAccountSummary()
+            throws Exception {
+        Bundle bundle = new Bundle();
+        bundle.putInt(KEY_DEFAULT_ACCOUNT_STATE,
+                DefaultAccountAndState.DEFAULT_ACCOUNT_STATE_SIM);
+        bundle.putString(Settings.ACCOUNT_TYPE, "SIM");
+        bundle.putString(Settings.ACCOUNT_NAME, "SIM");
+        when(mContentProviderClient.call(eq(QUERY_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS_METHOD), any(),
+                any())).thenReturn(bundle);
+        when(mContext.getResources()).thenReturn(mResources);
+        when(mResources.getString(eq(R.string.sim_card_label))).thenReturn("SIM");
+        mPreferenceController = new ContactsStoragePreferenceController(mContext,
+                CONTACTS_DEFAULT_ACCOUNT_PREFERENCE_KEY);
+
+        assertThat(mPreferenceController.getSummary()).isEqualTo("SIM");
+    }
+
+    @Test
     public void getSummary_googleAccountIsSetAsDefault_shouldReturnGoogleAccountTypeAndAccountName()
             throws Exception {
         Bundle bundle = new Bundle();
diff --git a/tests/robotests/src/com/android/settings/applications/contacts/ContactsStorageSettingsTest.java b/tests/robotests/src/com/android/settings/applications/contacts/ContactsStorageSettingsTest.java
index a8c86e1..4e873fb 100644
--- a/tests/robotests/src/com/android/settings/applications/contacts/ContactsStorageSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/applications/contacts/ContactsStorageSettingsTest.java
@@ -32,7 +32,6 @@
 import static org.mockito.Mockito.when;
 
 import android.accounts.Account;
-import android.accounts.AccountManager;
 import android.app.settings.SettingsEnums;
 import android.content.ContentProviderClient;
 import android.content.ContentResolver;
@@ -83,6 +82,8 @@
 
     private static final Account TEST_ACCOUNT3 = new Account("test@outlook.com", "type3");
 
+    private static final Account SIM_ACCOUNT = new Account("SIM", "SIM");
+
     @Rule
     public final MockitoRule mockito = MockitoJUnit.rule();
     @Spy
@@ -216,7 +217,9 @@
             throws Exception {
         Bundle currentDefaultAccount = new Bundle();
         currentDefaultAccount.putInt(KEY_DEFAULT_ACCOUNT_STATE,
-                DefaultAccountAndState.DEFAULT_ACCOUNT_STATE_LOCAL);
+                DefaultAccountAndState.DEFAULT_ACCOUNT_STATE_CLOUD);
+        currentDefaultAccount.putString(ContactsContract.Settings.ACCOUNT_NAME, TEST_ACCOUNT2.name);
+        currentDefaultAccount.putString(ContactsContract.Settings.ACCOUNT_TYPE, TEST_ACCOUNT2.type);
         when(mContentProviderClient.call(eq(QUERY_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS_METHOD), any(),
                 any())).thenReturn(currentDefaultAccount);
         Bundle eligibleAccountBundle = new Bundle();
@@ -253,6 +256,14 @@
                 "test@samsung.com");
         assertThat(setAccountBundle.getString(ContactsContract.Settings.ACCOUNT_TYPE)).isEqualTo(
                 "type2");
+
+        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+        verify(mContext).startActivity(intentCaptor.capture());
+        Intent moveContactsIntent = intentCaptor.getValue();
+        assertThat(moveContactsIntent.getAction()).isEqualTo(
+                ContactsContract.RawContacts.DefaultAccount.ACTION_MOVE_CONTACTS_TO_DEFAULT_ACCOUNT);
+        assertThat(moveContactsIntent.getPackage()).isEqualTo(
+                "com.android.providers.contacts");
     }
 
     @Test
@@ -299,6 +310,32 @@
     }
 
     @Test
+    public void verifyAccountPreference_defaultAccountIsSimAccount_createSimAccountPreference()
+            throws Exception {
+        Bundle currentDefaultAccount = new Bundle();
+        currentDefaultAccount.putInt(KEY_DEFAULT_ACCOUNT_STATE,
+                DefaultAccountAndState.DEFAULT_ACCOUNT_STATE_SIM);
+        currentDefaultAccount.putString(ContactsContract.Settings.ACCOUNT_NAME, SIM_ACCOUNT.name);
+        currentDefaultAccount.putString(ContactsContract.Settings.ACCOUNT_TYPE, SIM_ACCOUNT.type);
+        when(mContentProviderClient.call(eq(QUERY_DEFAULT_ACCOUNT_FOR_NEW_CONTACTS_METHOD), any(),
+                any())).thenReturn(currentDefaultAccount);
+        Bundle eligibleAccountBundle = new Bundle();
+        eligibleAccountBundle.putParcelableArrayList(KEY_ELIGIBLE_DEFAULT_ACCOUNTS,
+                new ArrayList<>());
+        when(mContentProviderClient.call(eq(QUERY_ELIGIBLE_DEFAULT_ACCOUNTS_METHOD), any(),
+                any())).thenReturn(eligibleAccountBundle);
+
+        mContactsStorageSettings.refreshUI();
+
+        SelectorWithWidgetPreference simPreference = mScreen.findPreference(
+                String.valueOf(SIM_ACCOUNT.hashCode()));
+        assertThat(simPreference.getTitle()).isEqualTo("SIM");
+        assertThat(simPreference.getSummary()).isEqualTo("SIM");
+        assertThat(simPreference.getIcon()).isNotNull();
+        assertThat(simPreference.isChecked()).isTrue();
+    }
+
+    @Test
     public void searchIndexProvider_shouldIndexResource() {
         final List<SearchIndexableResource> indexRes =
                 ContactsStorageSettings.SEARCH_INDEX_DATA_PROVIDER.getXmlResourcesToIndex(