diff options
author | Rohit Yengisetty <rohit@cyngn.com> | 2016-02-11 18:24:45 -0800 |
---|---|---|
committer | Richard MacGregor <rmacgregor@cyngn.com> | 2016-04-08 09:14:44 -0700 |
commit | 9a7a6177f8e718ea227bdc47a05988b24e146102 (patch) | |
tree | a7d6ac5824b6694be1afa6341a44a5aad038ebd6 /src | |
parent | 407efb4fbd7543f014066f868fa1ec2fd5a51bf8 (diff) | |
download | packages_apps_InCallUI-9a7a6177f8e718ea227bdc47a05988b24e146102.tar.gz packages_apps_InCallUI-9a7a6177f8e718ea227bdc47a05988b24e146102.tar.bz2 packages_apps_InCallUI-9a7a6177f8e718ea227bdc47a05988b24e146102.zip |
Add LookupProvider to ContactInfoCache
This provides the ability to query a LookupProvider for information
about non-contact callers
Change-Id: I8b848d80ed77307b0359e41bacf908edb9854387
Diffstat (limited to 'src')
-rw-r--r-- | src/com/android/incallui/CallCardFragment.java | 85 | ||||
-rw-r--r-- | src/com/android/incallui/CallCardPresenter.java | 32 | ||||
-rw-r--r-- | src/com/android/incallui/ContactInfoCache.java | 128 |
3 files changed, 224 insertions, 21 deletions
diff --git a/src/com/android/incallui/CallCardFragment.java b/src/com/android/incallui/CallCardFragment.java index ecc26944..683b8d9c 100644 --- a/src/com/android/incallui/CallCardFragment.java +++ b/src/com/android/incallui/CallCardFragment.java @@ -21,6 +21,7 @@ import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.content.Context; +import android.content.res.Resources; import android.graphics.drawable.AnimationDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.GradientDrawable; @@ -41,7 +42,6 @@ import android.view.ViewPropertyAnimator; import android.view.ViewTreeObserver; import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.view.accessibility.AccessibilityEvent; -import android.view.accessibility.AccessibilityManager; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.widget.ImageButton; @@ -52,6 +52,7 @@ import android.widget.Toast; import com.android.contacts.common.util.MaterialColorMapUtils.MaterialPalette; import com.android.contacts.common.widget.FloatingActionButtonController; import com.android.phone.common.animation.AnimUtils; +import com.cyanogen.lookup.phonenumber.response.StatusCode; import java.util.List; @@ -144,6 +145,11 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr private View mManageConferenceCallButton; + private View mPhotoContainer; + private TextView mLookupStatusMessage; + private TextView mContactInfoAttribution; + private TextView mSpamInfoView; + // Dark number info bar private TextView mInCallMessageLabel; @@ -247,7 +253,6 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr Trace.endSection(); return view; } - @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); @@ -324,6 +329,11 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr mCallStateLabel.setElegantTextHeight(false); mCallSubject = (TextView) view.findViewById(R.id.callSubject); + mLookupStatusMessage = (TextView) view.findViewById(R.id.lookupStatusMessage); + mContactInfoAttribution = (TextView) view.findViewById(R.id.contactInfoAttribution); + mSpamInfoView = (TextView) view.findViewById(R.id.spamInfo); + mPhotoContainer = view.findViewById(R.id.call_card_content); + mRecordingTimeLabel = (TextView) view.findViewById(R.id.recordingTime); mRecordingIcon = (TextView) view.findViewById(R.id.recordingIcon); @@ -555,7 +565,9 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr */ @Override public void setPrimary(String number, String name, boolean nameIsNumber, String label, - Drawable photo, boolean isSipCall, boolean isForwarded, boolean isContactPhotoShown) { + Drawable photo, boolean isSipCall, boolean isForwarded, boolean isContactPhotoShown, + String providerName, Drawable providerLogo, boolean isLookupInProgress, + StatusCode lookupStatus, boolean showSpamInfo, int spamCount) { Log.d(this, "Setting primary call"); // set the name field. setPrimaryName(name, nameIsNumber); @@ -576,6 +588,14 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr showCallTypeLabel(isSipCall, isForwarded); setDrawableToImageView(mPhoto, photo, isContactPhotoShown); + + setLookupProviderStatus(isLookupInProgress, lookupStatus, providerName, providerLogo, + showSpamInfo, spamCount); + if (showSpamInfo) { + mPhoto.setVisibility(View.GONE); + mPhotoContainer.setBackgroundColor(getContext().getResources().getColor( + R.color.contact_info_spam_info_text_color, getContext().getTheme())); + } } @Override @@ -924,7 +944,7 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr // that switch drawables in the middle of the cross-fade animations. Just set the // photo directly instead. view.setImageDrawable(photo); - view.setVisibility(isVisible ? View.VISIBLE : View.GONE); + view.setVisibility(isVisible ? View.VISIBLE : View.GONE); } } @@ -1274,6 +1294,63 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr Toast.makeText(getContext(), R.string.note_sent, Toast.LENGTH_LONG).show(); } + public void setLookupProviderStatus(boolean isLookupInProgress, StatusCode lookupStatus, + String providerName, Drawable providerLogo, boolean showSpamInfo, int spamCount) { + Resources res = getResources(); + mSpamInfoView.setVisibility(showSpamInfo ? View.VISIBLE : View.GONE); + if (showSpamInfo) { + mSpamInfoView.setText(res.getQuantityString( + R.plurals.spam_count_text, spamCount, spamCount)); + } + + boolean showLookupStatus = false; + boolean showContactAttribution = false; + if (isLookupInProgress) { + mLookupStatusMessage.setText( + res.getString(R.string.caller_info_loading, providerName)); + showLookupStatus = true; + showContactAttribution = false; + + } else { + switch (lookupStatus) { + case SUCCESS: + mContactInfoAttribution.setText( + res.getString(R.string.powered_by_provider, providerName)); + int logoSize = res.getDimensionPixelSize(R.dimen.contact_info_attribution_logo_size); + int logoPadding = res.getDimensionPixelSize(R.dimen.contact_info_attribution_logo_padding); + providerLogo.setBounds(0, 0, logoSize, logoSize); + mContactInfoAttribution.setCompoundDrawablesRelative(providerLogo, null, null, null); + mContactInfoAttribution.setCompoundDrawablePadding(logoPadding); + showContactAttribution = true; + showLookupStatus = false; + break; + case FAIL: + mLookupStatusMessage.setText( + res.getString(R.string.caller_info_failure, providerName)); + showLookupStatus = true; + showContactAttribution = false; + break; + case NO_RESULT: + mLookupStatusMessage.setText( + res.getString(R.string.caller_info_no_result, providerName)); + showLookupStatus = true; + showContactAttribution = false; + break; + case CONFIG_ERROR: + mLookupStatusMessage.setText( + res.getString(R.string.caller_info_unauthenticated, providerName)); + showLookupStatus = true; + showContactAttribution = false; + break; + default: + showLookupStatus = false; + showContactAttribution = false; + } + } + mLookupStatusMessage.setVisibility(showLookupStatus ? View.VISIBLE : View.GONE); + mContactInfoAttribution.setVisibility(showContactAttribution ? View.VISIBLE : View.GONE); + } + public void onDialpadVisibilityChange(boolean isShown) { mIsDialpadShowing = isShown; updateFabPosition(); diff --git a/src/com/android/incallui/CallCardPresenter.java b/src/com/android/incallui/CallCardPresenter.java index 10056bef..355b0b15 100644 --- a/src/com/android/incallui/CallCardPresenter.java +++ b/src/com/android/incallui/CallCardPresenter.java @@ -17,8 +17,6 @@ package com.android.incallui; import android.Manifest; -import android.app.Activity; -import android.app.FragmentManager; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; @@ -47,9 +45,10 @@ import com.android.incallui.InCallPresenter.InCallStateListener; import com.android.incallui.InCallPresenter.IncomingCallListener; import com.android.incalluibind.ObjectFactory; +import com.cyanogen.lookup.phonenumber.response.StatusCode; +import com.google.common.base.Preconditions; import java.lang.ref.WeakReference; -import com.google.common.base.Preconditions; /** * Presenter for the Call Card Fragment. @@ -639,7 +638,8 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi> if (mPrimary == null) { // Clear the primary display info. - ui.setPrimary(null, null, false, null, null, false, false, false); + ui.setPrimary(null, null, false, null, null, false, false, false, null, null, false, + StatusCode.NULL, false, 0); return; } @@ -659,7 +659,14 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi> getConferencePhoto(mPrimary), false /* isSipCall */, false /* isForwarded */, - showContactPhoto); + showContactPhoto, + null, + null, + false, + StatusCode.NULL, + false, + 0); + } else if (mPrimaryContactInfo != null) { Log.d(TAG, "Update primary display info for " + mPrimaryContactInfo); @@ -700,10 +707,17 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi> mPrimaryContactInfo.photo, mPrimaryContactInfo.isSipCall, isForwarded, - showContactPhoto); + showContactPhoto, + mPrimaryContactInfo.lookupProviderName, + mPrimaryContactInfo.lookupProviderBadge, + mPrimaryContactInfo.isLookupInProgress, + mPrimaryContactInfo.lookupStatus, + mPrimaryContactInfo.isSpam, + mPrimaryContactInfo.spamCount); } else { // Clear the primary display info. - ui.setPrimary(null, null, false, null, null, false, false, false); + ui.setPrimary(null, null, false, null, null, false, false, false, null, null, false, + StatusCode.NULL, false, 0); } if (mEmergencyCallListener != null) { @@ -1004,7 +1018,9 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi> void setVisible(boolean on); void setCallCardVisible(boolean visible); void setPrimary(String number, String name, boolean nameIsNumber, String label, - Drawable photo, boolean isSipCall, boolean isForwarded, boolean isContactPhotoShown); + Drawable photo, boolean isSipCall, boolean isForwarded, boolean isContactPhotoShown, + String providerName, Drawable providerLogo, boolean isLookupInProgress, + StatusCode lookupStatus, boolean showSpamInfo, int spamCount); void setSecondary(boolean show, String name, boolean nameIsNumber, String label, String providerLabel, boolean isConference, boolean isVideoCall, boolean isFullscreen); diff --git a/src/com/android/incallui/ContactInfoCache.java b/src/com/android/incallui/ContactInfoCache.java index 90b63752..740466d8 100644 --- a/src/com/android/incallui/ContactInfoCache.java +++ b/src/com/android/incallui/ContactInfoCache.java @@ -16,27 +16,27 @@ package com.android.incallui; -import android.content.ComponentName; import android.content.Context; import android.graphics.Bitmap; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.AsyncTask; +import android.os.Handler; import android.os.Looper; import android.provider.ContactsContract; import android.provider.ContactsContract.Contacts; import android.provider.ContactsContract.DisplayNameSources; import android.provider.ContactsContract.CommonDataKinds.Phone; import android.telecom.TelecomManager; +import android.telephony.PhoneNumberUtils; +import android.telephony.TelephonyManager; import android.text.TextUtils; -import com.android.contacts.common.model.Contact; -import com.android.contacts.common.model.RawContact; import com.android.contacts.common.util.PhoneNumberHelper; -import com.android.contacts.common.util.UriUtils; import com.android.dialer.calllog.ContactInfo; import com.android.dialer.service.CachedNumberLookupService; import com.android.dialer.service.CachedNumberLookupService.CachedContactInfo; +import com.android.dialer.util.ImageUtils; import com.android.incallui.incallapi.InCallPluginInfo; import com.android.incallui.incallapi.InCallPluginInfoAsyncTask; import com.android.incallui.service.PhoneNumberService; @@ -45,16 +45,19 @@ import com.android.services.telephony.common.MoreStrings; import com.cyanogen.ambient.incall.extension.InCallContactInfo; import com.cyanogen.ambient.incall.util.InCallHelper; +import com.cyanogen.lookup.phonenumber.contract.LookupProvider; +import com.cyanogen.lookup.phonenumber.provider.LookupProviderImpl; +import com.cyanogen.lookup.phonenumber.request.LookupRequest; +import com.cyanogen.lookup.phonenumber.response.LookupResponse; +import com.cyanogen.lookup.phonenumber.response.StatusCode; + import com.google.common.base.Objects; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.Maps; import com.google.common.collect.Sets; -import com.google.common.base.Objects; -import com.google.common.base.Preconditions; import java.lang.ref.WeakReference; -import java.util.ArrayList; import java.util.List; import java.util.HashMap; import java.util.Set; @@ -77,9 +80,11 @@ public class ContactInfoCache implements ContactsAsyncHelper.OnImageLoadComplete private final Context mContext; private final PhoneNumberService mPhoneNumberService; private final CachedNumberLookupService mCachedNumberLookupService; + private final LookupProvider mLookupProvider; private final ConcurrentHashMap<String, ContactCacheEntry> mInfoMap = new ConcurrentHashMap(); private final HashMap<String, Set<ContactInfoCacheCallback>> mCallBacks = Maps.newHashMap(); private InCallPluginInfoAsyncTask mPluginInfoAsyncTask; + private Handler mMainHandler = new Handler(Looper.getMainLooper()); private static ContactInfoCache sCache = null; @@ -98,6 +103,12 @@ public class ContactInfoCache implements ContactsAsyncHelper.OnImageLoadComplete mPhoneNumberService = ObjectFactory.newPhoneNumberService(context); mCachedNumberLookupService = com.android.dialerbind.ObjectFactory.newCachedNumberLookupService(); + LookupProvider lookupProvider = new LookupProviderImpl(context); + if (lookupProvider.initialize()) { + mLookupProvider = lookupProvider; + } else { + mLookupProvider = null; + } } public ContactCacheEntry getInfo(String callId) { @@ -236,6 +247,8 @@ public class ContactInfoCache implements ContactsAsyncHelper.OnImageLoadComplete sendInfoNotifications(callId, cacheEntry); if (didLocalLookup) { + boolean clearCallbacks = true; + // Before issuing a request for more data from other services, we only check that the // contact wasn't found in the local DB. We don't check the if the cache entry already // has a name because we allow overriding cnap data with data from other services. @@ -244,13 +257,32 @@ public class ContactInfoCache implements ContactsAsyncHelper.OnImageLoadComplete final PhoneNumberServiceListener listener = new PhoneNumberServiceListener(callId); mPhoneNumberService.getPhoneNumberInfo(cacheEntry.number, listener, listener, isIncoming); - } else if (cacheEntry.displayPhotoUri != null) { + clearCallbacks = false; + } + + if (!callerInfo.contactExists && mLookupProvider != null) { + cacheEntry.isLookupInProgress = true; + cacheEntry.lookupProviderName = mLookupProvider.getDisplayName(); + String countryIso = ((TelephonyManager) mContext.getSystemService( + Context.TELEPHONY_SERVICE)).getSimCountryIso().toUpperCase(); + String numberE164 = + PhoneNumberUtils.formatNumberToE164(cacheEntry.number, countryIso); + LookupRequest request = new LookupRequest(numberE164, new LookupResultCallback(callId)); + mLookupProvider.fetchInfo(request); + sendInfoNotifications(callId, cacheEntry); + clearCallbacks = false; + } + + if (cacheEntry.displayPhotoUri != null) { Log.d(TAG, "Contact lookup. Local contact found, starting image load"); // Load the image with a callback to update the image state. // When the load is finished, onImageLoadComplete() will be called. ContactsAsyncHelper.startObtainPhotoAsync(TOKEN_UPDATE_PHOTO_FOR_CALL_STATE, mContext, cacheEntry.displayPhotoUri, ContactInfoCache.this, callId); - } else { + clearCallbacks = false; + } + + if (clearCallbacks) { if (callerInfo.contactExists) { Log.d(TAG, "Contact lookup done. Local contact found, no image."); } else { @@ -391,6 +423,76 @@ public class ContactInfoCache implements ContactsAsyncHelper.OnImageLoadComplete } } + class LookupResultCallback implements LookupRequest.Callback { + + private String mCallId; + private ImageUtils.BitmapLoadRequest mBitmapLoadRequest; + + public LookupResultCallback(String callId) { + mCallId = callId; + } + + @Override + public void onNewInfo(LookupRequest lookupRequest, final LookupResponse response) { + final ContactCacheEntry oldEntry = mInfoMap.get(mCallId); + oldEntry.isLookupInProgress = false; + oldEntry.lookupStatus = response.mStatusCode; + + if (response == null) { + oldEntry.lookupProviderName = mLookupProvider.getDisplayName(); + oldEntry.lookupStatus = StatusCode.FAIL; + mMainHandler.post(new Runnable() { + @Override + public void run() { + sendInfoNotifications(mCallId, oldEntry); + clearCallbacks(mCallId); + } + }); + + } else { + final ContactCacheEntry newEntry = new ContactCacheEntry(); + newEntry.lookupProviderBadge = response.mAttributionLogo; + newEntry.lookupProviderName = response.mProviderName; + + if (response.mStatusCode == StatusCode.SUCCESS) { + newEntry.lookupStatus = StatusCode.SUCCESS; + newEntry.name = response.mName; + newEntry.number = response.mNumber; + newEntry.location = response.mAddress; + newEntry.spamCount = response.mSpamCount; + newEntry.isSpam = response.mIsSpam; + if (!TextUtils.isEmpty(response.mPhotoUrl)) { + newEntry.displayPhotoUri = Uri.parse(response.mPhotoUrl); + } + } + + mMainHandler.post(new Runnable() { + @Override + public void run() { + mInfoMap.put(mCallId, newEntry); + sendInfoNotifications(mCallId, newEntry); + + if (TextUtils.isEmpty(response.mPhotoUrl) || newEntry.isSpam) { + // don't expect another callback if there is no image or if spam + clearCallbacks(mCallId); + } else { + mBitmapLoadRequest = ImageUtils.getBitmapFromUrl(mContext, response.mPhotoUrl, + new ImageUtils.ImageLoadCallback<Bitmap>() { + @Override + public void onCompleted(Exception e, Bitmap result) { + if (result != null) { + onImageLoadComplete(TOKEN_UPDATE_PHOTO_FOR_CALL_STATE, + null, result, mCallId); + } + } + }); + } + } + }); + } + } + } + /** * Implemented for ContactsAsyncHelper.OnImageLoadCompleteListener interface. * make sure that the call state is reflected after the image is loaded. @@ -672,6 +774,14 @@ public class ContactInfoCache implements ContactsAsyncHelper.OnImageLoadComplete public boolean isEmergencyNumber; public List<InCallPluginInfo> inCallPluginInfoList; + // following fields are pertinent only when there is an active LookupProvider + public int spamCount; + public boolean isSpam = false; + public String lookupProviderName; + public Drawable lookupProviderBadge; + public boolean isLookupInProgress = false; + public StatusCode lookupStatus = StatusCode.NULL; + public ContactCacheEntry() {} public ContactCacheEntry(ContactCacheEntry entry) { |