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

Commit 947c23df authored by Xi Chen's avatar Xi Chen
Browse files

PullToRefresh feature for syncing contacts (Flag Control)

This feature only supports Google accounts. It will sync all Google
accounts in all contacts view, and will sync Google account itself in
Google contacts view.

BUG 28625097

Change-Id: Icdfff5e201d827d3f6866ad1d8835ef3fdbd43b0
parent 19daf295
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -84,4 +84,9 @@
    <!-- Color of background of all empty states. -->
    <color name="empty_state_background">#efefef</color>

    <!-- Colors of swipeRefreshLayout's spinning circle. -->
    <color name="swipe_refresh_color1">#0f9d58</color>
    <color name="swipe_refresh_color2">#dd4b37</color>
    <color name="swipe_refresh_color3">#4285f4</color>
    <color name="swipe_refresh_color4">#f4b400</color>
</resources>
+3 −0
Original line number Diff line number Diff line
@@ -292,4 +292,7 @@

    <!-- Minimum height for group name EditText -->
    <dimen name="group_name_edit_text_min_height">48dp</dimen>

    <!-- Distance to pull down before causing a refresh. -->
    <dimen name="pull_to_refresh_distance">40dp</dimen>
</resources>
+44 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ import android.support.v13.app.FragmentPagerAdapter;
import android.support.v4.view.GravityCompat;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.widget.SwipeRefreshLayout;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyCharacterMap;
@@ -54,6 +55,7 @@ import com.android.contacts.ContactSaveService;
import com.android.contacts.ContactsDrawerActivity;
import com.android.contacts.R;
import com.android.contacts.activities.ActionBarAdapter.TabState;
import com.android.contacts.common.Experiments;
import com.android.contacts.common.activity.RequestPermissionsActivity;
import com.android.contacts.common.interactions.ImportExportDialogFragment;
import com.android.contacts.common.list.ContactEntryListFragment;
@@ -72,6 +74,7 @@ import com.android.contacts.common.model.account.GoogleAccountType;
import com.android.contacts.common.util.Constants;
import com.android.contacts.common.util.ImplicitIntentsUtil;
import com.android.contacts.common.widget.FloatingActionButtonController;
import com.android.contacts.commonbind.experiments.Flags;
import com.android.contacts.editor.EditorIntents;
import com.android.contacts.interactions.ContactDeletionInteraction;
import com.android.contacts.interactions.ContactMultiDeletionInteraction;
@@ -1408,6 +1411,47 @@ public class PeopleActivity extends ContactsDrawerActivity implements
            }
            getSupportActionBar().setTitle(actionBarTitle);
        }

        // Determine whether the account has pullToRefresh feature
        if (Flags.getInstance(this).getBoolean(Experiments.PULL_TO_REFRESH)) {
            setSwipeRefreshLayoutEnabledOrNot(filter);
        }
    }

    private void setSwipeRefreshLayoutEnabledOrNot(ContactListFilter filter) {
        final SwipeRefreshLayout swipeRefreshLayout = mAllFragment.getSwipeRefreshLayout();
        if (swipeRefreshLayout == null) {
            if (Log.isLoggable(TAG, Log.DEBUG)) {
                Log.d(TAG, "Can not load swipeRefreshLayout, swipeRefreshLayout is null");
            }
            return;
        }
        swipeRefreshLayout.setRefreshing(false);
        swipeRefreshLayout.setEnabled(false);

        if (mActionBarAdapter.isSearchMode()) {
            return;
        }

        if (GoogleAccountType.ACCOUNT_TYPE.equals(filter.accountType) && filter.dataSet == null
                && filter.filterType == ContactListFilter.FILTER_TYPE_ACCOUNT) {
            swipeRefreshLayout.setEnabled(true);
            return;
        }
        // TODO(samchen): check against both FILTER_TYPE_ALL_ACCOUNTS and FILTER_TYPE_DEFAULT
        if (filter.filterType == ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS) {
            final List<AccountWithDataSet> accounts = AccountTypeManager.getInstance(this)
                    .getAccounts(/* contactsWritableOnly */ true);
            if (accounts != null && accounts.size() > 0) {
                for (AccountWithDataSet account : accounts) {
                    if (GoogleAccountType.ACCOUNT_TYPE.equals(account.type)
                            && filter.dataSet == null) {
                        swipeRefreshLayout.setEnabled(true);
                        return;
                    }
                }
            }
        }
    }

    private String getActionBarTitleForAccount(ContactListFilter filter) {
+1 −1
Original line number Diff line number Diff line
@@ -92,7 +92,7 @@ public abstract class ContactBrowseListFragment extends
    private boolean mSelectionVerified;
    private int mLastSelectedPosition = -1;
    private boolean mRefreshingContactUri;
    private ContactListFilter mFilter;
    protected ContactListFilter mFilter;
    private String mPersistentSelectionPrefix = PERSISTENT_SELECTION_PREFIX;

    protected OnContactBrowserActionListener mListener;
+77 −0
Original line number Diff line number Diff line
@@ -15,11 +15,17 @@
 */
package com.android.contacts.list;

import android.accounts.Account;
import android.content.ContentResolver;
import android.content.Context;
import android.content.CursorLoader;
import android.content.Loader;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.provider.ContactsContract;
import android.support.v4.widget.SwipeRefreshLayout;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
@@ -29,13 +35,19 @@ import android.widget.FrameLayout;
import android.widget.TextView;

import com.android.contacts.R;
import com.android.contacts.common.Experiments;
import com.android.contacts.common.list.ContactListAdapter;
import com.android.contacts.common.list.ContactListFilter;
import com.android.contacts.common.list.ContactListFilterController;
import com.android.contacts.common.list.ContactListItemView;
import com.android.contacts.common.list.DefaultContactListAdapter;
import com.android.contacts.common.list.FavoritesAndContactsLoader;
import com.android.contacts.common.model.AccountTypeManager;
import com.android.contacts.common.model.account.AccountWithDataSet;
import com.android.contacts.common.model.account.GoogleAccountType;
import com.android.contacts.commonbind.experiments.Flags;

import java.util.List;

/**
 * Fragment containing a contact list used for browsing (as compared to
@@ -45,6 +57,7 @@ public class DefaultContactBrowseListFragment extends ContactBrowseListFragment
    private View mSearchHeaderView;
    private View mSearchProgress;
    private TextView mSearchProgressText;
    private SwipeRefreshLayout mSwipeRefreshLayout;

    public DefaultContactBrowseListFragment() {
        setPhotoLoaderEnabled(true);
@@ -119,6 +132,10 @@ public class DefaultContactBrowseListFragment extends ContactBrowseListFragment
    protected void onCreateView(LayoutInflater inflater, ViewGroup container) {
        super.onCreateView(inflater, container);

        if (Flags.getInstance(getActivity()).getBoolean(Experiments.PULL_TO_REFRESH)) {
            initSwipeRefreshLayout();

        }
        // Putting the header view inside a container will allow us to make
        // it invisible later. See checkHeaderViewVisibility()
        FrameLayout headerContainer = new FrameLayout(inflater.getContext());
@@ -131,6 +148,62 @@ public class DefaultContactBrowseListFragment extends ContactBrowseListFragment
        mSearchProgressText = (TextView) mSearchHeaderView.findViewById(R.id.totalContactsText);
    }

    private void initSwipeRefreshLayout() {
        mSwipeRefreshLayout = (SwipeRefreshLayout) mView.findViewById(R.id.swipe_refresh);
        if (mSwipeRefreshLayout == null) {
            return;
        }

        mSwipeRefreshLayout.setEnabled(true);
        // Request sync contacts
        mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                syncContacts(mFilter);
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        mSwipeRefreshLayout.setRefreshing(false);
                    }
                }, 3000 /* spinning time */);
            }
        });
        mSwipeRefreshLayout.setColorSchemeResources(
                R.color.swipe_refresh_color1,
                R.color.swipe_refresh_color2,
                R.color.swipe_refresh_color3,
                R.color.swipe_refresh_color4);
        mSwipeRefreshLayout.setDistanceToTriggerSync(
                (int) getResources().getDimension(R.dimen.pull_to_refresh_distance));
    }

    /** Request sync for Google accounts(not include G+ accounts) in filter. */
    private void syncContacts(ContactListFilter filter) {
        if (filter == null) {
            return;
        }
        final Bundle bundle = new Bundle();
        bundle.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
        bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);

        if (GoogleAccountType.ACCOUNT_TYPE.equals(filter.accountType) && filter.dataSet == null) {
            final Account account = new Account(filter.accountName, filter.accountType);
            ContentResolver.requestSync(account, ContactsContract.AUTHORITY, bundle);
        } else {
            final List<AccountWithDataSet> accounts = AccountTypeManager.getInstance(
                    getActivity()).getAccounts(/* contactsWritableOnly= */ true);
            if (accounts != null && accounts.size() > 0) {
                for (AccountWithDataSet account : accounts) {
                    if (GoogleAccountType.ACCOUNT_TYPE.equals(account.type)
                            && filter.dataSet == null) {
                        ContentResolver.requestSync(new Account(account.name, account.type),
                                ContactsContract.AUTHORITY, bundle);
                    }
                }
            }
        }
    }

    @Override
    protected void setSearchMode(boolean flag) {
        super.setSearchMode(flag);
@@ -179,4 +252,8 @@ public class DefaultContactBrowseListFragment extends ContactBrowseListFragment
            }
        }
    }

    public SwipeRefreshLayout getSwipeRefreshLayout() {
        return mSwipeRefreshLayout;
    }
}
 No newline at end of file