Merge "UX update to edit linked contact modal" into ub-contactsdialer-h-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 20e0a65..008c66f 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -29,8 +29,7 @@
<application
android:name="com.android.contacts.ContactsApplication"
android:label="@string/applicationLabel"
- android:icon="@mipmap/ic_contacts_launcher_square"
- android:roundIcon="@mipmap/ic_contacts_launcher"
+ android:icon="@mipmap/ic_contacts_launcher"
android:taskAffinity="android.task.contacts"
android:hardwareAccelerated="true"
android:supportsRtl="true"
diff --git a/res-icons/mipmap-hdpi/ic_contacts_launcher.png b/res-icons/mipmap-hdpi/ic_contacts_launcher.png
index 86380d1..0fd1492 100644
--- a/res-icons/mipmap-hdpi/ic_contacts_launcher.png
+++ b/res-icons/mipmap-hdpi/ic_contacts_launcher.png
Binary files differ
diff --git a/res-icons/mipmap-hdpi/ic_contacts_launcher_square.png b/res-icons/mipmap-hdpi/ic_contacts_launcher_square.png
deleted file mode 100644
index 64eff00..0000000
--- a/res-icons/mipmap-hdpi/ic_contacts_launcher_square.png
+++ /dev/null
Binary files differ
diff --git a/res-icons/mipmap-mdpi/ic_contacts_launcher.png b/res-icons/mipmap-mdpi/ic_contacts_launcher.png
index 85132c5..e23930b 100644
--- a/res-icons/mipmap-mdpi/ic_contacts_launcher.png
+++ b/res-icons/mipmap-mdpi/ic_contacts_launcher.png
Binary files differ
diff --git a/res-icons/mipmap-mdpi/ic_contacts_launcher_square.png b/res-icons/mipmap-mdpi/ic_contacts_launcher_square.png
deleted file mode 100644
index b4ee821..0000000
--- a/res-icons/mipmap-mdpi/ic_contacts_launcher_square.png
+++ /dev/null
Binary files differ
diff --git a/res-icons/mipmap-xhdpi/ic_contacts_launcher.png b/res-icons/mipmap-xhdpi/ic_contacts_launcher.png
index c198749..aff0f31 100644
--- a/res-icons/mipmap-xhdpi/ic_contacts_launcher.png
+++ b/res-icons/mipmap-xhdpi/ic_contacts_launcher.png
Binary files differ
diff --git a/res-icons/mipmap-xhdpi/ic_contacts_launcher_square.png b/res-icons/mipmap-xhdpi/ic_contacts_launcher_square.png
deleted file mode 100644
index 6feeadf..0000000
--- a/res-icons/mipmap-xhdpi/ic_contacts_launcher_square.png
+++ /dev/null
Binary files differ
diff --git a/res-icons/mipmap-xxhdpi/ic_contacts_launcher.png b/res-icons/mipmap-xxhdpi/ic_contacts_launcher.png
index 4fa10a6..9cd2ebe 100644
--- a/res-icons/mipmap-xxhdpi/ic_contacts_launcher.png
+++ b/res-icons/mipmap-xxhdpi/ic_contacts_launcher.png
Binary files differ
diff --git a/res-icons/mipmap-xxhdpi/ic_contacts_launcher_square.png b/res-icons/mipmap-xxhdpi/ic_contacts_launcher_square.png
deleted file mode 100644
index 01a3fde..0000000
--- a/res-icons/mipmap-xxhdpi/ic_contacts_launcher_square.png
+++ /dev/null
Binary files differ
diff --git a/res-icons/mipmap-xxxhdpi/ic_contacts_launcher.png b/res-icons/mipmap-xxxhdpi/ic_contacts_launcher.png
index 10bda63..74c4179 100644
--- a/res-icons/mipmap-xxxhdpi/ic_contacts_launcher.png
+++ b/res-icons/mipmap-xxxhdpi/ic_contacts_launcher.png
Binary files differ
diff --git a/res-icons/mipmap-xxxhdpi/ic_contacts_launcher_square.png b/res-icons/mipmap-xxxhdpi/ic_contacts_launcher_square.png
deleted file mode 100644
index 328e067..0000000
--- a/res-icons/mipmap-xxxhdpi/ic_contacts_launcher_square.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/fab_blue.png b/res/drawable-hdpi/fab_blue.png
deleted file mode 100644
index 8ff3d29..0000000
--- a/res/drawable-hdpi/fab_blue.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/fab_pink.png b/res/drawable-hdpi/fab_pink.png
new file mode 100644
index 0000000..98b26d5
--- /dev/null
+++ b/res/drawable-hdpi/fab_pink.png
Binary files differ
diff --git a/res/drawable-mdpi/fab_blue.png b/res/drawable-mdpi/fab_blue.png
deleted file mode 100644
index 2ca6b4b..0000000
--- a/res/drawable-mdpi/fab_blue.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/fab_pink.png b/res/drawable-mdpi/fab_pink.png
new file mode 100644
index 0000000..46df9f8
--- /dev/null
+++ b/res/drawable-mdpi/fab_pink.png
Binary files differ
diff --git a/res/drawable-xhdpi/fab_blue.png b/res/drawable-xhdpi/fab_blue.png
deleted file mode 100644
index 300b07e..0000000
--- a/res/drawable-xhdpi/fab_blue.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/fab_pink.png b/res/drawable-xhdpi/fab_pink.png
new file mode 100644
index 0000000..5f214d6
--- /dev/null
+++ b/res/drawable-xhdpi/fab_pink.png
Binary files differ
diff --git a/res/drawable-xxhdpi/fab_blue.png b/res/drawable-xxhdpi/fab_blue.png
deleted file mode 100644
index 76d68ac..0000000
--- a/res/drawable-xxhdpi/fab_blue.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/fab_pink.png b/res/drawable-xxhdpi/fab_pink.png
new file mode 100644
index 0000000..6fbe669
--- /dev/null
+++ b/res/drawable-xxhdpi/fab_pink.png
Binary files differ
diff --git a/res/drawable-xxxhdpi/fab_blue.png b/res/drawable-xxxhdpi/fab_blue.png
deleted file mode 100644
index 1dd8a92..0000000
--- a/res/drawable-xxxhdpi/fab_blue.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxxhdpi/fab_pink.png b/res/drawable-xxxhdpi/fab_pink.png
new file mode 100644
index 0000000..5513227
--- /dev/null
+++ b/res/drawable-xxxhdpi/fab_pink.png
Binary files differ
diff --git a/res/layout/floating_action_button.xml b/res/layout/floating_action_button.xml
index 91afecd..a20d657 100644
--- a/res/layout/floating_action_button.xml
+++ b/res/layout/floating_action_button.xml
@@ -26,7 +26,7 @@
android:layout_gravity="bottom|end"
android:layout_marginBottom="@dimen/floating_action_button_margin_bottom"
android:layout_marginEnd="@dimen/floating_action_button_margin_right"
- android:background="@drawable/fab_blue"
+ android:background="@drawable/fab_pink"
android:elevation="@dimen/design_fab_elevation"
app:layout_dodgeInsetEdges="bottom" >
diff --git a/res/values/colors.xml b/res/values/colors.xml
index e2024fd..6dbe010 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -27,7 +27,7 @@
<color name="quickcontact_entry_sub_header_text_color">#737373</color>
<color name="quickcontact_entry_header_text_color">#202020</color>
- <color name="action_bar_background">#0288d1</color>
+ <color name="action_bar_background">#2a56c6</color>
<color name="nav_item_selected_background">#0f000000</color>
@@ -42,8 +42,8 @@
<!-- Color of the status bar above the contextual selection bar. -->
<color name="contextual_selection_bar_status_bar_color">#bababa</color>
- <color name="primary_color_dark">#0277bd</color>
- <color name="primary_color">#0288d1</color>
+ <color name="primary_color_dark">#2a56c6</color>
+ <color name="primary_color">#2a56c6</color>
<color name="group_primary_color_dark">#546E7A</color>
<color name="group_primary_color">#607D8B</color>
@@ -121,7 +121,7 @@
<color name="people_app_theme_color">#363636</color>
<!-- Color of the theme of the Dialer app -->
- <color name="dialtacts_theme_color">#0288d1</color>
+ <color name="dialtacts_theme_color">#2a56c6</color>
<!-- Color of image view placeholder. -->
<color name="image_placeholder">#DDDDDD</color>
@@ -245,7 +245,7 @@
<color name="search_video_call_icon_tint">@color/searchbox_hint_text_color</color>
<!-- Text color for an action in a snackbar. -->
- <color name="snackbar_action_text">#40c4ff</color>
+ <color name="snackbar_action_text">#ffffff</color>
<!-- Background color for a snackbar. -->
<color name="snackbar_background">#333333</color>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 48614b2..3afec1e 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1373,16 +1373,7 @@
<string name="import_from_sim">Import from SIM card</string>
<!-- Action string for selecting a SIM subscription for importing contacts -->
- <string name="import_from_sim_summary">Import from SIM <xliff:g id="sim_name">^1</xliff:g>\n<xliff:g id="sim_number">^2</xliff:g></string>
-
- <!-- Action string for selecting a SIM subscription for importing contacts, without a phone number -->
- <string name="import_from_sim_summary_no_number">Import from SIM <xliff:g id="sim_name">%1$s</xliff:g></string>
-
- <!-- Action string for selecting a SIM subscription for importing contacts -->
- <string name="import_from_sim_summary_by_carrier">Import from <xliff:g id="carrier_name">^1</xliff:g> SIM\n<xliff:g id="sim_number">^2</xliff:g></string>
-
- <!-- Action string for selecting a SIM subscription for importing contacts -->
- <string name="import_from_sim_summary_by_carrier_no_number">Import from <xliff:g id="carrier_name">%1$s</xliff:g> SIM</string>
+ <string name="import_from_sim_summary_fmt">Import from SIM <xliff:g id="sim_name">%1$s</xliff:g></string>
<!-- Action string for selecting a .vcf file to import contacts from [CHAR LIMIT=30] -->
<string name="import_from_vcf_file" product="default">Import from .vcf file</string>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index fc52bc5..ad0915e 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -397,7 +397,7 @@
<!-- Button style for main contacts no account empty view. -->
<style name="NoAccountViewButtonStyle" parent="@style/Widget.AppCompat.Button.Borderless">
<item name="android:textSize">14sp</item>
- <item name="android:textColor">#0288d1</item>
+ <item name="android:textColor">@color/primary_color</item>
<item name="android:fontFamily">sans-serif-medium</item>
<item name="android:textAllCaps">true</item>
</style>
@@ -405,7 +405,7 @@
<!-- Add contacts button style for empty states. -->
<style name="AddContactsButtonStyle" parent="@style/Widget.AppCompat.Button.Borderless">
<item name="android:textSize">16sp</item>
- <item name="android:textColor">#0288d1</item>
+ <item name="android:textColor">@color/primary_color</item>
<item name="android:fontFamily">sans-serif-medium</item>
<item name="android:textAllCaps">true</item>
</style>
diff --git a/src/com/android/contacts/ContactSaveService.java b/src/com/android/contacts/ContactSaveService.java
index 1b2c22d..853e676 100755
--- a/src/com/android/contacts/ContactSaveService.java
+++ b/src/com/android/contacts/ContactSaveService.java
@@ -45,6 +45,8 @@
import android.provider.ContactsContract.Profile;
import android.provider.ContactsContract.RawContacts;
import android.provider.ContactsContract.RawContactsEntity;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.os.ResultReceiver;
import android.text.TextUtils;
@@ -150,6 +152,7 @@
public static final String BROADCAST_GROUP_DELETED = "groupDeleted";
public static final String BROADCAST_SIM_IMPORT_COMPLETE = "simImportComplete";
+ public static final String EXTRA_CALLBACK_DATA = "extraCallbackData";
public static final String EXTRA_RESULT_CODE = "resultCode";
public static final String EXTRA_RESULT_COUNT = "count";
@@ -208,7 +211,7 @@
public void onCreate() {
super.onCreate();
mGroupsDao = new GroupsDaoImpl(this);
- mSimContactDao = new SimContactDao(this);
+ mSimContactDao = SimContactDao.create(this);
}
public static void registerListener(Listener listener) {
@@ -1685,12 +1688,14 @@
operations.add(builder.build());
}
- public static Intent createImportFromSimIntent(Context context,
- ArrayList<SimContact> contacts, AccountWithDataSet targetAccount) {
+ public static Intent createImportFromSimIntent(@NonNull Context context,
+ @NonNull ArrayList<SimContact> contacts, @NonNull AccountWithDataSet targetAccount,
+ @Nullable Bundle callbackData) {
return new Intent(context, ContactSaveService.class)
.setAction(ACTION_IMPORT_FROM_SIM)
.putExtra(EXTRA_SIM_CONTACTS, contacts)
- .putExtra(EXTRA_ACCOUNT, targetAccount);
+ .putExtra(EXTRA_ACCOUNT, targetAccount)
+ .putExtra(EXTRA_CALLBACK_DATA, callbackData);
}
private void importFromSim(Intent intent) {
@@ -1704,7 +1709,8 @@
// notify success
LocalBroadcastManager.getInstance(this).sendBroadcast(result
.putExtra(EXTRA_RESULT_COUNT, contacts.size())
- .putExtra(EXTRA_RESULT_CODE, RESULT_SUCCESS));
+ .putExtra(EXTRA_RESULT_CODE, RESULT_SUCCESS)
+ .putExtra(EXTRA_CALLBACK_DATA, intent.getBundleExtra(EXTRA_CALLBACK_DATA)));
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "importFromSim completed successfully");
}
diff --git a/src/com/android/contacts/SimImportFragment.java b/src/com/android/contacts/SimImportFragment.java
index 7ce00d2..ed043bf 100644
--- a/src/com/android/contacts/SimImportFragment.java
+++ b/src/com/android/contacts/SimImportFragment.java
@@ -40,6 +40,7 @@
import com.android.contacts.common.list.ContactListItemView;
import com.android.contacts.common.list.MultiSelectEntryContactListAdapter;
import com.android.contacts.common.model.AccountTypeManager;
+import com.android.contacts.common.model.SimCard;
import com.android.contacts.common.model.SimContact;
import com.android.contacts.common.model.account.AccountWithDataSet;
import com.android.contacts.common.preference.ContactsPreferences;
@@ -59,7 +60,8 @@
private static final String KEY_SELECTED_IDS = "selectedIds";
private static final String ARG_SUBSCRIPTION_ID = "subscriptionId";
- public static final int NO_SUBSCRIPTION_ID = -1;
+
+ public static final String CALLBACK_KEY_SUBSCRIPTION_ID = "simSubscriptionId";
private ContactsPreferences mPreferences;
private AccountTypeManager mAccountTypeManager;
@@ -88,8 +90,8 @@
mAdapter.setHasHeader(0, false);
final Bundle args = getArguments();
- mSubscriptionId = args == null ? NO_SUBSCRIPTION_ID : args.getInt(ARG_SUBSCRIPTION_ID,
- NO_SUBSCRIPTION_ID);
+ mSubscriptionId = args == null ? SimCard.NO_SUBSCRIPTION_ID :
+ args.getInt(ARG_SUBSCRIPTION_ID, SimCard.NO_SUBSCRIPTION_ID);
if (savedInstanceState == null) return;
mSelectedContacts = savedInstanceState.getLongArray(KEY_SELECTED_IDS);
@@ -198,9 +200,11 @@
}
private void importCurrentSelections() {
+ final Bundle callbackData = new Bundle();
+ callbackData.putInt(CALLBACK_KEY_SUBSCRIPTION_ID, mSubscriptionId);
ContactSaveService.startService(getContext(), ContactSaveService
.createImportFromSimIntent(getContext(), mAdapter.getSelectedContacts(),
- mAccountHeaderPresenter.getCurrentAccount()));
+ mAccountHeaderPresenter.getCurrentAccount(), callbackData));
}
@Override
@@ -321,7 +325,7 @@
public SimContactLoader(Context context, int subscriptionId) {
super(context);
- mDao = new SimContactDao(context);
+ mDao = SimContactDao.create(context);
mSubscriptionId = subscriptionId;
}
@@ -342,7 +346,7 @@
@Override
public ArrayList<SimContact> loadInBackground() {
- if (mSubscriptionId != NO_SUBSCRIPTION_ID) {
+ if (mSubscriptionId != SimCard.NO_SUBSCRIPTION_ID) {
return mDao.loadSimContacts(mSubscriptionId);
} else {
return mDao.loadSimContacts();
diff --git a/src/com/android/contacts/activities/ContactEditorActivity.java b/src/com/android/contacts/activities/ContactEditorActivity.java
index 3052a24..7cbae7a 100644
--- a/src/com/android/contacts/activities/ContactEditorActivity.java
+++ b/src/com/android/contacts/activities/ContactEditorActivity.java
@@ -304,10 +304,10 @@
}
@Override
- public void onEditOtherContactRequested(
- Uri contactLookupUri, ArrayList<ContentValues> values) {
- final Intent intent = EditorIntents.createEditOtherContactIntent(
- ContactEditorActivity.this, contactLookupUri, values);
+ public void onEditOtherRawContactRequested(
+ Uri contactLookupUri, long rawContactId, ArrayList<ContentValues> values) {
+ final Intent intent = EditorIntents.createEditOtherRawContactIntent(
+ ContactEditorActivity.this, contactLookupUri, rawContactId, values);
ImplicitIntentsUtil.startActivityInApp(
ContactEditorActivity.this, intent);
finish();
diff --git a/src/com/android/contacts/activities/PeopleActivity.java b/src/com/android/contacts/activities/PeopleActivity.java
index 0ee9965..172015b 100644
--- a/src/com/android/contacts/activities/PeopleActivity.java
+++ b/src/com/android/contacts/activities/PeopleActivity.java
@@ -755,7 +755,8 @@
ContactSaveService.startService(PeopleActivity.this,
ContactSaveService.createUndoIntent(PeopleActivity.this, intent));
}
- }).show();
+ }).setActionTextColor(ContextCompat.getColor(this, R.color.snackbar_action_text))
+ .show();
}
private class SaveServiceListener extends BroadcastReceiver {
diff --git a/src/com/android/contacts/common/database/SimContactDao.java b/src/com/android/contacts/common/database/SimContactDao.java
index 8d7855f..f5880a8 100644
--- a/src/com/android/contacts/common/database/SimContactDao.java
+++ b/src/com/android/contacts/common/database/SimContactDao.java
@@ -15,6 +15,7 @@
*/
package com.android.contacts.common.database;
+import android.annotation.TargetApi;
import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
import android.content.ContentResolver;
@@ -28,25 +29,25 @@
import android.os.RemoteException;
import android.provider.BaseColumns;
import android.provider.ContactsContract;
+import android.support.annotation.NonNull;
import android.support.annotation.VisibleForTesting;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
-import android.util.ArraySet;
-import android.util.Log;
+import android.util.SparseArray;
import com.android.contacts.common.Experiments;
+import com.android.contacts.common.compat.CompatUtils;
+import com.android.contacts.common.model.SimCard;
import com.android.contacts.common.model.SimContact;
import com.android.contacts.common.model.account.AccountWithDataSet;
import com.android.contacts.common.util.PermissionsUtil;
import com.android.contacts.util.SharedPreferenceUtil;
import com.android.contactsbind.experiments.Flags;
-import com.google.common.collect.Sets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import java.util.Set;
/**
* Provides data access methods for loading contacts from a SIM card and and migrating these
@@ -55,6 +56,10 @@
public class SimContactDao {
private static final String TAG = "SimContactDao";
+ // Set to true for manual testing on an emulator or phone without a SIM card
+ // DO NOT SUBMIT if set to true
+ private static final boolean USE_FAKE_INSTANCE = false;
+
@VisibleForTesting
public static final Uri ICC_CONTENT_URI = Uri.parse("content://icc/adn");
@@ -76,64 +81,49 @@
public void warmupSimQueryIfNeeded() {
// Not needed if we don't have an Assistant section
if (!Flags.getInstance().getBoolean(Experiments.ASSISTANT) ||
- !shouldLoad()) return;
+ !canReadSimContacts()) return;
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
- // We don't actually have to do any caching ourselves. Some other layer must do
- // caching of the data (OS or framework) because subsequent queries are very fast.
- final Cursor cursor = mResolver.query(ICC_CONTENT_URI, null, null, null, null);
- if (cursor != null) {
- cursor.close();
+ for (SimCard card : getSimCards()) {
+ // We don't actually have to do any caching ourselves. Some other layer must do
+ // caching of the data (OS or framework) because subsequent queries are very
+ // fast.
+ card.loadContacts(SimContactDao.this);
}
return null;
}
}.execute();
}
- public boolean shouldLoad() {
- final Set<String> simIds = hasTelephony() && hasPermissions() ? getSimCardIds() :
- Collections.<String>emptySet();
-
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "shouldLoad: hasTelephony? " + hasTelephony() +
- " hasPermissions? " + hasPermissions() +
- " SIM absent? " + (getSimState() != TelephonyManager.SIM_STATE_ABSENT) +
- " SIM ids=" + simIds +
- " imported=" + SharedPreferenceUtil.getImportedSims(mContext));
- }
+ public boolean canReadSimContacts() {
return hasTelephony() && hasPermissions() &&
- getSimState() != TelephonyManager.SIM_STATE_ABSENT &&
- !Sets.difference(simIds, SharedPreferenceUtil.getImportedSims(mContext))
- .isEmpty();
+ mTelephonyManager.getSimState() != TelephonyManager.SIM_STATE_ABSENT;
}
- public Set<String> getSimCardIds() {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
- final SubscriptionManager subscriptionManager = SubscriptionManager.from(mContext);
- final List<SubscriptionInfo> subscriptions = subscriptionManager
- .getActiveSubscriptionInfoList();
- if (subscriptions == null) {
- return Collections.emptySet();
- }
- final ArraySet<String> result = new ArraySet<>(
- subscriptionManager.getActiveSubscriptionInfoCount());
-
- for (SubscriptionInfo info : subscriptions) {
- result.add(info.getIccId());
- }
- return result;
+ public List<SimCard> getSimCards() {
+ if (!canReadSimContacts()) {
+ return Collections.emptyList();
}
- return Collections.singleton(getSimSerialNumber());
+ final List<SimCard> sims = CompatUtils.isMSIMCompatible() ?
+ getSimCardsFromSubscriptions() :
+ Collections.singletonList(SimCard.create(mTelephonyManager));
+ return SharedPreferenceUtil.restoreSimStates(mContext, sims);
}
- public int getSimState() {
- return mTelephonyManager.getSimState();
- }
-
- public String getSimSerialNumber() {
- return mTelephonyManager.getSimSerialNumber();
+ @NonNull
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP_MR1)
+ private List<SimCard> getSimCardsFromSubscriptions() {
+ final SubscriptionManager subscriptionManager = (SubscriptionManager)
+ mContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
+ final List<SubscriptionInfo> subscriptions = subscriptionManager
+ .getActiveSubscriptionInfoList();
+ final ArrayList<SimCard> result = new ArrayList<>();
+ for (SubscriptionInfo subscriptionInfo : subscriptions) {
+ result.add(SimCard.create(subscriptionInfo));
+ }
+ return result;
}
public ArrayList<SimContact> loadSimContacts(int subscriptionId) {
@@ -147,6 +137,10 @@
return loadFrom(ICC_CONTENT_URI);
}
+ public Context getContext() {
+ return mContext;
+ }
+
private ArrayList<SimContact> loadFrom(Uri uri) {
final Cursor cursor = mResolver.query(uri, null, null, null, null);
@@ -185,6 +179,31 @@
return mResolver.applyBatch(ContactsContract.AUTHORITY, ops);
}
+ public void persistSimState(SimCard sim) {
+ SharedPreferenceUtil.persistSimStates(mContext, Collections.singletonList(sim));
+ }
+
+ public void persistSimStates(List<SimCard> simCards) {
+ SharedPreferenceUtil.persistSimStates(mContext, simCards);
+ }
+
+ public SimCard getFirstSimCard() {
+ return getSimBySubscriptionId(SimCard.NO_SUBSCRIPTION_ID);
+ }
+
+ public SimCard getSimBySubscriptionId(int subscriptionId) {
+ final List<SimCard> sims = getSimCards();
+ if (subscriptionId == SimCard.NO_SUBSCRIPTION_ID && !sims.isEmpty()) {
+ return sims.get(0);
+ }
+ for (SimCard sim : getSimCards()) {
+ if (sim.getSubscriptionId() == subscriptionId) {
+ return sim;
+ }
+ }
+ return null;
+ }
+
private ArrayList<ContentProviderOperation> createImportOperations(List<SimContact> contacts,
AccountWithDataSet targetAccount) {
final ArrayList<ContentProviderOperation> ops = new ArrayList<>();
@@ -198,15 +217,6 @@
return emails != null ? emails.split(",") : null;
}
- public void persistImportSuccess() {
- // TODO: either need to have an assistant card per SIM card or show contacts from all
- // SIMs in the import view.
- final Set<String> simIds = getSimCardIds();
- for (String id : simIds) {
- SharedPreferenceUtil.addImportedSim(mContext, id);
- }
- }
-
private boolean hasTelephony() {
return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
}
@@ -215,4 +225,69 @@
return PermissionsUtil.hasContactsPermissions(mContext) &&
PermissionsUtil.hasPhonePermissions(mContext);
}
+
+ public static SimContactDao create(Context context) {
+ if (USE_FAKE_INSTANCE) {
+ return new DebugImpl(context)
+ .addSimCard(new SimCard("fake-sim-id1", 1, "Fake Carrier", "Card 1",
+ "15095550101", "us").withContacts(
+ new SimContact(1, "Sim One", "15095550111", null),
+ new SimContact(2, "Sim Two", "15095550112", null),
+ new SimContact(3, "Sim Three", "15095550113", null),
+ new SimContact(4, "Sim Four", "15095550114", null),
+ new SimContact(5, "411 & more", "411", null)
+ ))
+ .addSimCard(new SimCard("fake-sim-id2", 2, "Carrier Two", "Card 2",
+ "15095550102", "us").withContacts(
+ new SimContact(1, "John Sim", "15095550121", null),
+ new SimContact(2, "Bob Sim", "15095550122", null),
+ new SimContact(3, "Mary Sim", "15095550123", null),
+ new SimContact(4, "Alice Sim", "15095550124", null)
+ ));
+ }
+
+ return new SimContactDao(context);
+ }
+
+ // TODO remove this class and the USE_FAKE_INSTANCE flag once this code is not under
+ // active development or anytime after 3/1/2017
+ private static class DebugImpl extends SimContactDao {
+
+ private List<SimCard> mSimCards = new ArrayList<>();
+ private SparseArray<SimCard> mCardsBySubscription = new SparseArray<>();
+
+ public DebugImpl(Context context) {
+ super(context);
+ }
+
+ public DebugImpl addSimCard(SimCard sim) {
+ mSimCards.add(sim);
+ mCardsBySubscription.put(sim.getSubscriptionId(), sim);
+ return this;
+ }
+
+ @Override
+ public void warmupSimQueryIfNeeded() {
+ }
+
+ @Override
+ public List<SimCard> getSimCards() {
+ return SharedPreferenceUtil.restoreSimStates(getContext(), mSimCards);
+ }
+
+ @Override
+ public ArrayList<SimContact> loadSimContacts() {
+ return new ArrayList<>(mSimCards.get(0).getContacts());
+ }
+
+ @Override
+ public ArrayList<SimContact> loadSimContacts(int subscriptionId) {
+ return new ArrayList<>(mCardsBySubscription.get(subscriptionId).getContacts());
+ }
+
+ @Override
+ public boolean canReadSimContacts() {
+ return true;
+ }
+ }
}
diff --git a/src/com/android/contacts/common/interactions/ImportDialogFragment.java b/src/com/android/contacts/common/interactions/ImportDialogFragment.java
index 30c6603..2268854 100644
--- a/src/com/android/contacts/common/interactions/ImportDialogFragment.java
+++ b/src/com/android/contacts/common/interactions/ImportDialogFragment.java
@@ -24,14 +24,10 @@
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Resources;
-import android.os.Build;
import android.os.Bundle;
import android.provider.ContactsContract.Contacts;
-import android.support.annotation.RequiresApi;
-import android.support.v4.util.ArraySet;
-import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
+import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
@@ -44,15 +40,15 @@
import com.android.contacts.common.R;
import com.android.contacts.common.compat.CompatUtils;
import com.android.contacts.common.compat.PhoneNumberUtilsCompat;
+import com.android.contacts.common.database.SimContactDao;
import com.android.contacts.common.model.AccountTypeManager;
+import com.android.contacts.common.model.SimCard;
import com.android.contacts.common.model.account.AccountWithDataSet;
import com.android.contacts.common.util.AccountSelectionUtil;
import com.android.contacts.common.util.AccountsListAdapter.AccountListFilter;
import com.android.contacts.editor.SelectAccountDialogFragment;
import java.util.List;
-import java.util.Locale;
-import java.util.Set;
/**
* An dialog invoked to import/export contacts.
@@ -67,6 +63,7 @@
public static final String EXTRA_SIM_ONLY = "extraSimOnly";
private boolean mSimOnly = false;
+ private SimContactDao mSimDao;
private final String[] LOOKUP_PROJECTION = new String[] {
Contacts.LOOKUP_KEY
@@ -97,6 +94,7 @@
final Bundle args = getArguments();
mSimOnly = args != null && args.getBoolean(EXTRA_SIM_ONLY, false);
+ mSimDao = SimContactDao.create(getContext());
}
@Override
@@ -112,7 +110,6 @@
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Wrap our context to inflate list items using the correct theme
- final Resources res = getActivity().getResources();
final LayoutInflater dialogInflater = (LayoutInflater)getActivity()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
@@ -129,48 +126,7 @@
}
};
- final TelephonyManager manager =
- (TelephonyManager) getActivity().getSystemService(Context.TELEPHONY_SERVICE);
- if (res.getBoolean(R.bool.config_allow_import_from_vcf_file) && !mSimOnly) {
- adapter.add(new AdapterEntry(getString(R.string.import_from_vcf_file),
- R.string.import_from_vcf_file));
- }
-
- if (CompatUtils.isMSIMCompatible()) {
- mSubscriptionManager = SubscriptionManager.from(getActivity());
- if (manager != null && res.getBoolean(R.bool.config_allow_sim_import)) {
- List<SubscriptionInfo> subInfoRecords = null;
- try {
- subInfoRecords = mSubscriptionManager.getActiveSubscriptionInfoList();
- } catch (SecurityException e) {
- Log.w(TAG, "SecurityException thrown, lack permission for"
- + " getActiveSubscriptionInfoList", e);
- }
- if (subInfoRecords != null) {
- if (subInfoRecords.size() == 1) {
- adapter.add(new AdapterEntry(getString(R.string.import_from_sim),
- R.string.import_from_sim, subInfoRecords.get(0).getSubscriptionId()));
- } else if (hasUniqueNonNullCarrierNames(subInfoRecords)) {
- for (SubscriptionInfo record : subInfoRecords) {
- adapter.add(new AdapterEntry(getSubDescriptionForCarrier(record),
- R.string.import_from_sim, record.getSubscriptionId()));
- }
- } else {
- for (SubscriptionInfo record : subInfoRecords) {
- adapter.add(new AdapterEntry(getSubDescription(record),
- R.string.import_from_sim, record.getSubscriptionId()));
- }
- }
- }
- }
- } else {
- if (manager != null && manager.hasIccCard()
- && res.getBoolean(R.bool.config_allow_sim_import)) {
- adapter.add(new AdapterEntry(getString(R.string.import_from_sim),
- R.string.import_from_sim, -1));
- }
- }
-
+ addItems(adapter);
final DialogInterface.OnClickListener clickListener =
new DialogInterface.OnClickListener() {
@@ -201,6 +157,25 @@
.create();
}
+ private void addItems(ArrayAdapter<AdapterEntry> adapter) {
+ final Resources res = getActivity().getResources();
+ if (res.getBoolean(R.bool.config_allow_import_from_vcf_file) && !mSimOnly) {
+ adapter.add(new AdapterEntry(getString(R.string.import_from_vcf_file),
+ R.string.import_from_vcf_file));
+ }
+ final List<SimCard> sims = mSimDao.getSimCards();
+
+ if (sims.size() == 1) {
+ adapter.add(new AdapterEntry(getString(R.string.import_from_sim),
+ R.string.import_from_sim, SimCard.NO_SUBSCRIPTION_ID));
+ return;
+ }
+ for (SimCard sim : sims) {
+ adapter.add(new AdapterEntry(getSimDescription(sim), R.string.import_from_sim,
+ sim.getSubscriptionId()));
+ }
+ }
+
private boolean handleSimImportRequest(int subscriptionId) {
SimImportFragment.newInstance(subscriptionId).show(getFragmentManager(), "SimImport");
return true;
@@ -260,62 +235,23 @@
dismiss();
}
- @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1)
- private boolean hasUniqueNonNullCarrierNames(List<SubscriptionInfo> subscriptions) {
- final Set<CharSequence> names = new ArraySet<>();
- for (SubscriptionInfo subscription : subscriptions) {
- final CharSequence name = subscription.getCarrierName();
- if (name == null) {
- return false;
- }
- if (!names.add(name)) {
- return false;
- }
+ private CharSequence getSimDescription(SimCard sim) {
+ final CharSequence name = sim.getDisplayName();
+ CharSequence number = sim.getFormattedPhone();
+ // If formatting fails use the raw phone number
+ if (number == null) {
+ number = sim.getPhone();
}
- return true;
- }
-
- private CharSequence getSubDescription(SubscriptionInfo record) {
- final CharSequence name = record.getDisplayName();
- final CharSequence number = getFormattedNumber(record);
-
+ if (number != null) {
+ number = PhoneNumberUtilsCompat.createTtsSpannable(number);
+ }
if (TextUtils.isEmpty(number)) {
- return getString(R.string.import_from_sim_summary_no_number, name);
+ return getString(R.string.import_from_sim_summary_fmt, name);
}
-
- return TextUtils.expandTemplate(getString(R.string.import_from_sim_summary), name, number);
+ return new SpannableStringBuilder(getString(R.string.import_from_sim_summary_fmt, name))
+ .append('\n').append(number);
}
- private CharSequence getSubDescriptionForCarrier(SubscriptionInfo record) {
- final CharSequence carrierName = record.getCarrierName();
- final CharSequence number = getFormattedNumber(record);
-
- if (TextUtils.isEmpty(number)) {
- return getString(R.string.import_from_sim_summary_by_carrier_no_number, carrierName);
- }
-
- return TextUtils.expandTemplate(
- getString(R.string.import_from_sim_summary_by_carrier), carrierName, number);
- }
-
- private CharSequence getFormattedNumber(SubscriptionInfo subscription) {
- final String rawNumber = subscription.getNumber();
- if (rawNumber == null) {
- return null;
- }
- final String country = subscription.getCountryIso();
- final String number;
- if (country != null) {
- number = PhoneNumberUtilsCompat.formatNumber(rawNumber, null,
- country.toUpperCase(Locale.US));
- } else {
- number = rawNumber;
- }
- return PhoneNumberUtilsCompat.createTtsSpannable(number);
- }
-
-
-
private static class AdapterEntry {
public final CharSequence mLabel;
public final int mChoiceResourceId;
diff --git a/src/com/android/contacts/common/model/SimCard.java b/src/com/android/contacts/common/model/SimCard.java
new file mode 100644
index 0000000..9b5486b
--- /dev/null
+++ b/src/com/android/contacts/common/model/SimCard.java
@@ -0,0 +1,215 @@
+/*
+ * 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.common.model;
+
+import android.os.Build;
+import android.support.annotation.RequiresApi;
+import android.telephony.PhoneNumberUtils;
+import android.telephony.SubscriptionInfo;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+
+import com.android.contacts.common.database.SimContactDao;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+import java.util.Objects;
+
+/**
+ * Holds data for a SIM card in the device.
+ */
+public class SimCard {
+
+ private static final String TAG = "SimCard";
+
+ public static final int NO_SUBSCRIPTION_ID = -1;
+
+ // This state is created from the info we get from the system
+ private final String mSimId;
+ private final int mSubscriptionId;
+ private final CharSequence mCarrierName;
+ private final CharSequence mDisplayName;
+ private final String mPhoneNumber;
+ private final String mCountryCode;
+
+ // This is our own state that we associate with SIM cards. Currently these are only used
+ // in the GoogleContacts app.
+ // Note: these are logically immutable but are not final to reduce required constructor
+ // parameters
+ private boolean mDismissed = false;
+ private boolean mImported = false;
+
+ private List<SimContact> mContacts;
+
+ public SimCard(SimCard other) {
+ mSimId = other.mSimId;
+ mSubscriptionId = other.mSubscriptionId;
+ mCarrierName = other.mCarrierName;
+ mDisplayName = other.mDisplayName;
+ mPhoneNumber = other.mPhoneNumber;
+ mCountryCode = other.mCountryCode;
+ mDismissed = other.mDismissed;
+ mImported = other.mImported;
+ mContacts = other.mContacts;
+ }
+
+ public SimCard(String simId, int subscriptionId, CharSequence carrierName,
+ CharSequence displayName, String phoneNumber, String countryCode) {
+ mSimId = simId;
+ mSubscriptionId = subscriptionId;
+ mCarrierName = carrierName;
+ mDisplayName = displayName;
+ mPhoneNumber = phoneNumber;
+ mCountryCode = countryCode != null ? countryCode.toUpperCase(Locale.US) : null;
+ }
+
+ public SimCard(String simId, CharSequence carrierName,
+ CharSequence displayName, String phoneNumber, String countryCode) {
+ this(simId, NO_SUBSCRIPTION_ID, carrierName, displayName, phoneNumber, countryCode);
+ }
+
+ public String getSimId() {
+ return mSimId;
+ }
+
+ public int getSubscriptionId() {
+ return mSubscriptionId;
+ }
+
+ public CharSequence getDisplayName() {
+ return mDisplayName;
+ }
+
+ public String getPhone() {
+ return mPhoneNumber;
+ }
+
+ public CharSequence getFormattedPhone() {
+ if (mPhoneNumber == null) {
+ return null;
+ }
+ return PhoneNumberUtils.formatNumber(mPhoneNumber, mCountryCode);
+ }
+
+ public boolean hasContacts() {
+ if (mContacts == null) {
+ throw new IllegalStateException("Contacts not loaded.");
+ }
+ return !mContacts.isEmpty();
+ }
+
+ public int getContactCount() {
+ if (mContacts == null) {
+ throw new IllegalStateException("Contacts not loaded.");
+ }
+ return mContacts.size();
+ }
+
+ public boolean isDismissed() {
+ return mDismissed;
+ }
+
+ public boolean isImported() {
+ return mImported;
+ }
+
+ public boolean isImportable() {
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "isImportable: isDismissed? " + isDismissed() +
+ " isImported? " + isImported() + " contacts=" + mContacts);
+ }
+ return !isDismissed() && !isImported() && hasContacts();
+ }
+
+ public List<SimContact> getContacts() {
+ if (mContacts == null) {
+ throw new IllegalStateException("Contacts not loaded.");
+ }
+ return mContacts;
+ }
+
+ public synchronized void loadContacts(SimContactDao dao) {
+ if (mSubscriptionId == NO_SUBSCRIPTION_ID) {
+ // Load from the default SIM card.
+ mContacts = dao.loadSimContacts();
+ } else {
+ mContacts = dao.loadSimContacts(mSubscriptionId);
+ }
+ if (mContacts == null) {
+ mContacts = Collections.emptyList();
+ }
+ }
+
+ public SimCard withImportAndDismissStates(boolean imported, boolean dismissed) {
+ SimCard copy = new SimCard(this);
+ copy.mImported = imported;
+ copy.mDismissed = dismissed;
+ return copy;
+ }
+
+ public SimCard withImportedState(boolean imported) {
+ return withImportAndDismissStates(imported, mDismissed);
+ }
+
+ public SimCard withDismissedState(boolean dismissed) {
+ return withImportAndDismissStates(dismissed, mImported);
+ }
+
+ public SimCard withContacts(SimContact... contacts) {
+ final SimCard copy = new SimCard(this);
+ copy.mContacts = Arrays.asList(contacts);
+ return copy;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ SimCard simCard = (SimCard) o;
+
+ return mSubscriptionId == simCard.mSubscriptionId && mDismissed == simCard.mDismissed &&
+ mImported == simCard.mImported && Objects.equals(mSimId, simCard.mSimId) &&
+ Objects.equals(mPhoneNumber, simCard.mPhoneNumber) &&
+ Objects.equals(mCountryCode, simCard.mCountryCode);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = Objects.hash(mSimId, mPhoneNumber, mCountryCode);
+ result = 31 * result + mSubscriptionId;
+ result = 31 * result + (mDismissed ? 1 : 0);
+ result = 31 * result + (mImported ? 1 : 0);
+ return result;
+ }
+
+
+ @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1)
+ public static SimCard create(SubscriptionInfo info) {
+ return new SimCard(info.getIccId(), info.getSubscriptionId(),
+ info.getCarrierName(), info.getDisplayName(), info.getNumber(),
+ info.getCountryIso());
+ }
+
+ public static SimCard create(TelephonyManager telephony) {
+ SimCard simCard = new SimCard(telephony.getSimSerialNumber(),
+ telephony.getNetworkOperatorName(), "SIM", telephony.getLine1Number(),
+ telephony.getNetworkCountryIso());
+ return simCard;
+ }
+}
diff --git a/src/com/android/contacts/editor/AggregationSuggestionEngine.java b/src/com/android/contacts/editor/AggregationSuggestionEngine.java
index 8ababa8..62e55e5 100644
--- a/src/com/android/contacts/editor/AggregationSuggestionEngine.java
+++ b/src/com/android/contacts/editor/AggregationSuggestionEngine.java
@@ -29,7 +29,6 @@
import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.Nickname;
import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.provider.ContactsContract.CommonDataKinds.Photo;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Contacts.AggregationSuggestions;
@@ -41,6 +40,8 @@
import com.android.contacts.common.model.ValuesDelta;
import com.android.contacts.common.model.account.AccountWithDataSet;
import com.android.contacts.compat.AggregationSuggestionsCompat;
+
+import com.google.common.base.Objects;
import com.google.common.collect.Lists;
import java.util.ArrayList;
@@ -57,36 +58,26 @@
void onAggregationSuggestionChange();
}
- public static final class RawContact {
- public long rawContactId;
- public String accountType;
- public String accountName;
- public String dataSet;
-
- @Override
- public String toString() {
- return "ID: " + rawContactId + " account: " + accountType + "/" + accountName
- + " dataSet: " + dataSet;
- }
- }
-
public static final class Suggestion {
-
public long contactId;
- public long photoId;
- public String lookupKey;
+ public String contactLookupKey;
+ public long rawContactId;
public String name;
public String phoneNumber;
public String emailAddress;
public String nickname;
- public byte[] photo;
- public List<RawContact> rawContacts;
@Override
public String toString() {
- return "ID: " + contactId + " rawContacts: " + rawContacts + " name: " + name
- + " phone: " + phoneNumber + " email: " + emailAddress + " nickname: "
- + nickname + (photo != null ? " [has photo]" : "");
+ return Objects.toStringHelper(Suggestion.class)
+ .add("contactId", contactId)
+ .add("contactLookupKey", contactLookupKey)
+ .add("rawContactId", rawContactId)
+ .add("name", name)
+ .add("phoneNumber", phoneNumber)
+ .add("emailAddress", emailAddress)
+ .add("nickname", nickname)
+ .toString();
}
}
@@ -107,10 +98,11 @@
private static final long SUGGESTION_LOOKUP_DELAY_MILLIS = 300;
+ private static final int SUGGESTIONS_LIMIT = 3;
+
private final Context mContext;
private long[] mSuggestedContactIds = new long[0];
-
private Handler mMainHandler;
private Handler mHandler;
private long mContactId;
@@ -119,8 +111,6 @@
private Cursor mDataCursor;
private ContentObserver mContentObserver;
private Uri mSuggestionsUri;
- private int mSuggestionsLimit = 3;
- private boolean mPruneInvisibleContacts = false;
public AggregationSuggestionEngine(Context context) {
super("AggregationSuggestions", Process.THREAD_PRIORITY_BACKGROUND);
@@ -156,14 +146,6 @@
mAccountFilter = account;
}
- public void setSuggestionsLimit(int suggestionsLimit) {
- mSuggestionsLimit = suggestionsLimit;
- }
-
- public void setPruneInvisibleContacts (boolean pruneInvisibleContacts) {
- mPruneInvisibleContacts = pruneInvisibleContacts;
- }
-
public void setListener(Listener listener) {
mListener = listener;
}
@@ -238,7 +220,7 @@
// AggregationSuggestions.Builder() became visible in API level 23, so use it if applicable.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
final Builder uriBuilder = new AggregationSuggestions.Builder()
- .setLimit(mSuggestionsLimit)
+ .setLimit(SUGGESTIONS_LIMIT)
.setContactId(mContactId);
if (nameSb.length() != 0) {
uriBuilder.addNameParameter(nameSb.toString());
@@ -252,7 +234,7 @@
// For previous SDKs, use the backup plan.
final AggregationSuggestionsCompat.Builder uriBuilder =
new AggregationSuggestionsCompat.Builder()
- .setLimit(mSuggestionsLimit)
+ .setLimit(SUGGESTIONS_LIMIT)
.setContactId(mContactId);
if (nameSb.length() != 0) {
uriBuilder.addNameParameter(nameSb.toString());
@@ -288,42 +270,33 @@
public static final String SELECTION_PREFIX =
Data.MIMETYPE + " IN ('"
- + Phone.CONTENT_ITEM_TYPE + "','"
- + Email.CONTENT_ITEM_TYPE + "','"
- + StructuredName.CONTENT_ITEM_TYPE + "','"
- + Nickname.CONTENT_ITEM_TYPE + "','"
- + Photo.CONTENT_ITEM_TYPE + "')"
- + " AND " + Data.CONTACT_ID + " IN (";
+ + Phone.CONTENT_ITEM_TYPE + "','"
+ + Email.CONTENT_ITEM_TYPE + "','"
+ + StructuredName.CONTENT_ITEM_TYPE + "','"
+ + Nickname.CONTENT_ITEM_TYPE + "')"
+ + " AND " + Data.CONTACT_ID + " IN (";
public static final String[] COLUMNS = {
- Data._ID,
- Data.CONTACT_ID,
- Data.LOOKUP_KEY,
- Data.PHOTO_ID,
- Data.DISPLAY_NAME,
- Data.RAW_CONTACT_ID,
- Data.MIMETYPE,
- Data.DATA1,
- Data.IS_SUPER_PRIMARY,
- Photo.PHOTO,
- RawContacts.ACCOUNT_TYPE,
- RawContacts.ACCOUNT_NAME,
- RawContacts.DATA_SET
+ Data.CONTACT_ID,
+ Data.LOOKUP_KEY,
+ Data.RAW_CONTACT_ID,
+ Data.MIMETYPE,
+ Data.DATA1,
+ Data.IS_SUPER_PRIMARY,
+ RawContacts.ACCOUNT_TYPE,
+ RawContacts.ACCOUNT_NAME,
+ RawContacts.DATA_SET
};
- public static final int ID = 0;
- public static final int CONTACT_ID = 1;
- public static final int LOOKUP_KEY = 2;
- public static final int PHOTO_ID = 3;
- public static final int DISPLAY_NAME = 4;
- public static final int RAW_CONTACT_ID = 5;
- public static final int MIMETYPE = 6;
- public static final int DATA1 = 7;
- public static final int IS_SUPERPRIMARY = 8;
- public static final int PHOTO = 9;
- public static final int ACCOUNT_TYPE = 10;
- public static final int ACCOUNT_NAME = 11;
- public static final int DATA_SET = 12;
+ public static final int CONTACT_ID = 0;
+ public static final int LOOKUP_KEY = 1;
+ public static final int RAW_CONTACT_ID = 2;
+ public static final int MIMETYPE = 3;
+ public static final int DATA1 = 4;
+ public static final int IS_SUPERPRIMARY = 5;
+ public static final int ACCOUNT_TYPE = 6;
+ public static final int ACCOUNT_NAME = 7;
+ public static final int DATA_SET = 8;
}
private void loadAggregationSuggestions(Uri uri) {
@@ -352,12 +325,12 @@
sb.append(mSuggestedContactIds[i]);
}
sb.append(')');
- sb.toString();
Cursor dataCursor = contentResolver.query(Data.CONTENT_URI,
DataQuery.COLUMNS, sb.toString(), null, Data.CONTACT_ID);
if (dataCursor != null) {
- mMainHandler.sendMessage(mMainHandler.obtainMessage(MESSAGE_DATA_CURSOR, dataCursor));
+ mMainHandler.sendMessage(
+ mMainHandler.obtainMessage(MESSAGE_DATA_CURSOR, dataCursor));
}
} finally {
cursor.close();
@@ -370,8 +343,7 @@
final ArrayList<Long> newIds = new ArrayList<Long>(count);
while (cursor.moveToNext()) {
final long contactId = cursor.getLong(0);
- if (!changed &&
- Arrays.binarySearch(mSuggestedContactIds, contactId) < 0) {
+ if (!changed && Arrays.binarySearch(mSuggestedContactIds, contactId) < 0) {
changed = true;
}
newIds.add(contactId);
@@ -404,110 +376,59 @@
}
public List<Suggestion> getSuggestions() {
- final ArrayList<Long> visibleContacts = new ArrayList<>();
- if (mPruneInvisibleContacts) {
- final Uri contactFilterUri = Data.CONTENT_URI.buildUpon()
- .appendQueryParameter(Data.VISIBLE_CONTACTS_ONLY, "true")
- .build();
- final ContentResolver contentResolver = mContext.getContentResolver();
- final Cursor contactCursor = contentResolver.query(contactFilterUri,
- new String[]{Data.CONTACT_ID}, null, null, null);
- try {
- if (contactCursor != null) {
- while (contactCursor.moveToNext()) {
- final long contactId = contactCursor.getLong(0);
- visibleContacts.add(contactId);
- }
- }
- } finally {
- contactCursor.close();
- }
+ final ArrayList<Suggestion> list = Lists.newArrayList();
- }
-
- ArrayList<Suggestion> list = Lists.newArrayList();
- if (mDataCursor != null) {
+ if (mDataCursor != null && mAccountFilter != null) {
Suggestion suggestion = null;
- long currentContactId = -1;
+ long currentRawContactId = -1;
mDataCursor.moveToPosition(-1);
while (mDataCursor.moveToNext()) {
- long contactId = mDataCursor.getLong(DataQuery.CONTACT_ID);
- if (mPruneInvisibleContacts && !visibleContacts.contains(contactId)) {
- continue;
- }
- if (contactId != currentContactId) {
+ final long rawContactId = mDataCursor.getLong(DataQuery.RAW_CONTACT_ID);
+ if (rawContactId != currentRawContactId) {
suggestion = new Suggestion();
- suggestion.contactId = contactId;
- suggestion.name = mDataCursor.getString(DataQuery.DISPLAY_NAME);
- suggestion.lookupKey = mDataCursor.getString(DataQuery.LOOKUP_KEY);
- suggestion.rawContacts = Lists.newArrayList();
- // No restriction, add all suggestions.
- if (mAccountFilter == null) {
- list.add(suggestion);
- }
- currentContactId = contactId;
- }
-
- long rawContactId = mDataCursor.getLong(DataQuery.RAW_CONTACT_ID);
- if (!containsRawContact(suggestion, rawContactId)) {
- RawContact rawContact = new RawContact();
- rawContact.rawContactId = rawContactId;
- rawContact.accountName = mDataCursor.getString(DataQuery.ACCOUNT_NAME);
- rawContact.accountType = mDataCursor.getString(DataQuery.ACCOUNT_TYPE);
- rawContact.dataSet = mDataCursor.getString(DataQuery.DATA_SET);
+ suggestion.rawContactId = rawContactId;
+ suggestion.contactId = mDataCursor.getLong(DataQuery.CONTACT_ID);
+ suggestion.contactLookupKey = mDataCursor.getString(DataQuery.LOOKUP_KEY);
+ final String accountName = mDataCursor.getString(DataQuery.ACCOUNT_NAME);
+ final String accountType = mDataCursor.getString(DataQuery.ACCOUNT_TYPE);
+ final String dataSet = mDataCursor.getString(DataQuery.DATA_SET);
final AccountWithDataSet account = new AccountWithDataSet(
- rawContact.accountName, rawContact.accountType, rawContact.dataSet);
- // If we're restricting to a certain account, only add the suggestion if
- // it has a raw contact from that account.
- if (mAccountFilter != null && mAccountFilter.equals(account)
- && !list.contains(suggestion)) {
+ accountName, accountType, dataSet);
+ if (mAccountFilter.equals(account)) {
list.add(suggestion);
}
- suggestion.rawContacts.add(rawContact);
+ currentRawContactId = rawContactId;
}
- String mimetype = mDataCursor.getString(DataQuery.MIMETYPE);
+ final String mimetype = mDataCursor.getString(DataQuery.MIMETYPE);
if (Phone.CONTENT_ITEM_TYPE.equals(mimetype)) {
- String data = mDataCursor.getString(DataQuery.DATA1);
+ final String data = mDataCursor.getString(DataQuery.DATA1);
int superprimary = mDataCursor.getInt(DataQuery.IS_SUPERPRIMARY);
if (!TextUtils.isEmpty(data)
&& (superprimary != 0 || suggestion.phoneNumber == null)) {
suggestion.phoneNumber = data;
}
} else if (Email.CONTENT_ITEM_TYPE.equals(mimetype)) {
- String data = mDataCursor.getString(DataQuery.DATA1);
+ final String data = mDataCursor.getString(DataQuery.DATA1);
int superprimary = mDataCursor.getInt(DataQuery.IS_SUPERPRIMARY);
if (!TextUtils.isEmpty(data)
&& (superprimary != 0 || suggestion.emailAddress == null)) {
suggestion.emailAddress = data;
}
} else if (Nickname.CONTENT_ITEM_TYPE.equals(mimetype)) {
- String data = mDataCursor.getString(DataQuery.DATA1);
+ final String data = mDataCursor.getString(DataQuery.DATA1);
if (!TextUtils.isEmpty(data)) {
suggestion.nickname = data;
}
- } else if (Photo.CONTENT_ITEM_TYPE.equals(mimetype)) {
- long dataId = mDataCursor.getLong(DataQuery.ID);
- long photoId = mDataCursor.getLong(DataQuery.PHOTO_ID);
- if (dataId == photoId && !mDataCursor.isNull(DataQuery.PHOTO)) {
- suggestion.photo = mDataCursor.getBlob(DataQuery.PHOTO);
- suggestion.photoId = photoId;
+ } else if (StructuredName.CONTENT_ITEM_TYPE.equals(mimetype)) {
+ // DATA1 stores the display name for the raw contact.
+ final String data = mDataCursor.getString(DataQuery.DATA1);
+ if (!TextUtils.isEmpty(data) && suggestion.name == null) {
+ suggestion.name = data;
}
}
}
}
return list;
}
-
- public boolean containsRawContact(Suggestion suggestion, long rawContactId) {
- if (suggestion.rawContacts != null) {
- int count = suggestion.rawContacts.size();
- for (int i = 0; i < count; i++) {
- if (suggestion.rawContacts.get(i).rawContactId == rawContactId) {
- return true;
- }
- }
- }
- return false;
- }
}
diff --git a/src/com/android/contacts/editor/AggregationSuggestionView.java b/src/com/android/contacts/editor/AggregationSuggestionView.java
index 5a3da00..b89f06a 100644
--- a/src/com/android/contacts/editor/AggregationSuggestionView.java
+++ b/src/com/android/contacts/editor/AggregationSuggestionView.java
@@ -16,9 +16,10 @@
package com.android.contacts.editor;
+import android.content.ContentUris;
import android.content.Context;
-import android.graphics.BitmapFactory;
import android.net.Uri;
+import android.provider.ContactsContract;
import android.provider.ContactsContract.Contacts;
import android.text.TextUtils;
import android.util.AttributeSet;
@@ -28,16 +29,8 @@
import android.widget.TextView;
import com.android.contacts.R;
-import com.android.contacts.editor.AggregationSuggestionEngine.RawContact;
-import com.android.contacts.editor.AggregationSuggestionEngine.Suggestion;
import com.android.contacts.common.ContactPhotoManager;
-import com.android.contacts.common.model.AccountTypeManager;
-import com.android.contacts.common.model.account.AccountType;
-
-import com.google.common.collect.Lists;
-
-import java.util.ArrayList;
-import java.util.List;
+import com.android.contacts.editor.AggregationSuggestionEngine.Suggestion;
/**
* A view that contains a name, picture and other data for a contact aggregation suggestion.
@@ -45,25 +38,15 @@
public class AggregationSuggestionView extends LinearLayout {
public interface Listener {
-
/**
- * Callback that passes the contact ID to join with and, for convenience,
- * also the list of constituent raw contact IDs to avoid a separate query
- * for those.
+ * Callback that passes the contact URI and raw contact ID to edit instead of the
+ * current contact.
*/
- public void onJoinAction(long contactId, List<Long> rawContacIds);
-
- /**
- * Callback that passes the contact ID to edit instead of the current contact.
- */
- public void onEditAction(Uri contactLookupUri);
+ void onEditAction(Uri contactLookupUri, long rawContactId);
}
private Listener mListener;
- private long mContactId;
- private String mLookupKey;
- private List<RawContact> mRawContacts = Lists.newArrayList();
- private boolean mNewContact;
+ private Suggestion mSuggestion;
public AggregationSuggestionView(Context context) {
super(context);
@@ -77,22 +60,21 @@
super(context, attrs, defStyle);
}
- public void setNewContact(boolean flag) {
- mNewContact = flag;
- }
-
public void bindSuggestion(Suggestion suggestion) {
- mContactId = suggestion.contactId;
- mLookupKey = suggestion.lookupKey;
- mRawContacts = suggestion.rawContacts;
- ImageView photo = (ImageView) findViewById(R.id.aggregation_suggestion_photo);
- if (suggestion.photo != null) {
- photo.setImageBitmap(BitmapFactory.decodeByteArray(
- suggestion.photo, 0, suggestion.photo.length));
- } else {
- photo.setImageDrawable(ContactPhotoManager.getDefaultAvatarDrawableForContact(
- getResources(), false, null));
- }
+ mSuggestion = suggestion;
+ final ContactPhotoManager.DefaultImageRequest
+ request = new ContactPhotoManager.DefaultImageRequest(
+ suggestion.name, String.valueOf(suggestion.rawContactId), /* isCircular = */ false);
+ final Uri photoUri = Uri.withAppendedPath(ContentUris.withAppendedId(
+ ContactsContract.RawContacts.CONTENT_URI, suggestion.rawContactId),
+ ContactsContract.RawContacts.DisplayPhoto.CONTENT_DIRECTORY);
+ final ImageView photoView = (ImageView) findViewById(
+ R.id.aggregation_suggestion_photo);
+ ContactPhotoManager.getInstance(getContext()).loadDirectoryPhoto(photoView,
+ photoUri,
+ /* darkTheme = */ false,
+ /* isCircular = */ false,
+ request);
TextView name = (TextView) findViewById(R.id.aggregation_suggestion_name);
name.setText(suggestion.name);
@@ -111,48 +93,18 @@
data.setText(dataText);
}
- /**
- * Returns true if the suggested contact can be edited.
- */
- private boolean canEditSuggestedContact() {
- if (!mNewContact) {
- return false;
- }
-
- AccountTypeManager accountTypes = AccountTypeManager.getInstance(getContext());
- for (RawContact rawContact : mRawContacts) {
- String accountType = rawContact.accountType;
- String dataSet = rawContact.dataSet;
- if (accountType == null) {
- return true;
- }
- AccountType type = accountTypes.getAccountType(accountType, dataSet);
- if (type.areContactsWritable()) {
- return true;
- }
- }
-
- return false;
- }
-
public void setListener(Listener listener) {
mListener = listener;
}
public boolean handleItemClickEvent() {
if (mListener != null && isEnabled()) {
- if (canEditSuggestedContact()) {
- if (TextUtils.isEmpty(mLookupKey)) {
- return false;
- }
- mListener.onEditAction(Contacts.getLookupUri(mContactId, mLookupKey));
- } else {
- ArrayList<Long> rawContactIds = Lists.newArrayList();
- for (RawContact rawContact : mRawContacts) {
- rawContactIds.add(rawContact.rawContactId);
- }
- mListener.onJoinAction(mContactId, rawContactIds);
+ if (TextUtils.isEmpty(mSuggestion.contactLookupKey)) {
+ return false;
}
+ mListener.onEditAction(
+ Contacts.getLookupUri(mSuggestion.contactId, mSuggestion.contactLookupKey),
+ mSuggestion.rawContactId);
return true;
}
return false;
diff --git a/src/com/android/contacts/editor/ContactEditorFragment.java b/src/com/android/contacts/editor/ContactEditorFragment.java
index 0f1ff8e..65c30e8 100644
--- a/src/com/android/contacts/editor/ContactEditorFragment.java
+++ b/src/com/android/contacts/editor/ContactEditorFragment.java
@@ -241,10 +241,10 @@
void onSaveFinished(Intent resultIntent);
/**
- * User switched to editing a different contact (a suggestion from the
+ * User switched to editing a different raw contact (a suggestion from the
* aggregation engine).
*/
- void onEditOtherContactRequested(Uri contactLookupUri,
+ void onEditOtherRawContactRequested(Uri contactLookupUri, long rawContactId,
ArrayList<ContentValues> contentValues);
/**
@@ -259,14 +259,12 @@
*/
private static final class AggregationSuggestionAdapter extends BaseAdapter {
private final LayoutInflater mLayoutInflater;
- private final boolean mSetNewContact;
private final AggregationSuggestionView.Listener mListener;
private final List<AggregationSuggestionEngine.Suggestion> mSuggestions;
- public AggregationSuggestionAdapter(Activity activity, boolean setNewContact,
+ public AggregationSuggestionAdapter(Activity activity,
AggregationSuggestionView.Listener listener, List<Suggestion> suggestions) {
mLayoutInflater = activity.getLayoutInflater();
- mSetNewContact = setNewContact;
mListener = listener;
mSuggestions = suggestions;
}
@@ -277,7 +275,6 @@
final AggregationSuggestionView suggestionView =
(AggregationSuggestionView) mLayoutInflater.inflate(
R.layout.aggregation_suggestions_item, null);
- suggestionView.setNewContact(mSetNewContact);
suggestionView.setListener(mListener);
suggestionView.bindSuggestion(suggestion);
return suggestionView;
@@ -969,20 +966,6 @@
return false;
}
- /**
- * Whether editor inputs and the options menu should be enabled.
- */
- private boolean isEnabled() {
- return mEnabled;
- }
-
- /**
- * Returns the palette extra that was passed in.
- */
- private MaterialColorMapUtils.MaterialPalette getMaterialPalette() {
- return mMaterialPalette;
- }
-
//
// Account creation
//
@@ -1251,7 +1234,7 @@
if (mCopyReadOnlyName) {
copyReadOnlyName();
}
- editorView.setState(mState, getMaterialPalette(), mViewIdGenerator,
+ editorView.setState(mState, mMaterialPalette, mViewIdGenerator,
mHasNewContact, mIsUserProfile, mAccountWithDataSet,
mRawContactIdToDisplayAlone);
@@ -1266,7 +1249,7 @@
}
// The editor is ready now so make it visible
- editorView.setEnabled(isEnabled());
+ editorView.setEnabled(mEnabled);
editorView.setVisibility(View.VISIBLE);
// Refresh the ActionBar as the visibility of the join command
@@ -1567,7 +1550,6 @@
mAggregationSuggestionPopup.setAdapter(
new AggregationSuggestionAdapter(
getActivity(),
- mState.size() == 1 && mState.get(0).isContactInsert(),
/* listener =*/ this,
mAggregationSuggestionEngine.getSuggestions()));
mAggregationSuggestionPopup.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@@ -1589,19 +1571,6 @@
return getContent().getAggregationAnchorView();
}
- @Override
- public void onJoinAction(long contactId, List<Long> rawContactIdList) {
- final long rawContactIds[] = new long[rawContactIdList.size()];
- for (int i = 0; i < rawContactIds.length; i++) {
- rawContactIds[i] = rawContactIdList.get(i);
- }
- try {
- JoinSuggestedContactDialogFragment.show(this, rawContactIds);
- } catch (Exception ignored) {
- // No problem - the activity is no longer available to display the dialog
- }
- }
-
/**
* Joins the suggested contact (specified by the id's of constituent raw
* contacts), save all changes, and stay in the editor.
@@ -1616,20 +1585,20 @@
}
@Override
- public void onEditAction(Uri contactLookupUri) {
- SuggestionEditConfirmationDialogFragment.show(this, contactLookupUri);
+ public void onEditAction(Uri contactLookupUri, long rawContactId) {
+ SuggestionEditConfirmationDialogFragment.show(this, contactLookupUri, rawContactId);
}
/**
- * Abandons the currently edited contact and switches to editing the suggested
- * one, transferring all the data there
+ * Abandons the currently edited contact and switches to editing the selected raw contact,
+ * transferring all the data there
*/
- public void doEditSuggestedContact(Uri contactUri) {
+ public void doEditSuggestedContact(Uri contactUri, long rawContactId) {
if (mListener != null) {
// make sure we don't save this contact when closing down
mStatus = Status.CLOSING;
- mListener.onEditOtherContactRequested(
- contactUri, mState.get(0).getContentValues());
+ mListener.onEditOtherRawContactRequested(contactUri, rawContactId,
+ getContent().getCurrentRawContactDelta().getContentValues());
}
}
diff --git a/src/com/android/contacts/editor/EditorIntents.java b/src/com/android/contacts/editor/EditorIntents.java
index 2d05eb2..015e75b 100644
--- a/src/com/android/contacts/editor/EditorIntents.java
+++ b/src/com/android/contacts/editor/EditorIntents.java
@@ -81,17 +81,18 @@
}
/**
- * Returns an Intent to edit a different contact in the editor with whatever
+ * Returns an Intent to edit a different raw contact in the editor with whatever
* values were already entered on the current editor.
*/
- public static Intent createEditOtherContactIntent(Context context, Uri uri,
- ArrayList<ContentValues> contentValues) {
+ public static Intent createEditOtherRawContactIntent(Context context, Uri uri,
+ long rawContactId, ArrayList<ContentValues> contentValues) {
final Intent intent = new Intent(Intent.ACTION_EDIT, uri, context,
ContactEditorActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
| Intent.FLAG_ACTIVITY_FORWARD_RESULT);
intent.putExtra(ContactEditorFragment.INTENT_EXTRA_ADD_TO_DEFAULT_DIRECTORY, "");
-
+ intent.putExtra(ContactEditorFragment.INTENT_EXTRA_RAW_CONTACT_ID_TO_DISPLAY_ALONE,
+ rawContactId);
// Pass on all the data that has been entered so far
if (contentValues != null && contentValues.size() != 0) {
intent.putParcelableArrayListExtra(ContactsContract.Intents.Insert.DATA, contentValues);
diff --git a/src/com/android/contacts/editor/SuggestionEditConfirmationDialogFragment.java b/src/com/android/contacts/editor/SuggestionEditConfirmationDialogFragment.java
index 9408c7e..f94d5dc 100644
--- a/src/com/android/contacts/editor/SuggestionEditConfirmationDialogFragment.java
+++ b/src/com/android/contacts/editor/SuggestionEditConfirmationDialogFragment.java
@@ -16,8 +16,6 @@
package com.android.contacts.editor;
-import com.android.contacts.R;
-
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
@@ -25,13 +23,17 @@
import android.net.Uri;
import android.os.Bundle;
+import com.android.contacts.R;
+
public class SuggestionEditConfirmationDialogFragment extends DialogFragment {
private static final String ARG_CONTACT_URI = "contactUri";
+ private static final String ARG_RAW_CONTACT_ID = "rawContactId";
- public static void show(ContactEditorFragment fragment, Uri contactUri) {
+ public static void show(ContactEditorFragment fragment, Uri contactUri, long rawContactId) {
final Bundle args = new Bundle();
args.putParcelable(ARG_CONTACT_URI, contactUri);
+ args.putLong(ARG_RAW_CONTACT_ID, rawContactId);
final SuggestionEditConfirmationDialogFragment dialog = new
SuggestionEditConfirmationDialogFragment();
@@ -53,7 +55,9 @@
(ContactEditorFragment) getTargetFragment();
final Uri contactUri =
getArguments().getParcelable(ARG_CONTACT_URI);
- targetFragment.doEditSuggestedContact(contactUri);
+ final long rawContactId =
+ getArguments().getLong(ARG_RAW_CONTACT_ID);
+ targetFragment.doEditSuggestedContact(contactUri, rawContactId);
}
}
)
diff --git a/src/com/android/contacts/quickcontact/QuickContactActivity.java b/src/com/android/contacts/quickcontact/QuickContactActivity.java
index f69f2ec..3597607 100644
--- a/src/com/android/contacts/quickcontact/QuickContactActivity.java
+++ b/src/com/android/contacts/quickcontact/QuickContactActivity.java
@@ -32,7 +32,6 @@
import android.content.Loader;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
-import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
@@ -48,7 +47,6 @@
import android.os.Bundle;
import android.os.Trace;
import android.provider.CalendarContract;
-import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.Event;
import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
@@ -72,9 +70,7 @@
import android.provider.ContactsContract.RawContacts;
import android.support.graphics.drawable.VectorDrawableCompat;
import android.support.v4.app.ActivityCompat;
-import android.support.v4.content.ContextCompat;
import android.support.v7.graphics.Palette;
-import android.support.v7.widget.CardView;
import android.telecom.PhoneAccount;
import android.telecom.TelecomManager;
import android.text.BidiFormatter;
@@ -85,7 +81,6 @@
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
-import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
@@ -94,12 +89,6 @@
import android.view.View.OnClickListener;
import android.view.View.OnCreateContextMenuListener;
import android.view.WindowManager;
-import android.view.accessibility.AccessibilityEvent;
-import android.widget.Button;
-import android.widget.CheckBox;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
import android.widget.Toast;
import android.widget.Toolbar;
@@ -113,7 +102,6 @@
import com.android.contacts.common.CallUtil;
import com.android.contacts.common.ClipboardUtils;
import com.android.contacts.common.Collapser;
-import com.android.contacts.common.ContactPhotoManager;
import com.android.contacts.common.ContactsUtils;
import com.android.contacts.common.activity.RequestDesiredPermissionsActivity;
import com.android.contacts.common.activity.RequestPermissionsActivity;
@@ -135,7 +123,6 @@
import com.android.contacts.common.model.ContactLoader;
import com.android.contacts.common.model.RawContact;
import com.android.contacts.common.model.RawContactDeltaList;
-import com.android.contacts.common.model.ValuesDelta;
import com.android.contacts.common.model.account.AccountType;
import com.android.contacts.common.model.dataitem.CustomDataItem;
import com.android.contacts.common.model.dataitem.DataItem;
@@ -160,8 +147,6 @@
import com.android.contacts.common.util.UriUtils;
import com.android.contacts.common.util.ViewUtil;
import com.android.contacts.detail.ContactDisplayUtils;
-import com.android.contacts.editor.AggregationSuggestionEngine;
-import com.android.contacts.editor.AggregationSuggestionEngine.Suggestion;
import com.android.contacts.editor.ContactEditorFragment;
import com.android.contacts.editor.EditorIntents;
import com.android.contacts.editor.EditorUiUtils;
@@ -186,6 +171,7 @@
import com.android.contacts.widget.MultiShrinkScroller.MultiShrinkScrollerListener;
import com.android.contacts.widget.QuickContactImageView;
import com.android.contactsbind.HelpUtils;
+
import com.google.common.collect.Lists;
import java.util.ArrayList;
@@ -195,11 +181,8 @@
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.List;
import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;
/**
@@ -208,7 +191,7 @@
* {@link Intent#getSourceBounds()}.
*/
public class QuickContactActivity extends ContactsActivity implements
- AggregationSuggestionEngine.Listener, SplitContactConfirmationDialogFragment.Listener {
+ SplitContactConfirmationDialogFragment.Listener {
/**
* QuickContacts immediately takes up the full screen. All possible information is shown.
@@ -230,10 +213,7 @@
private static final String TAG = "QuickContact";
private static final String KEY_THEME_COLOR = "theme_color";
- private static final String KEY_IS_SUGGESTION_LIST_COLLAPSED = "is_suggestion_list_collapsed";
- private static final String KEY_SELECTED_SUGGESTION_CONTACTS = "selected_suggestion_contacts";
private static final String KEY_PREVIOUS_CONTACT_ID = "previous_contact_id";
- private static final String KEY_SUGGESTIONS_AUTO_SELECTED = "suggestions_auto_seleted";
private static final String KEY_SEND_TO_VOICE_MAIL_STATE = "sendToVoicemailState";
private static final String KEY_ARE_PHONE_OPTIONS_CHANGEABLE = "arePhoneOptionsChangable";
@@ -303,23 +283,7 @@
private ExpandingEntryCardView mAboutCard;
private ExpandingEntryCardView mPermissionExplanationCard;
- // Suggestion card.
- private boolean mShouldShowSuggestions = false;
- private CardView mCollapsedSuggestionCardView;
- private CardView mExpandSuggestionCardView;
- private View mCollapsedSuggestionHeader;
- private TextView mCollapsedSuggestionCardTitle;
- private TextView mExpandSuggestionCardTitle;
- private ImageView mSuggestionSummaryPhoto;
- private TextView mSuggestionForName;
- private TextView mSuggestionContactsNumber;
- private LinearLayout mSuggestionList;
- private Button mSuggestionsCancelButton;
- private Button mSuggestionsLinkButton;
- private boolean mIsSuggestionListCollapsed;
- private boolean mSuggestionsShouldAutoSelected = true;
private long mPreviousContactId = 0;
-
// Permission explanation card.
private boolean mShouldShowPermissionExplanation = false;
private String mPermissionExplanationCardSubHeader = "";
@@ -328,10 +292,6 @@
private AsyncTask<Void, Void, Cp2DataCardModel> mEntriesAndActionsTask;
private AsyncTask<Void, Void, Void> mRecentDataTask;
- private AggregationSuggestionEngine mAggregationSuggestionEngine;
- private List<Suggestion> mSuggestions;
-
- private TreeSet<Long> mSelectedAggregationIds = new TreeSet<>();
/**
* The last copy of Cp2DataCardModel that was passed to {@link #populateContactAndAboutCard}.
*/
@@ -535,211 +495,6 @@
}
};
- @Override
- public void onAggregationSuggestionChange() {
- if (!mShouldShowSuggestions) {
- return;
- }
- if (mAggregationSuggestionEngine == null) {
- return;
- }
- mSuggestions = mAggregationSuggestionEngine.getSuggestions();
- mCollapsedSuggestionCardView.setVisibility(View.GONE);
- mExpandSuggestionCardView.setVisibility(View.GONE);
- mSuggestionList.removeAllViews();
-
- if (mContactData == null) {
- return;
- }
-
- final String suggestionForName = mContactData.getDisplayName();
- final int suggestionNumber = mSuggestions.size();
-
- if (suggestionNumber <= 0) {
- mSelectedAggregationIds.clear();
- return;
- }
-
- ContactPhotoManager.DefaultImageRequest
- request = new ContactPhotoManager.DefaultImageRequest(
- suggestionForName, mContactData.getLookupKey(), ContactPhotoManager.TYPE_DEFAULT,
- /* isCircular */ true );
- final long photoId = mContactData.getPhotoId();
- final byte[] photoBytes = mContactData.getThumbnailPhotoBinaryData();
- if (photoBytes != null) {
- ContactPhotoManager.getInstance(this).loadThumbnail(mSuggestionSummaryPhoto, photoId,
- /* darkTheme */ false , /* isCircular */ true , request);
- } else {
- ContactPhotoManager.DEFAULT_AVATAR.applyDefaultImage(mSuggestionSummaryPhoto,
- -1, false, request);
- }
-
- final String suggestionTitle = getResources().getQuantityString(
- R.plurals.quickcontact_suggestion_card_title, suggestionNumber, suggestionNumber);
- mCollapsedSuggestionCardTitle.setText(suggestionTitle);
- mExpandSuggestionCardTitle.setText(suggestionTitle);
-
- mSuggestionForName.setText(suggestionForName);
- final int linkedContactsNumber = mContactData.getRawContacts().size();
- final String contactsInfo;
- final String accountName = mContactData.getRawContacts().get(0).getAccountName();
- if (linkedContactsNumber == 1 && accountName == null) {
- mSuggestionContactsNumber.setVisibility(View.INVISIBLE);
- }
- if (linkedContactsNumber == 1 && accountName != null) {
- contactsInfo = getResources().getString(R.string.contact_from_account_name,
- accountName);
- } else {
- contactsInfo = getResources().getString(
- R.string.quickcontact_contacts_number, linkedContactsNumber);
- }
- mSuggestionContactsNumber.setText(contactsInfo);
-
- final Set<Long> suggestionContactIds = new HashSet<>();
- for (Suggestion suggestion : mSuggestions) {
- mSuggestionList.addView(inflateSuggestionListView(suggestion));
- suggestionContactIds.add(suggestion.contactId);
- }
-
- if (mIsSuggestionListCollapsed) {
- collapseSuggestionList();
- } else {
- expandSuggestionList();
- }
-
- // Remove contact Ids that are not suggestions.
- final Set<Long> selectedSuggestionIds = com.google.common.collect.Sets.intersection(
- mSelectedAggregationIds, suggestionContactIds);
- mSelectedAggregationIds = new TreeSet<>(selectedSuggestionIds);
- if (!mSelectedAggregationIds.isEmpty()) {
- enableLinkButton();
- }
- }
-
- private void collapseSuggestionList() {
- mCollapsedSuggestionCardView.setVisibility(View.VISIBLE);
- mExpandSuggestionCardView.setVisibility(View.GONE);
- mIsSuggestionListCollapsed = true;
- }
-
- private void expandSuggestionList() {
- mCollapsedSuggestionCardView.setVisibility(View.GONE);
- mExpandSuggestionCardView.setVisibility(View.VISIBLE);
- mIsSuggestionListCollapsed = false;
- }
-
- private View inflateSuggestionListView(final Suggestion suggestion) {
- final LayoutInflater layoutInflater = LayoutInflater.from(this);
- final View suggestionView = layoutInflater.inflate(
- R.layout.quickcontact_suggestion_contact_item, null);
-
- ContactPhotoManager.DefaultImageRequest
- request = new ContactPhotoManager.DefaultImageRequest(
- suggestion.name, suggestion.lookupKey, ContactPhotoManager.TYPE_DEFAULT, /*
- isCircular */ true);
- final ImageView photo = (ImageView) suggestionView.findViewById(
- R.id.aggregation_suggestion_photo);
- if (suggestion.photo != null) {
- ContactPhotoManager.getInstance(this).loadThumbnail(photo, suggestion.photoId,
- /* darkTheme */ false, /* isCircular */ true, request);
- } else {
- ContactPhotoManager.DEFAULT_AVATAR.applyDefaultImage(photo, -1, false, request);
- }
-
- final TextView name = (TextView) suggestionView.findViewById(R.id.aggregation_suggestion_name);
- name.setText(suggestion.name);
-
- final TextView accountNameView = (TextView) suggestionView.findViewById(
- R.id.aggregation_suggestion_account_name);
- final String accountName = suggestion.rawContacts.get(0).accountName;
- if (!TextUtils.isEmpty(accountName)) {
- accountNameView.setText(
- getResources().getString(R.string.contact_from_account_name, accountName));
- } else {
- accountNameView.setVisibility(View.INVISIBLE);
- }
-
- final CheckBox checkbox = (CheckBox) suggestionView.findViewById(R.id.suggestion_checkbox);
- final int[][] stateSet = new int[][] {
- new int[] { android.R.attr.state_checked },
- new int[] { -android.R.attr.state_checked }
- };
- final int[] colors = new int[] { mColorFilterColor, mColorFilterColor };
- if (suggestion != null && suggestion.name != null) {
- checkbox.setContentDescription(suggestion.name + " " +
- getResources().getString(R.string.contact_from_account_name, accountName));
- }
- checkbox.setButtonTintList(new ColorStateList(stateSet, colors));
- checkbox.setChecked(mSuggestionsShouldAutoSelected ||
- mSelectedAggregationIds.contains(suggestion.contactId));
- if (checkbox.isChecked()) {
- mSelectedAggregationIds.add(suggestion.contactId);
- }
- checkbox.setTag(suggestion.contactId);
- checkbox.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- final CheckBox checkBox = (CheckBox) v;
- final Long contactId = (Long) checkBox.getTag();
- if (mSelectedAggregationIds.contains(mContactData.getId())) {
- mSelectedAggregationIds.remove(mContactData.getId());
- }
- if (checkBox.isChecked()) {
- mSelectedAggregationIds.add(contactId);
- if (mSelectedAggregationIds.size() >= 1) {
- enableLinkButton();
- }
- } else {
- mSelectedAggregationIds.remove(contactId);
- mSuggestionsShouldAutoSelected = false;
- if (mSelectedAggregationIds.isEmpty()) {
- disableLinkButton();
- }
- }
- }
- });
-
- return suggestionView;
- }
-
- private void enableLinkButton() {
- mSuggestionsLinkButton.setClickable(true);
- mSuggestionsLinkButton.getBackground().setColorFilter(mColorFilter);
- mSuggestionsLinkButton.setTextColor(
- ContextCompat.getColor(this, android.R.color.white));
- mSuggestionsLinkButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View view) {
- // Join selected contacts.
- if (!mSelectedAggregationIds.contains(mContactData.getId())) {
- mSelectedAggregationIds.add(mContactData.getId());
- }
-
- final Long[] contactIdsArray = mSelectedAggregationIds.toArray(
- new Long[mSelectedAggregationIds.size()]);
- final long[] contactIdsArray2 = new long[contactIdsArray.length];
- for (int i = 0; i < contactIdsArray.length; i++) {
- contactIdsArray2[i] = contactIdsArray[i];
- }
-
- final Intent intent = ContactSaveService.createJoinSeveralContactsIntent(
- QuickContactActivity.this, contactIdsArray2);
- QuickContactActivity.this.startService(intent);
-
- disableLinkButton();
- }
- });
- }
-
- private void disableLinkButton() {
- mSuggestionsLinkButton.setClickable(false);
- mSuggestionsLinkButton.getBackground().setColorFilter(
- ContextCompat.getColor(this, R.color.disabled_button_background),
- PorterDuff.Mode.SRC_ATOP);
- mSuggestionsLinkButton.setTextColor(
- ContextCompat.getColor(this, R.color.disabled_button_text));
- }
-
private interface ContextMenuIds {
static final int COPY_TEXT = 0;
static final int CLEAR_DEFAULT = 1;
@@ -1046,59 +801,6 @@
mPermissionExplanationCard =
(ExpandingEntryCardView) findViewById(R.id.permission_explanation_card);
- if (mShouldShowSuggestions) {
- mCollapsedSuggestionCardView = (CardView) findViewById(R.id.collapsed_suggestion_card);
- mExpandSuggestionCardView = (CardView) findViewById(R.id.expand_suggestion_card);
- mCollapsedSuggestionHeader = findViewById(R.id.collapsed_suggestion_header);
- mCollapsedSuggestionCardTitle = (TextView) findViewById(
- R.id.collapsed_suggestion_card_title);
- mExpandSuggestionCardTitle = (TextView) findViewById(R.id.expand_suggestion_card_title);
- mSuggestionSummaryPhoto = (ImageView) findViewById(R.id.suggestion_icon);
- mSuggestionForName = (TextView) findViewById(R.id.suggestion_for_name);
- mSuggestionContactsNumber = (TextView) findViewById(
- R.id.suggestion_for_contacts_number);
- mSuggestionList = (LinearLayout) findViewById(R.id.suggestion_list);
- mSuggestionsCancelButton = (Button) findViewById(R.id.cancel_button);
- mSuggestionsLinkButton = (Button) findViewById(R.id.link_button);
- if (savedInstanceState != null) {
- mIsSuggestionListCollapsed = savedInstanceState.getBoolean(
- KEY_IS_SUGGESTION_LIST_COLLAPSED, true);
- mPreviousContactId = savedInstanceState.getLong(KEY_PREVIOUS_CONTACT_ID);
- mSuggestionsShouldAutoSelected = savedInstanceState.getBoolean(
- KEY_SUGGESTIONS_AUTO_SELECTED, true);
- mSelectedAggregationIds = (TreeSet<Long>)
- savedInstanceState.getSerializable(KEY_SELECTED_SUGGESTION_CONTACTS);
- } else {
- mIsSuggestionListCollapsed = true;
- mSelectedAggregationIds.clear();
- }
- if (mSelectedAggregationIds.isEmpty()) {
- disableLinkButton();
- } else {
- enableLinkButton();
- }
- mCollapsedSuggestionHeader.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View view) {
- mCollapsedSuggestionCardView.setVisibility(View.GONE);
- mExpandSuggestionCardView.setVisibility(View.VISIBLE);
- mIsSuggestionListCollapsed = false;
- mExpandSuggestionCardTitle.requestFocus();
- mExpandSuggestionCardTitle.sendAccessibilityEvent(
- AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
- }
- });
-
- mSuggestionsCancelButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View view) {
- mCollapsedSuggestionCardView.setVisibility(View.VISIBLE);
- mExpandSuggestionCardView.setVisibility(View.GONE);
- mIsSuggestionListCollapsed = true;
- }
- });
- }
-
mPermissionExplanationCard.setOnClickListener(mEntryClickHandler);
mNoContactDetailsCard.setOnClickListener(mEntryClickHandler);
mContactCard.setOnClickListener(mEntryClickHandler);
@@ -1240,12 +942,7 @@
if (mColorFilter != null) {
savedInstanceState.putInt(KEY_THEME_COLOR, mColorFilterColor);
}
- savedInstanceState.putBoolean(KEY_IS_SUGGESTION_LIST_COLLAPSED, mIsSuggestionListCollapsed);
savedInstanceState.putLong(KEY_PREVIOUS_CONTACT_ID, mPreviousContactId);
- savedInstanceState.putBoolean(
- KEY_SUGGESTIONS_AUTO_SELECTED, mSuggestionsShouldAutoSelected);
- savedInstanceState.putSerializable(
- KEY_SELECTED_SUGGESTION_CONTACTS, mSelectedAggregationIds);
// Phone specific options
savedInstanceState.putBoolean(KEY_SEND_TO_VOICE_MAIL_STATE, mSendToVoicemailState);
@@ -1436,7 +1133,6 @@
private void bindDataToCards(Cp2DataCardModel cp2DataCardModel) {
startInteractionLoaders(cp2DataCardModel);
populateContactAndAboutCard(cp2DataCardModel, /* shouldAddPhoneticName */ true);
- populateSuggestionCard();
}
private void startInteractionLoaders(Cp2DataCardModel cp2DataCardModel) {
@@ -1549,53 +1245,6 @@
}
}
- private void populateSuggestionCard() {
- if (!mShouldShowSuggestions) {
- return;
- }
- // Initialize suggestion related view and data.
- if (mPreviousContactId != mContactData.getId()) {
- mCollapsedSuggestionCardView.setVisibility(View.GONE);
- mExpandSuggestionCardView.setVisibility(View.GONE);
- mIsSuggestionListCollapsed = true;
- mSuggestionsShouldAutoSelected = true;
- mSuggestionList.removeAllViews();
- }
-
- // Do not show the card when it's directory contact or invisible.
- if (DirectoryContactUtil.isDirectoryContact(mContactData)
- || InvisibleContactUtil.isInvisibleAndAddable(mContactData, this)) {
- return;
- }
-
- if (mAggregationSuggestionEngine == null) {
- mAggregationSuggestionEngine = new AggregationSuggestionEngine(this);
- mAggregationSuggestionEngine.setListener(this);
- mAggregationSuggestionEngine.setSuggestionsLimit(getResources().getInteger(
- R.integer.quickcontact_suggestions_limit));
- mAggregationSuggestionEngine.start();
- }
-
- mAggregationSuggestionEngine.setContactId(mContactData.getId());
- if (mPreviousContactId != 0
- && mPreviousContactId != mContactData.getId()) {
- // Clear selected Ids when listing suggestions for new contact Id.
- mSelectedAggregationIds.clear();
- }
- mPreviousContactId = mContactData.getId();
-
- // Trigger suggestion engine to compute suggestions.
- if (mContactData.getId() <= 0) {
- return;
- }
- final ContentValues values = new ContentValues();
- values.put(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,
- mContactData.getDisplayName());
- values.put(ContactsContract.CommonDataKinds.StructuredName.PHONETIC_FAMILY_NAME,
- mContactData.getPhoneticName());
- mAggregationSuggestionEngine.onNameChange(ValuesDelta.fromBefore(values));
- }
-
private void populateContactAndAboutCard(Cp2DataCardModel cp2DataCardModel,
boolean shouldAddPhoneticName) {
mCachedCp2DataCardModel = cp2DataCardModel;
@@ -2515,8 +2164,6 @@
if (imageViewDrawable == mPhotoView.getDrawable()) {
mHasComputedThemeColor = true;
setThemeColor(palette);
- // update color and photo in suggestion card
- onAggregationSuggestionChange();
}
}
}.execute();
@@ -2534,9 +2181,6 @@
mContactCard.setColorAndFilter(mColorFilterColor, mColorFilter);
mRecentCard.setColorAndFilter(mColorFilterColor, mColorFilter);
mAboutCard.setColorAndFilter(mColorFilterColor, mColorFilter);
- if (mShouldShowSuggestions) {
- mSuggestionsCancelButton.setTextColor(mColorFilterColor);
- }
}
private void updateStatusBarColor() {
@@ -2892,9 +2536,6 @@
@Override
public void onDestroy() {
super.onDestroy();
- if (mAggregationSuggestionEngine != null) {
- mAggregationSuggestionEngine.quit();
- }
}
/**
diff --git a/src/com/android/contacts/util/SharedPreferenceUtil.java b/src/com/android/contacts/util/SharedPreferenceUtil.java
index 2f899e3..80e4825 100644
--- a/src/com/android/contacts/util/SharedPreferenceUtil.java
+++ b/src/com/android/contacts/util/SharedPreferenceUtil.java
@@ -21,8 +21,13 @@
import android.telephony.SubscriptionInfo;
import android.telephony.TelephonyManager;
+import com.android.contacts.common.model.SimCard;
+
+import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
public class SharedPreferenceUtil {
@@ -45,6 +50,9 @@
private static final String PREFERENCE_KEY_IMPORTED_SIM_CARDS =
"importedSimCards";
+ private static final String PREFERENCE_KEY_DISMISSED_SIM_CARDS =
+ "dismissedSimCards";
+
public static boolean getHamburgerPromoDisplayedBefore(Context context) {
return getSharedPreferences(context)
.getBoolean(PREFERENCE_KEY_HAMBURGER_PROMO_DISPLAYED_BEFORE, false);
@@ -141,22 +149,49 @@
.putInt(buildSharedPrefsName(accountName), value + 1).apply();
}
- /**
- * Persist an identifier for a SIM card which has been successfully imported.
- *
- * @param simId an identifier for the SIM card this should be one of
- * {@link TelephonyManager#getSimSerialNumber()} or {@link SubscriptionInfo#getIccId()}
- * depending on API level. The source of the value should be consistent on a particular device
- */
- public static void addImportedSim(Context context, String simId) {
- final Set<String> current = new HashSet<>(getImportedSims(context));
- current.add(simId);
+ public static void persistSimStates(Context context, Collection<SimCard> sims) {
+ final Set<String> imported = new HashSet<>(getImportedSims(context));
+ final Set<String> dismissed = new HashSet<>(getDismissedSims(context));
+ for (SimCard sim : sims) {
+ if (sim.isImported()) {
+ imported.add(sim.getSimId());
+ } else {
+ imported.remove(sim.getSimId());
+ }
+ if (sim.isDismissed()) {
+ dismissed.add(sim.getSimId());
+ } else {
+ dismissed.remove(sim.getSimId());
+ }
+ }
getSharedPreferences(context).edit()
- .putStringSet(PREFERENCE_KEY_IMPORTED_SIM_CARDS, current).apply();
+ .putStringSet(PREFERENCE_KEY_IMPORTED_SIM_CARDS, imported)
+ .putStringSet(PREFERENCE_KEY_DISMISSED_SIM_CARDS, dismissed)
+ .apply();
}
- public static Set<String> getImportedSims(Context context) {
+ public static List<SimCard> restoreSimStates(Context context, List<SimCard> sims) {
+ final Set<String> imported = getImportedSims(context);
+ final Set<String> dismissed = getDismissedSims(context);
+ List<SimCard> result = new ArrayList<>();
+ for (SimCard sim : sims) {
+ result.add(sim.withImportAndDismissStates(imported.contains(sim.getSimId()),
+ dismissed.contains(sim.getSimId())));
+ }
+ return result;
+ }
+
+ private static Set<String> getImportedSims(Context context) {
return getSharedPreferences(context)
.getStringSet(PREFERENCE_KEY_IMPORTED_SIM_CARDS, Collections.<String>emptySet());
}
+
+ private static Set<String> getDismissedSims(Context context) {
+ return getSharedPreferences(context)
+ .getStringSet(PREFERENCE_KEY_DISMISSED_SIM_CARDS, Collections.<String>emptySet());
+ }
+
+ public static void clear(Context context) {
+ getSharedPreferences(context).edit().clear().commit();
+ }
}
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index 472ee1c..740e293 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -36,8 +36,7 @@
<uses-permission android:name="android.permission.READ_SOCIAL_STREAM" />
<application
- android:icon="@mipmap/ic_contacts_launcher_square"
- android:roundIcon="@mipmap/ic_contacts_launcher"
+ android:icon="@mipmap/ic_contacts_launcher"
android:label="@string/applicationLabel">
<uses-library android:name="android.test.runner" />
diff --git a/tests/res/xml/contacts_contactsdatakind.xml b/tests/res/xml/contacts_contactsdatakind.xml
index c7d3bd9..20c85ad 100644
--- a/tests/res/xml/contacts_contactsdatakind.xml
+++ b/tests/res/xml/contacts_contactsdatakind.xml
@@ -24,7 +24,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
accountType="com.android.contacts.tests.testauth.basic"
accountTypeLabel="@string/applicationLabel"
- accountTypeIcon="@mipmap/ic_contacts_launcher_square"
+ accountTypeIcon="@mipmap/ic_contacts_launcher"
>
<EditSchema
>
@@ -96,7 +96,7 @@
<ContactsDataKind
android:mimeType="vnd.android.cursor.item/vnd.contactstest.profile"
- android:icon="@mipmap/ic_contacts_launcher_square"
+ android:icon="@mipmap/ic_contacts_launcher"
android:summaryColumn="data2"
android:detailColumn="data3" />
diff --git a/tests/res/xml/test_basic_authenticator.xml b/tests/res/xml/test_basic_authenticator.xml
index 83bd135..40b9088 100644
--- a/tests/res/xml/test_basic_authenticator.xml
+++ b/tests/res/xml/test_basic_authenticator.xml
@@ -19,7 +19,7 @@
<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
android:accountType="com.android.contacts.tests.testauth.basic"
- android:icon="@mipmap/ic_contacts_launcher_square"
- android:smallIcon="@mipmap/ic_contacts_launcher_square"
+ android:icon="@mipmap/ic_contacts_launcher"
+ android:smallIcon="@mipmap/ic_contacts_launcher"
android:label="@string/applicationLabel"
/>
diff --git a/tests/src/com/android/contacts/tests/AdbHelpers.java b/tests/src/com/android/contacts/tests/AdbHelpers.java
index c7e2188..0024dd1 100644
--- a/tests/src/com/android/contacts/tests/AdbHelpers.java
+++ b/tests/src/com/android/contacts/tests/AdbHelpers.java
@@ -16,13 +16,17 @@
package com.android.contacts.tests;
import android.content.Context;
+import android.content.SharedPreferences;
import android.os.Build;
import android.os.Bundle;
+import android.preference.PreferenceManager;
import android.support.annotation.RequiresApi;
+import android.support.test.InstrumentationRegistry;
import android.util.Log;
import com.android.contacts.common.model.account.AccountWithDataSet;
import com.android.contacts.common.preference.ContactsPreferences;
+import com.android.contacts.util.SharedPreferenceUtil;
/**
* Contains utility methods that can be invoked directly from adb using RunMethodInstrumentation.
@@ -73,4 +77,17 @@
public static void clearDefaultAccount(Context context) {
new ContactsPreferences(context).clearDefaultAccount();
}
+
+ public static void clearPreferences(Context context) {
+ SharedPreferenceUtil.clear(context);
+ }
+
+ public static void dumpPreferences(Context context) {
+ Log.d(TAG, "preferences=" + getAppContext().getSharedPreferences(
+ getAppContext().getPackageName(), Context.MODE_PRIVATE).getAll());
+ }
+
+ private static Context getAppContext() {
+ return InstrumentationRegistry.getTargetContext();
+ }
}