1 /* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17 package com.android.dialer.calllog; 18 19 import android.content.Context; 20 import android.provider.CallLog; 21 import android.telecom.PhoneAccount; 22 import android.telecom.PhoneAccountHandle; 23 import android.telecom.TelecomManager; 24 import android.text.TextUtils; 25 import android.util.Log; 26 import android.util.Pair; 27 28 import com.android.contacts.common.CallUtil; 29 import com.android.contacts.common.util.PhoneNumberHelper; 30 import com.android.dialer.util.PhoneNumberUtil; 31 import com.google.common.collect.Sets; 32 33 import java.util.HashMap; 34 import java.util.Map; 35 import java.util.Set; 36 37 /** 38 * Keeps a cache of recently made queries to the Telecom process. The aim of this cache is to 39 * reduce the number of cross-process requests to TelecomManager, which can negatively affect 40 * performance. 41 * 42 * This is designed with the specific use case of the {@link CallLogAdapter} in mind. 43 */ 44 public class TelecomCallLogCache { 45 private final Context mContext; 46 47 // Maps from a phone-account/number pair to a boolean because multiple numbers could return true 48 // for the voicemail number if those numbers are not pre-normalized. 49 // TODO: Dialer should be fixed so as not to check isVoicemail() so often but at the time of 50 // this writing, that was a much larger undertaking than creating this cache. 51 private final Map<Pair<PhoneAccountHandle, CharSequence>, Boolean> mVoicemailQueryCache = 52 new HashMap<>(); 53 private final Map<PhoneAccountHandle, String> mPhoneAccountLabelCache = new HashMap<>(); 54 private final Map<PhoneAccountHandle, Integer> mPhoneAccountColorCache = new HashMap<>(); 55 56 private boolean mHasCheckedForVideoEnabled; 57 private boolean mIsVideoEnabled; 58 59 public TelecomCallLogCache(Context context) { 60 mContext = context; 61 } 62 63 public void reset() { 64 mVoicemailQueryCache.clear(); 65 mPhoneAccountLabelCache.clear(); 66 mPhoneAccountColorCache.clear(); 67 68 mHasCheckedForVideoEnabled = false; 69 mIsVideoEnabled = false; 70 } 71 72 /** 73 * Returns true if the given number is the number of the configured voicemail. To be able to 74 * mock-out this, it is not a static method. 75 */ 76 public boolean isVoicemailNumber(PhoneAccountHandle accountHandle, CharSequence number) { 77 if (TextUtils.isEmpty(number)) { 78 return false; 79 } 80 81 Pair<PhoneAccountHandle, CharSequence> key = new Pair<>(accountHandle, number); 82 if (mVoicemailQueryCache.containsKey(key)) { 83 return mVoicemailQueryCache.get(key); 84 } else { 85 Boolean isVoicemail = 86 PhoneNumberUtil.isVoicemailNumber(mContext, accountHandle, number.toString()); 87 mVoicemailQueryCache.put(key, isVoicemail); 88 return isVoicemail; 89 } 90 } 91 92 /** 93 * Extract account label from PhoneAccount object. 94 */ 95 public String getAccountLabel(PhoneAccountHandle accountHandle) { 96 if (mPhoneAccountLabelCache.containsKey(accountHandle)) { 97 return mPhoneAccountLabelCache.get(accountHandle); 98 } else { 99 String label = PhoneAccountUtils.getAccountLabel(mContext, accountHandle); 100 mPhoneAccountLabelCache.put(accountHandle, label); 101 return label; 102 } 103 } 104 105 /** 106 * Extract account color from PhoneAccount object. 107 */ 108 public int getAccountColor(PhoneAccountHandle accountHandle) { 109 if (mPhoneAccountColorCache.containsKey(accountHandle)) { 110 return mPhoneAccountColorCache.get(accountHandle); 111 } else { 112 Integer color = PhoneAccountUtils.getAccountColor(mContext, accountHandle); 113 mPhoneAccountColorCache.put(accountHandle, color); 114 return color; 115 } 116 } 117 118 public boolean isVideoEnabled() { 119 if (!mHasCheckedForVideoEnabled) { 120 mIsVideoEnabled = CallUtil.isVideoEnabled(mContext); 121 } 122 return mIsVideoEnabled; 123 } 124 } 125