1 /*
2  * Copyright (C) 2023 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.companion.datatransfer.contextsync;
18 
19 import android.companion.ContextSyncMessage;
20 import android.os.Bundle;
21 
22 import java.util.ArrayList;
23 import java.util.Collection;
24 import java.util.HashMap;
25 import java.util.HashSet;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.Objects;
29 import java.util.Set;
30 
31 /** A read-only snapshot of an {@link ContextSyncMessage}. */
32 class CallMetadataSyncData {
33 
34     final Map<String, CallMetadataSyncData.Call> mCalls = new HashMap<>();
35     final List<CallMetadataSyncData.CallCreateRequest> mCallCreateRequests = new ArrayList<>();
36     final List<CallMetadataSyncData.CallControlRequest> mCallControlRequests = new ArrayList<>();
37     final List<CallMetadataSyncData.CallFacilitator> mCallFacilitators = new ArrayList<>();
38 
addCall(CallMetadataSyncData.Call call)39     public void addCall(CallMetadataSyncData.Call call) {
40         mCalls.put(call.getId(), call);
41     }
42 
hasCall(String id)43     public boolean hasCall(String id) {
44         return mCalls.containsKey(id);
45     }
46 
getCalls()47     public Collection<CallMetadataSyncData.Call> getCalls() {
48         return mCalls.values();
49     }
50 
addCallCreateRequest(CallMetadataSyncData.CallCreateRequest request)51     public void addCallCreateRequest(CallMetadataSyncData.CallCreateRequest request) {
52         mCallCreateRequests.add(request);
53     }
54 
getCallCreateRequests()55     public List<CallMetadataSyncData.CallCreateRequest> getCallCreateRequests() {
56         return mCallCreateRequests;
57     }
58 
addCallControlRequest(CallMetadataSyncData.CallControlRequest request)59     public void addCallControlRequest(CallMetadataSyncData.CallControlRequest request) {
60         mCallControlRequests.add(request);
61     }
62 
getCallControlRequests()63     public List<CallMetadataSyncData.CallControlRequest> getCallControlRequests() {
64         return mCallControlRequests;
65     }
66 
addFacilitator(CallFacilitator facilitator)67     public void addFacilitator(CallFacilitator facilitator) {
68         mCallFacilitators.add(facilitator);
69     }
70 
getFacilitators()71     public List<CallFacilitator> getFacilitators() {
72         return mCallFacilitators;
73     }
74 
75     public static class CallFacilitator {
76         private String mName;
77         private String mIdentifier;
78         private String mExtendedIdentifier;
79         private boolean mIsTel;
80 
CallFacilitator()81         CallFacilitator() {}
82 
CallFacilitator(String name, String identifier, String extendedIdentifier)83         CallFacilitator(String name, String identifier, String extendedIdentifier) {
84             mName = name;
85             mIdentifier = identifier;
86             mExtendedIdentifier = extendedIdentifier;
87         }
88 
getName()89         public String getName() {
90             return mName;
91         }
92 
getIdentifier()93         public String getIdentifier() {
94             return mIdentifier;
95         }
96 
getExtendedIdentifier()97         public String getExtendedIdentifier() {
98             return mExtendedIdentifier;
99         }
100 
isTel()101         public boolean isTel() {
102             return mIsTel;
103         }
104 
setName(String name)105         public void setName(String name) {
106             mName = name;
107         }
108 
setIdentifier(String identifier)109         public void setIdentifier(String identifier) {
110             mIdentifier = identifier;
111         }
112 
setExtendedIdentifier(String extendedIdentifier)113         public void setExtendedIdentifier(String extendedIdentifier) {
114             mExtendedIdentifier = extendedIdentifier;
115         }
116 
setIsTel(boolean isTel)117         public void setIsTel(boolean isTel) {
118             mIsTel = isTel;
119         }
120     }
121 
122     public static class CallControlRequest {
123         private String mId;
124         private int mControl;
125 
setId(String id)126         public void setId(String id) {
127             mId = id;
128         }
129 
setControl(int control)130         public void setControl(int control) {
131             mControl = control;
132         }
133 
getId()134         public String getId() {
135             return mId;
136         }
137 
getControl()138         public int getControl() {
139             return mControl;
140         }
141     }
142 
143     public static class CallCreateRequest {
144         private String mId;
145         private String mAddress;
146         private CallFacilitator mFacilitator;
147 
setId(String id)148         public void setId(String id) {
149             mId = id;
150         }
151 
setAddress(String address)152         public void setAddress(String address) {
153             mAddress = address;
154         }
155 
setFacilitator(CallFacilitator facilitator)156         public void setFacilitator(CallFacilitator facilitator) {
157             mFacilitator = facilitator;
158         }
159 
getId()160         public String getId() {
161             return mId;
162         }
163 
getAddress()164         public String getAddress() {
165             return mAddress;
166         }
167 
getFacilitator()168         public CallFacilitator getFacilitator() {
169             return mFacilitator;
170         }
171     }
172 
173     public static class Call {
174 
175         private static final String EXTRA_CALLER_ID =
176                 "com.android.server.companion.datatransfer.contextsync.extra.CALLER_ID";
177         private static final String EXTRA_APP_ICON =
178                 "com.android.server.companion.datatransfer.contextsync.extra.APP_ICON";
179         private static final String EXTRA_FACILITATOR_NAME =
180                 "com.android.server.companion.datatransfer.contextsync.extra.FACILITATOR_NAME";
181         private static final String EXTRA_FACILITATOR_ID =
182                 "com.android.server.companion.datatransfer.contextsync.extra.FACILITATOR_ID";
183         private static final String EXTRA_FACILITATOR_EXT_ID =
184                 "com.android.server.companion.datatransfer.contextsync.extra.FACILITATOR_EXT_ID";
185         private static final String EXTRA_STATUS =
186                 "com.android.server.companion.datatransfer.contextsync.extra.STATUS";
187         private static final String EXTRA_DIRECTION =
188                 "com.android.server.companion.datatransfer.contextsync.extra.DIRECTION";
189         private static final String EXTRA_CONTROLS =
190                 "com.android.server.companion.datatransfer.contextsync.extra.CONTROLS";
191         private String mId;
192         private String mCallerId;
193         private byte[] mAppIcon;
194         private CallFacilitator mFacilitator;
195         private int mStatus;
196         private int mDirection;
197         private final Set<Integer> mControls = new HashSet<>();
198 
fromBundle(Bundle bundle)199         public static Call fromBundle(Bundle bundle) {
200             final Call call = new Call();
201             if (bundle != null) {
202                 call.setId(bundle.getString(CrossDeviceSyncController.EXTRA_CALL_ID));
203                 call.setCallerId(bundle.getString(EXTRA_CALLER_ID));
204                 call.setAppIcon(bundle.getByteArray(EXTRA_APP_ICON));
205                 final String facilitatorName = bundle.getString(EXTRA_FACILITATOR_NAME);
206                 final String facilitatorIdentifier = bundle.getString(EXTRA_FACILITATOR_ID);
207                 final String facilitatorExtendedIdentifier =
208                         bundle.getString(EXTRA_FACILITATOR_EXT_ID);
209                 call.setFacilitator(new CallFacilitator(facilitatorName, facilitatorIdentifier,
210                         facilitatorExtendedIdentifier));
211                 call.setStatus(bundle.getInt(EXTRA_STATUS));
212                 call.setDirection(bundle.getInt(EXTRA_DIRECTION));
213                 call.setControls(new HashSet<>(bundle.getIntegerArrayList(EXTRA_CONTROLS)));
214             }
215             return call;
216         }
217 
writeToBundle()218         public Bundle writeToBundle() {
219             final Bundle bundle = new Bundle();
220             bundle.putString(CrossDeviceSyncController.EXTRA_CALL_ID, mId);
221             bundle.putString(EXTRA_CALLER_ID, mCallerId);
222             bundle.putByteArray(EXTRA_APP_ICON, mAppIcon);
223             bundle.putString(EXTRA_FACILITATOR_NAME, mFacilitator.getName());
224             bundle.putString(EXTRA_FACILITATOR_ID, mFacilitator.getIdentifier());
225             bundle.putString(EXTRA_FACILITATOR_EXT_ID, mFacilitator.getExtendedIdentifier());
226             bundle.putInt(EXTRA_STATUS, mStatus);
227             bundle.putInt(EXTRA_DIRECTION, mDirection);
228             bundle.putIntegerArrayList(EXTRA_CONTROLS, new ArrayList<>(mControls));
229             return bundle;
230         }
231 
setId(String id)232         void setId(String id) {
233             mId = id;
234         }
235 
setCallerId(String callerId)236         void setCallerId(String callerId) {
237             mCallerId = callerId;
238         }
239 
setAppIcon(byte[] appIcon)240         void setAppIcon(byte[] appIcon) {
241             mAppIcon = appIcon;
242         }
243 
setFacilitator(CallFacilitator facilitator)244         void setFacilitator(CallFacilitator facilitator) {
245             mFacilitator = facilitator;
246         }
247 
setStatus(int status)248         void setStatus(int status) {
249             mStatus = status;
250         }
251 
setDirection(int direction)252         void setDirection(int direction) {
253             mDirection = direction;
254         }
255 
addControl(int control)256         void addControl(int control) {
257             mControls.add(control);
258         }
259 
setControls(Set<Integer> controls)260         void setControls(Set<Integer> controls) {
261             mControls.clear();
262             mControls.addAll(controls);
263         }
264 
getId()265         String getId() {
266             return mId;
267         }
268 
getCallerId()269         String getCallerId() {
270             return mCallerId;
271         }
272 
getAppIcon()273         byte[] getAppIcon() {
274             return mAppIcon;
275         }
276 
getFacilitator()277         CallFacilitator getFacilitator() {
278             return mFacilitator;
279         }
280 
getStatus()281         int getStatus() {
282             return mStatus;
283         }
284 
getDirection()285         int getDirection() {
286             return mDirection;
287         }
288 
getControls()289         Set<Integer> getControls() {
290             return mControls;
291         }
292 
hasControl(int control)293         boolean hasControl(int control) {
294             return mControls.contains(control);
295         }
296 
297         @Override
equals(Object other)298         public boolean equals(Object other) {
299             if (other instanceof CallMetadataSyncData.Call) {
300                 return mId != null && mId.equals(((Call) other).getId());
301             }
302             return false;
303         }
304 
305         @Override
hashCode()306         public int hashCode() {
307             return Objects.hashCode(mId);
308         }
309     }
310 }
311