diff options
Diffstat (limited to 'src/com/android/dialer/calllog/CallLogAdapter.java')
-rwxr-xr-x | src/com/android/dialer/calllog/CallLogAdapter.java | 153 |
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 + } } |