1 /* 2 * Copyright (C) 2015 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.app.calllog.calllogcache; 18 19 import android.content.Context; 20 import android.support.annotation.Nullable; 21 import android.telecom.PhoneAccountHandle; 22 import android.text.TextUtils; 23 import android.util.ArrayMap; 24 import com.android.dialer.app.calllog.CallLogAdapter; 25 import com.android.dialer.calllogutils.PhoneAccountUtils; 26 import com.android.dialer.telecom.TelecomUtil; 27 import com.android.dialer.util.CallUtil; 28 import java.util.Map; 29 import javax.annotation.concurrent.ThreadSafe; 30 31 /** 32 * This is the base class for the CallLogCaches. 33 * 34 * <p>Keeps a cache of recently made queries to the Telecom/Telephony processes. The aim of this 35 * cache is to reduce the number of cross-process requests to TelecomManager, which can negatively 36 * affect performance. 37 * 38 * <p>This is designed with the specific use case of the {@link CallLogAdapter} in mind. 39 */ 40 @ThreadSafe 41 public class CallLogCache { 42 // TODO: Dialer should be fixed so as not to check isVoicemail() so often but at the time of 43 // this writing, that was a much larger undertaking than creating this cache. 44 45 protected final Context context; 46 47 private boolean hasCheckedForVideoAvailability; 48 private int videoAvailability; 49 private final Map<PhoneAccountHandle, String> phoneAccountLabelCache = new ArrayMap<>(); 50 private final Map<PhoneAccountHandle, Integer> phoneAccountColorCache = new ArrayMap<>(); 51 private final Map<PhoneAccountHandle, Boolean> phoneAccountCallWithNoteCache = new ArrayMap<>(); 52 CallLogCache(Context context)53 public CallLogCache(Context context) { 54 this.context = context; 55 } 56 reset()57 public synchronized void reset() { 58 phoneAccountLabelCache.clear(); 59 phoneAccountColorCache.clear(); 60 phoneAccountCallWithNoteCache.clear(); 61 hasCheckedForVideoAvailability = false; 62 videoAvailability = 0; 63 } 64 65 /** 66 * Returns true if the given number is the number of the configured voicemail. To be able to 67 * mock-out this, it is not a static method. 68 */ isVoicemailNumber( PhoneAccountHandle accountHandle, @Nullable CharSequence number)69 public synchronized boolean isVoicemailNumber( 70 PhoneAccountHandle accountHandle, @Nullable CharSequence number) { 71 if (TextUtils.isEmpty(number)) { 72 return false; 73 } 74 return TelecomUtil.isVoicemailNumber(context, accountHandle, number.toString()); 75 } 76 77 /** 78 * Returns {@code true} when the current sim supports checking video calling capabilities via the 79 * {@link android.provider.ContactsContract.CommonDataKinds.Phone#CARRIER_PRESENCE} column. 80 */ canRelyOnVideoPresence()81 public boolean canRelyOnVideoPresence() { 82 if (!hasCheckedForVideoAvailability) { 83 videoAvailability = CallUtil.getVideoCallingAvailability(context); 84 hasCheckedForVideoAvailability = true; 85 } 86 return (videoAvailability & CallUtil.VIDEO_CALLING_PRESENCE) != 0; 87 } 88 89 /** Extract account label from PhoneAccount object. */ getAccountLabel(PhoneAccountHandle accountHandle)90 public synchronized String getAccountLabel(PhoneAccountHandle accountHandle) { 91 if (phoneAccountLabelCache.containsKey(accountHandle)) { 92 return phoneAccountLabelCache.get(accountHandle); 93 } else { 94 String label = PhoneAccountUtils.getAccountLabel(context, accountHandle); 95 phoneAccountLabelCache.put(accountHandle, label); 96 return label; 97 } 98 } 99 100 /** Extract account color from PhoneAccount object. */ getAccountColor(PhoneAccountHandle accountHandle)101 public synchronized int getAccountColor(PhoneAccountHandle accountHandle) { 102 if (phoneAccountColorCache.containsKey(accountHandle)) { 103 return phoneAccountColorCache.get(accountHandle); 104 } else { 105 Integer color = PhoneAccountUtils.getAccountColor(context, accountHandle); 106 phoneAccountColorCache.put(accountHandle, color); 107 return color; 108 } 109 } 110 111 /** 112 * Determines if the PhoneAccount supports specifying a call subject (i.e. calling with a note) 113 * for outgoing calls. 114 * 115 * @param accountHandle The PhoneAccount handle. 116 * @return {@code true} if calling with a note is supported, {@code false} otherwise. 117 */ doesAccountSupportCallSubject(PhoneAccountHandle accountHandle)118 public synchronized boolean doesAccountSupportCallSubject(PhoneAccountHandle accountHandle) { 119 if (phoneAccountCallWithNoteCache.containsKey(accountHandle)) { 120 return phoneAccountCallWithNoteCache.get(accountHandle); 121 } else { 122 Boolean supportsCallWithNote = 123 PhoneAccountUtils.getAccountSupportsCallSubject(context, accountHandle); 124 phoneAccountCallWithNoteCache.put(accountHandle, supportsCallWithNote); 125 return supportsCallWithNote; 126 } 127 } 128 } 129