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

Commit a455bd58 authored by Xi Chen's avatar Xi Chen
Browse files

Missing contacts & accounts issue

This CL is to solve missing contacts & accounts after adding new
accounts from Settings. New accounts will appear in the app immediately.
If the sync of the Google account is not initialized, it uses spinning circle
to indicate sync is in progress.

BUG 30378161

Change-Id: I370e63e10b16791011f533cf7ca325bff8ccd3f2
parent 47957ad2
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -208,7 +208,8 @@ public class PeopleActivity extends ContactsDrawerActivity implements
            // the syncs is in progress.
            if (syncableAccounts != null && syncableAccounts.size() > 0) {
                for (Account account: syncableAccounts) {
                    if (SyncUtil.isSyncStatusPendingOrActive(account)) {
                    if (SyncUtil.isSyncStatusPendingOrActive(account)
                            || SyncUtil.isUnsyncableGoogleAccount(account)) {
                        swipeRefreshLayout.setRefreshing(true);
                        return;
                    }
+42 −3
Original line number Diff line number Diff line
@@ -88,7 +88,9 @@ public class DefaultContactBrowseListFragment extends ContactBrowseListFragment

    private void bindListHeader(int numberOfContacts) {
        final ContactListFilter filter = getFilter();
        if (!isSearchMode() && numberOfContacts <= 0) {
        // If the phone has at least one Google account whose sync status is unsyncable or pending
        // or active, we have to make mAccountFilterContainer visible.
        if (!isSearchMode() && numberOfContacts <= 0 && shouldShowEmptyView(filter)) {
            if (filter != null && filter.isContactsFilterType()) {
                makeViewVisible(mEmptyHomeView);
            } else {
@@ -111,6 +113,38 @@ public class DefaultContactBrowseListFragment extends ContactBrowseListFragment
        }
    }

    /**
     * If at least one Google account is unsyncable or its sync status is pending or active, we
     * should not show empty view even if the number of contacts is 0. We should show sync status
     * with empty list instead.
     */
    private boolean shouldShowEmptyView(ContactListFilter filter) {
        if (filter == null) {
            return true;
        }
        // TODO(samchen) : Check ContactListFilter.FILTER_TYPE_CUSTOM
        if (ContactListFilter.FILTER_TYPE_DEFAULT == filter.filterType
                || ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS == filter.filterType) {
            final List<AccountWithDataSet> accounts = AccountTypeManager.getInstance(getContext())
                    .getAccounts(/* contactsWritableOnly */ true);
            final List<Account> syncableAccounts = filter.getSyncableAccounts(accounts);

            if (syncableAccounts != null && syncableAccounts.size() > 0) {
                for (Account account : syncableAccounts) {
                    if (SyncUtil.isSyncStatusPendingOrActive(account)
                            || SyncUtil.isUnsyncableGoogleAccount(account)) {
                        return false;
                    }
                }
            }
        } else if (ContactListFilter.FILTER_TYPE_ACCOUNT == filter.filterType) {
            final Account account = new Account(filter.accountName, filter.accountType);
            return !(SyncUtil.isSyncStatusPendingOrActive(account)
                    || SyncUtil.isUnsyncableGoogleAccount(account));
        }
        return true;
    }

    // Show the view that's specified by id and hide the other two.
    private void makeViewVisible(View view) {
        mEmptyAccountView.setVisibility(view == mEmptyAccountView ? View.VISIBLE : View.GONE);
@@ -251,7 +285,10 @@ public class DefaultContactBrowseListFragment extends ContactBrowseListFragment
                (int) getResources().getDimension(R.dimen.pull_to_refresh_distance));
    }

    /** Request sync for Google accounts(not include Google+ accounts) in filter. */
    /**
     * Request sync for the Google accounts (not include Google+ accounts) specified by the given
     * filter.
     */
    private void syncContacts(ContactListFilter filter) {
        if (filter == null) {
            return;
@@ -265,7 +302,9 @@ public class DefaultContactBrowseListFragment extends ContactBrowseListFragment
        final List<Account> syncableAccounts = filter.getSyncableAccounts(accounts);
        if (syncableAccounts != null && syncableAccounts.size() > 0) {
            for (Account account : syncableAccounts) {
                if (!SyncUtil.isSyncStatusPendingOrActive(account)) {
                 // We can prioritize Contacts sync if sync is not initialized yet.
                if (!SyncUtil.isSyncStatusPendingOrActive(account)
                        || SyncUtil.isUnsyncableGoogleAccount(account)) {
                    ContentResolver.requestSync(account, ContactsContract.AUTHORITY, bundle);
                }
            }
+17 −0
Original line number Diff line number Diff line
@@ -19,6 +19,10 @@ import android.accounts.Account;
import android.content.ContentResolver;
import android.provider.ContactsContract;

import com.android.contacts.common.model.account.GoogleAccountType;

import java.util.List;

/**
 * Utilities related to sync.
 */
@@ -29,7 +33,20 @@ public final class SyncUtil {
    }

    public static final boolean isSyncStatusPendingOrActive(Account account) {
        if (account == null) {
            return false;
        }
        return ContentResolver.isSyncPending(account, ContactsContract.AUTHORITY)
                || ContentResolver.isSyncActive(account, ContactsContract.AUTHORITY);
    }

    /**
     * Returns true if the given Google account is not syncable.
     */
    public static final boolean isUnsyncableGoogleAccount(Account account) {
        if (account == null || !GoogleAccountType.ACCOUNT_TYPE.equals(account.type)) {
            return false;
        }
        return ContentResolver.getIsSyncable(account, ContactsContract.AUTHORITY) <= 0;
    }
}
+51 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 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.contacts.util;

import android.accounts.Account;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;

import java.util.ArrayList;
import java.util.List;

/**
 * Tests for SyncUtil.
 */
@SmallTest
public class SyncUtilTests extends AndroidTestCase {
    private static final String TAG = "SyncUtilTests";

    private static final String GOOGLE_TYPE = "com.google";
    private static final String NOT_GOOGLE_TYPE = "com.abc";
    private static final String ACCOUNT_NAME = "ACCOUNT_NAME";

    private final Account mGoogleAccount;
    private final Account mOtherAccount;

    public SyncUtilTests() {
        mGoogleAccount = new Account(ACCOUNT_NAME, GOOGLE_TYPE);
        mOtherAccount = new Account(ACCOUNT_NAME, NOT_GOOGLE_TYPE);
    }

    public void testIsUnsyncableGoogleAccount() throws Exception {
        // The account names of mGoogleAccount and mOtherAccount are not valid, so both accounts
        // are not syncable.
        assertTrue(SyncUtil.isUnsyncableGoogleAccount(mGoogleAccount));
        assertFalse(SyncUtil.isUnsyncableGoogleAccount(mOtherAccount));
        assertFalse(SyncUtil.isUnsyncableGoogleAccount(null));
    }
}