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 put(K key, V value)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 remove(K key)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 removeValue(V value)59 public boolean removeValue(V value) { 60 if (value == null) { 61 return false; 62 } 63 return remove(getKey(value)); 64 } 65 getValue(K key)66 public V getValue(K key) { 67 return mPrimaryMap.get(key); 68 } 69 getKey(V value)70 public K getKey(V value) { 71 return mSecondaryMap.get(value); 72 } 73 clear()74 public void clear() { 75 mPrimaryMap.clear(); 76 mSecondaryMap.clear(); 77 } 78 } 79 80 private final BiMap<String, Call> mCalls = new BiMap<>(); 81 replaceCall(Call newCall, Call callToReplace)82 void replaceCall(Call newCall, Call callToReplace) { 83 // Use the old call's ID for the new call. 84 String callId = getCallId(callToReplace); 85 mCalls.put(callId, newCall); 86 } 87 addCall(Call call, String id)88 void addCall(Call call, String id) { 89 if (call == null) { 90 return; 91 } 92 mCalls.put(id, call); 93 } 94 addCall(Call call)95 void addCall(Call call) { 96 addCall(call, call.getId()); 97 } 98 removeCall(Call call)99 void removeCall(Call call) { 100 if (call == null) { 101 return; 102 } 103 mCalls.removeValue(call); 104 } 105 removeCall(String callId)106 void removeCall(String callId) { 107 mCalls.remove(callId); 108 } 109 getCallId(Call call)110 String getCallId(Call call) { 111 if (call == null || mCalls.getKey(call) == null) { 112 return null; 113 } 114 return call.getId(); 115 } 116 getCall(Object objId)117 Call getCall(Object objId) { 118 String callId = null; 119 if (objId instanceof String) { 120 callId = (String) objId; 121 } 122 123 return mCalls.getValue(callId); 124 } 125 clear()126 void clear() { 127 mCalls.clear(); 128 } 129 } 130