Merge "Check newly-created group rather than the last one"
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 4edacdf..880460b 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -376,10 +376,9 @@
<item name="android:fontFamily">sans-serif</item>
</style>
- <!-- Inherit from Theme.Material.Light.Dialog instead of Theme.Material.Light.Dialog.Alert
- since the Alert dialog is private. They are identical anyway. -->
- <style name="ContactsAlertDialogTheme" parent="@android:style/Theme.Material.Light.Dialog">
+ <style name="ContactsAlertDialogTheme" parent="Theme.AppCompat.Light.Dialog.MinWidth">
<item name="android:colorAccent">@color/primary_color</item>
+ <item name="colorAccent">@color/primary_color</item>
</style>
<style name="EditKindIconStyle">
diff --git a/src/com/android/contacts/ContactSaveService.java b/src/com/android/contacts/ContactSaveService.java
index b9fc949..b68d34c 100755
--- a/src/com/android/contacts/ContactSaveService.java
+++ b/src/com/android/contacts/ContactSaveService.java
@@ -133,6 +133,7 @@
public static final int CP2_ERROR = 0;
public static final int CONTACTS_LINKED = 1;
public static final int CONTACTS_SPLIT = 2;
+ public static final int BAD_ARGUMENTS = 3;
private static final HashSet<String> ALLOWED_DATA_COLUMNS = Sets.newHashSet(
Data.MIMETYPE,
@@ -1155,14 +1156,17 @@
private void splitContact(Intent intent) {
final long rawContactIds[][] = (long[][]) intent
.getSerializableExtra(EXTRA_RAW_CONTACT_IDS);
+ final ResultReceiver receiver = intent.getParcelableExtra(EXTRA_RESULT_RECEIVER);
if (rawContactIds == null) {
Log.e(TAG, "Invalid argument for splitContact request");
+ if (receiver != null) {
+ receiver.send(BAD_ARGUMENTS, new Bundle());
+ }
return;
}
final int batchSize = MAX_CONTACTS_PROVIDER_BATCH_SIZE;
final ContentResolver resolver = getContentResolver();
final ArrayList<ContentProviderOperation> operations = new ArrayList<>(batchSize);
- final ResultReceiver receiver = intent.getParcelableExtra(EXTRA_RESULT_RECEIVER);
for (int i = 0; i < rawContactIds.length; i++) {
for (int j = 0; j < rawContactIds.length; j++) {
if (i != j) {
@@ -1295,6 +1299,9 @@
final long[][] separatedRawContactIds = getSeparatedRawContactIds(contactIds);
if (rawContactIds == null) {
Log.e(TAG, "Invalid arguments for joinSeveralContacts request");
+ if (receiver != null) {
+ receiver.send(BAD_ARGUMENTS, new Bundle());
+ }
return;
}
diff --git a/src/com/android/contacts/GroupListLoader.java b/src/com/android/contacts/GroupListLoader.java
index fbb68db..5bb240f 100644
--- a/src/com/android/contacts/GroupListLoader.java
+++ b/src/com/android/contacts/GroupListLoader.java
@@ -40,6 +40,8 @@
Groups._ID,
Groups.TITLE,
Groups.SUMMARY_COUNT,
+ Groups.GROUP_IS_READ_ONLY,
+ Groups.SYSTEM_ID,
};
public final static int ACCOUNT_NAME = 0;
@@ -48,16 +50,18 @@
public final static int GROUP_ID = 3;
public final static int TITLE = 4;
public final static int MEMBER_COUNT = 5;
+ public final static int IS_READ_ONLY = 6;
+ public final static int SYSTEM_ID = 7;
private static final Uri GROUP_LIST_URI = Groups.CONTENT_SUMMARY_URI;
public GroupListLoader(Context context) {
+ // Sort groups from all accounts alphabettically and in a localized way.
super(context,
GROUP_LIST_URI,
COLUMNS,
DEFAULT_SELECTION,
null,
- Groups.ACCOUNT_TYPE + ", " + Groups.ACCOUNT_NAME + ", " + Groups.DATA_SET + ", " +
- Groups.TITLE + " COLLATE NOCASE ASC");
+ Groups.TITLE + " COLLATE LOCALIZED ASC");
}
}
diff --git a/src/com/android/contacts/activities/PeopleActivity.java b/src/com/android/contacts/activities/PeopleActivity.java
index aa507e7..892e831 100644
--- a/src/com/android/contacts/activities/PeopleActivity.java
+++ b/src/com/android/contacts/activities/PeopleActivity.java
@@ -253,6 +253,14 @@
mProviderStatusWatcher.addListener(this);
mIsRecreatedInstance = (savedState != null);
+
+ // Use FILTER_TYPE_ALL_ACCOUNTS filter if the activity is not a re-created one.
+ // This is useful when user upgrades app while an account filter or a custom filter was
+ // stored in sharedPreference in a previous version of Contacts app.
+ final ContactListFilter filter = mIsRecreatedInstance
+ ? mContactListFilterController.getFilter() : createAllAccountsFilter();
+ persistFilterIfNeeded(filter);
+
createViewsAndFragments(savedState);
if (Log.isLoggable(Constants.PERFORMANCE_TAG, Log.DEBUG)) {
@@ -401,10 +409,7 @@
mAllFragment.setOnContactListActionListener(new ContactBrowserActionListener());
mAllFragment.setCheckBoxListListener(new CheckBoxListListener());
- final int listType = mContactListFilterController.getFilter().filterType ==
- ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS
- ? ListEvent.ListType.ALL_CONTACTS : ListEvent.ListType.ACCOUNT;
- mAllFragment.setListType(listType);
+ mAllFragment.setListType(ListEvent.ListType.ALL_CONTACTS);
if (areGroupWritableAccountsAvailable() && mGroupsFragment != null) {
mGroupsFragment.setListener(this);
@@ -513,8 +518,7 @@
final int tabToOpen;
switch (actionCode) {
case ContactsRequest.ACTION_ALL_CONTACTS:
- filter = ContactListFilter.createFilterWithType(
- ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS);
+ filter = createAllAccountsFilter();
tabToOpen = TabState.ALL;
break;
case ContactsRequest.ACTION_CONTACTS_WITH_PHONES:
@@ -925,6 +929,9 @@
if (groupListItems != null) {
// Add each group
for (GroupListItem groupListItem : groupListItems) {
+ if (GroupUtil.isEmptyFFCGroup(groupListItem)) {
+ continue;
+ }
final String title = groupListItem.getTitle();
final MenuItem menuItem =
subMenu.add(R.id.nav_groups_items, Menu.NONE, Menu.NONE, title);
@@ -964,6 +971,7 @@
public boolean onMenuItemClick(MenuItem item) {
final DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
+ mAllFragment.setListType(ListEvent.ListType.ACCOUNT);
AccountFilterUtil.handleAccountFilterResult(
mContactListFilterController, AppCompatActivity.RESULT_OK, intent);
return true;
@@ -1085,15 +1093,14 @@
ContactListFilter currentFilter = mAllFragment.getFilter();
if (currentFilter != null
&& currentFilter.filterType == ContactListFilter.FILTER_TYPE_SINGLE_CONTACT) {
- filter = ContactListFilter.createFilterWithType(
- ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS);
+ filter = createAllAccountsFilter();
setFilterAndUpdateTitle(filter);
} else {
filter = ContactListFilter.createFilterWithType(
ContactListFilter.FILTER_TYPE_SINGLE_CONTACT);
setFilterAndUpdateTitle(filter, /* restoreSelectedUri */ false);
}
- mContactListFilterController.setContactListFilter(filter, true);
+ persistFilterIfNeeded(filter);
}
}
@@ -1266,12 +1273,7 @@
} else if (id == R.id.nav_help) {
HelpUtils.launchHelpAndFeedbackForMainScreen(this);
} else if (id == R.id.nav_all_contacts) {
- final Intent intent = new Intent();
- final ContactListFilter filter = ContactListFilter.createFilterWithType(
- ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS);
- intent.putExtra(AccountFilterUtil.EXTRA_CONTACT_LIST_FILTER, filter);
- AccountFilterUtil.handleAccountFilterResult(
- mContactListFilterController, AppCompatActivity.RESULT_OK, intent);
+ switchToAllContacts();
} else if (id == R.id.nav_blocked_numbers) {
final Intent intent = TelecomManagerUtil.createManageBlockedNumbersIntent(
(TelecomManager) getSystemService(Context.TELECOM_SERVICE));
@@ -1459,6 +1461,9 @@
Logger.logScreenView(this, ScreenType.SEARCH_EXIT);
Logger.logSearchEvent(mAllFragment.createSearchState());
}
+ } else if (mContactListFilterController.getFilter().filterType !=
+ ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS) {
+ switchToAllContacts();
} else {
super.onBackPressed();
}
@@ -1538,4 +1543,22 @@
getSupportActionBar().setTitle(actionBarTitle);
}
}
+
+ private void switchToAllContacts() {
+ final Intent intent = new Intent();
+ final ContactListFilter filter = createAllAccountsFilter();
+ intent.putExtra(AccountFilterUtil.EXTRA_CONTACT_LIST_FILTER, filter);
+ AccountFilterUtil.handleAccountFilterResult(
+ mContactListFilterController, AppCompatActivity.RESULT_OK, intent);
+ }
+
+ private ContactListFilter createAllAccountsFilter() {
+ return ContactListFilter.createFilterWithType(ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS);
+ }
+
+ // Persist filter only when it's of the type FILTER_TYPE_ALL_ACCOUNTS.
+ private void persistFilterIfNeeded(ContactListFilter filter) {
+ mContactListFilterController.setContactListFilter(filter, /* persistent */
+ filter.filterType == ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS);
+ }
}
diff --git a/src/com/android/contacts/group/GroupListItem.java b/src/com/android/contacts/group/GroupListItem.java
index a06ec38..f2359b6 100644
--- a/src/com/android/contacts/group/GroupListItem.java
+++ b/src/com/android/contacts/group/GroupListItem.java
@@ -27,9 +27,12 @@
private final String mTitle;
private final boolean mIsFirstGroupInAccount;
private final int mMemberCount;
+ private final boolean mIsReadOnly;
+ private final String mSystemId;
public GroupListItem(String accountName, String accountType, String dataSet, long groupId,
- String title, boolean isFirstGroupInAccount, int memberCount) {
+ String title, boolean isFirstGroupInAccount, int memberCount, boolean isReadOnly,
+ String systemId) {
mAccountName = accountName;
mAccountType = accountType;
mDataSet = dataSet;
@@ -37,6 +40,8 @@
mTitle = title;
mIsFirstGroupInAccount = isFirstGroupInAccount;
mMemberCount = memberCount;
+ mIsReadOnly = isReadOnly;
+ mSystemId = systemId;
}
public String getAccountName() {
@@ -70,4 +75,12 @@
public boolean isFirstGroupInAccount() {
return mIsFirstGroupInAccount;
}
+
+ public boolean isReadOnly() {
+ return mIsReadOnly;
+ }
+
+ public String getSystemId() {
+ return mSystemId;
+ }
}
\ No newline at end of file
diff --git a/src/com/android/contacts/group/GroupNameEditDialogFragment.java b/src/com/android/contacts/group/GroupNameEditDialogFragment.java
index bc877a2..8fcd63d 100644
--- a/src/com/android/contacts/group/GroupNameEditDialogFragment.java
+++ b/src/com/android/contacts/group/GroupNameEditDialogFragment.java
@@ -15,7 +15,6 @@
*/
package com.android.contacts.group;
-import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.FragmentManager;
@@ -23,10 +22,10 @@
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle;
+import android.support.v7.app.AlertDialog;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
-import android.view.ContextThemeWrapper;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
@@ -91,9 +90,7 @@
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Build a dialog with two buttons and a view of a single EditText input field
- final ContextThemeWrapper context = new ContextThemeWrapper(getActivity(),
- android.R.style.Theme_Holo_Light_Dialog_MinWidth);
- final AlertDialog.Builder builder = new AlertDialog.Builder(context)
+ final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
.setTitle(mIsInsert
? R.string.group_name_dialog_insert_title
: R.string.group_name_dialog_update_title)
diff --git a/src/com/android/contacts/group/GroupUtil.java b/src/com/android/contacts/group/GroupUtil.java
index a45cdb5..2057a94 100644
--- a/src/com/android/contacts/group/GroupUtil.java
+++ b/src/com/android/contacts/group/GroupUtil.java
@@ -22,14 +22,20 @@
import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract.Groups;
+import android.text.TextUtils;
import android.widget.ImageView;
import com.android.contacts.GroupListLoader;
import com.android.contacts.activities.GroupMembersActivity;
import com.android.contacts.common.ContactPhotoManager;
import com.android.contacts.common.ContactPhotoManager.DefaultImageRequest;
+import com.android.contacts.common.model.account.GoogleAccountType;
import com.google.common.base.Objects;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
/**
* Group utility methods.
*/
@@ -38,6 +44,10 @@
private static final String LEGACY_CONTACTS_AUTHORITY = "contacts";
private static final String LEGACY_CONTACTS_URI = "content://contacts/groups";
+ // System IDs of FFC groups in Google accounts
+ private static final Set<String> FFC_GROUPS =
+ new HashSet(Arrays.asList("Friends", "Family", "Coworkers"));
+
private GroupUtil() {
}
@@ -52,6 +62,8 @@
long groupId = cursor.getLong(GroupListLoader.GROUP_ID);
String title = cursor.getString(GroupListLoader.TITLE);
int memberCount = cursor.getInt(GroupListLoader.MEMBER_COUNT);
+ boolean isReadOnly = cursor.getInt(GroupListLoader.IS_READ_ONLY) == 1;
+ String systemId = cursor.getString(GroupListLoader.SYSTEM_ID);
// Figure out if this is the first group for this account name / account type pair by
// checking the previous entry. This is to determine whether or not we need to display an
@@ -71,7 +83,7 @@
}
return new GroupListItem(accountName, accountType, dataSet, groupId, title,
- isFirstGroupInAccount, memberCount);
+ isFirstGroupInAccount, memberCount, isReadOnly, systemId);
}
/**
@@ -122,4 +134,19 @@
final Uri legacyContentUri = Uri.parse(LEGACY_CONTACTS_URI);
return ContentUris.withAppendedId(legacyContentUri, groupId);
}
+
+ /**
+ * Returns true if it's an empty and read-only group of a Google account and the system ID of
+ * the group is one of "Friends", "Family" and "Coworkers".
+ */
+ public static boolean isEmptyFFCGroup(GroupListItem groupListItem) {
+ return GoogleAccountType.ACCOUNT_TYPE.equals(groupListItem.getAccountType())
+ && groupListItem.isReadOnly()
+ && isSystemIdFFC(groupListItem.getSystemId())
+ && (groupListItem.getMemberCount() <= 0);
+ }
+
+ private static boolean isSystemIdFFC(String systemId) {
+ return !TextUtils.isEmpty(systemId) && FFC_GROUPS.contains(systemId);
+ }
}
\ No newline at end of file
diff --git a/src/com/android/contacts/list/ContactBrowseListFragment.java b/src/com/android/contacts/list/ContactBrowseListFragment.java
index 436c3a2..2060068 100644
--- a/src/com/android/contacts/list/ContactBrowseListFragment.java
+++ b/src/com/android/contacts/list/ContactBrowseListFragment.java
@@ -216,7 +216,11 @@
mFilter = filter;
mLastSelectedPosition = -1;
- saveFilter();
+
+ if (filter.filterType == ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS) {
+ saveFilter();
+ }
+
if (restoreSelectedUri) {
mSelectedContactUri = null;
restoreSelectedUri(true);