1 /* 2 * Copyright (C) 2014 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.server.telecom; 18 19 import android.util.ArrayMap; 20 21 import com.android.internal.annotations.VisibleForTesting; 22 23 import java.util.Map; 24 25 /** Utility to map {@link Call} objects to unique IDs. IDs are generated when a call is added. */ 26 @VisibleForTesting 27 public class CallIdMapper { 28 /** 29 * A very basic bidirectional map. 30 */ 31 static class BiMap<K, V> { 32 private Map<K, V> mPrimaryMap = new ArrayMap<>(); 33 private Map<V, K> mSecondaryMap = new ArrayMap<>(); 34 35 public boolean put(K key, V value) { 36 if (key == null || value == null || mPrimaryMap.containsKey(key) || 37 mSecondaryMap.containsKey(value)) { 38 return false; 39 } 40 41 mPrimaryMap.put(key, value); 42 mSecondaryMap.put(value, key); 43 return true; 44 } 45 46 public boolean remove(K key) { 47 if (key == null) { 48 return false; 49 } 50 if (mPrimaryMap.containsKey(key)) { 51 V value = getValue(key); 52 mPrimaryMap.remove(key); 53 mSecondaryMap.remove(value); 54 return true; 55 } 56 return false; 57 } 58 59 public boolean removeValue(V value) { 60 if (value == null) { 61 return false; 62 } 63 return remove(getKey(value)); 64 } 65 66 public V getValue(K key) { 67 return mPrimaryMap.get(key); 68 } 69 70 public K getKey(V value) { 71 return mSecondaryMap.get(value); 72 } 73 74 public void clear() { 75 mPrimaryMap.clear(); 76 mSecondaryMap.clear(); 77 } 78 } 79 80 public interface ICallInfo { 81 String getCallId(Call call); 82 } 83 84 private final BiMap<String, Call> mCalls = new BiMap<>(); 85 private ICallInfo mCallInfo; 86 87 public CallIdMapper(ICallInfo callInfo) { 88 mCallInfo = callInfo; 89 } 90 91 void replaceCall(Call newCall, Call callToReplace) { 92 // Use the old call's ID for the new call. 93 String callId = getCallId(callToReplace); 94 mCalls.put(callId, newCall); 95 } 96 97 void addCall(Call call, String id) { 98 if (call == null) { 99 return; 100 } 101 mCalls.put(id, call); 102 } 103 104 void addCall(Call call) { 105 addCall(call, mCallInfo.getCallId(call)); 106 } 107 108 void removeCall(Call call) { 109 if (call == null) { 110 return; 111 } 112 mCalls.removeValue(call); 113 } 114 115 void removeCall(String callId) { 116 mCalls.remove(callId); 117 } 118 119 String getCallId(Call call) { 120 if (call == null || mCalls.getKey(call) == null) { 121 return null; 122 } 123 return mCallInfo.getCallId(call); 124 } 125 126 Call getCall(Object objId) { 127 String callId = null; 128 if (objId instanceof String) { 129 callId = (String) objId; 130 } 131 132 return mCalls.getValue(callId); 133 } 134 135 void clear() { 136 mCalls.clear(); 137 } 138 } 139