blob: 8aa381c5354e50acee24cf1bb400bce352966fb6 [file] [log] [blame]
Alexandre Savard4a19d752012-09-19 13:19:24 -04001/*
Alexandre Lision68855472013-10-10 16:20:46 -04002 * Copyright (C) 2004-2013 Savoir-Faire Linux Inc.
Alexandre Savard4a19d752012-09-19 13:19:24 -04003 *
Alexandre Lision68855472013-10-10 16:20:46 -04004 * Author: Alexandre Lision <alexandre.lision@savoirfairelinux>
5 * Alexandre Savard <alexandre.savard@gmail.com>
Alexandre Savard4a19d752012-09-19 13:19:24 -04006 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 * Additional permission under GNU GPL version 3 section 7:
22 *
23 * If you modify this program, or any covered work, by linking or
24 * combining it with the OpenSSL project's OpenSSL library (or a
25 * modified version of that library), containing parts covered by the
26 * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
27 * grants you additional permission to convey the resulting work.
28 * Corresponding Source for a non-source form of such a combination
29 * shall include the source code for the parts of OpenSSL used as well
30 * as that of the covered work.
31 */
Alexandre Lision064e1e02013-10-01 16:18:42 -040032package org.sflphone.model;
Alexandre Savard4a19d752012-09-19 13:19:24 -040033
Alexandre Lision5ed2c972013-10-11 15:36:33 -040034import java.io.InvalidObjectException;
alisiona4325152013-04-19 11:10:03 -040035import java.util.ArrayList;
alisionfde875f2013-05-28 17:01:54 -040036import java.util.Random;
alisiona4325152013-04-19 11:10:03 -040037
Alexandre Lision5ed2c972013-10-11 15:36:33 -040038import org.sflphone.service.StringMap;
39
alision806e18e2013-06-21 15:30:17 -040040import android.content.ContentResolver;
Alexandre Savard557a5742012-10-24 13:54:53 -040041import android.os.Parcel;
alisiona4325152013-04-19 11:10:03 -040042import android.os.Parcelable;
Alexandre Savard4a19d752012-09-19 13:19:24 -040043import android.util.Log;
Alexandre Savard4a19d752012-09-19 13:19:24 -040044
alisionfde875f2013-05-28 17:01:54 -040045public class SipCall implements Parcelable {
alision371b77e2013-04-23 14:51:26 -040046
alisionfde875f2013-05-28 17:01:54 -040047 private static final String TAG = SipCall.class.getSimpleName();
Alexandre Savard2f1ae542012-10-26 17:05:00 -040048
alisionfde875f2013-05-28 17:01:54 -040049 private String mCallID = "";
Alexandre Lision3ee516e2013-10-07 17:32:15 -040050 private Account mAccount = null;
alision907bde72013-06-20 14:40:37 -040051 private CallContact contact = null;
alisiondf1dac92013-06-27 17:35:53 -040052 private boolean isRecording = false;
Alexandre Lision3c6b7102013-09-16 16:56:46 -040053 private long timestamp_start = 0;
alisiondf1dac92013-06-27 17:35:53 -040054
alision50fa0722013-06-25 17:29:44 -040055 public static final String USER_ID = "user_id";
Alexandre Savard2b01c822012-09-20 15:00:37 -040056
alisionfde875f2013-05-28 17:01:54 -040057 private int mCallType = state.CALL_TYPE_UNDETERMINED;
58 private int mCallState = state.CALL_STATE_NONE;
59 private int mMediaState = state.MEDIA_STATE_NONE;
Alexandre Savard2b01c822012-09-20 15:00:37 -040060
alisionfde875f2013-05-28 17:01:54 -040061 /************************
62 * Construtors
alisionfde875f2013-05-28 17:01:54 -040063 ***********************/
Alexandre Savard557a5742012-10-24 13:54:53 -040064
alisionfde875f2013-05-28 17:01:54 -040065 private SipCall(Parcel in) {
66 ArrayList<String> list = in.createStringArrayList();
Alexandre Savard557a5742012-10-24 13:54:53 -040067
alisionfde875f2013-05-28 17:01:54 -040068 mCallID = list.get(0);
Alexandre Lision3ee516e2013-10-07 17:32:15 -040069 mAccount = in.readParcelable(Account.class.getClassLoader());
alision907bde72013-06-20 14:40:37 -040070 contact = in.readParcelable(CallContact.class.getClassLoader());
alisiondf1dac92013-06-27 17:35:53 -040071 isRecording = in.readByte() == 1;
alisionfde875f2013-05-28 17:01:54 -040072 mCallType = in.readInt();
73 mCallState = in.readInt();
74 mMediaState = in.readInt();
Alexandre Lisionebeb3662013-09-17 16:20:54 -040075 timestamp_start = in.readLong();
Alexandre Savard7a46f542012-09-20 11:23:33 -040076 }
Alexandre Savard4a19d752012-09-19 13:19:24 -040077
Alexandre Lision3ee516e2013-10-07 17:32:15 -040078 public SipCall(String id, Account account, int call_type, int call_state, int media_state, CallContact c) {
alisionfde875f2013-05-28 17:01:54 -040079 mCallID = id;
Alexandre Lision3ee516e2013-10-07 17:32:15 -040080 mAccount = account;
alisionfde875f2013-05-28 17:01:54 -040081 mCallType = call_type;
82 mCallState = call_state;
83 mMediaState = media_state;
alision907bde72013-06-20 14:40:37 -040084 contact = c;
Alexandre Savard4a19d752012-09-19 13:19:24 -040085 }
86
alisionfde875f2013-05-28 17:01:54 -040087 public interface state {
88 public static final int CALL_TYPE_UNDETERMINED = 0;
89 public static final int CALL_TYPE_INCOMING = 1;
90 public static final int CALL_TYPE_OUTGOING = 2;
91
92 public static final int CALL_STATE_NONE = 0;
93 public static final int CALL_STATE_INCOMING = 1;
94 public static final int CALL_STATE_RINGING = 2;
95 public static final int CALL_STATE_CURRENT = 3;
96 public static final int CALL_STATE_HUNGUP = 4;
97 public static final int CALL_STATE_BUSY = 5;
98 public static final int CALL_STATE_FAILURE = 6;
99 public static final int CALL_STATE_HOLD = 7;
100 public static final int CALL_STATE_UNHOLD = 8;
101
102 public static final int MEDIA_STATE_NONE = 0; // No media currently
103 public static final int MEDIA_STATE_ACTIVE = 1; // Media is active
104 public static final int MEDIA_STATE_LOCAL_HOLD = 2; // Media is put on hold bu user
105 public static final int MEDIA_STATE_REMOTE_HOLD = 3; // Media is put on hold by peer
106 public static final int MEDIA_STATE_ERROR = 5; // Media is in error state
Alexandre Savard4a19d752012-09-19 13:19:24 -0400107 }
108
alisionfde875f2013-05-28 17:01:54 -0400109 @Override
110 public int describeContents() {
111 return 0;
112 }
113
114 @Override
115 public void writeToParcel(Parcel out, int flags) {
116 ArrayList<String> list = new ArrayList<String>();
117
alisionfde875f2013-05-28 17:01:54 -0400118 list.add(mCallID);
alisionfde875f2013-05-28 17:01:54 -0400119
120 out.writeStringList(list);
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400121 out.writeParcelable(mAccount, 0);
122
alision907bde72013-06-20 14:40:37 -0400123 out.writeParcelable(contact, 0);
alisiondf1dac92013-06-27 17:35:53 -0400124 out.writeByte((byte) (isRecording ? 1 : 0));
alisionfde875f2013-05-28 17:01:54 -0400125 out.writeInt(mCallType);
126 out.writeInt(mCallState);
127 out.writeInt(mMediaState);
Alexandre Lisionebeb3662013-09-17 16:20:54 -0400128 out.writeLong(timestamp_start);
alisionfde875f2013-05-28 17:01:54 -0400129 }
130
131 public static final Parcelable.Creator<SipCall> CREATOR = new Parcelable.Creator<SipCall>() {
132 public SipCall createFromParcel(Parcel in) {
133 return new SipCall(in);
134 }
135
136 public SipCall[] newArray(int size) {
137 return new SipCall[size];
138 }
139 };
140
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400141 public void setCallID(String callID) {
alisionfde875f2013-05-28 17:01:54 -0400142 mCallID = callID;
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400143 }
144
145 public String getCallId() {
alisionfde875f2013-05-28 17:01:54 -0400146 return mCallID;
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400147 }
148
Alexandre Lision3c6b7102013-09-16 16:56:46 -0400149 public long getTimestamp_start() {
150 return timestamp_start;
151 }
152
Alexandre Lision3c6b7102013-09-16 16:56:46 -0400153 public void setTimestamp_start(long timestamp_start) {
154 this.timestamp_start = timestamp_start;
155 }
156
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400157 public void setAccount(Account account) {
158 mAccount = account;
Alexandre Savard73bc56f2012-10-25 13:35:54 -0400159 }
160
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400161 public Account getAccount() {
162 return mAccount;
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400163 }
164
Alexandre Savard2f1ae542012-10-26 17:05:00 -0400165 public void setCallType(int callType) {
alisionfde875f2013-05-28 17:01:54 -0400166 mCallType = callType;
Alexandre Savard2f1ae542012-10-26 17:05:00 -0400167 }
168
169 public int getCallType() {
alisionfde875f2013-05-28 17:01:54 -0400170 return mCallType;
Alexandre Savard2f1ae542012-10-26 17:05:00 -0400171 }
172
alision85704182013-05-29 15:23:03 -0400173 public String getCallTypeString() {
174 switch (mCallType) {
175 case state.CALL_TYPE_INCOMING:
176 return "CALL_TYPE_INCOMING";
177 case state.CALL_TYPE_OUTGOING:
178 return "CALL_TYPE_OUTGOING";
179 default:
180 return "CALL_TYPE_UNDETERMINED";
181 }
182 }
183
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400184 public void setCallState(int callState) {
alisionfde875f2013-05-28 17:01:54 -0400185 mCallState = callState;
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400186 }
187
Alexandre Savarddf544262012-10-25 14:24:08 -0400188 public int getCallStateInt() {
alisionfde875f2013-05-28 17:01:54 -0400189 return mCallState;
190 }
191
192 public String getmCallID() {
193 return mCallID;
194 }
195
196 public void setmCallID(String mCallID) {
197 this.mCallID = mCallID;
198 }
199
alision907bde72013-06-20 14:40:37 -0400200 public CallContact getContact() {
201 return contact;
alisionfde875f2013-05-28 17:01:54 -0400202 }
203
alision907bde72013-06-20 14:40:37 -0400204 public void setContact(CallContact contacts) {
205 contact = contacts;
alisionfde875f2013-05-28 17:01:54 -0400206 }
207
208 public int getmCallType() {
209 return mCallType;
210 }
211
212 public void setmCallType(int mCallType) {
213 this.mCallType = mCallType;
214 }
215
alisionfde875f2013-05-28 17:01:54 -0400216 public int getmMediaState() {
217 return mMediaState;
218 }
219
220 public void setmMediaState(int mMediaState) {
221 this.mMediaState = mMediaState;
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400222 }
223
Alexandre Savarddf544262012-10-25 14:24:08 -0400224 public String getCallStateString() {
Alexandre Savarddf544262012-10-25 14:24:08 -0400225
alisionfde875f2013-05-28 17:01:54 -0400226 String text_state;
227
228 switch (mCallState) {
229 case state.CALL_STATE_INCOMING:
230 text_state = "INCOMING";
alision11e8e162013-05-28 10:33:14 -0400231 break;
alisionfde875f2013-05-28 17:01:54 -0400232 case state.CALL_STATE_RINGING:
233 text_state = "RINGING";
alision11e8e162013-05-28 10:33:14 -0400234 break;
alisionfde875f2013-05-28 17:01:54 -0400235 case state.CALL_STATE_CURRENT:
236 text_state = "CURRENT";
alision11e8e162013-05-28 10:33:14 -0400237 break;
alisionfde875f2013-05-28 17:01:54 -0400238 case state.CALL_STATE_HUNGUP:
239 text_state = "HUNGUP";
alision11e8e162013-05-28 10:33:14 -0400240 break;
alisionfde875f2013-05-28 17:01:54 -0400241 case state.CALL_STATE_BUSY:
242 text_state = "BUSY";
alision11e8e162013-05-28 10:33:14 -0400243 break;
alisionfde875f2013-05-28 17:01:54 -0400244 case state.CALL_STATE_FAILURE:
245 text_state = "FAILURE";
alision11e8e162013-05-28 10:33:14 -0400246 break;
alisionfde875f2013-05-28 17:01:54 -0400247 case state.CALL_STATE_HOLD:
248 text_state = "HOLD";
alision11e8e162013-05-28 10:33:14 -0400249 break;
alisionfde875f2013-05-28 17:01:54 -0400250 case state.CALL_STATE_UNHOLD:
251 text_state = "UNHOLD";
alision11e8e162013-05-28 10:33:14 -0400252 break;
253 default:
alisionfde875f2013-05-28 17:01:54 -0400254 text_state = "NULL";
Alexandre Savarddf544262012-10-25 14:24:08 -0400255 }
256
alisionfde875f2013-05-28 17:01:54 -0400257 return text_state;
Alexandre Savarddf544262012-10-25 14:24:08 -0400258 }
259
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400260 public void setMediaState(int mediaState) {
alisionfde875f2013-05-28 17:01:54 -0400261 mMediaState = mediaState;
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400262 }
263
264 public int getMediaState() {
alisionfde875f2013-05-28 17:01:54 -0400265 return mMediaState;
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400266 }
267
alisiondf1dac92013-06-27 17:35:53 -0400268 public boolean isRecording() {
269 return isRecording;
270 }
271
272 public void setRecording(boolean isRecording) {
273 this.isRecording = isRecording;
274 }
275
alisionfde875f2013-05-28 17:01:54 -0400276 public static class SipCallBuilder {
277
278 private String bCallID = "";
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400279 private Account bAccount = null;
alision907bde72013-06-20 14:40:37 -0400280 private CallContact bContact = null;
alisionfde875f2013-05-28 17:01:54 -0400281
282 private int bCallType = state.CALL_TYPE_UNDETERMINED;
283 private int bCallState = state.CALL_STATE_NONE;
284 private int bMediaState = state.MEDIA_STATE_NONE;
285
alisionfde875f2013-05-28 17:01:54 -0400286 public SipCallBuilder setCallType(int bCallType) {
287 this.bCallType = bCallType;
288 return this;
289 }
290
291 public SipCallBuilder setMediaState(int state) {
292 this.bMediaState = state;
293 return this;
294 }
295
296 public SipCallBuilder setCallState(int state) {
297 this.bCallState = state;
298 return this;
299 }
alision85704182013-05-29 15:23:03 -0400300
alisionfde875f2013-05-28 17:01:54 -0400301 private static final String TAG = SipCallBuilder.class.getSimpleName();
alision85704182013-05-29 15:23:03 -0400302
alisionfde875f2013-05-28 17:01:54 -0400303 public SipCallBuilder startCallCreation(String id) {
304 bCallID = id;
alisionfde875f2013-05-28 17:01:54 -0400305 bCallType = SipCall.state.CALL_TYPE_INCOMING;
306 return this;
307 }
308
309 public SipCallBuilder startCallCreation() {
310 Random random = new Random();
Tristan Matthews1a4962d2013-07-18 16:27:10 -0400311 bCallID = Integer.toString(Math.abs(random.nextInt()));
alisionfde875f2013-05-28 17:01:54 -0400312 return this;
313 }
314
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400315 public SipCallBuilder setAccount(Account a) {
316 bAccount = a;
alisionfde875f2013-05-28 17:01:54 -0400317 return this;
318 }
319
alision907bde72013-06-20 14:40:37 -0400320 public SipCallBuilder setContact(CallContact c) {
321 bContact = c;
alisionfde875f2013-05-28 17:01:54 -0400322 return this;
323 }
324
Alexandre Lision5ed2c972013-10-11 15:36:33 -0400325 public SipCall build() throws InvalidObjectException {
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400326 if (bCallID.contentEquals("") || bAccount == null || bContact == null) {
Alexandre Lision5ed2c972013-10-11 15:36:33 -0400327 throw new InvalidObjectException("SipCallBuilder's parameters missing");
alisionfde875f2013-05-28 17:01:54 -0400328 }
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400329 return new SipCall(bCallID, bAccount, bCallType, bCallState, bMediaState, bContact);
alisionfde875f2013-05-28 17:01:54 -0400330 }
331
332 public static SipCallBuilder getInstance() {
333 return new SipCallBuilder();
334 }
335
alision806e18e2013-06-21 15:30:17 -0400336 public static SipCall buildMyselfCall(ContentResolver cr, String displayName) {
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400337 return new SipCall("default", null, SipCall.state.CALL_TYPE_UNDETERMINED, state.CALL_STATE_NONE, state.MEDIA_STATE_NONE,
alisiondf1dac92013-06-27 17:35:53 -0400338 CallContact.ContactBuilder.buildUserContact(cr, displayName));
alision806e18e2013-06-21 15:30:17 -0400339
340 }
341
alisionfde875f2013-05-28 17:01:54 -0400342 }
343
alision85704182013-05-29 15:23:03 -0400344 public void printCallInfo() {
345 Log.i(TAG, "CallInfo: CallID: " + mCallID);
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400346 Log.i(TAG, " AccountID: " + mAccount.getAccountID());
alision85704182013-05-29 15:23:03 -0400347 Log.i(TAG, " CallState: " + mCallState);
348 Log.i(TAG, " CallType: " + mCallType);
349 }
Alexandre Savard73bc56f2012-10-25 13:35:54 -0400350
alision5f899632013-04-22 17:26:56 -0400351 /**
352 * Compare sip calls based on call ID
353 */
354 @Override
alision11e8e162013-05-28 10:33:14 -0400355 public boolean equals(Object c) {
alision465ceba2013-07-04 09:24:30 -0400356 if (c instanceof SipCall && ((SipCall) c).mCallID.contentEquals((mCallID))) {
alision5f899632013-04-22 17:26:56 -0400357 return true;
358 }
359 return false;
alision11e8e162013-05-28 10:33:14 -0400360
alision5f899632013-04-22 17:26:56 -0400361 }
alision7f18fc82013-05-01 09:37:33 -0400362
alision85704182013-05-29 15:23:03 -0400363 public boolean isOutGoing() {
364 if (mCallType == state.CALL_TYPE_OUTGOING)
365 return true;
366
367 return false;
368 }
369
370 public boolean isRinging() {
371 if (mCallState == state.CALL_STATE_RINGING || mCallState == state.CALL_STATE_NONE)
372 return true;
373
374 return false;
375 }
376
377 public boolean isIncoming() {
378 if (mCallType == state.CALL_TYPE_INCOMING)
379 return true;
380
381 return false;
382 }
383
384 public void setCallState(String newState) {
385 if (newState.equals("INCOMING")) {
386 setCallState(SipCall.state.CALL_STATE_INCOMING);
387 } else if (newState.equals("RINGING")) {
388 setCallState(SipCall.state.CALL_STATE_RINGING);
389 } else if (newState.equals("CURRENT")) {
390 setCallState(SipCall.state.CALL_STATE_CURRENT);
391 } else if (newState.equals("HUNGUP")) {
392 setCallState(SipCall.state.CALL_STATE_HUNGUP);
393 } else if (newState.equals("BUSY")) {
394 setCallState(SipCall.state.CALL_STATE_BUSY);
395 } else if (newState.equals("FAILURE")) {
396 setCallState(SipCall.state.CALL_STATE_FAILURE);
397 } else if (newState.equals("HOLD")) {
398 setCallState(SipCall.state.CALL_STATE_HOLD);
399 } else if (newState.equals("UNHOLD")) {
400 setCallState(SipCall.state.CALL_STATE_CURRENT);
401 } else {
402 setCallState(SipCall.state.CALL_STATE_NONE);
403 }
alision907bde72013-06-20 14:40:37 -0400404
alision85704182013-05-29 15:23:03 -0400405 }
406
407 public boolean isOngoing() {
alision907bde72013-06-20 14:40:37 -0400408 if (mCallState == state.CALL_STATE_RINGING || mCallState == state.CALL_STATE_NONE || mCallState == state.CALL_STATE_FAILURE
409 || mCallState == state.CALL_STATE_BUSY || mCallState == state.CALL_STATE_HUNGUP)
alision85704182013-05-29 15:23:03 -0400410 return false;
411
412 return true;
413 }
alision04a00182013-05-10 17:05:29 -0400414
alisiondf1dac92013-06-27 17:35:53 -0400415 public boolean isOnHold() {
416 return mCallState == state.CALL_STATE_HOLD;
417 }
418
Alexandre Lision6ae652d2013-09-26 16:39:20 -0400419 public boolean isCurrent() {
420 return mCallState == state.CALL_STATE_CURRENT;
421 }
422
Alexandre Savard4a19d752012-09-19 13:19:24 -0400423}