Merge "Import translations. DO NOT MERGE" into ub-contactsdialer-h-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index e87b846..8dc6e4d 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -16,8 +16,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.contacts"
- android:versionCode="10609"
- android:versionName="1.6.9">
+ android:versionCode="10610"
+ android:versionName="1.6.10">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="25" />
diff --git a/res/layout/people_activity.xml b/res/layout/people_activity.xml
index 8810af0..978f47a 100644
--- a/res/layout/people_activity.xml
+++ b/res/layout/people_activity.xml
@@ -20,6 +20,14 @@
android:layout_width="match_parent"
android:layout_height="match_parent" >
+ <!-- This is kind of a hack. Really we should be able to put the ContactsUnavailableFragment
+ into contacts_list_container but that causes issues with the fragment back stack
+ on older API levels -->
+ <FrameLayout
+ android:id="@+id/contacts_unavailable_container"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent" />
+
<FrameLayout
android:id="@+id/contacts_list_container"
android:layout_height="match_parent"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index dfef475..3ad9d89 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -218,13 +218,13 @@
<string name="menu_unredirect_calls_to_vm">Unroute to voicemail</string>
<!-- Warning dialog contents after users select to delete a ReadOnly contact. [CHAR LIMIT=NONE] -->
- <string name="readOnlyContactWarning">Contacts from your read-only accounts cannot be deleted, but they can be hidden.</string>
+ <string name="readOnlyContactWarning">This contact is read-only. It can\'t be deleted, but you can hide it.</string>
<!-- Positive button text of the warning dialog contents after users select to delete a ReadOnly contact. [CHAR LIMIT=30]-->
- <string name="readOnlyContactWarning_positive_button">Hide</string>
+ <string name="readOnlyContactWarning_positive_button">Hide Contact</string>
<!-- Warning dialog contents after users selects to delete a contact with ReadOnly and Writable sources. [CHAR LIMIT=NONE]-->
- <string name="readOnlyContactDeleteConfirmation">The contact to be deleted has details from multiple accounts. Details from read-only accounts will be hidden, not deleted.</string>
+ <string name="readOnlyContactDeleteConfirmation">Read-only accounts in this contact will be hidden, not deleted.</string>
<!-- Confirmation dialog. Shown after user selects to delete one writable contact [CHAR LIMIT=NONE] -->
<string name="single_delete_confirmation">Delete this contact?</string>
@@ -1877,11 +1877,10 @@
<string name="account_sync_off">Account sync is off. Tap to turn on.</string>
<!-- Title of dialog to turn auto-sync on [CHAR LIMIT=100] -->
- <string name="turn_auto_sync_on_dialog_title">Turn auto-sync on?</string>
+ <string name="turn_auto_sync_on_dialog_title">Turn on auto-sync?</string>
<!-- Text of dialog to turn auto-sync on [CHAR LIMIT=500] -->
- <string name="turn_auto_sync_on_dialog_body">Changes you make to all apps and accounts,
- not just Contacts, will be synchronized between the web and your devices.</string>
+ <string name="turn_auto_sync_on_dialog_body">Changes you make to all apps and accounts, not just Google Contacts, will be kept up to date between the web and your devices.</string>
<!-- Confirm button text for dialog to turn auto-sync on [CHAR LIMIT=30] -->
<string name="turn_auto_sync_on_dialog_confirm_btn">Turn on</string>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index ad0915e..ab1a4ba 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -91,6 +91,8 @@
<item name="list_item_avatar_offset_top">-1dp</item>
<!-- Favorites -->
<item name="favorites_padding_bottom">0dip</item>
+ <!-- Popup menu -->
+ <item name="android:popupMenuStyle">@style/PopupMenuStyle</item>
</style>
<style name="PeopleActivityTheme" parent="@style/PeopleThemeAppCompat">
@@ -166,6 +168,17 @@
<!-- Favorites -->
<item name="favorites_padding_bottom">0dip</item>
<item name="drawerArrowStyle">@style/DrawerArrowStyle</item>
+ <!-- Popup menu -->
+ <item name="android:popupMenuStyle">@style/PopupMenuStyleAppCompat</item>
+ <item name="popupMenuStyle">@style/PopupMenuStyleAppCompat</item>
+ </style>
+
+ <style name="PopupMenuStyle" parent="@android:style/Widget.PopupMenu">
+ <item name="android:popupBackground">@android:color/white</item>
+ </style>
+
+ <style name="PopupMenuStyleAppCompat" parent="Widget.AppCompat.PopupMenu">
+ <item name="android:popupBackground">@android:color/white</item>
</style>
<style name="ContactsActionButtonStyle" parent="Widget.AppCompat.ActionButton">
diff --git a/src/com/android/contacts/ContactSaveService.java b/src/com/android/contacts/ContactSaveService.java
index 853e676..d2a65a8 100755
--- a/src/com/android/contacts/ContactSaveService.java
+++ b/src/com/android/contacts/ContactSaveService.java
@@ -49,6 +49,7 @@
import android.support.annotation.Nullable;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.os.ResultReceiver;
+import android.telephony.SubscriptionInfo;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
@@ -62,6 +63,7 @@
import com.android.contacts.common.model.RawContactDelta;
import com.android.contacts.common.model.RawContactDeltaList;
import com.android.contacts.common.model.RawContactModifier;
+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;
@@ -70,11 +72,11 @@
import com.android.contacts.compat.PinnedPositionsCompat;
import com.android.contacts.util.ContactPhotoUtils;
import com.android.contactsbind.FeedbackHelper;
-
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -149,10 +151,16 @@
public static final String ACTION_IMPORT_FROM_SIM = "importFromSim";
public static final String EXTRA_SIM_CONTACTS = "simContacts";
+ public static final String EXTRA_SIM_SUBSCRIPTION_ID = "simSubscriptionId";
+
+ // For debugging and testing what happens when requests are queued up.
+ public static final String ACTION_SLEEP = "sleep";
+ public static final String EXTRA_SLEEP_DURATION = "sleepDuration";
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 BROADCAST_SERVICE_STATE_CHANGED = "serviceStateChanged";
public static final String EXTRA_RESULT_CODE = "resultCode";
public static final String EXTRA_RESULT_COUNT = "count";
@@ -197,6 +205,9 @@
private static final CopyOnWriteArrayList<Listener> sListeners =
new CopyOnWriteArrayList<Listener>();
+ // Holds the current state of the service
+ private static final State sState = new State();
+
private Handler mMainHandler;
private GroupsDao mGroupsDao;
private SimContactDao mSimContactDao;
@@ -230,6 +241,15 @@
sListeners.remove(listener);
}
+ public static State getState() {
+ return sState;
+ }
+
+ private void notifyStateChanged() {
+ LocalBroadcastManager.getInstance(this)
+ .sendBroadcast(new Intent(BROADCAST_SERVICE_STATE_CHANGED));
+ }
+
/**
* Returns true if the ContactSaveService was started successfully and false if an exception
* was thrown and a Toast error message was displayed.
@@ -279,8 +299,17 @@
return getApplicationContext().getSystemService(name);
}
+ // Parent classes Javadoc says not to override this method but we're doing it just to update
+ // our state which should be OK since we're still doing the work in onHandleIntent
@Override
- protected void onHandleIntent(Intent intent) {
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ sState.onStart(intent);
+ notifyStateChanged();
+ return super.onStartCommand(intent, flags, startId);
+ }
+
+ @Override
+ protected void onHandleIntent(final Intent intent) {
if (intent == null) {
Log.d(TAG, "onHandleIntent: could not handle null intent");
return;
@@ -332,7 +361,12 @@
undo(intent);
} else if (ACTION_IMPORT_FROM_SIM.equals(action)) {
importFromSim(intent);
+ } else if (ACTION_SLEEP.equals(action)) {
+ sleepForDebugging(intent);
}
+
+ sState.onFinish(intent);
+ notifyStateChanged();
}
/**
@@ -1688,36 +1722,82 @@
operations.add(builder.build());
}
- public static Intent createImportFromSimIntent(@NonNull Context context,
- @NonNull ArrayList<SimContact> contacts, @NonNull AccountWithDataSet targetAccount,
- @Nullable Bundle callbackData) {
+ /**
+ * Returns an intent that can be used to import the contacts into targetAccount.
+ *
+ * @param context context to use for creating the intent
+ * @param subscriptionId the subscriptionId of the SIM card that is being imported. See
+ * {@link SubscriptionInfo#getSubscriptionId()}. Upon completion the
+ * SIM for that subscription ID will be marked as imported
+ * @param contacts the contacts to import
+ * @param targetAccount the account import the contacts into
+ */
+ public static Intent createImportFromSimIntent(Context context, int subscriptionId,
+ ArrayList<SimContact> contacts, AccountWithDataSet targetAccount) {
return new Intent(context, ContactSaveService.class)
.setAction(ACTION_IMPORT_FROM_SIM)
.putExtra(EXTRA_SIM_CONTACTS, contacts)
- .putExtra(EXTRA_ACCOUNT, targetAccount)
- .putExtra(EXTRA_CALLBACK_DATA, callbackData);
+ .putExtra(EXTRA_SIM_SUBSCRIPTION_ID, subscriptionId)
+ .putExtra(EXTRA_ACCOUNT, targetAccount);
}
private void importFromSim(Intent intent) {
final Intent result = new Intent(BROADCAST_SIM_IMPORT_COMPLETE)
.putExtra(EXTRA_OPERATION_REQUESTED_AT_TIME, System.currentTimeMillis());
+ final int subscriptionId = intent.getIntExtra(EXTRA_SIM_SUBSCRIPTION_ID,
+ SimCard.NO_SUBSCRIPTION_ID);
try {
final AccountWithDataSet targetAccount = intent.getParcelableExtra(EXTRA_ACCOUNT);
final ArrayList<SimContact> contacts =
intent.getParcelableArrayListExtra(EXTRA_SIM_CONTACTS);
mSimContactDao.importContacts(contacts, targetAccount);
+
+ // Update the imported state of the SIM card that was imported
+ final SimCard sim = mSimContactDao.getSimBySubscriptionId(subscriptionId);
+ if (sim != null) {
+ mSimContactDao.persistSimState(sim.withImportedState(true));
+ }
+
// notify success
LocalBroadcastManager.getInstance(this).sendBroadcast(result
.putExtra(EXTRA_RESULT_COUNT, contacts.size())
.putExtra(EXTRA_RESULT_CODE, RESULT_SUCCESS)
- .putExtra(EXTRA_CALLBACK_DATA, intent.getBundleExtra(EXTRA_CALLBACK_DATA)));
+ .putExtra(EXTRA_SIM_SUBSCRIPTION_ID, subscriptionId));
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "importFromSim completed successfully");
}
} catch (RemoteException|OperationApplicationException e) {
FeedbackHelper.sendFeedback(this, TAG, "Failed to import contacts from SIM card", e);
LocalBroadcastManager.getInstance(this).sendBroadcast(result
- .putExtra(EXTRA_RESULT_CODE, RESULT_FAILURE));
+ .putExtra(EXTRA_RESULT_CODE, RESULT_FAILURE)
+ .putExtra(EXTRA_SIM_SUBSCRIPTION_ID, subscriptionId));
+ }
+ }
+
+ /**
+ * Returns an intent that can start this service and cause it to sleep for the specified time.
+ *
+ * This exists purely for debugging and manual testing. Since this service uses a single thread
+ * it is useful to have a way to test behavior when work is queued up and most of the other
+ * operations complete too quickly to simulate that under normal conditions.
+ */
+ public static Intent createSleepIntent(Context context, long millis) {
+ return new Intent(context, ContactSaveService.class).setAction(ACTION_SLEEP)
+ .putExtra(EXTRA_SLEEP_DURATION, millis);
+ }
+
+ private void sleepForDebugging(Intent intent) {
+ long duration = intent.getLongExtra(EXTRA_SLEEP_DURATION, 1000);
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "sleeping for " + duration + "ms");
+ }
+ try {
+ Thread.sleep(duration);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "finished sleeping");
}
}
@@ -1874,4 +1954,62 @@
return contentResolver.delete(groupUri, null, null);
}
}
+
+ /**
+ * Keeps track of which operations have been requested but have not yet finished for this
+ * service.
+ */
+ public static class State {
+ private final CopyOnWriteArrayList<Intent> mPending;
+
+ public State() {
+ mPending = new CopyOnWriteArrayList<>();
+ }
+
+ public State(Collection<Intent> pendingActions) {
+ mPending = new CopyOnWriteArrayList<>(pendingActions);
+ }
+
+ public boolean isIdle() {
+ return mPending.isEmpty();
+ }
+
+ public Intent getCurrentIntent() {
+ return mPending.isEmpty() ? null : mPending.get(0);
+ }
+
+ /**
+ * Returns the first intent requested that has the specified action or null if no intent
+ * with that action has been requested.
+ */
+ public Intent getNextIntentWithAction(String action) {
+ for (Intent intent : mPending) {
+ if (action.equals(intent.getAction())) {
+ return intent;
+ }
+ }
+ return null;
+ }
+
+ public boolean isActionPending(String action) {
+ return getNextIntentWithAction(action) != null;
+ }
+
+ private void onFinish(Intent intent) {
+ if (mPending.isEmpty()) {
+ return;
+ }
+ final String action = mPending.get(0).getAction();
+ if (action.equals(intent.getAction())) {
+ mPending.remove(0);
+ }
+ }
+
+ private void onStart(Intent intent) {
+ if (intent.getAction() == null) {
+ return;
+ }
+ mPending.add(intent);
+ }
+ }
}
diff --git a/src/com/android/contacts/SimImportFragment.java b/src/com/android/contacts/SimImportFragment.java
index 2bd4bac..d9030a8 100644
--- a/src/com/android/contacts/SimImportFragment.java
+++ b/src/com/android/contacts/SimImportFragment.java
@@ -65,8 +65,6 @@
private static final String KEY_SELECTED_IDS = "selectedIds";
private static final String ARG_SUBSCRIPTION_ID = "subscriptionId";
- public static final String CALLBACK_KEY_SUBSCRIPTION_ID = "simSubscriptionId";
-
private ContactsPreferences mPreferences;
private AccountTypeManager mAccountTypeManager;
private SimContactAdapter mAdapter;
@@ -221,11 +219,10 @@
}
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(), callbackData));
+ .createImportFromSimIntent(getContext(), mSubscriptionId,
+ mAdapter.getSelectedContacts(),
+ mAccountHeaderPresenter.getCurrentAccount()));
}
@Override
diff --git a/src/com/android/contacts/activities/ContactEditorSpringBoardActivity.java b/src/com/android/contacts/activities/ContactEditorSpringBoardActivity.java
index 3d47b8f..9e39c5b 100644
--- a/src/com/android/contacts/activities/ContactEditorSpringBoardActivity.java
+++ b/src/com/android/contacts/activities/ContactEditorSpringBoardActivity.java
@@ -15,6 +15,8 @@
import com.android.contacts.AppCompatContactsActivity;
import com.android.contacts.R;
import com.android.contacts.common.activity.RequestPermissionsActivity;
+import com.android.contacts.common.logging.EditorEvent;
+import com.android.contacts.common.logging.Logger;
import com.android.contacts.common.model.AccountTypeManager;
import com.android.contacts.common.util.ImplicitIntentsUtil;
import com.android.contacts.common.util.MaterialColorMapUtils.MaterialPalette;
@@ -108,6 +110,8 @@
// Go straight to editor if we're passed a raw contact Uri.
if (ContactsContract.AUTHORITY.equals(authority) &&
RawContacts.CONTENT_ITEM_TYPE.equals(type)) {
+ Logger.logEditorEvent(
+ EditorEvent.EventType.SHOW_RAW_CONTACT_PICKER, /* numberRawContacts */ 0);
final long rawContactId = ContentUris.parseId(mUri);
startEditorAndForwardExtras(getIntentForRawContact(rawContactId));
} else if (android.provider.Contacts.AUTHORITY.equals(authority)) {
@@ -169,6 +173,8 @@
* the editor is started normally and handles creation of a new writable raw contact.
*/
private void loadEditor() {
+ Logger.logEditorEvent(
+ EditorEvent.EventType.SHOW_RAW_CONTACT_PICKER, /* numberRawContacts */ 0);
final Intent intent;
if (mHasWritableAccount) {
intent = getIntentForRawContact(mResult.rawContacts.get(mWritableAccountPosition).id);
diff --git a/src/com/android/contacts/activities/PeopleActivity.java b/src/com/android/contacts/activities/PeopleActivity.java
index 4532833..c2198bb 100644
--- a/src/com/android/contacts/activities/PeopleActivity.java
+++ b/src/com/android/contacts/activities/PeopleActivity.java
@@ -107,7 +107,6 @@
private View mFloatingActionButtonContainer;
private boolean wasLastFabAnimationScaleIn = false;
- private ContactsUnavailableFragment mContactsUnavailableFragment;
private ProviderStatusWatcher mProviderStatusWatcher;
private Integer mProviderStatus;
@@ -219,24 +218,6 @@
return (mProviderStatus != null) && mProviderStatus.equals(ProviderStatus.STATUS_NORMAL);
}
- /**
- * Initialize fragments that are (or may not be) in the layout.
- *
- * For the fragments that are in the layout, we initialize them in
- * {@link #createViewsAndFragments()} after inflating the layout.
- *
- * However, the {@link ContactsUnavailableFragment} is a special fragment which may not
- * be in the layout, so we have to do the initialization here.
- *
- * The ContactsUnavailableFragment is always created at runtime.
- */
- @Override
- public void onAttachFragment(Fragment fragment) {
- if (fragment instanceof ContactsUnavailableFragment) {
- mContactsUnavailableFragment = (ContactsUnavailableFragment)fragment;
- }
- }
-
@Override
protected void onCreate(Bundle savedState) {
if (Log.isLoggable(Constants.PERFORMANCE_TAG, Log.DEBUG)) {
@@ -562,27 +543,27 @@
// actually at least one real account (not "local" account) on device.
if (shouldShowList()) {
if (mAllFragment != null) {
- transaction.show(mAllFragment);
+ final Fragment unavailableFragment = fragmentManager
+ .findFragmentByTag(TAG_UNAVAILABLE);
+ if (unavailableFragment != null) {
+ transaction.remove(unavailableFragment);
+ }
+ if (mAllFragment.isHidden()) {
+ transaction.show(mAllFragment);
+ }
mAllFragment.setContactsAvailable(areContactsAvailable());
mAllFragment.setEnabled(true);
}
- if (mContactsUnavailableFragment != null) {
- transaction.hide(mContactsUnavailableFragment);
- }
} else {
// Setting up the page so that the user can still use the app
// even without an account.
if (mAllFragment != null) {
mAllFragment.setEnabled(false);
- transaction.hide(mAllFragment);
}
- if (mContactsUnavailableFragment == null) {
- mContactsUnavailableFragment = new ContactsUnavailableFragment();
- transaction.add(R.id.contacts_list_container, mContactsUnavailableFragment,
- TAG_UNAVAILABLE);
- }
- transaction.show(mContactsUnavailableFragment);
- mContactsUnavailableFragment.updateStatus(mProviderStatus);
+ final ContactsUnavailableFragment fragment = new ContactsUnavailableFragment();
+ transaction.hide(mAllFragment);
+ transaction.replace(R.id.contacts_unavailable_container, fragment, TAG_UNAVAILABLE);
+ fragment.updateStatus(mProviderStatus);
}
if (!transaction.isEmpty()) {
transaction.commit();
diff --git a/src/com/android/contacts/common/database/SimContactDao.java b/src/com/android/contacts/common/database/SimContactDao.java
index 89b4a3f..8805c52 100644
--- a/src/com/android/contacts/common/database/SimContactDao.java
+++ b/src/com/android/contacts/common/database/SimContactDao.java
@@ -71,6 +71,10 @@
// to work on any phone.
private static final int IMPORT_MAX_BATCH_SIZE = 300;
+ // How many SIM contacts to consider in a single query. This prevents hitting the SQLite
+ // query parameter limit.
+ static final int QUERY_MAX_BATCH_SIZE = 100;
+
// 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;
@@ -196,9 +200,9 @@
public Map<AccountWithDataSet, Set<SimContact>> findAccountsOfExistingSimContacts(
List<SimContact> contacts) {
final Map<AccountWithDataSet, Set<SimContact>> result = new ArrayMap<>();
- for (int i = 0; i < contacts.size(); i += IMPORT_MAX_BATCH_SIZE) {
+ for (int i = 0; i < contacts.size(); i += QUERY_MAX_BATCH_SIZE) {
findAccountsOfExistingSimContacts(
- contacts.subList(i, Math.min(contacts.size(), i + IMPORT_MAX_BATCH_SIZE)),
+ contacts.subList(i, Math.min(contacts.size(), i + QUERY_MAX_BATCH_SIZE)),
result);
}
return result;
@@ -381,16 +385,16 @@
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(
+ .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(
+ .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),
@@ -403,7 +407,7 @@
// 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 {
+ public static class DebugImpl extends SimContactDao {
private List<SimCard> mSimCards = new ArrayList<>();
private SparseArray<SimCard> mCardsBySubscription = new SparseArray<>();
@@ -445,9 +449,6 @@
// Query used for detecting existing contacts that may match a SimContact.
private static final class DataQuery {
- // How many SIM contacts to consider in a single query. This prevents hitting the SQLite
- // query parameter limit.
- static final int MAX_BATCH_SIZE = 100;
public static final String[] PROJECTION = new String[] {
ContactsContract.Data.RAW_CONTACT_ID, Phone.NUMBER, Phone.DISPLAY_NAME
diff --git a/src/com/android/contacts/common/logging/EditorEvent.java b/src/com/android/contacts/common/logging/EditorEvent.java
new file mode 100644
index 0000000..e5b42f8
--- /dev/null
+++ b/src/com/android/contacts/common/logging/EditorEvent.java
@@ -0,0 +1,40 @@
+/*
+ * 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.logging;
+
+import com.google.common.base.MoreObjects;
+
+public class EditorEvent {
+
+ /** The editor event type that is logged. */
+ public int eventType;
+
+ /** The number of raw contacts shown in the raw contacts picker. */
+ public int numberRawContacts;
+
+ public static final class EventType {
+ public static final int UNKNOWN = 0;
+ public static final int SHOW_RAW_CONTACT_PICKER = 1;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("eventType", eventType)
+ .add("numberRawContacts", numberRawContacts)
+ .toString();
+ }
+}
diff --git a/src/com/android/contacts/common/logging/Logger.java b/src/com/android/contacts/common/logging/Logger.java
index 68cbbbb..cb75ca9 100644
--- a/src/com/android/contacts/common/logging/Logger.java
+++ b/src/com/android/contacts/common/logging/Logger.java
@@ -96,8 +96,19 @@
}
}
+ public static void logEditorEvent(int eventType, int numberRawContacts) {
+ final Logger logger = getInstance();
+ if (logger != null) {
+ final EditorEvent event = new EditorEvent();
+ event.eventType = eventType;
+ event.numberRawContacts = numberRawContacts;
+ logger.logEditorEventImpl(event);
+ }
+ }
+
public abstract void logScreenViewImpl(int screenType, int previousScreenType);
public abstract void logSearchEventImpl(SearchState searchState);
public abstract void logListEventImpl(ListEvent event);
public abstract void logQuickContactEventImpl(QuickContactEvent event);
+ public abstract void logEditorEventImpl(EditorEvent event);
}
diff --git a/src/com/android/contacts/editor/PickRawContactDialogFragment.java b/src/com/android/contacts/editor/PickRawContactDialogFragment.java
index dd4eb30..1136f82 100644
--- a/src/com/android/contacts/editor/PickRawContactDialogFragment.java
+++ b/src/com/android/contacts/editor/PickRawContactDialogFragment.java
@@ -17,6 +17,8 @@
import com.android.contacts.R;
import com.android.contacts.common.ContactPhotoManager;
+import com.android.contacts.common.logging.EditorEvent;
+import com.android.contacts.common.logging.Logger;
import com.android.contacts.common.model.AccountTypeManager;
import com.android.contacts.common.model.account.AccountDisplayInfo;
import com.android.contacts.common.model.account.AccountDisplayInfoFactory;
@@ -181,6 +183,10 @@
}
});
builder.setCancelable(true);
+ if (savedInstanceState == null) {
+ Logger.logEditorEvent(EditorEvent.EventType.SHOW_RAW_CONTACT_PICKER,
+ /* numberRawContacts */ mAdapter.getCount());
+ }
return builder.create();
}
diff --git a/src/com/android/contacts/quickcontact/QuickContactActivity.java b/src/com/android/contacts/quickcontact/QuickContactActivity.java
index 52c66d5..f8d7436 100644
--- a/src/com/android/contacts/quickcontact/QuickContactActivity.java
+++ b/src/com/android/contacts/quickcontact/QuickContactActivity.java
@@ -908,7 +908,7 @@
} else if (requestCode == REQUEST_CODE_JOIN) {
// Ignore failed requests
if (resultCode != Activity.RESULT_OK) {
- processIntent(data);
+ return;
}
if (data != null) {
joinAggregate(ContentUris.parseId(data.getData()));