Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fa433271 authored by Dongzhuo Zhang's avatar Dongzhuo Zhang
Browse files

Add Contacts Stroage fragment class for Contacts Storage settings page.

Test: atest SettingsRoboTests:com.android.settings.applications.contacts.ContactsStorageSettingsTest

Bug: 368641291
Flag: com.android.settings.flags.enable_contacts_default_account_in_settings

Change-Id: I6ece3eeea64d07d4a97574f67549a72267371df8
parent efd16c7d
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
<!--
  ~ Copyright (C) 2024 The Android Open Source Project
  ~
  ~ Licensed under the Apache License, Version 2.0 (the "License");
  ~ you may not use this file except in compliance with the License.
  ~ You may obtain a copy of the License at
  ~
  ~      http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing, software
  ~ distributed under the License is distributed on an "AS IS" BASIS,
  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24.0dp"
        android:height="24.0dp"
        android:viewportWidth="24.0"
        android:viewportHeight="24.0">
    <path
        android:pathData="M19.400000,10.000000c-0.700000,-3.400000 -3.700000,-6.000000 -7.400000,-6.000000c-1.500000,0.000000 -2.900000,0.400000 -4.000000,1.200000l1.500000,1.500000C10.200000,6.200000 11.100000,6.000000 12.000000,6.000000c3.000000,0.000000 5.500000,2.500000 5.500000,5.500000L17.500000,12.000000L19.000000,12.000000c1.700000,0.000000 3.000000,1.300000 3.000000,3.000000c0.000000,1.100000 -0.600000,2.100000 -1.600000,2.600000l1.500000,1.500000c1.300000,-0.900000 2.100000,-2.400000 2.100000,-4.100000C24.000000,12.400000 21.900000,10.200000 19.400000,10.000000zM3.000000,5.300000L5.800000,8.000000C2.600000,8.200000 0.000000,10.800000 0.000000,14.000000c0.000000,3.300000 2.700000,6.000000 6.000000,6.000000l11.700000,0.000000l2.000000,2.000000l1.300000,-1.300000L4.300000,4.000000L3.000000,5.300000zM7.700000,10.000000l8.000000,8.000000L6.000000,18.000000c-2.200000,0.000000 -4.000000,-1.800000 -4.000000,-4.000000c0.000000,-2.200000 1.800000,-4.000000 4.000000,-4.000000L7.700000,10.000000z"
        android:fillColor="#000000"/>
</vector>
+8 −0
Original line number Diff line number Diff line
@@ -13691,6 +13691,14 @@
    <string name="keywords_contacts_storage">contacts, storage, account</string>
    <!-- Text for Contacts Storage Settings title [CHAR LIMIT=50]-->
    <string name="contacts_storage_settings_title">Contacts storage</string>
    <!-- Text for "device only" preference label in Contacts Storage Settings [CHAR LIMIT=34] -->
    <string name="contacts_storage_device_only_preference_label">Device only</string>
    <!-- Text for "device only" preference summary in Contacts Storage Settings [CHAR LIMIT=NONE] -->
    <string name="contacts_storage_device_only_preference_summary">New contacts won\'t be synced with an account</string>
    <!-- Text for explaining the selection in Contacts Storage Settings [CHAR LIMIT=NONE] -->
    <string name="contacts_storage_selection_message">Contacts will be saved to your device and synced to your account by default</string>
    <!-- Text for displaying when no account is set as default account [CHAR LIMIT=50] -->
    <string name="contacts_storage_no_account_set">No default set</string>
    <!-- Text for add account selection message when no account has been added [CHAR LIMIT=100] -->
    <string name="contacts_storage_first_time_add_account_message">Add an account to get started</string>
</resources>
+1 −0
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@
        android:summary="@string/summary_placeholder"
        android:order="13"
        settings:controller="com.android.settings.applications.contacts.ContactsStoragePreferenceController"
        android:fragment="com.android.settings.applications.contacts.ContactsStorageSettings"
        settings:keywords="@string/keywords_contacts_storage">
    </Preference>

+32 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ Copyright (C) 2024 The Android Open Source Project
  ~
  ~ Licensed under the Apache License, Version 2.0 (the "License");
  ~ you may not use this file except in compliance with the License.
  ~ You may obtain a copy of the License at
  ~
  ~      http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing, software
  ~ distributed under the License is distributed on an "AS IS" BASIS,
  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  -->
<PreferenceScreen
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:settings="http://schemas.android.com/apk/res-auto"
    android:title="@string/contacts_storage_settings_title">

    <com.android.settingslib.widget.TopIntroPreference
        android:title="@string/contacts_storage_selection_message" />

    <com.android.settingslib.widget.SelectorWithWidgetPreference
        android:key="device_only_account_preference"
        android:summary="@string/contacts_storage_device_only_preference_summary"
        android:title="@string/contacts_storage_device_only_preference_label"
        android:icon="@drawable/cloud_off"
        android:order="999"
        settings:allowDividerAbove="true"/>
</PreferenceScreen>
+195 −0
Original line number Diff line number Diff line

/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.settings.applications.contacts;

import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.provider.Settings.ACTION_ADD_ACCOUNT;
import static android.provider.Settings.EXTRA_ACCOUNT_TYPES;

import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.UserHandle;
import android.provider.ContactsContract.Settings;

import androidx.annotation.NonNull;
import androidx.annotation.UiThread;
import androidx.preference.Preference;
import androidx.preference.Preference.OnPreferenceClickListener;
import androidx.preference.PreferenceScreen;

import com.android.settings.R;
import com.android.settings.accounts.AddAccountSettings;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.RestrictedPreference;
import com.android.settingslib.accounts.AuthenticatorHelper;
import com.android.settingslib.search.SearchIndexable;
import com.android.settingslib.widget.SelectorWithWidgetPreference;

import java.util.HashMap;
import java.util.Map;

/**
 * Settings page for contacts default account
 */
@SearchIndexable
public class ContactsStorageSettings extends DashboardFragment
        implements SelectorWithWidgetPreference.OnClickListener, OnPreferenceClickListener {
    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
            new BaseSearchIndexProvider(R.xml.contacts_storage_settings);
    private static final String TAG = "ContactsStorageSettings";
    private static final String PREF_KEY_ADD_ACCOUNT = "add_account";
    private static final String PREF_KEY_DEVICE_ONLY = "device_only_account_preference";
    private final Map<String, Account> mAccountMap = new HashMap<>();
    private AuthenticatorHelper mAuthenticatorHelper;

    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        mAuthenticatorHelper = new AuthenticatorHelper(context,
                new UserHandle(UserHandle.myUserId()), null);
    }

    @UiThread
    @Override
    public void onRadioButtonClicked(@NonNull SelectorWithWidgetPreference selectedPref) {
        final String selectedPreferenceKey = selectedPref.getKey();
        // Check if current provider is different from the selected provider.
        for (String preferenceKey : mAccountMap.keySet()) {
            if (selectedPreferenceKey.equals(preferenceKey)) {
                selectedPref.setChecked(true);
                //TODO: Call DefaultAccount.setDefaultAccountForNewContacts once
                // the implementation is ready.
                Settings.setDefaultAccount(getContentResolver(), mAccountMap.get(preferenceKey));
            } else {
                SelectorWithWidgetPreference unSelectedPreference =
                        getPreferenceScreen().findPreference(preferenceKey);
                if (unSelectedPreference != null) {
                    unSelectedPreference.setChecked(false);
                }
            }
        }
    }

    public boolean onPreferenceClick(@NonNull Preference preference) {
        if (PREF_KEY_ADD_ACCOUNT.equals(preference.getKey())) {
            Resources resources = Resources.getSystem();
            String[] accountTypesArray =
                    resources.getStringArray(
                            com.android.internal.R.array.config_rawContactsEligibleDefaultAccountTypes);
            Intent intent = new Intent(ACTION_ADD_ACCOUNT);
            intent.setClass(getContext(), AddAccountSettings.class);
            intent.putExtra(EXTRA_ACCOUNT_TYPES, accountTypesArray);
            intent.addFlags(FLAG_ACTIVITY_NEW_TASK);
            getContext().startActivity(intent);
            return true;
        }
        return false;
    }

    @Override
    public void onCreatePreferences(@NonNull Bundle savedInstanceState,
        @NonNull String rootKey) {
        super.onCreatePreferences(savedInstanceState, rootKey);
        refreshUI();
    }

    @UiThread
    void refreshUI() {
        // Clear all the accounts stored in the map and later on re-fetch the eligible accounts
        // when creating eligible account preferences.
        mAccountMap.clear();
        final PreferenceScreen screen = getPreferenceScreen();
        AccountManager accountManager = AccountManager.get(getPrefContext());
        //TODO: Call DefaultAccount.getDefaultAccountForNewContacts once
        // implementation is ready.
        Account[] accounts = accountManager.getAccounts();

        for (int i = 0; i < accounts.length; i++) {
            screen.addPreference(buildAccountPreference(accounts[i], i));
        }
        screen.addPreference(buildAddAccountPreference(accounts.length == 0));
        setupDeviceOnlyPreference();

        //TODO: Call DefaultAccount.ListEligibleCloudAccounts once the
        // implementation is ready. And differentiate device only account vs account not set case.
        Account currentDefaultAccount = Settings.getDefaultAccount(getContentResolver());
        String preferenceKey = currentDefaultAccount != null ?
                String.valueOf(currentDefaultAccount.hashCode()) : PREF_KEY_DEVICE_ONLY;
        SelectorWithWidgetPreference preference = getPreferenceScreen().findPreference(
                preferenceKey);
        if (preference != null) {
            preference.setChecked(true);
        }
    }

    private void setupDeviceOnlyPreference() {
        SelectorWithWidgetPreference preference = findPreference(PREF_KEY_DEVICE_ONLY);
        if (preference != null) {
            preference.setOnClickListener(this);
            mAccountMap.put(PREF_KEY_DEVICE_ONLY, null);
        }
    }

    //TODO: Add preference category on account preferences.
    private Preference buildAccountPreference(Account account, int order) {
        SelectorWithWidgetPreference preference = new SelectorWithWidgetPreference(
                getPrefContext());
        preference.setTitle(mAuthenticatorHelper.getLabelForType(getPrefContext(), account.type));
        preference.setIcon(mAuthenticatorHelper.getDrawableForType(getPrefContext(), account.type));
        preference.setSummary(account.name);
        preference.setKey(String.valueOf(account.hashCode()));
        preference.setOnClickListener(this);
        preference.setOrder(order);
        mAccountMap.put(String.valueOf(account.hashCode()), account);
        return preference;
    }

    private RestrictedPreference buildAddAccountPreference(boolean noAccountBeenAdded) {
        RestrictedPreference preference = new RestrictedPreference(getPrefContext());
        preference.setKey(PREF_KEY_ADD_ACCOUNT);
        if (noAccountBeenAdded) {
            preference.setTitle(R.string.contacts_storage_first_time_add_account_message);
        } else {
            preference.setTitle(R.string.add_account_label);
        }
        preference.setIcon(R.drawable.ic_add_24dp);
        preference.setOnPreferenceClickListener(this);
        preference.setOrder(998);
        return preference;
    }

    @Override
    protected int getPreferenceScreenResId() {
        return R.xml.contacts_storage_settings;
    }

    @Override
    protected String getLogTag() {
        return TAG;
    }

    @Override
    public int getMetricsCategory() {
        return SettingsEnums.CONTACTS_STORAGE;
    }
}
Loading