blob: 63989f53efb3ac7d4669e56a5cf65b0dd91ff710 [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
Alexandre Savard2b01c822012-09-20 15:00:37 -040055
alisionfde875f2013-05-28 17:01:54 -040056 private int mCallType = state.CALL_TYPE_UNDETERMINED;
57 private int mCallState = state.CALL_STATE_NONE;
58 private int mMediaState = state.MEDIA_STATE_NONE;
Alexandre Lisiond5686032013-10-29 11:09:21 -040059
60 ArrayList<SipMessage> messages;
Alexandre Savard2b01c822012-09-20 15:00:37 -040061
alisionfde875f2013-05-28 17:01:54 -040062 /************************
63 * Construtors
alisionfde875f2013-05-28 17:01:54 -040064 ***********************/
Alexandre Savard557a5742012-10-24 13:54:53 -040065
alisionfde875f2013-05-28 17:01:54 -040066 private SipCall(Parcel in) {
Alexandre Savard557a5742012-10-24 13:54:53 -040067
Alexandre Lisiond5686032013-10-29 11:09:21 -040068 mCallID = in.readString();
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 Lisiond5686032013-10-29 11:09:21 -040076
77 messages = new ArrayList<SipMessage>();
78 in.readTypedList(messages, SipMessage.CREATOR);
Alexandre Savard7a46f542012-09-20 11:23:33 -040079 }
Alexandre Savard4a19d752012-09-19 13:19:24 -040080
Alexandre Lision3ee516e2013-10-07 17:32:15 -040081 public SipCall(String id, Account account, int call_type, int call_state, int media_state, CallContact c) {
alisionfde875f2013-05-28 17:01:54 -040082 mCallID = id;
Alexandre Lision3ee516e2013-10-07 17:32:15 -040083 mAccount = account;
alisionfde875f2013-05-28 17:01:54 -040084 mCallType = call_type;
85 mCallState = call_state;
86 mMediaState = media_state;
alision907bde72013-06-20 14:40:37 -040087 contact = c;
Alexandre Lisiond5686032013-10-29 11:09:21 -040088 messages = new ArrayList<SipMessage>();
Alexandre Savard4a19d752012-09-19 13:19:24 -040089 }
90
alisionfde875f2013-05-28 17:01:54 -040091 public interface state {
92 public static final int CALL_TYPE_UNDETERMINED = 0;
93 public static final int CALL_TYPE_INCOMING = 1;
94 public static final int CALL_TYPE_OUTGOING = 2;
95
96 public static final int CALL_STATE_NONE = 0;
97 public static final int CALL_STATE_INCOMING = 1;
98 public static final int CALL_STATE_RINGING = 2;
99 public static final int CALL_STATE_CURRENT = 3;
100 public static final int CALL_STATE_HUNGUP = 4;
101 public static final int CALL_STATE_BUSY = 5;
102 public static final int CALL_STATE_FAILURE = 6;
103 public static final int CALL_STATE_HOLD = 7;
104 public static final int CALL_STATE_UNHOLD = 8;
105
106 public static final int MEDIA_STATE_NONE = 0; // No media currently
107 public static final int MEDIA_STATE_ACTIVE = 1; // Media is active
108 public static final int MEDIA_STATE_LOCAL_HOLD = 2; // Media is put on hold bu user
109 public static final int MEDIA_STATE_REMOTE_HOLD = 3; // Media is put on hold by peer
110 public static final int MEDIA_STATE_ERROR = 5; // Media is in error state
Alexandre Savard4a19d752012-09-19 13:19:24 -0400111 }
112
alisionfde875f2013-05-28 17:01:54 -0400113 @Override
114 public int describeContents() {
115 return 0;
116 }
117
118 @Override
119 public void writeToParcel(Parcel out, int flags) {
alisionfde875f2013-05-28 17:01:54 -0400120
Alexandre Lisiond5686032013-10-29 11:09:21 -0400121 out.writeString(mCallID);
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400122 out.writeParcelable(mAccount, 0);
123
alision907bde72013-06-20 14:40:37 -0400124 out.writeParcelable(contact, 0);
alisiondf1dac92013-06-27 17:35:53 -0400125 out.writeByte((byte) (isRecording ? 1 : 0));
alisionfde875f2013-05-28 17:01:54 -0400126 out.writeInt(mCallType);
127 out.writeInt(mCallState);
128 out.writeInt(mMediaState);
Alexandre Lisionebeb3662013-09-17 16:20:54 -0400129 out.writeLong(timestamp_start);
Alexandre Lisiond5686032013-10-29 11:09:21 -0400130
131 out.writeTypedList(messages);
alisionfde875f2013-05-28 17:01:54 -0400132 }
133
134 public static final Parcelable.Creator<SipCall> CREATOR = new Parcelable.Creator<SipCall>() {
135 public SipCall createFromParcel(Parcel in) {
136 return new SipCall(in);
137 }
138
139 public SipCall[] newArray(int size) {
140 return new SipCall[size];
141 }
142 };
143
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400144 public void setCallID(String callID) {
alisionfde875f2013-05-28 17:01:54 -0400145 mCallID = callID;
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400146 }
147
148 public String getCallId() {
alisionfde875f2013-05-28 17:01:54 -0400149 return mCallID;
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400150 }
151
Alexandre Lision3c6b7102013-09-16 16:56:46 -0400152 public long getTimestamp_start() {
153 return timestamp_start;
154 }
155
Alexandre Lision3c6b7102013-09-16 16:56:46 -0400156 public void setTimestamp_start(long timestamp_start) {
157 this.timestamp_start = timestamp_start;
158 }
159
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400160 public void setAccount(Account account) {
161 mAccount = account;
Alexandre Savard73bc56f2012-10-25 13:35:54 -0400162 }
163
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400164 public Account getAccount() {
165 return mAccount;
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400166 }
167
Alexandre Savard2f1ae542012-10-26 17:05:00 -0400168 public void setCallType(int callType) {
alisionfde875f2013-05-28 17:01:54 -0400169 mCallType = callType;
Alexandre Savard2f1ae542012-10-26 17:05:00 -0400170 }
171
172 public int getCallType() {
alisionfde875f2013-05-28 17:01:54 -0400173 return mCallType;
Alexandre Savard2f1ae542012-10-26 17:05:00 -0400174 }
175
alision85704182013-05-29 15:23:03 -0400176 public String getCallTypeString() {
177 switch (mCallType) {
178 case state.CALL_TYPE_INCOMING:
179 return "CALL_TYPE_INCOMING";
180 case state.CALL_TYPE_OUTGOING:
181 return "CALL_TYPE_OUTGOING";
182 default:
183 return "CALL_TYPE_UNDETERMINED";
184 }
185 }
186
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400187 public void setCallState(int callState) {
alisionfde875f2013-05-28 17:01:54 -0400188 mCallState = callState;
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400189 }
190
Alexandre Savarddf544262012-10-25 14:24:08 -0400191 public int getCallStateInt() {
alisionfde875f2013-05-28 17:01:54 -0400192 return mCallState;
193 }
194
195 public String getmCallID() {
196 return mCallID;
197 }
198
199 public void setmCallID(String mCallID) {
200 this.mCallID = mCallID;
201 }
202
alision907bde72013-06-20 14:40:37 -0400203 public CallContact getContact() {
204 return contact;
alisionfde875f2013-05-28 17:01:54 -0400205 }
206
alision907bde72013-06-20 14:40:37 -0400207 public void setContact(CallContact contacts) {
208 contact = contacts;
alisionfde875f2013-05-28 17:01:54 -0400209 }
210
211 public int getmCallType() {
212 return mCallType;
213 }
214
215 public void setmCallType(int mCallType) {
216 this.mCallType = mCallType;
217 }
218
alisionfde875f2013-05-28 17:01:54 -0400219 public int getmMediaState() {
220 return mMediaState;
221 }
222
223 public void setmMediaState(int mMediaState) {
224 this.mMediaState = mMediaState;
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400225 }
226
Alexandre Savarddf544262012-10-25 14:24:08 -0400227 public String getCallStateString() {
Alexandre Savarddf544262012-10-25 14:24:08 -0400228
alisionfde875f2013-05-28 17:01:54 -0400229 String text_state;
230
231 switch (mCallState) {
232 case state.CALL_STATE_INCOMING:
233 text_state = "INCOMING";
alision11e8e162013-05-28 10:33:14 -0400234 break;
alisionfde875f2013-05-28 17:01:54 -0400235 case state.CALL_STATE_RINGING:
236 text_state = "RINGING";
alision11e8e162013-05-28 10:33:14 -0400237 break;
alisionfde875f2013-05-28 17:01:54 -0400238 case state.CALL_STATE_CURRENT:
239 text_state = "CURRENT";
alision11e8e162013-05-28 10:33:14 -0400240 break;
alisionfde875f2013-05-28 17:01:54 -0400241 case state.CALL_STATE_HUNGUP:
242 text_state = "HUNGUP";
alision11e8e162013-05-28 10:33:14 -0400243 break;
alisionfde875f2013-05-28 17:01:54 -0400244 case state.CALL_STATE_BUSY:
245 text_state = "BUSY";
alision11e8e162013-05-28 10:33:14 -0400246 break;
alisionfde875f2013-05-28 17:01:54 -0400247 case state.CALL_STATE_FAILURE:
248 text_state = "FAILURE";
alision11e8e162013-05-28 10:33:14 -0400249 break;
alisionfde875f2013-05-28 17:01:54 -0400250 case state.CALL_STATE_HOLD:
251 text_state = "HOLD";
alision11e8e162013-05-28 10:33:14 -0400252 break;
alisionfde875f2013-05-28 17:01:54 -0400253 case state.CALL_STATE_UNHOLD:
254 text_state = "UNHOLD";
alision11e8e162013-05-28 10:33:14 -0400255 break;
256 default:
alisionfde875f2013-05-28 17:01:54 -0400257 text_state = "NULL";
Alexandre Savarddf544262012-10-25 14:24:08 -0400258 }
259
alisionfde875f2013-05-28 17:01:54 -0400260 return text_state;
Alexandre Savarddf544262012-10-25 14:24:08 -0400261 }
262
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400263 public void setMediaState(int mediaState) {
alisionfde875f2013-05-28 17:01:54 -0400264 mMediaState = mediaState;
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400265 }
266
267 public int getMediaState() {
alisionfde875f2013-05-28 17:01:54 -0400268 return mMediaState;
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400269 }
270
alisiondf1dac92013-06-27 17:35:53 -0400271 public boolean isRecording() {
272 return isRecording;
273 }
274
275 public void setRecording(boolean isRecording) {
276 this.isRecording = isRecording;
277 }
278
alisionfde875f2013-05-28 17:01:54 -0400279 public static class SipCallBuilder {
280
281 private String bCallID = "";
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400282 private Account bAccount = null;
alision907bde72013-06-20 14:40:37 -0400283 private CallContact bContact = null;
alisionfde875f2013-05-28 17:01:54 -0400284
285 private int bCallType = state.CALL_TYPE_UNDETERMINED;
286 private int bCallState = state.CALL_STATE_NONE;
287 private int bMediaState = state.MEDIA_STATE_NONE;
288
alisionfde875f2013-05-28 17:01:54 -0400289 public SipCallBuilder setCallType(int bCallType) {
290 this.bCallType = bCallType;
291 return this;
292 }
293
294 public SipCallBuilder setMediaState(int state) {
295 this.bMediaState = state;
296 return this;
297 }
298
299 public SipCallBuilder setCallState(int state) {
300 this.bCallState = state;
301 return this;
302 }
alision85704182013-05-29 15:23:03 -0400303
alisionfde875f2013-05-28 17:01:54 -0400304 private static final String TAG = SipCallBuilder.class.getSimpleName();
alision85704182013-05-29 15:23:03 -0400305
alisionfde875f2013-05-28 17:01:54 -0400306 public SipCallBuilder startCallCreation(String id) {
307 bCallID = id;
alisionfde875f2013-05-28 17:01:54 -0400308 bCallType = SipCall.state.CALL_TYPE_INCOMING;
309 return this;
310 }
311
312 public SipCallBuilder startCallCreation() {
313 Random random = new Random();
Tristan Matthews1a4962d2013-07-18 16:27:10 -0400314 bCallID = Integer.toString(Math.abs(random.nextInt()));
alisionfde875f2013-05-28 17:01:54 -0400315 return this;
316 }
317
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400318 public SipCallBuilder setAccount(Account a) {
319 bAccount = a;
alisionfde875f2013-05-28 17:01:54 -0400320 return this;
321 }
322
alision907bde72013-06-20 14:40:37 -0400323 public SipCallBuilder setContact(CallContact c) {
324 bContact = c;
alisionfde875f2013-05-28 17:01:54 -0400325 return this;
326 }
327
Alexandre Lision5ed2c972013-10-11 15:36:33 -0400328 public SipCall build() throws InvalidObjectException {
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400329 if (bCallID.contentEquals("") || bAccount == null || bContact == null) {
Alexandre Lision5ed2c972013-10-11 15:36:33 -0400330 throw new InvalidObjectException("SipCallBuilder's parameters missing");
alisionfde875f2013-05-28 17:01:54 -0400331 }
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400332 return new SipCall(bCallID, bAccount, bCallType, bCallState, bMediaState, bContact);
alisionfde875f2013-05-28 17:01:54 -0400333 }
334
335 public static SipCallBuilder getInstance() {
336 return new SipCallBuilder();
337 }
338
alision806e18e2013-06-21 15:30:17 -0400339 public static SipCall buildMyselfCall(ContentResolver cr, String displayName) {
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400340 return new SipCall("default", null, SipCall.state.CALL_TYPE_UNDETERMINED, state.CALL_STATE_NONE, state.MEDIA_STATE_NONE,
alisiondf1dac92013-06-27 17:35:53 -0400341 CallContact.ContactBuilder.buildUserContact(cr, displayName));
alision806e18e2013-06-21 15:30:17 -0400342
343 }
344
alisionfde875f2013-05-28 17:01:54 -0400345 }
346
alision85704182013-05-29 15:23:03 -0400347 public void printCallInfo() {
348 Log.i(TAG, "CallInfo: CallID: " + mCallID);
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400349 Log.i(TAG, " AccountID: " + mAccount.getAccountID());
alision85704182013-05-29 15:23:03 -0400350 Log.i(TAG, " CallState: " + mCallState);
351 Log.i(TAG, " CallType: " + mCallType);
352 }
Alexandre Savard73bc56f2012-10-25 13:35:54 -0400353
alision5f899632013-04-22 17:26:56 -0400354 /**
355 * Compare sip calls based on call ID
356 */
357 @Override
alision11e8e162013-05-28 10:33:14 -0400358 public boolean equals(Object c) {
alision465ceba2013-07-04 09:24:30 -0400359 if (c instanceof SipCall && ((SipCall) c).mCallID.contentEquals((mCallID))) {
alision5f899632013-04-22 17:26:56 -0400360 return true;
361 }
362 return false;
alision11e8e162013-05-28 10:33:14 -0400363
alision5f899632013-04-22 17:26:56 -0400364 }
alision7f18fc82013-05-01 09:37:33 -0400365
alision85704182013-05-29 15:23:03 -0400366 public boolean isOutGoing() {
367 if (mCallType == state.CALL_TYPE_OUTGOING)
368 return true;
369
370 return false;
371 }
372
373 public boolean isRinging() {
374 if (mCallState == state.CALL_STATE_RINGING || mCallState == state.CALL_STATE_NONE)
375 return true;
376
377 return false;
378 }
379
380 public boolean isIncoming() {
381 if (mCallType == state.CALL_TYPE_INCOMING)
382 return true;
383
384 return false;
385 }
386
387 public void setCallState(String newState) {
388 if (newState.equals("INCOMING")) {
389 setCallState(SipCall.state.CALL_STATE_INCOMING);
390 } else if (newState.equals("RINGING")) {
391 setCallState(SipCall.state.CALL_STATE_RINGING);
392 } else if (newState.equals("CURRENT")) {
393 setCallState(SipCall.state.CALL_STATE_CURRENT);
394 } else if (newState.equals("HUNGUP")) {
395 setCallState(SipCall.state.CALL_STATE_HUNGUP);
396 } else if (newState.equals("BUSY")) {
397 setCallState(SipCall.state.CALL_STATE_BUSY);
398 } else if (newState.equals("FAILURE")) {
399 setCallState(SipCall.state.CALL_STATE_FAILURE);
400 } else if (newState.equals("HOLD")) {
401 setCallState(SipCall.state.CALL_STATE_HOLD);
402 } else if (newState.equals("UNHOLD")) {
403 setCallState(SipCall.state.CALL_STATE_CURRENT);
404 } else {
405 setCallState(SipCall.state.CALL_STATE_NONE);
406 }
alision907bde72013-06-20 14:40:37 -0400407
alision85704182013-05-29 15:23:03 -0400408 }
409
410 public boolean isOngoing() {
alision907bde72013-06-20 14:40:37 -0400411 if (mCallState == state.CALL_STATE_RINGING || mCallState == state.CALL_STATE_NONE || mCallState == state.CALL_STATE_FAILURE
412 || mCallState == state.CALL_STATE_BUSY || mCallState == state.CALL_STATE_HUNGUP)
alision85704182013-05-29 15:23:03 -0400413 return false;
414
415 return true;
416 }
alision04a00182013-05-10 17:05:29 -0400417
alisiondf1dac92013-06-27 17:35:53 -0400418 public boolean isOnHold() {
419 return mCallState == state.CALL_STATE_HOLD;
420 }
421
Alexandre Lision6ae652d2013-09-26 16:39:20 -0400422 public boolean isCurrent() {
423 return mCallState == state.CALL_STATE_CURRENT;
424 }
425
Alexandre Lisiond5686032013-10-29 11:09:21 -0400426 public void addSipMessage(SipMessage message) {
427 messages.add(message);
428 }
429
430 public ArrayList<SipMessage> getMessages() {
431 return messages;
432 }
433
Alexandre Savard4a19d752012-09-19 13:19:24 -0400434}