From 37aa2f3d402bdb233d3c922fcde4f9aa6a262d68 Mon Sep 17 00:00:00 2001 From: Nancy Chen Date: Wed, 25 Nov 2015 11:20:17 -0800 Subject: Adapt TelecomCallLogCache to pre-MSIM. TelecomCallLogCache creates a mapping between PhoneAccount and per-SIM information like voicemail number which is not relevant pre-LMr1. Create a compatibility classes so that MSIM functionality is factored out pre-LMr1. Bug: 25776171 Change-Id: I67b012110829121dffa42d542aa0395d683fa78b --- src/com/android/dialer/calllog/CallLogAdapter.java | 18 +-- .../dialer/calllog/CallLogListItemHelper.java | 12 +- .../dialer/calllog/CallLogListItemViewHolder.java | 32 ++--- .../dialer/calllog/CallLogQueryHandler.java | 1 - .../android/dialer/calllog/PhoneAccountUtils.java | 1 - .../dialer/calllog/PhoneCallDetailsHelper.java | 13 +- .../dialer/calllog/TelecomCallLogCache.java | 145 --------------------- .../dialer/calllog/calllogcache/CallLogCache.java | 96 ++++++++++++++ .../calllog/calllogcache/CallLogCacheLollipop.java | 73 +++++++++++ .../calllogcache/CallLogCacheLollipopMr1.java | 110 ++++++++++++++++ .../dialer/calllog/TestTelecomCallLogCache.java | 26 +++- 11 files changed, 344 insertions(+), 183 deletions(-) delete mode 100644 src/com/android/dialer/calllog/TelecomCallLogCache.java create mode 100644 src/com/android/dialer/calllog/calllogcache/CallLogCache.java create mode 100644 src/com/android/dialer/calllog/calllogcache/CallLogCacheLollipop.java create mode 100644 src/com/android/dialer/calllog/calllogcache/CallLogCacheLollipopMr1.java diff --git a/src/com/android/dialer/calllog/CallLogAdapter.java b/src/com/android/dialer/calllog/CallLogAdapter.java index ea2dbd246..6f015651c 100644 --- a/src/com/android/dialer/calllog/CallLogAdapter.java +++ b/src/com/android/dialer/calllog/CallLogAdapter.java @@ -45,6 +45,7 @@ import com.android.contacts.common.preference.ContactsPreferences; import com.android.contacts.common.util.PermissionsUtil; import com.android.dialer.PhoneCallDetails; import com.android.dialer.R; +import com.android.dialer.calllog.calllogcache.CallLogCache; import com.android.dialer.contactinfo.ContactInfoCache; import com.android.dialer.contactinfo.ContactInfoCache.OnContactInfoChangedListener; import com.android.dialer.database.FilteredNumberAsyncQueryHandler; @@ -131,8 +132,8 @@ public class CallLogAdapter extends GroupingListAdapter /** Instance of helper class for managing views. */ private final CallLogListItemHelper mCallLogListItemHelper; - /** Cache for repeated requests to TelecomManager. */ - protected final TelecomCallLogCache mTelecomCallLogCache; + /** Cache for repeated requests to Telecom/Telephony. */ + protected final CallLogCache mCallLogCache; /** Helper to group call log entries. */ private final CallLogGroupBuilder mCallLogGroupBuilder; @@ -260,11 +261,12 @@ public class CallLogAdapter extends GroupingListAdapter Resources resources = mContext.getResources(); CallTypeHelper callTypeHelper = new CallTypeHelper(resources); - mTelecomCallLogCache = new TelecomCallLogCache(mContext); + mCallLogCache = CallLogCache.getCallLogCache(mContext); + PhoneCallDetailsHelper phoneCallDetailsHelper = - new PhoneCallDetailsHelper(mContext, resources, mTelecomCallLogCache); + new PhoneCallDetailsHelper(mContext, resources, mCallLogCache); mCallLogListItemHelper = - new CallLogListItemHelper(phoneCallDetailsHelper, resources, mTelecomCallLogCache); + new CallLogListItemHelper(phoneCallDetailsHelper, resources, mCallLogCache); mCallLogGroupBuilder = new CallLogGroupBuilder(this); mFilteredNumberAsyncQueryHandler = new FilteredNumberAsyncQueryHandler(mContext.getContentResolver()); @@ -331,7 +333,7 @@ public class CallLogAdapter extends GroupingListAdapter @VisibleForTesting /* package */ void pauseCache() { mContactInfoCache.stop(); - mTelecomCallLogCache.reset(); + mCallLogCache.reset(); } @Override @@ -360,7 +362,7 @@ public class CallLogAdapter extends GroupingListAdapter view, mContext, mExpandCollapseListener, - mTelecomCallLogCache, + mCallLogCache, mCallLogListItemHelper, mVoicemailPlaybackPresenter, mFilteredNumberAsyncQueryHandler, @@ -451,7 +453,7 @@ public class CallLogAdapter extends GroupingListAdapter final String countryIso = c.getString(CallLogQuery.COUNTRY_ISO); final ContactInfo cachedContactInfo = ContactInfoHelper.getContactInfo(c); final boolean isVoicemailNumber = - mTelecomCallLogCache.isVoicemailNumber(accountHandle, number); + mCallLogCache.isVoicemailNumber(accountHandle, number); // Note: Binding of the action buttons is done as required in configureActionViews when the // user expands the actions ViewStub. diff --git a/src/com/android/dialer/calllog/CallLogListItemHelper.java b/src/com/android/dialer/calllog/CallLogListItemHelper.java index fb2bab8cc..5d2bc8591 100644 --- a/src/com/android/dialer/calllog/CallLogListItemHelper.java +++ b/src/com/android/dialer/calllog/CallLogListItemHelper.java @@ -25,6 +25,7 @@ import android.util.Log; import com.android.dialer.PhoneCallDetails; import com.android.dialer.util.AppCompatConstants; import com.android.dialer.R; +import com.android.dialer.calllog.calllogcache.CallLogCache; /** * Helper class to fill in the views of a call log entry. @@ -36,21 +37,22 @@ import com.android.dialer.R; private final PhoneCallDetailsHelper mPhoneCallDetailsHelper; /** Resources to look up strings. */ private final Resources mResources; - private final TelecomCallLogCache mTelecomCallLogCache; + private final CallLogCache mCallLogCache; /** * Creates a new helper instance. * * @param phoneCallDetailsHelper used to set the details of a phone call - * @param phoneNumberHelper used to process phone number + * @param resources The object from which resources can be retrieved + * @param callLogCache A cache for values retrieved from telecom/telephony */ public CallLogListItemHelper( PhoneCallDetailsHelper phoneCallDetailsHelper, Resources resources, - TelecomCallLogCache telecomCallLogCache) { + CallLogCache callLogCache) { mPhoneCallDetailsHelper = phoneCallDetailsHelper; mResources = resources; - mTelecomCallLogCache = telecomCallLogCache; + mCallLogCache = callLogCache; } /** @@ -187,7 +189,7 @@ import com.android.dialer.R; } int stringID = getCallDescriptionStringID(details.callTypes, details.isRead); - String accountLabel = mTelecomCallLogCache.getAccountLabel(details.accountHandle); + String accountLabel = mCallLogCache.getAccountLabel(details.accountHandle); // Use chosen string resource to build up the message. CharSequence onAccountLabel = accountLabel == null diff --git a/src/com/android/dialer/calllog/CallLogListItemViewHolder.java b/src/com/android/dialer/calllog/CallLogListItemViewHolder.java index 88af54785..d6cb1d433 100644 --- a/src/com/android/dialer/calllog/CallLogListItemViewHolder.java +++ b/src/com/android/dialer/calllog/CallLogListItemViewHolder.java @@ -49,6 +49,7 @@ import com.android.contacts.common.testing.NeededForTesting; import com.android.contacts.common.util.UriUtils; import com.android.dialer.DialtactsActivity; import com.android.dialer.R; +import com.android.dialer.calllog.calllogcache.CallLogCache; import com.android.dialer.database.FilteredNumberAsyncQueryHandler; import com.android.dialer.filterednumber.BlockNumberDialogFragment; import com.android.dialer.filterednumber.FilteredNumbersUtil; @@ -189,7 +190,7 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder public ContactInfo info; private final Context mContext; - private final TelecomCallLogCache mTelecomCallLogCache; + private final CallLogCache mCallLogCache; private final CallLogListItemHelper mCallLogListItemHelper; private final VoicemailPlaybackPresenter mVoicemailPlaybackPresenter; private final FilteredNumberAsyncQueryHandler mFilteredNumberAsyncQueryHandler; @@ -203,7 +204,7 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder private CallLogListItemViewHolder( Context context, View.OnClickListener expandCollapseListener, - TelecomCallLogCache telecomCallLogCache, + CallLogCache callLogCache, CallLogListItemHelper callLogListItemHelper, VoicemailPlaybackPresenter voicemailPlaybackPresenter, FilteredNumberAsyncQueryHandler filteredNumberAsyncQueryHandler, @@ -219,7 +220,7 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder mContext = context; mExpandCollapseListener = expandCollapseListener; - mTelecomCallLogCache = telecomCallLogCache; + mCallLogCache = callLogCache; mCallLogListItemHelper = callLogListItemHelper; mVoicemailPlaybackPresenter = voicemailPlaybackPresenter; mFilteredNumberAsyncQueryHandler = filteredNumberAsyncQueryHandler; @@ -253,7 +254,7 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder View view, Context context, View.OnClickListener expandCollapseListener, - TelecomCallLogCache telecomCallLogCache, + CallLogCache callLogCache, CallLogListItemHelper callLogListItemHelper, VoicemailPlaybackPresenter voicemailPlaybackPresenter, FilteredNumberAsyncQueryHandler filteredNumberAsyncQueryHandler, @@ -262,7 +263,7 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder return new CallLogListItemViewHolder( context, expandCollapseListener, - telecomCallLogCache, + callLogCache, callLogListItemHelper, voicemailPlaybackPresenter, filteredNumberAsyncQueryHandler, @@ -300,7 +301,7 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder // 3) Number is a SIP address if (PhoneNumberUtil.canPlaceCallsTo(number, numberPresentation) - && !mTelecomCallLogCache.isVoicemailNumber(accountHandle, number) + && !mCallLogCache.isVoicemailNumber(accountHandle, number) && !PhoneNumberUtil.isSipNumber(number)) { menu.add(ContextMenu.NONE, R.id.context_menu_edit_before_call, ContextMenu.NONE, R.string.action_edit_number_before_call) @@ -421,7 +422,7 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder // Treat as normal list item; show call button, if possible. if (PhoneNumberUtil.canPlaceCallsTo(number, numberPresentation)) { boolean isVoicemailNumber = - mTelecomCallLogCache.isVoicemailNumber(accountHandle, number); + mCallLogCache.isVoicemailNumber(accountHandle, number); if (isVoicemailNumber) { // Call to generic voicemail number, in case there are multiple accounts. primaryActionButtonView.setTag( @@ -470,7 +471,7 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder } // If one of the calls had video capabilities, show the video call button. - if (mTelecomCallLogCache.isVideoEnabled() && canPlaceCallToNumber && + if (mCallLogCache.isVideoEnabled() && canPlaceCallToNumber && phoneCallDetailsViews.callTypeIcons.isVideoShown()) { videoCallButtonView.setTag(IntentProvider.getReturnVideoCallIntentProvider(number)); videoCallButtonView.setVisibility(View.VISIBLE); @@ -524,9 +525,9 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder mCallLogListItemHelper.setActionContentDescriptions(this); boolean supportsCallSubject = - mTelecomCallLogCache.doesAccountSupportCallSubject(accountHandle); + mCallLogCache.doesAccountSupportCallSubject(accountHandle); boolean isVoicemailNumber = - mTelecomCallLogCache.isVoicemailNumber(accountHandle, number); + mCallLogCache.isVoicemailNumber(accountHandle, number); callWithNoteButtonView.setVisibility( supportsCallSubject && !isVoicemailNumber ? View.VISIBLE : View.GONE); } @@ -572,7 +573,7 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder public void updatePhoto() { quickContactView.assignContactUri(info.lookupUri); - final boolean isVoicemail = mTelecomCallLogCache.isVoicemailNumber(accountHandle, number); + final boolean isVoicemail = mCallLogCache.isVoicemailNumber(accountHandle, number); int contactType = ContactPhotoManager.TYPE_DEFAULT; if (isVoicemail) { contactType = ContactPhotoManager.TYPE_VOICEMAIL; @@ -628,15 +629,16 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder @NeededForTesting public static CallLogListItemViewHolder createForTest(Context context) { Resources resources = context.getResources(); - TelecomCallLogCache telecomCallLogCache = new TelecomCallLogCache(context); + CallLogCache callLogCache = + CallLogCache.getCallLogCache(context); PhoneCallDetailsHelper phoneCallDetailsHelper = new PhoneCallDetailsHelper( - context, resources, telecomCallLogCache); + context, resources, callLogCache); CallLogListItemViewHolder viewHolder = new CallLogListItemViewHolder( context, null /* expandCollapseListener */, - telecomCallLogCache, - new CallLogListItemHelper(phoneCallDetailsHelper, resources, telecomCallLogCache), + callLogCache, + new CallLogListItemHelper(phoneCallDetailsHelper, resources, callLogCache), null /* voicemailPlaybackPresenter */, null /* filteredNumberAsyncQueryHandler */, null /* filteredNumberDialogCallback */, diff --git a/src/com/android/dialer/calllog/CallLogQueryHandler.java b/src/com/android/dialer/calllog/CallLogQueryHandler.java index d99284698..be2e40de4 100644 --- a/src/com/android/dialer/calllog/CallLogQueryHandler.java +++ b/src/com/android/dialer/calllog/CallLogQueryHandler.java @@ -38,7 +38,6 @@ import android.util.Log; import com.android.contacts.common.compat.SdkVersionOverride; import com.android.contacts.common.database.NoNullCursorAsyncQueryHandler; import com.android.contacts.common.util.PermissionsUtil; -import com.android.dialer.filterednumber.FilteredNumbersUtil; import com.android.dialer.util.AppCompatConstants; import com.android.dialer.util.TelecomUtil; import com.android.dialer.voicemail.VoicemailStatusHelperImpl; diff --git a/src/com/android/dialer/calllog/PhoneAccountUtils.java b/src/com/android/dialer/calllog/PhoneAccountUtils.java index ceadabce2..7dc329237 100644 --- a/src/com/android/dialer/calllog/PhoneAccountUtils.java +++ b/src/com/android/dialer/calllog/PhoneAccountUtils.java @@ -23,7 +23,6 @@ import android.telecom.PhoneAccountHandle; import android.telecom.TelecomManager; import android.text.TextUtils; -import com.android.contacts.common.util.PermissionsUtil; import com.android.dialer.util.TelecomUtil; import java.util.ArrayList; diff --git a/src/com/android/dialer/calllog/PhoneCallDetailsHelper.java b/src/com/android/dialer/calllog/PhoneCallDetailsHelper.java index 4d201b07b..e6b850872 100644 --- a/src/com/android/dialer/calllog/PhoneCallDetailsHelper.java +++ b/src/com/android/dialer/calllog/PhoneCallDetailsHelper.java @@ -35,6 +35,7 @@ import com.android.contacts.common.testing.NeededForTesting; import com.android.contacts.common.util.PhoneNumberHelper; import com.android.dialer.PhoneCallDetails; import com.android.dialer.R; +import com.android.dialer.calllog.calllogcache.CallLogCache; import com.android.dialer.util.DialerUtils; import java.util.ArrayList; @@ -55,7 +56,7 @@ public class PhoneCallDetailsHelper { private CharSequence mPhoneTypeLabelForTest; - private final TelecomCallLogCache mTelecomCallLogCache; + private final CallLogCache mCallLogCache; /** Calendar used to construct dates */ private final Calendar mCalendar; @@ -75,10 +76,10 @@ public class PhoneCallDetailsHelper { public PhoneCallDetailsHelper( Context context, Resources resources, - TelecomCallLogCache telecomCallLogCache) { + CallLogCache callLogCache) { mContext = context; mResources = resources; - mTelecomCallLogCache = telecomCallLogCache; + mCallLogCache = callLogCache; mCalendar = Calendar.getInstance(); } @@ -115,12 +116,12 @@ public class PhoneCallDetailsHelper { setCallCountAndDate(views, callCount, callLocationAndDate); // Set the account label if it exists. - String accountLabel = mTelecomCallLogCache.getAccountLabel(details.accountHandle); + String accountLabel = mCallLogCache.getAccountLabel(details.accountHandle); if (accountLabel != null) { views.callAccountLabel.setVisibility(View.VISIBLE); views.callAccountLabel.setText(accountLabel); - int color = mTelecomCallLogCache.getAccountColor(details.accountHandle); + int color = mCallLogCache.getAccountColor(details.accountHandle); if (color == PhoneAccount.NO_HIGHLIGHT_COLOR) { int defaultColor = R.color.dialtacts_secondary_text_color; views.callAccountLabel.setTextColor(mContext.getResources().getColor(defaultColor)); @@ -198,7 +199,7 @@ public class PhoneCallDetailsHelper { // Only show a label if the number is shown and it is not a SIP address. if (!TextUtils.isEmpty(details.number) && !PhoneNumberHelper.isUriNumber(details.number.toString()) - && !mTelecomCallLogCache.isVoicemailNumber(details.accountHandle, details.number)) { + && !mCallLogCache.isVoicemailNumber(details.accountHandle, details.number)) { if (TextUtils.isEmpty(details.namePrimary) && !TextUtils.isEmpty(details.geocode)) { numberFormattedLabel = details.geocode; diff --git a/src/com/android/dialer/calllog/TelecomCallLogCache.java b/src/com/android/dialer/calllog/TelecomCallLogCache.java deleted file mode 100644 index 6363b91ec..000000000 --- a/src/com/android/dialer/calllog/TelecomCallLogCache.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (C) 2013 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.dialer.calllog; - -import android.content.Context; -import android.provider.CallLog; -import android.telecom.PhoneAccount; -import android.telecom.PhoneAccountHandle; -import android.telecom.TelecomManager; -import android.text.TextUtils; -import android.util.Log; -import android.util.Pair; - -import com.android.contacts.common.CallUtil; -import com.android.contacts.common.util.PhoneNumberHelper; -import com.android.dialer.util.PhoneNumberUtil; -import com.google.common.collect.Sets; - -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -/** - * Keeps a cache of recently made queries to the Telecom process. The aim of this cache is to - * reduce the number of cross-process requests to TelecomManager, which can negatively affect - * performance. - * - * This is designed with the specific use case of the {@link CallLogAdapter} in mind. - */ -public class TelecomCallLogCache { - private final Context mContext; - - // Maps from a phone-account/number pair to a boolean because multiple numbers could return true - // for the voicemail number if those numbers are not pre-normalized. - // TODO: Dialer should be fixed so as not to check isVoicemail() so often but at the time of - // this writing, that was a much larger undertaking than creating this cache. - private final Map, Boolean> mVoicemailQueryCache = - new HashMap<>(); - private final Map mPhoneAccountLabelCache = new HashMap<>(); - private final Map mPhoneAccountColorCache = new HashMap<>(); - private final Map mPhoneAccountCallWithNoteCache = new HashMap<>(); - - private boolean mHasCheckedForVideoEnabled; - private boolean mIsVideoEnabled; - - public TelecomCallLogCache(Context context) { - mContext = context; - } - - public void reset() { - mVoicemailQueryCache.clear(); - mPhoneAccountLabelCache.clear(); - mPhoneAccountColorCache.clear(); - mPhoneAccountCallWithNoteCache.clear(); - - mHasCheckedForVideoEnabled = false; - mIsVideoEnabled = false; - } - - /** - * Returns true if the given number is the number of the configured voicemail. To be able to - * mock-out this, it is not a static method. - */ - public boolean isVoicemailNumber(PhoneAccountHandle accountHandle, CharSequence number) { - if (TextUtils.isEmpty(number)) { - return false; - } - - Pair key = new Pair<>(accountHandle, number); - if (mVoicemailQueryCache.containsKey(key)) { - return mVoicemailQueryCache.get(key); - } else { - Boolean isVoicemail = - PhoneNumberUtil.isVoicemailNumber(mContext, accountHandle, number.toString()); - mVoicemailQueryCache.put(key, isVoicemail); - return isVoicemail; - } - } - - /** - * Extract account label from PhoneAccount object. - */ - public String getAccountLabel(PhoneAccountHandle accountHandle) { - if (mPhoneAccountLabelCache.containsKey(accountHandle)) { - return mPhoneAccountLabelCache.get(accountHandle); - } else { - String label = PhoneAccountUtils.getAccountLabel(mContext, accountHandle); - mPhoneAccountLabelCache.put(accountHandle, label); - return label; - } - } - - /** - * Extract account color from PhoneAccount object. - */ - public int getAccountColor(PhoneAccountHandle accountHandle) { - if (mPhoneAccountColorCache.containsKey(accountHandle)) { - return mPhoneAccountColorCache.get(accountHandle); - } else { - Integer color = PhoneAccountUtils.getAccountColor(mContext, accountHandle); - mPhoneAccountColorCache.put(accountHandle, color); - return color; - } - } - - public boolean isVideoEnabled() { - if (!mHasCheckedForVideoEnabled) { - mIsVideoEnabled = CallUtil.isVideoEnabled(mContext); - mHasCheckedForVideoEnabled = true; - } - return mIsVideoEnabled; - } - - /** - * Determines if the PhoneAccount supports specifying a call subject (i.e. calling with a note) - * for outgoing calls. - * - * @param accountHandle The PhoneAccount handle. - * @return {@code true} if calling with a note is supported, {@code false} otherwise. - */ - public boolean doesAccountSupportCallSubject(PhoneAccountHandle accountHandle) { - if (mPhoneAccountCallWithNoteCache.containsKey(accountHandle)) { - return mPhoneAccountCallWithNoteCache.get(accountHandle); - } else { - Boolean supportsCallWithNote = - PhoneAccountUtils.getAccountSupportsCallSubject(mContext, accountHandle); - mPhoneAccountCallWithNoteCache.put(accountHandle, supportsCallWithNote); - return supportsCallWithNote; - } - } -} diff --git a/src/com/android/dialer/calllog/calllogcache/CallLogCache.java b/src/com/android/dialer/calllog/calllogcache/CallLogCache.java new file mode 100644 index 000000000..e64c0121d --- /dev/null +++ b/src/com/android/dialer/calllog/calllogcache/CallLogCache.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2015 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.dialer.calllog.calllogcache; + +import android.content.Context; +import android.telecom.PhoneAccountHandle; + +import com.android.contacts.common.CallUtil; +import com.android.contacts.common.compat.CompatUtils; +import com.android.dialer.calllog.CallLogAdapter; + +/** + * This is the base class for the CallLogCaches. + * + * Keeps a cache of recently made queries to the Telecom/Telephony processes. The aim of this cache + * is to reduce the number of cross-process requests to TelecomManager, which can negatively affect + * performance. + * + * This is designed with the specific use case of the {@link CallLogAdapter} in mind. + */ +public abstract class CallLogCache { + // TODO: Dialer should be fixed so as not to check isVoicemail() so often but at the time of + // this writing, that was a much larger undertaking than creating this cache. + + protected final Context mContext; + + private boolean mHasCheckedForVideoEnabled; + private boolean mIsVideoEnabled; + + public CallLogCache(Context context) { + mContext = context; + } + + /** + * Return the most compatible version of the TelecomCallLogCache. + */ + public static CallLogCache getCallLogCache(Context context) { + if (CompatUtils.isMSIMCompatible()) { + return new CallLogCacheLollipopMr1(context); + } + return new CallLogCacheLollipop(context); + } + + public void reset() { + mHasCheckedForVideoEnabled = false; + mIsVideoEnabled = false; + } + + /** + * Returns true if the given number is the number of the configured voicemail. To be able to + * mock-out this, it is not a static method. + */ + public abstract boolean isVoicemailNumber(PhoneAccountHandle accountHandle, + CharSequence number); + + public boolean isVideoEnabled() { + if (!mHasCheckedForVideoEnabled) { + mIsVideoEnabled = CallUtil.isVideoEnabled(mContext); + mHasCheckedForVideoEnabled = true; + } + return mIsVideoEnabled; + } + + /** + * Extract account label from PhoneAccount object. + */ + public abstract String getAccountLabel(PhoneAccountHandle accountHandle); + + /** + * Extract account color from PhoneAccount object. + */ + public abstract int getAccountColor(PhoneAccountHandle accountHandle); + + /** + * Determines if the PhoneAccount supports specifying a call subject (i.e. calling with a note) + * for outgoing calls. + * + * @param accountHandle The PhoneAccount handle. + * @return {@code true} if calling with a note is supported, {@code false} otherwise. + */ + public abstract boolean doesAccountSupportCallSubject(PhoneAccountHandle accountHandle); +} diff --git a/src/com/android/dialer/calllog/calllogcache/CallLogCacheLollipop.java b/src/com/android/dialer/calllog/calllogcache/CallLogCacheLollipop.java new file mode 100644 index 000000000..770cc9d3e --- /dev/null +++ b/src/com/android/dialer/calllog/calllogcache/CallLogCacheLollipop.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2015 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.dialer.calllog.calllogcache; + +import android.content.Context; +import android.telecom.PhoneAccount; +import android.telecom.PhoneAccountHandle; +import android.telephony.PhoneNumberUtils; +import android.text.TextUtils; + +/** + * This is a compatibility class for the CallLogCache for versions of dialer before Lollipop Mr1 + * (the introduction of phone accounts). + * + * This class should not be initialized directly and instead be acquired from + * {@link CallLogCache#getCallLogCache}. + */ +class CallLogCacheLollipop extends CallLogCache { + private String mVoicemailNumber; + + /* package */ CallLogCacheLollipop(Context context) { + super(context); + } + + @Override + public boolean isVoicemailNumber(PhoneAccountHandle accountHandle, CharSequence number) { + if (TextUtils.isEmpty(number)) { + return false; + } + + String numberString = number.toString(); + + if (!TextUtils.isEmpty(mVoicemailNumber)) { + return PhoneNumberUtils.compare(numberString, mVoicemailNumber); + } + + if (PhoneNumberUtils.isVoiceMailNumber(numberString)) { + mVoicemailNumber = numberString; + return true; + } + + return false; + } + + @Override + public String getAccountLabel(PhoneAccountHandle accountHandle) { + return null; + } + + @Override + public int getAccountColor(PhoneAccountHandle accountHandle) { + return PhoneAccount.NO_HIGHLIGHT_COLOR; + } + + @Override + public boolean doesAccountSupportCallSubject(PhoneAccountHandle accountHandle) { + return false; + } +} diff --git a/src/com/android/dialer/calllog/calllogcache/CallLogCacheLollipopMr1.java b/src/com/android/dialer/calllog/calllogcache/CallLogCacheLollipopMr1.java new file mode 100644 index 000000000..d1e3f7bcf --- /dev/null +++ b/src/com/android/dialer/calllog/calllogcache/CallLogCacheLollipopMr1.java @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2013 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.dialer.calllog.calllogcache; + +import android.content.Context; +import android.telecom.PhoneAccountHandle; +import android.text.TextUtils; +import android.util.Pair; + +import com.android.dialer.calllog.PhoneAccountUtils; +import com.android.dialer.util.PhoneNumberUtil; + +import java.util.HashMap; +import java.util.Map; + +/** + * This is the CallLogCache for versions of dialer Lollipop Mr1 and above with support for + * multi-SIM devices. + * + * This class should not be initialized directly and instead be acquired from + * {@link CallLogCache#getCallLogCache}. + */ +class CallLogCacheLollipopMr1 extends CallLogCache { + // Maps from a phone-account/number pair to a boolean because multiple numbers could return true + // for the voicemail number if those numbers are not pre-normalized. + private final Map, Boolean> mVoicemailQueryCache = + new HashMap<>(); + private final Map mPhoneAccountLabelCache = new HashMap<>(); + private final Map mPhoneAccountColorCache = new HashMap<>(); + private final Map mPhoneAccountCallWithNoteCache = new HashMap<>(); + + /* package */ CallLogCacheLollipopMr1(Context context) { + super(context); + } + + @Override + public void reset() { + mVoicemailQueryCache.clear(); + mPhoneAccountLabelCache.clear(); + mPhoneAccountColorCache.clear(); + mPhoneAccountCallWithNoteCache.clear(); + + super.reset(); + } + + @Override + public boolean isVoicemailNumber(PhoneAccountHandle accountHandle, CharSequence number) { + if (TextUtils.isEmpty(number)) { + return false; + } + + Pair key = new Pair<>(accountHandle, number); + if (mVoicemailQueryCache.containsKey(key)) { + return mVoicemailQueryCache.get(key); + } else { + Boolean isVoicemail = + PhoneNumberUtil.isVoicemailNumber(mContext, accountHandle, number.toString()); + mVoicemailQueryCache.put(key, isVoicemail); + return isVoicemail; + } + } + + @Override + public String getAccountLabel(PhoneAccountHandle accountHandle) { + if (mPhoneAccountLabelCache.containsKey(accountHandle)) { + return mPhoneAccountLabelCache.get(accountHandle); + } else { + String label = PhoneAccountUtils.getAccountLabel(mContext, accountHandle); + mPhoneAccountLabelCache.put(accountHandle, label); + return label; + } + } + + @Override + public int getAccountColor(PhoneAccountHandle accountHandle) { + if (mPhoneAccountColorCache.containsKey(accountHandle)) { + return mPhoneAccountColorCache.get(accountHandle); + } else { + Integer color = PhoneAccountUtils.getAccountColor(mContext, accountHandle); + mPhoneAccountColorCache.put(accountHandle, color); + return color; + } + } + + @Override + public boolean doesAccountSupportCallSubject(PhoneAccountHandle accountHandle) { + if (mPhoneAccountCallWithNoteCache.containsKey(accountHandle)) { + return mPhoneAccountCallWithNoteCache.get(accountHandle); + } else { + Boolean supportsCallWithNote = + PhoneAccountUtils.getAccountSupportsCallSubject(mContext, accountHandle); + mPhoneAccountCallWithNoteCache.put(accountHandle, supportsCallWithNote); + return supportsCallWithNote; + } + } +} diff --git a/tests/src/com/android/dialer/calllog/TestTelecomCallLogCache.java b/tests/src/com/android/dialer/calllog/TestTelecomCallLogCache.java index 5475ec337..fcf988412 100644 --- a/tests/src/com/android/dialer/calllog/TestTelecomCallLogCache.java +++ b/tests/src/com/android/dialer/calllog/TestTelecomCallLogCache.java @@ -17,13 +17,20 @@ package com.android.dialer.calllog; import android.content.Context; +import android.telecom.PhoneAccount; import android.telecom.PhoneAccountHandle; +import com.android.dialer.calllog.calllogcache.CallLogCache; + /** - * Modified version of {@link com.android.dialer.calllog.PhoneNumberDisplayHelper} to be used in + * Modified version of {@link com.android.dialer.calllog.calllogcache.CallLogCache} to be used in * tests that allows injecting the voicemail number. + * + * NOTE: This tests the pre-LMR1 version because currently none of the tests involve multi-SIM, + * but... + * TODO: write tests to test multi-SIM functionality in TelecomCallLogCache. */ -public final class TestTelecomCallLogCache extends TelecomCallLogCache { +public final class TestTelecomCallLogCache extends CallLogCache { private CharSequence mVoicemailNumber; public TestTelecomCallLogCache(Context context, CharSequence voicemailNumber) { @@ -35,4 +42,19 @@ public final class TestTelecomCallLogCache extends TelecomCallLogCache { public boolean isVoicemailNumber(PhoneAccountHandle accountHandle, CharSequence number) { return mVoicemailNumber.equals(number); } + + @Override + public String getAccountLabel(PhoneAccountHandle accountHandle) { + return null; + } + + @Override + public int getAccountColor(PhoneAccountHandle accountHandle) { + return PhoneAccount.NO_HIGHLIGHT_COLOR; + } + + @Override + public boolean doesAccountSupportCallSubject(PhoneAccountHandle accountHandle) { + return false; + } } -- cgit v1.2.3