summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYujing Gu <guy@codeaurora.org>2014-07-24 14:32:13 +0800
committerLinux Build Service Account <lnxbuild@localhost>2014-11-04 08:54:05 -0700
commit1122a58d3e8b4f85ffbc97aecbf76f57b2711065 (patch)
tree016a909cb7800b40b0de2a6186d3d0eadb444706
parent704df5781b585da8feb6a8a1ab41fbb65b6f7345 (diff)
downloadandroid_packages_apps_ContactsCommon-1122a58d3e8b4f85ffbc97aecbf76f57b2711065.tar.gz
android_packages_apps_ContactsCommon-1122a58d3e8b4f85ffbc97aecbf76f57b2711065.tar.bz2
android_packages_apps_ContactsCommon-1122a58d3e8b4f85ffbc97aecbf76f57b2711065.zip
Add the support for SIM and Phone account
- Add SIM and Phone account type - Add insert/update/delete operation for SIM contacts - Add the support for filter SIM contacts - Add support to save anr and email for SIM contacts Change-Id: I1aaa9046462ed114488e4cd0cfa0d061a7330c69
-rw-r--r--Android.mk2
-rw-r--r--TestCommon/src/com/android/contacts/common/test/mocks/MockAccountTypeManager.java5
-rw-r--r--src/com/android/contacts/common/ContactTileLoaderFactory.java16
-rw-r--r--src/com/android/contacts/common/MoreContactUtils.java167
-rw-r--r--src/com/android/contacts/common/SimContactsConstants.java77
-rw-r--r--src/com/android/contacts/common/SimContactsOperation.java340
-rw-r--r--src/com/android/contacts/common/list/ContactEntryListFragment.java26
-rw-r--r--src/com/android/contacts/common/list/DefaultContactListAdapter.java51
-rw-r--r--src/com/android/contacts/common/list/PhoneNumberListAdapter.java29
-rw-r--r--src/com/android/contacts/common/model/AccountTypeManager.java90
-rw-r--r--src/com/android/contacts/common/model/RawContactDelta.java138
-rw-r--r--src/com/android/contacts/common/model/ValuesDelta.java16
-rw-r--r--src/com/android/contacts/common/model/account/AccountType.java63
-rw-r--r--src/com/android/contacts/common/model/account/PhoneAccountType.java99
-rw-r--r--src/com/android/contacts/common/model/account/SimAccountType.java123
-rw-r--r--src/com/android/contacts/common/util/AccountSelectionUtil.java35
-rw-r--r--src/com/android/contacts/common/util/AccountsListAdapter.java23
17 files changed, 1275 insertions, 25 deletions
diff --git a/Android.mk b/Android.mk
index 626a737b..3687e476 100644
--- a/Android.mk
+++ b/Android.mk
@@ -28,6 +28,8 @@ LOCAL_AAPT_FLAGS := \
--auto-add-overlay \
--extra-packages com.android.phone.common
+LOCAL_JAVA_LIBRARIES := telephony-common
+
LOCAL_STATIC_JAVA_LIBRARIES := \
com.android.vcard \
guava \
diff --git a/TestCommon/src/com/android/contacts/common/test/mocks/MockAccountTypeManager.java b/TestCommon/src/com/android/contacts/common/test/mocks/MockAccountTypeManager.java
index ab2d3954..d3dd722c 100644
--- a/TestCommon/src/com/android/contacts/common/test/mocks/MockAccountTypeManager.java
+++ b/TestCommon/src/com/android/contacts/common/test/mocks/MockAccountTypeManager.java
@@ -66,6 +66,11 @@ public class MockAccountTypeManager extends AccountTypeManager {
}
@Override
+ public List<AccountWithDataSet> getAccounts(boolean writableOnly, int flag) {
+ return Arrays.asList(mAccounts);
+ }
+
+ @Override
public List<AccountWithDataSet> getGroupWritableAccounts() {
return Arrays.asList(mAccounts);
}
diff --git a/src/com/android/contacts/common/ContactTileLoaderFactory.java b/src/com/android/contacts/common/ContactTileLoaderFactory.java
index f8b0c359..4377d057 100644
--- a/src/com/android/contacts/common/ContactTileLoaderFactory.java
+++ b/src/com/android/contacts/common/ContactTileLoaderFactory.java
@@ -23,6 +23,8 @@ import android.net.Uri;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.RawContacts;
+import android.text.TextUtils;
/**
* Used to create {@link CursorLoader}s to load different groups of
@@ -88,10 +90,16 @@ public final class ContactTileLoaderFactory {
}
public static CursorLoader createStrequentPhoneOnlyLoader(Context context) {
- Uri uri = Contacts.CONTENT_STREQUENT_URI.buildUpon()
- .appendQueryParameter(ContactsContract.STREQUENT_PHONE_ONLY, "true").build();
-
- return new CursorLoader(context, uri, COLUMNS_PHONE_ONLY, null, null, null);
+ Uri.Builder builder = Contacts.CONTENT_STREQUENT_URI.buildUpon();
+ builder.appendQueryParameter(ContactsContract.STREQUENT_PHONE_ONLY, "true");
+ // Do not show contacts in disabled SIM card
+ String disabledSimFilter = MoreContactUtils.getDisabledSimFilter();
+ if (!TextUtils.isEmpty(disabledSimFilter)) {
+ builder.appendQueryParameter(RawContacts.ACCOUNT_NAME, disabledSimFilter);
+ builder.appendQueryParameter(SimContactsConstants
+ .WITHOUT_SIM_FLAG, "true");
+ }
+ return new CursorLoader(context, builder.build(), COLUMNS_PHONE_ONLY, null, null, null);
}
public static CursorLoader createStarredLoader(Context context) {
diff --git a/src/com/android/contacts/common/MoreContactUtils.java b/src/com/android/contacts/common/MoreContactUtils.java
index 16b4e8d9..52fd564b 100644
--- a/src/com/android/contacts/common/MoreContactUtils.java
+++ b/src/com/android/contacts/common/MoreContactUtils.java
@@ -16,6 +16,8 @@
package com.android.contacts.common;
+import android.accounts.Account;
+
import com.google.i18n.phonenumbers.NumberParseException;
import com.google.i18n.phonenumbers.PhoneNumberUtil;
@@ -23,13 +25,20 @@ import android.content.Context;
import android.content.Intent;
import android.graphics.Rect;
import android.net.Uri;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemProperties;
import android.provider.ContactsContract;
+import android.provider.Settings;
+import android.telephony.SubscriptionManager;
import android.telephony.PhoneNumberUtils;
+import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.view.View;
import android.widget.TextView;
import com.android.contacts.common.model.account.AccountType;
+import com.android.internal.telephony.IIccPhoneBook;
/**
* Shared static contact utility methods.
@@ -232,4 +241,162 @@ public class MoreContactUtils {
intent.setData(lookupUri);
return intent;
}
+
+ /** get disabled SIM card's name */
+ public static String getDisabledSimFilter() {
+ int count = TelephonyManager.getDefault().getPhoneCount();
+ StringBuilder simFilter = new StringBuilder("");
+
+ for (int i = 0; i < count; i++) {
+ if (!TelephonyManager.getDefault().hasIccCard(i)) {
+ continue;
+ }
+ if (TelephonyManager.SIM_STATE_UNKNOWN == TelephonyManager
+ .getDefault().getSimState(i)) {
+ simFilter.append(getSimAccountName(i) + ',');
+ }
+ }
+
+ return simFilter.toString();
+ }
+
+ public static boolean isAPMOnAndSIMPowerDown(Context context) {
+ if (context == null) {
+ return false;
+ }
+ boolean isAirPlaneMode = Settings.System.getInt(context.getContentResolver(),
+ Settings.System.AIRPLANE_MODE_ON, 0) == 1;
+ boolean isSIMPowerDown = SystemProperties.getInt(
+ "persist.radio.apm_sim_not_pwdn", 0) == 0;
+ return isAirPlaneMode && isSIMPowerDown;
+ }
+
+ /**
+ * Get SIM card account name
+ */
+ public static String getSimAccountName(int subscription) {
+ if (TelephonyManager.getDefault().isMultiSimEnabled()) {
+ return SimContactsConstants.SIM_NAME + (subscription + 1);
+ } else {
+ return SimContactsConstants.SIM_NAME;
+ }
+ }
+
+ public static int getSubscription(String accountType, String accountName) {
+ int subscription = SimContactsConstants.SUB_INVALID;
+ if (accountType == null || accountName == null)
+ return subscription;
+ if (accountType.equals(SimContactsConstants.ACCOUNT_TYPE_SIM)) {
+ if (accountName.equals(SimContactsConstants.SIM_NAME)
+ || accountName.equals(SimContactsConstants.SIM_NAME_1)) {
+ subscription = SimContactsConstants.SUB_1;
+ } else if (accountName.equals(SimContactsConstants.SIM_NAME_2)) {
+ subscription = SimContactsConstants.SUB_2;
+ }
+ }
+ return subscription;
+ }
+
+ public static int getAnrCount(int slot) {
+ int anrCount = 0;
+ long[] subId = SubscriptionManager.getSubId(slot);
+ try {
+ IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface(
+ ServiceManager.getService("simphonebook"));
+
+ if (iccIpb != null) {
+ if (subId != null
+ && TelephonyManager.getDefault().isMultiSimEnabled()) {
+ anrCount = iccIpb.getAnrCountUsingSubId(subId[0]);
+ } else {
+ anrCount = iccIpb.getAnrCount();
+ }
+ }
+ } catch (RemoteException ex) {
+ // ignore it
+ }
+
+ return anrCount;
+ }
+
+ public static int getAdnCount(int slot) {
+ int adnCount = 0;
+ long[] subId = SubscriptionManager.getSubId(slot);
+ try {
+ IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface(
+ ServiceManager.getService("simphonebook"));
+
+ if (iccIpb != null) {
+ if (subId != null
+ && TelephonyManager.getDefault().isMultiSimEnabled()) {
+ adnCount = iccIpb.getAdnCountUsingSubId(subId[0]);
+ } else {
+ adnCount = iccIpb.getAdnCount();
+ }
+ }
+ } catch (RemoteException ex) {
+ // ignore it
+ }
+
+ return adnCount;
+ }
+
+ public static int getEmailCount(int slot) {
+ int emailCount = 0;
+ long[] subId = SubscriptionManager.getSubId(slot);
+ try {
+ IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface(
+ ServiceManager.getService("simphonebook"));
+
+ if (iccIpb != null) {
+ if (subId != null
+ && TelephonyManager.getDefault().isMultiSimEnabled()) {
+ emailCount = iccIpb.getEmailCountUsingSubId(subId[0]);
+ } else {
+ emailCount = iccIpb.getEmailCount();
+ }
+ }
+ } catch (RemoteException ex) {
+ // ignore it
+ }
+
+ return emailCount;
+ }
+
+ /**
+ * Returns the subscription's card can save anr or not.
+ */
+ public static boolean canSaveAnr(int slot) {
+ return getAnrCount(slot) > 0 ? true : false;
+ }
+
+ /**
+ * Returns the subscription's card can save email or not.
+ */
+ public static boolean canSaveEmail(int slot) {
+ return getEmailCount(slot) > 0 ? true : false;
+ }
+
+ public static int getOneSimAnrCount(int slot) {
+ int count = 0;
+ int anrCount = getAnrCount(slot);
+ int adnCount = getAdnCount(slot);
+ if (adnCount > 0) {
+ count = anrCount % adnCount != 0 ? (anrCount / adnCount + 1)
+ : (anrCount / adnCount);
+ }
+ return count;
+ }
+
+ public static int getOneSimEmailCount(int slot) {
+ int count = 0;
+ int emailCount = getEmailCount(slot);
+ int adnCount = getAdnCount(slot);
+ if (adnCount > 0) {
+ count = emailCount % adnCount != 0 ? (emailCount
+ / adnCount + 1)
+ : (emailCount / adnCount);
+ }
+ return count;
+ }
}
diff --git a/src/com/android/contacts/common/SimContactsConstants.java b/src/com/android/contacts/common/SimContactsConstants.java
new file mode 100644
index 00000000..759dcd9e
--- /dev/null
+++ b/src/com/android/contacts/common/SimContactsConstants.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2014, The Linux Foundation. All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of The Linux Foundation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ */
+package com.android.contacts.common;
+
+import android.telephony.SubscriptionManager;
+import com.android.internal.telephony.PhoneConstants;
+
+public interface SimContactsConstants {
+
+ public static final String SIM_NAME_1 = "SIM1";
+ public static final String SIM_NAME_2 = "SIM2";
+ public static final String SIM_NAME = "SIM";
+ public static final String PHONE_NAME = "PHONE";
+ public static final String PASSWORD = "";
+ public static final String ACCOUNT_TYPE_SIM = "com.android.sim";
+ public static final String ACCOUNT_TYPE_PHONE = "com.android.localphone";
+ public static final String SUB = PhoneConstants.SLOT_KEY;
+ public static final String ACCOUNT_TYPE = "account_type";
+ public static final String ACCOUNT_NAME = "account_name";
+ public static final String ACCOUNT_DATA = "data_set";
+ public static final String STR_TAG = "tag";
+ public static final String STR_NUMBER = "number";
+ public static final String STR_EMAILS = "emails";
+ public static final String STR_ANRS = "anrs";
+ public static final String STR_NEW_TAG = "newTag";
+ public static final String STR_NEW_NUMBER = "newNumber";
+ public static final String STR_NEW_EMAILS = "newEmails";
+ public static final String STR_NEW_ANRS = "newAnrs";
+ public static final String INTENT_EXPORT_COMPLETE =
+ "com.android.sim.INTENT_EXPORT_COMPLETE";
+ public static final String SIM_URI = "content://icc/adn";
+ public static final String SIM_SUB_URI = "content://icc/adn/subId/";
+ public static final String WITHOUT_SIM_FLAG ="no_sim";
+ public static final String IS_CONTACT = "is_contact";
+ public static final String RESULT_KEY = "result";
+ public static final String ACTION_MULTI_PICK =
+ "com.android.contacts.action.MULTI_PICK";
+ public static final String ACTION_MULTI_PICK_EMAIL =
+ "com.android.contacts.action.MULTI_PICK_EMAIL";
+ public static final String ACTION_MULTI_PICK_CALL =
+ "com.android.contacts.action.MULTI_PICK_CALL";
+ public static final String ACTION_MULTI_PICK_SIM =
+ "com.android.contacts.action.MULTI_PICK_SIM";
+ public static final int SUB_1 = PhoneConstants.SUB1;
+ public static final int SUB_2 = PhoneConstants.SUB2;
+ public static final int SUB_INVALID = SubscriptionManager.INVALID_SLOT_ID;
+
+}
+
+
diff --git a/src/com/android/contacts/common/SimContactsOperation.java b/src/com/android/contacts/common/SimContactsOperation.java
new file mode 100644
index 00000000..55c7b79f
--- /dev/null
+++ b/src/com/android/contacts/common/SimContactsOperation.java
@@ -0,0 +1,340 @@
+/*
+ * Copyright (C) 2014, The Linux Foundation. All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of The Linux Foundation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ */
+
+package com.android.contacts.common;
+
+import android.content.AsyncQueryHandler;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.ContentUris;
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.CommonDataKinds;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.provider.ContactsContract.CommonDataKinds.StructuredName;
+import android.provider.ContactsContract.RawContacts;
+import android.telephony.PhoneNumberUtils;
+import android.telephony.TelephonyManager;
+import android.telephony.SubscriptionManager;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.contacts.common.SimContactsConstants;
+
+public class SimContactsOperation {
+
+ private static final String TAG = "SimContactsOperation";
+ private static final boolean DBG = true;
+ private static final int QUERY_TOKEN = 0;
+ private static final int INSERT_TOKEN = 1;
+ private static final int UPDATE_TOKEN = 2;
+ private static final int DELETE_TOKEN = 3;
+
+ public static final String[] ACCOUNT_PROJECTION = new String[] {
+ RawContacts._ID,
+ RawContacts.CONTACT_ID,
+ RawContacts.ACCOUNT_NAME,
+ RawContacts.ACCOUNT_TYPE,
+ };
+
+
+ private static final int ACCOUNT_COLUMN_RAW_ID = 0;
+ private static final int ACCOUNT_COLUMN_CONTACT_ID = 1;
+ private static final int ACCOUNT_COLUMN_NAME = 2;
+ private static final int ACCOUNT_COLUMN_TYPE = 3;
+ private static final int ACCOUNT_COLUMN_PHONE_NAME = 4;
+
+
+
+ private static Context mContext;
+ private ContentResolver mResolver;
+ private ContentValues mValues = new ContentValues();
+
+
+ public SimContactsOperation(Context context) {
+ this.mContext = context;
+ this.mResolver = context.getContentResolver();
+ }
+
+
+ public Uri insert(ContentValues values, int subscription) {
+
+ Uri uri = getContentUri(subscription);
+ String number = values.getAsString(SimContactsConstants.STR_NUMBER);
+ String anrs = values.getAsString(SimContactsConstants.STR_ANRS);
+ String emails = values.getAsString(SimContactsConstants.STR_EMAILS);
+ values.put(SimContactsConstants.STR_NUMBER,PhoneNumberUtils.stripSeparators(number));
+ values.put(SimContactsConstants.STR_ANRS,PhoneNumberUtils.stripSeparators(anrs));
+ values.put(SimContactsConstants.STR_EMAILS,emails);
+
+ Uri resultUri;
+ resultUri = mResolver.insert(uri,values);
+ return resultUri;
+ }
+
+ public int update(ContentValues values,int subscription) {
+ Uri uri = getContentUri(subscription);
+
+ int result;
+ String oldNumber = values.getAsString(SimContactsConstants.STR_NUMBER);
+ String newNumber = values.getAsString(SimContactsConstants.STR_NEW_NUMBER);
+ String oldAnrs = values.getAsString(SimContactsConstants.STR_ANRS);
+ String newAnrs = values.getAsString(SimContactsConstants.STR_NEW_ANRS);
+ values.put(SimContactsConstants.STR_NUMBER,PhoneNumberUtils.stripSeparators(oldNumber));
+ values.put(SimContactsConstants.STR_NEW_NUMBER,PhoneNumberUtils.stripSeparators(newNumber));
+ values.put(SimContactsConstants.STR_ANRS,PhoneNumberUtils.stripSeparators(oldAnrs));
+ values.put(SimContactsConstants.STR_NEW_ANRS,PhoneNumberUtils.stripSeparators(newAnrs));
+
+ result = mResolver.update(uri,values,null,null);
+ return result;
+
+ }
+
+ public int delete(ContentValues values, int subscription) {
+ int result;
+ StringBuilder buf = new StringBuilder();
+ String num = null;
+ String name = values.getAsString(SimContactsConstants.STR_TAG);
+ String number = values.getAsString(SimContactsConstants.STR_NUMBER);
+ String emails = values.getAsString(SimContactsConstants.STR_EMAILS);
+ String anrs = values.getAsString(SimContactsConstants.STR_ANRS);
+ if (number != null)
+ num = PhoneNumberUtils.stripSeparators(number);
+ if (anrs != null)
+ anrs = PhoneNumberUtils.stripSeparators(anrs);
+ Uri uri = getContentUri(subscription);
+
+
+ if (!TextUtils.isEmpty(name)) {
+ buf.append("tag='");
+ buf.append(name);
+ buf.append("'");
+ }
+ if (!TextUtils.isEmpty(num)) {
+ buf.append(" AND number='");
+ buf.append(num);
+ buf.append("'");
+ }
+ if (!TextUtils.isEmpty(emails)) {
+ buf.append(" AND emails='");
+ buf.append(emails);
+ buf.append("'");
+ }
+ if (!TextUtils.isEmpty(anrs)) {
+ buf.append(" AND anrs='");
+ buf.append(anrs);
+ buf.append("'");
+ }
+
+ result = mResolver.delete(uri,buf.toString(),null);
+ return result;
+
+ }
+
+ private Uri getContentUri(int subscription) {
+ Uri uri = null;
+ long[] subId = SubscriptionManager.getSubId(subscription);
+
+ if (subId != null && TelephonyManager.getDefault().isMultiSimEnabled()) {
+ uri = Uri.parse(SimContactsConstants.SIM_SUB_URI + subId[0]);
+ } else {
+ uri = Uri.parse(SimContactsConstants.SIM_URI);
+ }
+ return uri;
+ }
+
+ private static Cursor setupAccountCursor(long contactId) {
+ ContentResolver resolver = mContext.getContentResolver();
+
+ Cursor cursor = null;
+ try {
+ cursor = resolver.query(RawContacts.CONTENT_URI,
+ ACCOUNT_PROJECTION,
+ RawContacts.CONTACT_ID + "="
+ + Long.toString(contactId), null, null);
+ } catch (Exception e) {
+ Log.e(TAG, e.getMessage());
+ } finally {
+ if (cursor != null && cursor.moveToFirst()) {
+ return cursor;
+ }
+ if (cursor != null) {
+ cursor.close();
+ }
+ cursor = null;
+ return null;
+ }
+ }
+
+ public static ContentValues getSimAccountValues(long contactId) {
+ ContentValues mValues = new ContentValues();
+ Cursor cursor = setupAccountCursor(contactId);
+ if (cursor == null || cursor.getCount() == 0) {
+ mValues.clear();
+ return mValues;
+ }
+ long rawContactId = cursor.getLong(cursor.getColumnIndex(RawContacts._ID));
+ String accountName = cursor.getString(cursor.getColumnIndex(RawContacts.ACCOUNT_NAME));
+ String accountType = cursor.getString(cursor.getColumnIndex(RawContacts.ACCOUNT_TYPE));
+ cursor.close();
+ if (SimContactsConstants.ACCOUNT_TYPE_SIM.equals(accountType)) {
+ mValues.clear();
+ String name = getContactItems(rawContactId,StructuredName.CONTENT_ITEM_TYPE,
+ ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME);
+ mValues.put(SimContactsConstants.STR_TAG,name);
+
+ String number = getContactPhoneNumber(rawContactId,
+ Phone.CONTENT_ITEM_TYPE, String.valueOf(Phone.TYPE_MOBILE),
+ ContactsContract.CommonDataKinds.Phone.DATA);
+ mValues.put(SimContactsConstants.STR_NUMBER,number);
+
+ int sub = getSimSubscription(contactId);
+
+ if (MoreContactUtils.canSaveAnr(sub)) {
+ String anrs = getContactPhoneNumber(rawContactId,
+ Phone.CONTENT_ITEM_TYPE, String.valueOf(Phone.TYPE_HOME),
+ ContactsContract.CommonDataKinds.Phone.DATA);
+ mValues.put(SimContactsConstants.STR_ANRS, anrs);
+ }
+
+ if (MoreContactUtils.canSaveEmail(sub)) {
+ String emails = getContactItems(rawContactId,
+ Email.CONTENT_ITEM_TYPE, ContactsContract.CommonDataKinds.Email.DATA);
+ mValues.put(SimContactsConstants.STR_EMAILS, emails);
+ }
+ }
+ return mValues;
+ }
+
+ public static int getSimSubscription(long contactId) {
+ int subscription = SimContactsConstants.SUB_INVALID;
+ Cursor cursor = setupAccountCursor(contactId);
+ if (cursor == null || cursor.getCount() == 0) {
+ return subscription;
+ }
+
+ String accountName = cursor.getString(cursor.getColumnIndex(RawContacts.ACCOUNT_NAME));
+ String accountType = cursor.getString(cursor.getColumnIndex(RawContacts.ACCOUNT_TYPE));
+ if (accountType == null || accountName == null) {
+ return subscription;
+ }
+ if (SimContactsConstants.ACCOUNT_TYPE_SIM.equals(accountType)) {
+ subscription = MoreContactUtils.getSubscription(accountType, accountName);
+ }
+ cursor.close();
+ return subscription;
+ }
+
+
+ private static String getContactItems(long rawContactId, String selectionArg,
+ String columnName) {
+ StringBuilder retval = new StringBuilder();
+ Uri baseUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
+ Uri dataUri = Uri.withAppendedPath(baseUri, RawContacts.Data.CONTENT_DIRECTORY);
+
+ Cursor c = null;
+ try {
+ c = mContext.getContentResolver().query(dataUri, null,
+ Data.MIMETYPE + "=?", new String[] {selectionArg}, null);
+ if (c == null || c.getCount() == 0) {
+ if(c != null) {
+ c.close();
+ }
+ return null;
+ }
+ c.moveToPosition(-1);
+
+ while (c.moveToNext()) {
+ if (!TextUtils.isEmpty(retval.toString())) {
+ retval.append(",");
+ }
+ retval.append(c.getString(c.getColumnIndex(columnName)));
+ }
+
+ } catch (Exception e) {
+ Log.e(TAG, e.getMessage());
+ } finally {
+ if (c != null) {
+ c.close();
+ }
+ }
+
+ return retval.toString();
+ }
+
+ private static
+ String getContactPhoneNumber(long rawContactId, String selectionArg1,
+ String selectionArg2, String columnName) {
+ StringBuilder retval = new StringBuilder();
+ Uri baseUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
+ Uri dataUri = Uri.withAppendedPath(baseUri, RawContacts.Data.CONTENT_DIRECTORY);
+
+ Cursor c = null;
+ try {
+ c = mContext.getContentResolver().query(dataUri, null,
+ Data.MIMETYPE + "=? AND " + Phone.TYPE + "=?",
+ new String[] {selectionArg1,selectionArg2}, null);
+ if (c == null || c.getCount() == 0) {
+ if(c != null) {
+ c.close();
+ }
+ return null;
+ }
+ c.moveToPosition(-1);
+
+ while (c.moveToNext()) {
+ if (!TextUtils.isEmpty(retval.toString())) {
+ retval.append(",");
+ }
+ retval.append(c.getString(c.getColumnIndex(columnName)));
+ }
+
+ } catch (Exception e) {
+ Log.e(TAG, e.getMessage());
+ } finally {
+ if (c != null) {
+ c.close();
+ }
+ }
+
+ return retval.toString();
+ }
+
+
+ private void log(String msg) {
+ if (DBG) Log.d(TAG, msg);
+ }
+
+}
diff --git a/src/com/android/contacts/common/list/ContactEntryListFragment.java b/src/com/android/contacts/common/list/ContactEntryListFragment.java
index 62515e23..715fade1 100644
--- a/src/com/android/contacts/common/list/ContactEntryListFragment.java
+++ b/src/com/android/contacts/common/list/ContactEntryListFragment.java
@@ -19,9 +19,11 @@ package com.android.contacts.common.list;
import android.app.Activity;
import android.app.LoaderManager;
import android.app.LoaderManager.LoaderCallbacks;
+import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.CursorLoader;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.Loader;
import android.content.res.Resources;
import android.database.Cursor;
@@ -51,6 +53,7 @@ import com.android.contacts.common.preference.ContactsPreferences;
import com.android.contacts.common.util.ContactListViewUtils;
import com.android.contacts.common.util.SchedulingUtils;
import com.android.dialerbind.analytics.AnalyticsFragment;
+import com.android.internal.telephony.TelephonyIntents;
import java.util.Locale;
@@ -148,6 +151,13 @@ public abstract class ContactEntryListFragment<T extends ContactEntryListAdapter
private LoaderManager mLoaderManager;
+ private BroadcastReceiver mSIMStateReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context arg0, Intent arg1) {
+ reloadData();
+ }
+ };
+
private Handler mDelayedDirectorySearchHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
@@ -254,6 +264,14 @@ public abstract class ContactEntryListFragment<T extends ContactEntryListAdapter
restoreSavedState(savedState);
mAdapter = createListAdapter();
mContactsPrefs = new ContactsPreferences(mContext);
+ restoreSavedState(savedState);
+
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
+ filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
+ if (mContext != null) {
+ mContext.registerReceiver(mSIMStateReceiver, filter);
+ }
}
public void restoreSavedState(Bundle savedState) {
@@ -460,6 +478,14 @@ public abstract class ContactEntryListFragment<T extends ContactEntryListAdapter
mAdapter.clearPartitions();
}
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ if (mContext != null) {
+ mContext.unregisterReceiver(mSIMStateReceiver);
+ }
+ }
+
protected void reloadData() {
removePendingDirectorySearchRequests();
mAdapter.onDataReload();
diff --git a/src/com/android/contacts/common/list/DefaultContactListAdapter.java b/src/com/android/contacts/common/list/DefaultContactListAdapter.java
index 8774777c..48425334 100644
--- a/src/com/android/contacts/common/list/DefaultContactListAdapter.java
+++ b/src/com/android/contacts/common/list/DefaultContactListAdapter.java
@@ -26,11 +26,15 @@ import android.preference.PreferenceManager;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Directory;
+import android.provider.ContactsContract.RawContacts;
import android.provider.ContactsContract.SearchSnippets;
import android.text.TextUtils;
import android.view.View;
+import com.android.contacts.common.model.account.SimAccountType;
import com.android.contacts.common.preference.ContactsPreferences;
+import com.android.contacts.common.MoreContactUtils;
+import com.android.contacts.common.SimContactsConstants;
import java.util.ArrayList;
import java.util.List;
@@ -47,6 +51,21 @@ public class DefaultContactListAdapter extends ContactListAdapter {
super(context);
}
+ /** append Uri QueryParameter to filter contacts in SIM card */
+ private void appendUriQueryParameterWithoutSim(CursorLoader loader,
+ String key, String value) {
+ if (null == loader || null == key || null == value) {
+ return;
+ }
+
+ Uri uri = loader.getUri();
+ if (null != uri) {
+ uri = uri.buildUpon().appendQueryParameter(key, value)
+ .appendQueryParameter(SimContactsConstants.WITHOUT_SIM_FLAG, "true").build();
+ loader.setUri(uri);
+ }
+ }
+
@Override
public void configureLoader(CursorLoader loader, long directoryId) {
if (loader instanceof ProfileAndContactsLoader) {
@@ -79,6 +98,19 @@ public class DefaultContactListAdapter extends ContactListAdapter {
loader.setUri(builder.build());
loader.setProjection(getProjection(true));
}
+ boolean isAirMode = MoreContactUtils.isAPMOnAndSIMPowerDown(getContext());
+
+ if (isAirMode) {
+ appendUriQueryParameterWithoutSim(loader, RawContacts.ACCOUNT_TYPE,
+ SimAccountType.ACCOUNT_TYPE);
+ } else {
+ // Do not show contacts when SIM card is disabled
+ String disabledSimFilter = MoreContactUtils.getDisabledSimFilter();
+ if (!TextUtils.isEmpty(disabledSimFilter)) {
+ appendUriQueryParameterWithoutSim(
+ loader, RawContacts.ACCOUNT_NAME, disabledSimFilter);
+ }
+ }
} else {
configureUri(loader, directoryId, filter);
loader.setProjection(getProjection(false));
@@ -139,10 +171,21 @@ public class DefaultContactListAdapter extends ContactListAdapter {
StringBuilder selection = new StringBuilder();
List<String> selectionArgs = new ArrayList<String>();
+ boolean isAirMode = MoreContactUtils.isAPMOnAndSIMPowerDown(getContext());
+ String disabledSimFilter = MoreContactUtils.getDisabledSimFilter();
+
switch (filter.filterType) {
case ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS: {
// We have already added directory=0 to the URI, which takes care of this
// filter
+ // Do not show contacts in SIM card when airplane mode is on
+ if (isAirMode) {
+ appendUriQueryParameterWithoutSim(loader, RawContacts.ACCOUNT_TYPE,
+ SimAccountType.ACCOUNT_TYPE);
+ } else if (!TextUtils.isEmpty(disabledSimFilter)) {
+ appendUriQueryParameterWithoutSim(loader, RawContacts.ACCOUNT_NAME,
+ disabledSimFilter);
+ }
break;
}
case ContactListFilter.FILTER_TYPE_SINGLE_CONTACT: {
@@ -163,6 +206,14 @@ public class DefaultContactListAdapter extends ContactListAdapter {
if (isCustomFilterForPhoneNumbersOnly()) {
selection.append(" AND " + Contacts.HAS_PHONE_NUMBER + "=1");
}
+ // Do not show contacts in SIM card when airplane mode is on
+ if (isAirMode) {
+ appendUriQueryParameterWithoutSim(loader, RawContacts.ACCOUNT_TYPE,
+ SimAccountType.ACCOUNT_TYPE);
+ } else if (!TextUtils.isEmpty(disabledSimFilter)) {
+ appendUriQueryParameterWithoutSim(loader, RawContacts.ACCOUNT_NAME,
+ disabledSimFilter);
+ }
break;
}
case ContactListFilter.FILTER_TYPE_ACCOUNT: {
diff --git a/src/com/android/contacts/common/list/PhoneNumberListAdapter.java b/src/com/android/contacts/common/list/PhoneNumberListAdapter.java
index 8c8700c7..5f5e37f1 100644
--- a/src/com/android/contacts/common/list/PhoneNumberListAdapter.java
+++ b/src/com/android/contacts/common/list/PhoneNumberListAdapter.java
@@ -28,6 +28,8 @@ import android.provider.ContactsContract.CommonDataKinds.SipAddress;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.Directory;
+import android.provider.ContactsContract.RawContacts;
+import android.text.TextUtils;
import android.telephony.PhoneNumberUtils;
import android.text.TextUtils;
import android.util.Log;
@@ -41,6 +43,9 @@ import com.android.contacts.common.extensions.ExtendedPhoneDirectoriesManager;
import com.android.contacts.common.extensions.ExtensionsFactory;
import com.android.contacts.common.preference.ContactsPreferences;
import com.android.contacts.common.util.Constants;
+import com.android.contacts.common.SimContactsConstants;
+import com.android.contacts.common.MoreContactUtils;
+import com.android.contacts.common.model.account.SimAccountType;
import java.util.ArrayList;
import java.util.List;
@@ -193,6 +198,13 @@ public class PhoneNumberListAdapter extends ContactEntryListAdapter {
// Remove duplicates when it is possible.
builder.appendQueryParameter(ContactsContract.REMOVE_DUPLICATE_ENTRIES, "true");
+
+ // Do not show contacts in disabled SIM card
+ String disabledSimFilter = MoreContactUtils.getDisabledSimFilter();
+ if (!TextUtils.isEmpty(disabledSimFilter)) {
+ String disabledSimName = getDisabledSimName(disabledSimFilter);
+ loader.setSelection(RawContacts.ACCOUNT_NAME+ "<>" + disabledSimName);
+ }
loader.setUri(builder.build());
// TODO a projection that includes the search snippet
@@ -541,4 +553,21 @@ public class PhoneNumberListAdapter extends ContactEntryListAdapter {
.encodedFragment(cursor.getString(lookUpKeyColumn))
.build();
}
+
+ private String getDisabledSimName(String disabledSimFilter){
+ String[] disabledSimArray = disabledSimFilter.split(",");//it will never be null
+ String disabledSimName = "";
+ for (int i = 0; i < disabledSimArray.length; i++) {
+ if (i < disabledSimArray.length -1) {
+ //If disabledSimArray[i] is not the last one of the array,
+ //add "or" after every member of the array.
+ disabledSimName = disabledSimName + "'" + disabledSimArray[i] + "'" + "or";
+ } else {
+ //If disabledSimArray[i] is the last one of the array,
+ //should not add anything after it.
+ disabledSimName = disabledSimName + "'" + disabledSimArray[i] + "'";
+ }
+ }
+ return disabledSimName;
+ }
}
diff --git a/src/com/android/contacts/common/model/AccountTypeManager.java b/src/com/android/contacts/common/model/AccountTypeManager.java
index 6efe8199..ba303c4d 100644
--- a/src/com/android/contacts/common/model/AccountTypeManager.java
+++ b/src/com/android/contacts/common/model/AccountTypeManager.java
@@ -38,6 +38,7 @@ import android.os.Message;
import android.os.SystemClock;
import android.provider.ContactsContract;
import android.text.TextUtils;
+import android.telephony.TelephonyManager;
import android.util.Log;
import android.util.TimingLogger;
@@ -50,7 +51,10 @@ import com.android.contacts.common.model.account.ExchangeAccountType;
import com.android.contacts.common.model.account.ExternalAccountType;
import com.android.contacts.common.model.account.FallbackAccountType;
import com.android.contacts.common.model.account.GoogleAccountType;
+import com.android.contacts.common.model.account.PhoneAccountType;
+import com.android.contacts.common.model.account.SimAccountType;
import com.android.contacts.common.model.dataitem.DataKind;
+import com.android.contacts.common.SimContactsConstants;
import com.android.contacts.common.testing.NeededForTesting;
import com.android.contacts.common.util.Constants;
import com.google.common.annotations.VisibleForTesting;
@@ -79,6 +83,13 @@ public abstract class AccountTypeManager {
private static final Object mInitializationLock = new Object();
private static AccountTypeManager mAccountTypeManager;
+ public static final int FLAG_ALL_ACCOUNTS = 0;
+ public static final int FLAG_ALL_ACCOUNTS_WITHOUT_SIM = 1;
+ /**
+ * without sim and phone accounts
+ */
+ public static final int FLAG_ALL_ACCOUNTS_WITHOUT_LOCAL = 2;
+
/**
* Requests the singleton instance of {@link AccountTypeManager} with data bound from
* the available authenticators. This method can safely be called from the UI thread.
@@ -112,6 +123,8 @@ public abstract class AccountTypeManager {
* contact writable accounts (if contactWritableOnly is true).
*/
// TODO: Consider splitting this into getContactWritableAccounts() and getAllAccounts()
+ public abstract List<AccountWithDataSet> getAccounts(boolean contactWritableOnly, int flag);
+
public abstract List<AccountWithDataSet> getAccounts(boolean contactWritableOnly);
/**
@@ -418,6 +431,10 @@ class AccountTypeManagerImpl extends AccountTypeManager
accountType = new GoogleAccountType(mContext, auth.packageName);
} else if (ExchangeAccountType.isExchangeType(type)) {
accountType = new ExchangeAccountType(mContext, auth.packageName, type);
+ } else if (SimAccountType.ACCOUNT_TYPE.equals(type)) {
+ accountType = new SimAccountType(mContext, auth.packageName);
+ } else if (PhoneAccountType.ACCOUNT_TYPE.equals(type)) {
+ accountType = new PhoneAccountType(mContext, auth.packageName);
} else {
Log.d(TAG, "Registering external account type=" + type
+ ", packageName=" + auth.packageName);
@@ -563,15 +580,86 @@ class AccountTypeManagerImpl extends AccountTypeManager
return null;
}
+ @Override
+ public List<AccountWithDataSet> getAccounts(boolean contactWritableOnly) {
+ return getAccounts(contactWritableOnly, FLAG_ALL_ACCOUNTS);
+ }
+
/**
* Return list of all known, contact writable {@link AccountWithDataSet}'s.
*/
@Override
- public List<AccountWithDataSet> getAccounts(boolean contactWritableOnly) {
+ public List<AccountWithDataSet> getAccounts(boolean contactWritableOnly,
+ int flag) {
ensureAccountsLoaded();
+ boolean isAirMode = MoreContactUtils.isAPMOnAndSIMPowerDown(mContext);
+ switch (flag) {
+ case FLAG_ALL_ACCOUNTS:
+ return trimAccountByType(
+ contactWritableOnly ? mContactWritableAccounts : mAccounts,
+ isAirMode ? SimAccountType.ACCOUNT_TYPE : null);
+ case FLAG_ALL_ACCOUNTS_WITHOUT_LOCAL:
+ return trimAccountByType(
+ contactWritableOnly ? mContactWritableAccounts : mAccounts,
+ SimAccountType.ACCOUNT_TYPE, PhoneAccountType.ACCOUNT_TYPE);
+ case FLAG_ALL_ACCOUNTS_WITHOUT_SIM:
+ return trimAccountByType(
+ contactWritableOnly ? mContactWritableAccounts : mAccounts,
+ SimAccountType.ACCOUNT_TYPE);
+ }
return contactWritableOnly ? mContactWritableAccounts : mAccounts;
}
+ private boolean isSimStateUnknown(Account account) {
+ int subscription = SimContactsConstants.SUB_INVALID;
+ subscription = MoreContactUtils.getSubscription(account.type, account.name);
+
+ if (subscription > SimContactsConstants.SUB_INVALID
+ && TelephonyManager.getDefault().getSimState(subscription)
+ == TelephonyManager.SIM_STATE_UNKNOWN) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ private boolean isSimAccountInvalid(Account account) {
+ if ((SimContactsConstants.ACCOUNT_TYPE_SIM).equals(account.type)) {
+ if (TelephonyManager.getDefault().isMultiSimEnabled()) {
+ if (account.name.equals(SimContactsConstants.SIM_NAME))
+ return true;
+ } else {
+ if (!account.name.equals(SimContactsConstants.SIM_NAME)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private List<AccountWithDataSet> trimAccountByType(final List<AccountWithDataSet> list,
+ String... trimAccountTypes) {
+ List<AccountWithDataSet> tempList = Lists.newArrayList();
+ outer: for (AccountWithDataSet accountWithDataSet : list) {
+ if (trimAccountTypes != null && trimAccountTypes.length > 0) {
+ for (String type : trimAccountTypes) {
+ if (type != null && type.equals(accountWithDataSet.type)) {
+ continue outer;
+ }
+ }
+ }
+
+ if (isSimStateUnknown(accountWithDataSet)) {
+ continue outer;
+ }
+ if (isSimAccountInvalid(accountWithDataSet)) {
+ continue outer;
+ }
+ tempList.add(accountWithDataSet);
+ }
+ return tempList;
+ }
+
/**
* Return the list of all known, group writable {@link AccountWithDataSet}'s.
*/
diff --git a/src/com/android/contacts/common/model/RawContactDelta.java b/src/com/android/contacts/common/model/RawContactDelta.java
index 7304f023..cf5bf304 100644
--- a/src/com/android/contacts/common/model/RawContactDelta.java
+++ b/src/com/android/contacts/common/model/RawContactDelta.java
@@ -24,15 +24,20 @@ import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import android.provider.BaseColumns;
+import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.Profile;
import android.provider.ContactsContract.RawContacts;
+import android.text.TextUtils;
import android.util.Log;
import com.android.contacts.common.model.AccountTypeManager;
import com.android.contacts.common.model.ValuesDelta;
import com.android.contacts.common.model.account.AccountType;
import com.android.contacts.common.testing.NeededForTesting;
+import com.android.contacts.common.SimContactsConstants;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
@@ -416,6 +421,139 @@ public class RawContactDelta implements Parcelable {
}
}
+ public ContentValues buildSimDiff() {
+ ContentValues values = new ContentValues();
+ ArrayList<ValuesDelta> names = getMimeEntries(StructuredName.CONTENT_ITEM_TYPE);
+ ArrayList<ValuesDelta> phones = getMimeEntries(Phone.CONTENT_ITEM_TYPE);
+ ArrayList<ValuesDelta> emails = getMimeEntries(Email.CONTENT_ITEM_TYPE);
+
+ ValuesDelta nameValuesDelta = null;
+ ValuesDelta emailValuesDelta = null;
+
+ if (getMimeEntriesCount(StructuredName.CONTENT_ITEM_TYPE, true) > 0) {
+ nameValuesDelta = names.get(0);
+ names.get(0).putNull(StructuredName.GIVEN_NAME);
+ names.get(0).putNull(StructuredName.FAMILY_NAME);
+ names.get(0).putNull(StructuredName.PREFIX);
+ names.get(0).putNull(StructuredName.MIDDLE_NAME);
+ names.get(0).putNull(StructuredName.SUFFIX);
+ names.get(0).put(StructuredName.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
+ }
+ if (emails != null && emails.size() > 0) {
+ emailValuesDelta = emails.get(0);
+ }
+
+ String name = null;
+ String number = null;
+ String newName = null;
+ String newNumber = null;
+ StringBuilder email = new StringBuilder();
+ StringBuilder anr = new StringBuilder();
+ StringBuilder newEmail = new StringBuilder();
+ StringBuilder newAnr = new StringBuilder();
+
+ if (nameValuesDelta != null) {
+ if (isContactInsert()) {
+ name = nameValuesDelta.getAsString(StructuredName.DISPLAY_NAME);
+ } else {
+ if (nameValuesDelta.getBefore() != null) {
+ name = nameValuesDelta.getBefore()
+ .getAsString(StructuredName.DISPLAY_NAME);
+ }
+ if (nameValuesDelta.getAfter() != null) {
+ newName = nameValuesDelta.getAfter()
+ .getAsString(StructuredName.DISPLAY_NAME);
+ }
+ }
+ }
+
+ if (isContactInsert() && phones != null) {
+ for (ValuesDelta valuesDelta : phones) {
+ if (valuesDelta.getAfter() != null
+ && valuesDelta.getAfter().size() != 0) {
+ if (Phone.TYPE_MOBILE == valuesDelta.getAfter().getAsLong(Phone.TYPE)) {
+ if (TextUtils.isEmpty(number)) {
+ number = valuesDelta.getAfter().getAsString(Phone.NUMBER);
+ } else {
+ // don't supports to save two mobile number,so gives
+ // invalid str here
+ number = SimContactsConstants.STR_ANRS;
+ }
+ } else {
+ anr.append(valuesDelta.getAfter().getAsString(Phone.NUMBER));
+ anr.append(",");
+ }
+ }
+ }
+ } else if(phones != null) {
+ for (ValuesDelta valuesDelta : phones) {
+ if (valuesDelta.getBefore() != null
+ && valuesDelta.getBefore().size() != 0) {
+ if (Phone.TYPE_MOBILE == valuesDelta.getBefore().getAsLong(Phone.TYPE) ) {
+ number = valuesDelta.getBefore().getAsString(Phone.NUMBER);
+ } else {
+ anr.append(valuesDelta.getBefore().getAsString(Phone.NUMBER));
+ anr.append(",");
+ }
+ }
+ if (valuesDelta.getAfter() != null
+ && valuesDelta.getAfter().size() != 0) {
+ if (Phone.TYPE_MOBILE == valuesDelta.getAsLong(Phone.TYPE)) {
+ if (TextUtils.isEmpty(newNumber)) {
+ newNumber = valuesDelta.getAfter().getAsString(Phone.NUMBER);
+ } else {
+ newNumber = SimContactsConstants.STR_ANRS;
+ }
+ } else {
+ newAnr.append(valuesDelta.getAfter().getAsString(Phone.NUMBER));
+ newAnr.append(",");
+ }
+ }
+ }
+ }
+
+ if (isContactInsert() && emails != null) {
+ for (ValuesDelta valuesDelta : emails) {
+ if (valuesDelta.getAfter() != null
+ && valuesDelta.getAfter().size() != 0) {
+ email.append(valuesDelta.getAfter().getAsString(Email.DATA));
+ email.append(",");
+ }
+ }
+ } else if (emails != null) {
+ for (ValuesDelta valuesDelta : emails) {
+ if (valuesDelta.getBefore() != null
+ && valuesDelta.getBefore().size() != 0) {
+ email.append(valuesDelta.getBefore().getAsString(Email.DATA));
+ email.append(",");
+ }
+ if (valuesDelta.getAfter() != null
+ && valuesDelta.getAfter().size() != 0) {
+ newEmail.append(valuesDelta.getAfter().getAsString(Email.DATA));
+ newEmail.append(",");
+ }
+ }
+ }
+
+ if (isContactInsert()) {
+ if (name != null || number != null || anr != null || email != null) {
+ values.put(SimContactsConstants.STR_TAG, name);
+ values.put(SimContactsConstants.STR_NUMBER, number);
+ values.put(SimContactsConstants.STR_EMAILS, email.toString());
+ values.put(SimContactsConstants.STR_ANRS, anr.toString());
+ }
+ } else {
+ values.put(SimContactsConstants.STR_TAG, name);
+ values.put(SimContactsConstants.STR_NUMBER, number);
+ values.put(SimContactsConstants.STR_EMAILS, email.toString());
+ values.put(SimContactsConstants.STR_ANRS, anr.toString());
+ values.put(SimContactsConstants.STR_NEW_TAG, newName);
+ values.put(SimContactsConstants.STR_NEW_NUMBER, newNumber);
+ values.put(SimContactsConstants.STR_NEW_EMAILS, newEmail.toString());
+ values.put(SimContactsConstants.STR_NEW_ANRS, newAnr.toString());
+ }
+ return values;
+ }
/**
* Build a list of {@link ContentProviderOperation} that will transform the
* current "before" {@link Entity} state into the modified state which this
diff --git a/src/com/android/contacts/common/model/ValuesDelta.java b/src/com/android/contacts/common/model/ValuesDelta.java
index e30cdd62..2db7e1c8 100644
--- a/src/com/android/contacts/common/model/ValuesDelta.java
+++ b/src/com/android/contacts/common/model/ValuesDelta.java
@@ -23,6 +23,7 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.provider.BaseColumns;
import android.provider.ContactsContract;
+import android.provider.ContactsContract.Data;
import com.android.contacts.common.testing.NeededForTesting;
import com.google.common.collect.Sets;
@@ -61,6 +62,17 @@ public class ValuesDelta implements Parcelable {
final ValuesDelta entry = new ValuesDelta();
entry.mBefore = before;
entry.mAfter = new ContentValues();
+
+ // init data1 to mAfter map. when no operation edittext of
+ // sim phone in the UI, the mAfter init have no data1 value,
+ // it will cause the builddiff data not right.
+ if (before.containsKey(Data.DATA1)) {
+ String contactInfo = before.getAsString(Data.DATA1);
+ if (null != contactInfo && !"".equals(contactInfo)) {
+ entry.mAfter.put(Data.DATA1, contactInfo);
+ }
+ }
+
return entry;
}
@@ -83,6 +95,10 @@ public class ValuesDelta implements Parcelable {
return mAfter;
}
+ public ContentValues getBefore() {
+ return mBefore;
+ }
+
public boolean containsKey(String key) {
return ((mAfter != null && mAfter.containsKey(key)) ||
(mBefore != null && mBefore.containsKey(key)));
diff --git a/src/com/android/contacts/common/model/account/AccountType.java b/src/com/android/contacts/common/model/account/AccountType.java
index 53ab47d9..560d33d0 100644
--- a/src/com/android/contacts/common/model/account/AccountType.java
+++ b/src/com/android/contacts/common/model/account/AccountType.java
@@ -16,17 +16,22 @@
package com.android.contacts.common.model.account;
+import android.accounts.AccountManager;
+import android.accounts.AuthenticatorDescription;
import android.content.ContentValues;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.RawContacts;
+import android.util.Log;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
+import com.android.contacts.common.MoreContactUtils;
import com.android.contacts.common.R;
import com.android.contacts.common.model.dataitem.DataKind;
import com.google.common.annotations.VisibleForTesting;
@@ -39,6 +44,7 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
+import java.util.Map;
/**
* Internal structure that represents constraints and styles for a specific data
@@ -96,6 +102,11 @@ public abstract class AccountType {
protected boolean mIsInitialized;
+ private Map<String, AuthenticatorDescription> mTypeToAuthDescription
+ = new HashMap<String, AuthenticatorDescription>();
+
+ private AuthenticatorDescription[] mAuthDescs;
+
protected static class DefinitionException extends Exception {
public DefinitionException(String message) {
super(message);
@@ -196,12 +207,6 @@ public abstract class AccountType {
public String getViewGroupActivity() {
return null;
}
-
- public CharSequence getDisplayLabel(Context context) {
- // Note this resource is defined in the sync adapter package, not resourcePackageName.
- return getResourceText(context, syncAdapterPackageName, titleRes, accountType);
- }
-
/**
* @return resource ID for the "invite contact" action label, or -1 if not defined.
*/
@@ -276,15 +281,47 @@ public abstract class AccountType {
}
}
+ public void updateAuthDescriptions(Context context) {
+ mAuthDescs = AccountManager.get(context).getAuthenticatorTypes();
+ for (int i = 0; i < mAuthDescs.length; i++) {
+ mTypeToAuthDescription.put(mAuthDescs[i].type, mAuthDescs[i]);
+ }
+ }
+ public CharSequence getDisplayLabel(Context context) {
+ CharSequence label = null;
+ updateAuthDescriptions(context);
+ if (mTypeToAuthDescription.containsKey(accountType)) {
+ try {
+ AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType);
+ Context authContext = context.createPackageContext(desc.packageName, 0);
+ label = authContext.getResources().getText(desc.labelId);
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.w(TAG, "No label name for account type " + accountType);
+ } catch (Resources.NotFoundException e) {
+ Log.w(TAG, "No label icon for account type " + accountType);
+ }
+ }
+ return label;
+ }
+
public Drawable getDisplayIcon(Context context) {
- if (this.titleRes != -1 && this.syncAdapterPackageName != null) {
- final PackageManager pm = context.getPackageManager();
- return pm.getDrawable(this.syncAdapterPackageName, this.iconRes, null);
- } else if (this.titleRes != -1) {
- return context.getResources().getDrawable(this.iconRes);
- } else {
- return null;
+ Drawable icon = null;
+ updateAuthDescriptions(context);
+ if (mTypeToAuthDescription.containsKey(accountType)) {
+ try {
+ AuthenticatorDescription desc = mTypeToAuthDescription
+ .get(accountType);
+ Context authContext = context.createPackageContext(
+ desc.packageName, 0);
+ icon = authContext.getResources().getDrawable(desc.iconId);
+ } catch (PackageManager.NameNotFoundException e) {
+ } catch (Resources.NotFoundException e) {
+ }
+ }
+ if (icon == null) {
+ icon = context.getPackageManager().getDefaultActivityIcon();
}
+ return icon;
}
/**
diff --git a/src/com/android/contacts/common/model/account/PhoneAccountType.java b/src/com/android/contacts/common/model/account/PhoneAccountType.java
new file mode 100644
index 00000000..f6e1f1f5
--- /dev/null
+++ b/src/com/android/contacts/common/model/account/PhoneAccountType.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2014, The Linux Foundation. All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of The Linux Foundation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.android.contacts.common.model.account;
+
+import android.content.Context;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.Resources;
+import android.os.SystemProperties;
+import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.provider.ContactsContract.CommonDataKinds.StructuredName;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+import android.view.inputmethod.EditorInfo;
+
+import com.android.contacts.common.R;
+import com.android.contacts.common.SimContactsConstants;
+import com.android.contacts.common.model.account.AccountType.DefinitionException;
+import com.google.android.collect.Lists;
+
+
+public class PhoneAccountType extends BaseAccountType{
+ private static final String TAG = "PhoneAccountType";
+
+ public static final String ACCOUNT_TYPE = SimContactsConstants.ACCOUNT_TYPE_PHONE;
+ public static final int FLAGS_PERSON_NAME = EditorInfo.TYPE_CLASS_TEXT
+ | EditorInfo.TYPE_TEXT_FLAG_CAP_WORDS | EditorInfo.TYPE_TEXT_VARIATION_PERSON_NAME;
+ protected static final int FLAGS_PHONE = EditorInfo.TYPE_CLASS_PHONE;
+
+ public PhoneAccountType(Context context, String resPackageName) {
+ this.accountType = ACCOUNT_TYPE;
+ this.resourcePackageName = null;
+ this.syncAdapterPackageName = resPackageName;
+
+ try {
+
+ addDataKindStructuredName(context);
+ addDataKindDisplayName(context);
+ addDataKindPhoneticName(context);
+ addDataKindNickname(context);
+ addDataKindPhone(context);
+ addDataKindEmail(context);
+ addDataKindStructuredPostal(context);
+ addDataKindIm(context);
+ addDataKindOrganization(context);
+ addDataKindPhoto(context);
+ addDataKindNote(context);
+ addDataKindWebsite(context);
+ //addDataKindGroupMembership(context);
+ if (context.getResources().getBoolean(
+ com.android.internal.R.bool.config_built_in_sip_phone)) {
+ addDataKindSipAddress(context);
+ }
+
+ mIsInitialized = true;
+ } catch (DefinitionException e) {
+ Log.e(TAG, "Problem building account type", e);
+ }
+
+ }
+
+ @Override
+ public boolean isGroupMembershipEditable() {
+ return true;
+ }
+
+ @Override
+ public boolean areContactsWritable() {
+ return true;
+ }
+
+}
diff --git a/src/com/android/contacts/common/model/account/SimAccountType.java b/src/com/android/contacts/common/model/account/SimAccountType.java
new file mode 100644
index 00000000..6473f2b0
--- /dev/null
+++ b/src/com/android/contacts/common/model/account/SimAccountType.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2014, The Linux Foundation. All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of The Linux Foundation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.android.contacts.common.model.account;
+
+import android.content.Context;
+import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.provider.ContactsContract.CommonDataKinds.StructuredName;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.util.Log;
+import android.view.inputmethod.EditorInfo;
+import android.graphics.drawable.Drawable;
+
+import com.android.contacts.common.R;
+import com.android.contacts.common.SimContactsConstants;
+import com.android.contacts.common.model.account.AccountType.DefinitionException;
+import com.android.contacts.common.model.dataitem.DataKind;
+import com.google.android.collect.Lists;
+
+public class SimAccountType extends BaseAccountType{
+ private static final String TAG = "SimContactsType";
+
+ public static final String ACCOUNT_TYPE = SimContactsConstants.ACCOUNT_TYPE_SIM;
+ public static final int FLAGS_PERSON_NAME = EditorInfo.TYPE_CLASS_TEXT
+ | EditorInfo.TYPE_TEXT_FLAG_CAP_WORDS | EditorInfo.TYPE_TEXT_VARIATION_PERSON_NAME;
+ public static final int FLAGS_PHONETIC = EditorInfo.TYPE_CLASS_TEXT
+ | EditorInfo.TYPE_TEXT_VARIATION_PHONETIC;
+ protected static final int FLAGS_PHONE = EditorInfo.TYPE_CLASS_PHONE;
+ private static Context mContext;
+
+ public SimAccountType(Context context, String resPackageName) {
+ this.accountType = ACCOUNT_TYPE;
+ this.resourcePackageName = resPackageName;
+ this.syncAdapterPackageName = resPackageName;
+
+ this.mContext = context;
+
+ try {
+ addDataKindStructuredName(context);
+ addDataKindDisplayName(context);
+ addDataKindPhone(context);
+ addDataKindEmail(context);
+ mIsInitialized = true;
+ } catch (DefinitionException e) {
+ Log.e(TAG, "Problem building account type", e);
+ }
+ }
+
+ @Override
+ protected DataKind addDataKindStructuredName(Context context) throws DefinitionException {
+ final DataKind kind = super.addDataKindStructuredName(context);
+ kind.fieldList = Lists.newArrayList();
+ kind.fieldList.add(new EditField(StructuredName.DISPLAY_NAME, R.string.nameLabelsGroup,
+ FLAGS_PERSON_NAME));
+
+ return kind;
+ }
+
+ @Override
+ protected DataKind addDataKindPhone(Context context) throws DefinitionException {
+ final DataKind kind = super.addDataKindPhone(context);
+
+ kind.iconAltRes = R.drawable.ic_text_holo_light;
+ kind.typeOverallMax = 2;
+ kind.typeColumn = Phone.TYPE;
+ kind.typeList = Lists.newArrayList();
+ kind.typeList.add(buildPhoneType(Phone.TYPE_MOBILE));
+ kind.typeList.add(buildPhoneType(Phone.TYPE_HOME));// This is used to save ANR records
+ kind.fieldList = Lists.newArrayList();
+ kind.fieldList.add(new EditField(Phone.NUMBER, R.string.phoneLabelsGroup, FLAGS_PHONE));
+
+ return kind;
+ }
+
+ @Override
+ protected DataKind addDataKindEmail(Context context) throws DefinitionException {
+ final DataKind kind = super.addDataKindEmail(context);
+
+ kind.typeOverallMax = 1;
+ kind.typeColumn = Email.TYPE;
+ kind.fieldList = Lists.newArrayList();
+ kind.fieldList.add(new EditField(Email.ADDRESS, R.string.emailLabelsGroup, FLAGS_EMAIL));
+ return kind;
+ }
+
+
+ @Override
+ public boolean isGroupMembershipEditable() {
+ return true;
+ }
+
+ @Override
+ public boolean areContactsWritable() {
+ return true;
+ }
+
+}
diff --git a/src/com/android/contacts/common/util/AccountSelectionUtil.java b/src/com/android/contacts/common/util/AccountSelectionUtil.java
index 8f314882..6a573574 100644
--- a/src/com/android/contacts/common/util/AccountSelectionUtil.java
+++ b/src/com/android/contacts/common/util/AccountSelectionUtil.java
@@ -63,7 +63,7 @@ public class AccountSelectionUtil {
final private Context mContext;
final private int mResId;
- final protected List<AccountWithDataSet> mAccountList;
+ protected List<AccountWithDataSet> mAccountList;
public AccountSelectedListener(Context context, List<AccountWithDataSet> accountList,
int resId) {
@@ -79,6 +79,15 @@ public class AccountSelectionUtil {
dialog.dismiss();
doImport(mContext, mResId, mAccountList.get(which));
}
+ /**
+ * Reset the account list for this listener, to make sure the selected
+ * items reflect the displayed items.
+ *
+ * @param accountList The reset account list.
+ */
+ void setAccountList(List<AccountWithDataSet> accountList) {
+ mAccountList = accountList;
+ }
}
public static Dialog getSelectAccountDialog(Context context, int resId) {
@@ -90,15 +99,28 @@ public class AccountSelectionUtil {
return getSelectAccountDialog(context, resId, onClickListener, null);
}
+ public static Dialog getSelectAccountDialog(Context context, int resId,
+ DialogInterface.OnClickListener onClickListener,
+ DialogInterface.OnCancelListener onCancelListener) {
+ return getSelectAccountDialog(context, resId, onClickListener,
+ onCancelListener, true);
+ }
+
/**
* When OnClickListener or OnCancelListener is null, uses a default listener.
* The default OnCancelListener just closes itself with {@link Dialog#dismiss()}.
*/
public static Dialog getSelectAccountDialog(Context context, int resId,
DialogInterface.OnClickListener onClickListener,
- DialogInterface.OnCancelListener onCancelListener) {
+ DialogInterface.OnCancelListener onCancelListener, boolean includeSIM) {
final AccountTypeManager accountTypes = AccountTypeManager.getInstance(context);
- final List<AccountWithDataSet> writableAccountList = accountTypes.getAccounts(true);
+ List<AccountWithDataSet> writableAccountList = accountTypes.getAccounts(true);
+ if (includeSIM) {
+ writableAccountList = accountTypes.getAccounts(true);
+ } else {
+ writableAccountList = accountTypes.getAccounts(true,
+ AccountTypeManager.FLAG_ALL_ACCOUNTS_WITHOUT_SIM);
+ }
Log.i(LOG_TAG, "The number of available accounts: " + writableAccountList.size());
@@ -143,6 +165,13 @@ public class AccountSelectionUtil {
AccountSelectedListener accountSelectedListener =
new AccountSelectedListener(context, writableAccountList, resId);
onClickListener = accountSelectedListener;
+ } else if (onClickListener instanceof AccountSelectedListener) {
+ // Because the writableAccountList is different if includeSIM or not, so
+ // should reset the account list for the AccountSelectedListener which
+ // is initialized with FLAG_ALL_ACCOUNTS.
+ // Reset the account list to make sure the selected account is contained
+ // in these display accounts.
+ ((AccountSelectedListener) onClickListener).setAccountList(writableAccountList);
}
if (onCancelListener == null) {
onCancelListener = new DialogInterface.OnCancelListener() {
diff --git a/src/com/android/contacts/common/util/AccountsListAdapter.java b/src/com/android/contacts/common/util/AccountsListAdapter.java
index 84435df8..575dddbd 100644
--- a/src/com/android/contacts/common/util/AccountsListAdapter.java
+++ b/src/com/android/contacts/common/util/AccountsListAdapter.java
@@ -29,6 +29,8 @@ import com.android.contacts.common.R;
import com.android.contacts.common.model.AccountTypeManager;
import com.android.contacts.common.model.account.AccountType;
import com.android.contacts.common.model.account.AccountWithDataSet;
+import com.android.contacts.common.model.account.PhoneAccountType;
+import com.android.contacts.common.model.account.SimAccountType;
import java.util.ArrayList;
import java.util.List;
@@ -48,7 +50,8 @@ public final class AccountsListAdapter extends BaseAdapter {
public enum AccountListFilter {
ALL_ACCOUNTS, // All read-only and writable accounts
ACCOUNTS_CONTACT_WRITABLE, // Only where the account type is contact writable
- ACCOUNTS_GROUP_WRITABLE // Only accounts where the account type is group writable
+ ACCOUNTS_GROUP_WRITABLE, // Only accounts where the account type is group writable
+ ACCOUNTS_CONTACT_WRITABLE_WITHOUT_SIM
}
public AccountsListAdapter(Context context, AccountListFilter accountListFilter) {
@@ -75,10 +78,22 @@ public final class AccountsListAdapter extends BaseAdapter {
private List<AccountWithDataSet> getAccounts(AccountListFilter accountListFilter) {
if (accountListFilter == AccountListFilter.ACCOUNTS_GROUP_WRITABLE) {
- return new ArrayList<AccountWithDataSet>(mAccountTypes.getGroupWritableAccounts());
+ return new ArrayList<AccountWithDataSet>(mAccountTypes.getAccounts(true,
+ AccountTypeManager.FLAG_ALL_ACCOUNTS_WITHOUT_LOCAL));
}
- return new ArrayList<AccountWithDataSet>(mAccountTypes.getAccounts(
- accountListFilter == AccountListFilter.ACCOUNTS_CONTACT_WRITABLE));
+ final List<AccountWithDataSet> writableAccountList = mAccountTypes
+ .getAccounts(accountListFilter == AccountListFilter.ACCOUNTS_CONTACT_WRITABLE
+ || accountListFilter == AccountListFilter.ACCOUNTS_CONTACT_WRITABLE_WITHOUT_SIM);
+ List<AccountWithDataSet> deletedList = new ArrayList<AccountWithDataSet>();
+
+ if (accountListFilter == AccountListFilter.ACCOUNTS_CONTACT_WRITABLE_WITHOUT_SIM) {
+ for (AccountWithDataSet account : writableAccountList) {
+ if (SimAccountType.ACCOUNT_TYPE.equals(account.type))
+ deletedList.add(account);
+ }
+ writableAccountList.removeAll(deletedList);
+ }
+ return writableAccountList;
}
@Override