blob: 729db0a27adb85fab00770e37450f9ed691b531d [file] [log] [blame]
Sailesh Nepale59bb192014-04-01 18:33:59 -07001/*
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
Tyler Gunn7cc70b42014-09-12 22:17:27 -070017package com.android.server.telecom;
Sailesh Nepale59bb192014-04-01 18:33:59 -070018
Santos Cordon4bc02452014-11-19 15:51:12 -080019import android.util.ArrayMap;
20
21import java.util.Map;
Sailesh Nepale59bb192014-04-01 18:33:59 -070022
Sailesh Nepale59bb192014-04-01 18:33:59 -070023/** Utility to map {@link Call} objects to unique IDs. IDs are generated when a call is added. */
24class CallIdMapper {
Santos Cordon4bc02452014-11-19 15:51:12 -080025 /**
26 * A very basic bidirectional map.
27 */
28 static class BiMap<K, V> {
29 private Map<K, V> mPrimaryMap = new ArrayMap<>();
30 private Map<V, K> mSecondaryMap = new ArrayMap<>();
31
32 public boolean put(K key, V value) {
33 if (key == null || value == null || mPrimaryMap.containsKey(key) ||
34 mSecondaryMap.containsKey(value)) {
35 return false;
36 }
37
38 mPrimaryMap.put(key, value);
39 mSecondaryMap.put(value, key);
40 return true;
41 }
42
43 public boolean remove(K key) {
44 if (key == null) {
45 return false;
46 }
47 if (mPrimaryMap.containsKey(key)) {
48 V value = getValue(key);
49 mPrimaryMap.remove(key);
50 mSecondaryMap.remove(value);
51 return true;
52 }
53 return false;
54 }
55
56 public boolean removeValue(V value) {
57 if (value == null) {
58 return false;
59 }
60 return remove(getKey(value));
61 }
62
63 public V getValue(K key) {
64 return mPrimaryMap.get(key);
65 }
66
67 public K getKey(V value) {
68 return mSecondaryMap.get(value);
69 }
70
71 public void clear() {
72 mPrimaryMap.clear();
73 mSecondaryMap.clear();
74 }
75 }
76
77 private final BiMap<String, Call> mCalls = new BiMap<>();
Sailesh Nepale59bb192014-04-01 18:33:59 -070078 private final String mCallIdPrefix;
Sailesh Nepale2ea6532014-04-01 19:45:45 -070079 private static int sIdCount;
Sailesh Nepale59bb192014-04-01 18:33:59 -070080
81 CallIdMapper(String callIdPrefix) {
82 ThreadUtil.checkOnMainThread();
83 mCallIdPrefix = callIdPrefix + "@";
84 }
85
Sailesh Nepal0e5410a2014-04-04 01:20:58 -070086 void replaceCall(Call newCall, Call callToReplace) {
87 ThreadUtil.checkOnMainThread();
88
89 // Use the old call's ID for the new call.
90 String callId = getCallId(callToReplace);
91 mCalls.put(callId, newCall);
92 }
93
Santos Cordona1610702014-06-04 20:22:56 -070094 void addCall(Call call, String id) {
Jay Shrauner969755a2014-08-11 20:34:43 -070095 if (call == null) {
96 return;
97 }
Santos Cordona1610702014-06-04 20:22:56 -070098 ThreadUtil.checkOnMainThread();
99 mCalls.put(id, call);
100 }
101
Sailesh Nepale59bb192014-04-01 18:33:59 -0700102 void addCall(Call call) {
103 ThreadUtil.checkOnMainThread();
Santos Cordona1610702014-06-04 20:22:56 -0700104 addCall(call, getNewId());
Sailesh Nepale59bb192014-04-01 18:33:59 -0700105 }
106
107 void removeCall(Call call) {
Jay Shrauner969755a2014-08-11 20:34:43 -0700108 if (call == null) {
109 return;
110 }
Sailesh Nepale59bb192014-04-01 18:33:59 -0700111 ThreadUtil.checkOnMainThread();
Santos Cordon4bc02452014-11-19 15:51:12 -0800112 mCalls.removeValue(call);
Sailesh Nepale59bb192014-04-01 18:33:59 -0700113 }
114
Santos Cordon682fe6b2014-05-20 08:56:39 -0700115 void removeCall(String callId) {
116 ThreadUtil.checkOnMainThread();
117 mCalls.remove(callId);
118 }
119
Sailesh Nepale59bb192014-04-01 18:33:59 -0700120 String getCallId(Call call) {
Jay Shrauner969755a2014-08-11 20:34:43 -0700121 if (call == null) {
122 return null;
123 }
Sailesh Nepale59bb192014-04-01 18:33:59 -0700124 ThreadUtil.checkOnMainThread();
Santos Cordon4bc02452014-11-19 15:51:12 -0800125 return mCalls.getKey(call);
Sailesh Nepale59bb192014-04-01 18:33:59 -0700126 }
127
128 Call getCall(Object objId) {
129 ThreadUtil.checkOnMainThread();
130
131 String callId = null;
132 if (objId instanceof String) {
133 callId = (String) objId;
134 }
Santos Cordon0fbe6322014-08-14 04:04:25 -0700135 if (!isValidCallId(callId) && !isValidConferenceId(callId)) {
Jay Shrauner969755a2014-08-11 20:34:43 -0700136 return null;
137 }
Sailesh Nepale59bb192014-04-01 18:33:59 -0700138
Santos Cordon4bc02452014-11-19 15:51:12 -0800139 return mCalls.getValue(callId);
Sailesh Nepale59bb192014-04-01 18:33:59 -0700140 }
141
Santos Cordon682fe6b2014-05-20 08:56:39 -0700142 void clear() {
143 mCalls.clear();
144 }
145
Sailesh Nepale59bb192014-04-01 18:33:59 -0700146 boolean isValidCallId(String callId) {
147 // Note, no need for thread check, this method is thread safe.
148 return callId != null && callId.startsWith(mCallIdPrefix);
149 }
Santos Cordona1610702014-06-04 20:22:56 -0700150
Santos Cordon0fbe6322014-08-14 04:04:25 -0700151 boolean isValidConferenceId(String callId) {
152 return callId != null;
153 }
154
Santos Cordona1610702014-06-04 20:22:56 -0700155 String getNewId() {
156 sIdCount++;
157 return mCallIdPrefix + sIdCount;
158 }
Sailesh Nepale59bb192014-04-01 18:33:59 -0700159}