summaryrefslogtreecommitdiffstats
path: root/src/com/android/dialer/calllog/CallLogAdapter.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/dialer/calllog/CallLogAdapter.java')
-rwxr-xr-xsrc/com/android/dialer/calllog/CallLogAdapter.java153
1 files changed, 128 insertions, 25 deletions
diff --git a/src/com/android/dialer/calllog/CallLogAdapter.java b/src/com/android/dialer/calllog/CallLogAdapter.java
index 65e149a47..01b07b68f 100755
--- a/src/com/android/dialer/calllog/CallLogAdapter.java
+++ b/src/com/android/dialer/calllog/CallLogAdapter.java
@@ -20,16 +20,20 @@ import android.accounts.Account;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
+import android.content.Loader;
import android.content.res.Resources;
import android.database.Cursor;
+import android.database.sqlite.SQLiteFullException;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.provider.CallLog.Calls;
+import android.provider.ContactsContract;
import android.provider.ContactsContract.PhoneLookup;
import android.telecom.PhoneAccountHandle;
import android.telephony.PhoneNumberUtils;
import android.telephony.SubscriptionManager;
import android.text.TextUtils;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.AccessibilityDelegate;
@@ -37,6 +41,8 @@ import android.view.ViewGroup;
import android.view.ViewStub;
import android.view.ViewTreeObserver;
import android.view.accessibility.AccessibilityEvent;
+import android.widget.AbsListView;
+import android.widget.AbsListView.OnScrollListener;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
@@ -45,6 +51,8 @@ import com.android.common.widget.GroupingListAdapter;
import com.android.contacts.common.CallUtil;
import com.android.contacts.common.ContactPhotoManager;
import com.android.contacts.common.ContactPhotoManager.DefaultImageRequest;
+import com.android.contacts.common.model.Contact;
+import com.android.contacts.common.model.ContactLoader;
import com.android.contacts.common.util.UriUtils;
import com.android.dialer.DialtactsActivity;
import com.android.dialer.PhoneCallDetails;
@@ -57,6 +65,7 @@ import com.android.dialer.calllog.CallLogAdapterHelper.NumberWithCountryIso;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Objects;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
@@ -64,8 +73,10 @@ import java.util.LinkedList;
* Adapter class to fill in data for the Call Log.
*/
public class CallLogAdapter extends GroupingListAdapter
- implements CallLogAdapterHelper.Callback, CallLogGroupBuilder.GroupCreator {
+ implements CallLogAdapterHelper.Callback, CallLogGroupBuilder.GroupCreator,
+ OnScrollListener {
+ private static final String TAG = CallLogAdapter.class.getSimpleName();
private static final int VOICEMAIL_TRANSCRIPTION_MAX_LINES = 10;
/** The enumeration of {@link android.os.AsyncTask} objects used in this class. */
@@ -225,7 +236,6 @@ public class CallLogAdapter extends GroupingListAdapter
Toast.LENGTH_SHORT);
Resources resources = mContext.getResources();
- CallTypeHelper callTypeHelper = new CallTypeHelper(resources);
mCallLogBackgroundColor = resources.getColor(R.color.background_dialer_list_items);
mExpandedBackgroundColor = resources.getColor(R.color.call_log_expanded_background_color);
mExpandedTranslationZ = resources.getDimension(R.dimen.call_log_expanded_translation_z);
@@ -235,7 +245,7 @@ public class CallLogAdapter extends GroupingListAdapter
mAdapterHelper = new CallLogAdapterHelper(context, this,
contactInfoHelper, mPhoneNumberHelper);
PhoneCallDetailsHelper phoneCallDetailsHelper = new PhoneCallDetailsHelper(
- resources, callTypeHelper, new PhoneNumberUtilsWrapper());
+ mContext, resources, new PhoneNumberUtilsWrapper());
mCallLogViewsHelper =
new CallLogListItemHelper(
phoneCallDetailsHelper, mPhoneNumberHelper, resources);
@@ -463,7 +473,10 @@ public class CallLogAdapter extends GroupingListAdapter
Calls.DURATION_TYPE_ACTIVE, subId, operator);
}
- mCallLogViewsHelper.setPhoneCallDetails(mContext, views, details);
+ if (!mAdapterHelper.isBusy()) {
+ // Only update views when ListView's scroll state is not SCROLL_STATE_FLING.
+ mCallLogViewsHelper.setPhoneCallDetails(mContext, views, details);
+ }
int contactType = ContactPhotoManager.TYPE_DEFAULT;
@@ -529,10 +542,8 @@ public class CallLogAdapter extends GroupingListAdapter
* @return The day group for the call.
*/
private int getDayGroupForCall(long callId) {
- if (mDayGroups.containsKey(callId)) {
- return mDayGroups.get(callId);
- }
- return CallLogGroupBuilder.DAY_GROUP_NONE;
+ Integer result = mDayGroups.get(callId);
+ return result == null ? CallLogGroupBuilder.DAY_GROUP_NONE : result.intValue();
}
/**
* Determines if a call log row with the given Id is expanded.
@@ -736,7 +747,7 @@ public class CallLogAdapter extends GroupingListAdapter
}
protected void bindBadge(
- View view, ContactInfo info, final PhoneCallDetails details, int callType) {
+ View view, final ContactInfo info, final PhoneCallDetails details, int callType) {
// Do not show badge in call log.
if (!mIsCallLog) {
final ViewStub stub = (ViewStub) view.findViewById(R.id.link_stub);
@@ -749,14 +760,30 @@ public class CallLogAdapter extends GroupingListAdapter
mBadgeText = (TextView) inflated.findViewById(R.id.badge_text);
}
- mBadgeContainer.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- final Intent intent =
- DialtactsActivity.getAddNumberToContactIntent(details.number);
- mContext.startActivity(intent);
- }
- });
+ mBadgeContainer.setVisibility(View.VISIBLE);
+ mBadgeImageView = (ImageView) mBadgeContainer.findViewById(R.id.badge_image);
+ mBadgeText = (TextView) mBadgeContainer.findViewById(R.id.badge_text);
+
+ final View clickableArea = mBadgeContainer.findViewById(R.id.badge_link_container);
+ if (clickableArea != null) {
+ clickableArea.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ // If no lookup uri is provided, we need to rely on what information
+ // we have available; namely the phone number and name.
+ if (info.lookupUri == null) {
+ final Intent intent =
+ DialtactsActivity.getAddToContactIntent(details.name,
+ details.number,
+ details.numberType);
+ DialerUtils.startActivityWithErrorToast(mContext, intent,
+ R.string.add_contact_not_available);
+ } else {
+ addContactFromLookupUri(info.lookupUri);
+ }
+ }
+ });
+ }
mBadgeImageView.setImageResource(R.drawable.ic_person_add_24dp);
mBadgeText.setText(R.string.recentCalls_addToContact);
} else {
@@ -835,14 +862,18 @@ public class CallLogAdapter extends GroupingListAdapter
if (!needsUpdate) return;
- if (countryIso == null) {
- mContext.getContentResolver().update(Calls.CONTENT_URI_WITH_VOICEMAIL, values,
- Calls.NUMBER + " = ? AND " + Calls.COUNTRY_ISO + " IS NULL",
- new String[]{ number });
- } else {
- mContext.getContentResolver().update(Calls.CONTENT_URI_WITH_VOICEMAIL, values,
- Calls.NUMBER + " = ? AND " + Calls.COUNTRY_ISO + " = ?",
- new String[]{ number, countryIso });
+ try {
+ if (countryIso == null) {
+ mContext.getContentResolver().update(Calls.CONTENT_URI_WITH_VOICEMAIL, values,
+ Calls.NUMBER + " = ? AND " + Calls.COUNTRY_ISO + " IS NULL",
+ new String[]{ number });
+ } else {
+ mContext.getContentResolver().update(Calls.CONTENT_URI_WITH_VOICEMAIL, values,
+ Calls.NUMBER + " = ? AND " + Calls.COUNTRY_ISO + " = ?",
+ new String[]{ number, countryIso });
+ }
+ } catch (SQLiteFullException e) {
+ Log.e(TAG, "Unable to update contact info in call log db", e);
}
}
@@ -1079,4 +1110,76 @@ public class CallLogAdapter extends GroupingListAdapter
public void setQueryString(String filter) {
mFilterString = filter;
}
+
+ /**
+ * Invokes the "add contact" activity given the expanded contact information stored in a
+ * lookup URI. This can include, for example, address and website information.
+ *
+ * @param lookupUri The lookup URI.
+ */
+ private void addContactFromLookupUri(Uri lookupUri) {
+ Contact contactToSave = ContactLoader.parseEncodedContactEntity(lookupUri);
+ if (contactToSave == null) {
+ return;
+ }
+
+ // Note: This code mirrors code in Contacts/QuickContactsActivity.
+ final Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
+ intent.setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE);
+
+ ArrayList<ContentValues> values = contactToSave.getContentValues();
+ // Only pre-fill the name field if the provided display name is an nickname
+ // or better (e.g. structured name, nickname)
+ if (contactToSave.getDisplayNameSource()
+ >= ContactsContract.DisplayNameSources.NICKNAME) {
+ intent.putExtra(ContactsContract.Intents.Insert.NAME,
+ contactToSave.getDisplayName());
+ } else if (contactToSave.getDisplayNameSource()
+ == ContactsContract.DisplayNameSources.ORGANIZATION) {
+ // This is probably an organization. Instead of copying the organization
+ // name into a name entry, copy it into the organization entry. This
+ // way we will still consider the contact an organization.
+ final ContentValues organization = new ContentValues();
+ organization.put(ContactsContract.CommonDataKinds.Organization.COMPANY,
+ contactToSave.getDisplayName());
+ organization.put(ContactsContract.Data.MIMETYPE,
+ ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE);
+ values.add(organization);
+ }
+
+ // Last time used and times used are aggregated values from the usage stat
+ // table. They need to be removed from data values so the SQL table can insert
+ // properly
+ for (ContentValues value : values) {
+ value.remove(ContactsContract.Data.LAST_TIME_USED);
+ value.remove(ContactsContract.Data.TIMES_USED);
+ }
+ intent.putExtra(ContactsContract.Intents.Insert.DATA, values);
+
+ DialerUtils.startActivityWithErrorToast(mContext, intent,
+ R.string.add_contact_not_available);
+ }
+
+ @Override
+ public void onScrollStateChanged(AbsListView view, int scrollState) {
+ switch (scrollState) {
+ case OnScrollListener.SCROLL_STATE_IDLE:
+ mAdapterHelper.setBusy(false);
+ dataSetChanged();
+ break;
+ case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
+ mAdapterHelper.setBusy(false);
+ break;
+ case OnScrollListener.SCROLL_STATE_FLING:
+ // Do not update views when scroll state is SCROLL_STATE_FLING
+ mAdapterHelper.setBusy(true);
+ break;
+ }
+ }
+
+ @Override
+ public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
+ int totalItemCount) {
+ // no-op
+ }
}