blob: 479d83377e56e5768bcc6b9410203feca4ee4ae1 [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
alision806e18e2013-06-21 15:30:17 -040038import android.content.ContentResolver;
Alexandre Savard557a5742012-10-24 13:54:53 -040039import android.os.Parcel;
alisiona4325152013-04-19 11:10:03 -040040import android.os.Parcelable;
Alexandre Savard4a19d752012-09-19 13:19:24 -040041import android.util.Log;
Alexandre Savard4a19d752012-09-19 13:19:24 -040042
alisionfde875f2013-05-28 17:01:54 -040043public class SipCall implements Parcelable {
alision371b77e2013-04-23 14:51:26 -040044
alisionfde875f2013-05-28 17:01:54 -040045 private static final String TAG = SipCall.class.getSimpleName();
Alexandre Savard2f1ae542012-10-26 17:05:00 -040046
alisionfde875f2013-05-28 17:01:54 -040047 private String mCallID = "";
Alexandre Lision3ee516e2013-10-07 17:32:15 -040048 private Account mAccount = null;
alision907bde72013-06-20 14:40:37 -040049 private CallContact contact = null;
alisiondf1dac92013-06-27 17:35:53 -040050 private boolean isRecording = false;
Alexandre Lision3c6b7102013-09-16 16:56:46 -040051 private long timestamp_start = 0;
Alexandre Lisiona8b78722013-12-13 10:18:33 -050052
Alexandre Savard2b01c822012-09-20 15:00:37 -040053
alisionfde875f2013-05-28 17:01:54 -040054 private int mCallType = state.CALL_TYPE_UNDETERMINED;
55 private int mCallState = state.CALL_STATE_NONE;
56 private int mMediaState = state.MEDIA_STATE_NONE;
Alexandre Lisiond5686032013-10-29 11:09:21 -040057
58 ArrayList<SipMessage> messages;
Alexandre Savard2b01c822012-09-20 15:00:37 -040059
alisionfde875f2013-05-28 17:01:54 -040060 /************************
61 * Construtors
alisionfde875f2013-05-28 17:01:54 -040062 ***********************/
Alexandre Savard557a5742012-10-24 13:54:53 -040063
alisionfde875f2013-05-28 17:01:54 -040064 private SipCall(Parcel in) {
Alexandre Savard557a5742012-10-24 13:54:53 -040065
Alexandre Lisiond5686032013-10-29 11:09:21 -040066 mCallID = in.readString();
Alexandre Lision3ee516e2013-10-07 17:32:15 -040067 mAccount = in.readParcelable(Account.class.getClassLoader());
alision907bde72013-06-20 14:40:37 -040068 contact = in.readParcelable(CallContact.class.getClassLoader());
alisiondf1dac92013-06-27 17:35:53 -040069 isRecording = in.readByte() == 1;
alisionfde875f2013-05-28 17:01:54 -040070 mCallType = in.readInt();
71 mCallState = in.readInt();
72 mMediaState = in.readInt();
Alexandre Lisionebeb3662013-09-17 16:20:54 -040073 timestamp_start = in.readLong();
Alexandre Lisiond5686032013-10-29 11:09:21 -040074
75 messages = new ArrayList<SipMessage>();
76 in.readTypedList(messages, SipMessage.CREATOR);
Alexandre Savard7a46f542012-09-20 11:23:33 -040077 }
Alexandre Savard4a19d752012-09-19 13:19:24 -040078
Alexandre Lision3ee516e2013-10-07 17:32:15 -040079 public SipCall(String id, Account account, int call_type, int call_state, int media_state, CallContact c) {
alisionfde875f2013-05-28 17:01:54 -040080 mCallID = id;
Alexandre Lision3ee516e2013-10-07 17:32:15 -040081 mAccount = account;
alisionfde875f2013-05-28 17:01:54 -040082 mCallType = call_type;
83 mCallState = call_state;
84 mMediaState = media_state;
alision907bde72013-06-20 14:40:37 -040085 contact = c;
Alexandre Lisiond5686032013-10-29 11:09:21 -040086 messages = new ArrayList<SipMessage>();
Alexandre Savard4a19d752012-09-19 13:19:24 -040087 }
88
alisionfde875f2013-05-28 17:01:54 -040089 public interface state {
90 public static final int CALL_TYPE_UNDETERMINED = 0;
91 public static final int CALL_TYPE_INCOMING = 1;
92 public static final int CALL_TYPE_OUTGOING = 2;
93
94 public static final int CALL_STATE_NONE = 0;
95 public static final int CALL_STATE_INCOMING = 1;
96 public static final int CALL_STATE_RINGING = 2;
97 public static final int CALL_STATE_CURRENT = 3;
98 public static final int CALL_STATE_HUNGUP = 4;
99 public static final int CALL_STATE_BUSY = 5;
100 public static final int CALL_STATE_FAILURE = 6;
101 public static final int CALL_STATE_HOLD = 7;
102 public static final int CALL_STATE_UNHOLD = 8;
103
104 public static final int MEDIA_STATE_NONE = 0; // No media currently
105 public static final int MEDIA_STATE_ACTIVE = 1; // Media is active
106 public static final int MEDIA_STATE_LOCAL_HOLD = 2; // Media is put on hold bu user
107 public static final int MEDIA_STATE_REMOTE_HOLD = 3; // Media is put on hold by peer
108 public static final int MEDIA_STATE_ERROR = 5; // Media is in error state
Alexandre Savard4a19d752012-09-19 13:19:24 -0400109 }
110
alisionfde875f2013-05-28 17:01:54 -0400111 @Override
112 public int describeContents() {
113 return 0;
114 }
115
116 @Override
117 public void writeToParcel(Parcel out, int flags) {
alisionfde875f2013-05-28 17:01:54 -0400118
Alexandre Lisiond5686032013-10-29 11:09:21 -0400119 out.writeString(mCallID);
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400120 out.writeParcelable(mAccount, 0);
121
alision907bde72013-06-20 14:40:37 -0400122 out.writeParcelable(contact, 0);
alisiondf1dac92013-06-27 17:35:53 -0400123 out.writeByte((byte) (isRecording ? 1 : 0));
alisionfde875f2013-05-28 17:01:54 -0400124 out.writeInt(mCallType);
125 out.writeInt(mCallState);
126 out.writeInt(mMediaState);
Alexandre Lisionebeb3662013-09-17 16:20:54 -0400127 out.writeLong(timestamp_start);
Alexandre Lisiond5686032013-10-29 11:09:21 -0400128
129 out.writeTypedList(messages);
alisionfde875f2013-05-28 17:01:54 -0400130 }
131
132 public static final Parcelable.Creator<SipCall> CREATOR = new Parcelable.Creator<SipCall>() {
133 public SipCall createFromParcel(Parcel in) {
134 return new SipCall(in);
135 }
136
137 public SipCall[] newArray(int size) {
138 return new SipCall[size];
139 }
140 };
141
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400142 public void setCallID(String callID) {
alisionfde875f2013-05-28 17:01:54 -0400143 mCallID = callID;
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400144 }
145
146 public String getCallId() {
alisionfde875f2013-05-28 17:01:54 -0400147 return mCallID;
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400148 }
149
Alexandre Lision3c6b7102013-09-16 16:56:46 -0400150 public long getTimestamp_start() {
151 return timestamp_start;
152 }
153
Alexandre Lision3c6b7102013-09-16 16:56:46 -0400154 public void setTimestamp_start(long timestamp_start) {
155 this.timestamp_start = timestamp_start;
156 }
157
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400158 public void setAccount(Account account) {
159 mAccount = account;
Alexandre Savard73bc56f2012-10-25 13:35:54 -0400160 }
161
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400162 public Account getAccount() {
163 return mAccount;
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400164 }
165
Alexandre Savard2f1ae542012-10-26 17:05:00 -0400166 public void setCallType(int callType) {
alisionfde875f2013-05-28 17:01:54 -0400167 mCallType = callType;
Alexandre Savard2f1ae542012-10-26 17:05:00 -0400168 }
169
170 public int getCallType() {
alisionfde875f2013-05-28 17:01:54 -0400171 return mCallType;
Alexandre Savard2f1ae542012-10-26 17:05:00 -0400172 }
173
alision85704182013-05-29 15:23:03 -0400174 public String getCallTypeString() {
175 switch (mCallType) {
176 case state.CALL_TYPE_INCOMING:
177 return "CALL_TYPE_INCOMING";
178 case state.CALL_TYPE_OUTGOING:
179 return "CALL_TYPE_OUTGOING";
180 default:
181 return "CALL_TYPE_UNDETERMINED";
182 }
183 }
184
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400185 public void setCallState(int callState) {
alisionfde875f2013-05-28 17:01:54 -0400186 mCallState = callState;
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400187 }
188
Alexandre Savarddf544262012-10-25 14:24:08 -0400189 public int getCallStateInt() {
alisionfde875f2013-05-28 17:01:54 -0400190 return mCallState;
191 }
192
193 public String getmCallID() {
194 return mCallID;
195 }
196
197 public void setmCallID(String mCallID) {
198 this.mCallID = mCallID;
199 }
200
alision907bde72013-06-20 14:40:37 -0400201 public CallContact getContact() {
202 return contact;
alisionfde875f2013-05-28 17:01:54 -0400203 }
204
alision907bde72013-06-20 14:40:37 -0400205 public void setContact(CallContact contacts) {
206 contact = contacts;
alisionfde875f2013-05-28 17:01:54 -0400207 }
208
209 public int getmCallType() {
210 return mCallType;
211 }
212
213 public void setmCallType(int mCallType) {
214 this.mCallType = mCallType;
215 }
216
alisionfde875f2013-05-28 17:01:54 -0400217 public int getmMediaState() {
218 return mMediaState;
219 }
220
221 public void setmMediaState(int mMediaState) {
222 this.mMediaState = mMediaState;
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400223 }
224
Alexandre Savarddf544262012-10-25 14:24:08 -0400225 public String getCallStateString() {
Alexandre Savarddf544262012-10-25 14:24:08 -0400226
alisionfde875f2013-05-28 17:01:54 -0400227 String text_state;
228
229 switch (mCallState) {
230 case state.CALL_STATE_INCOMING:
231 text_state = "INCOMING";
alision11e8e162013-05-28 10:33:14 -0400232 break;
alisionfde875f2013-05-28 17:01:54 -0400233 case state.CALL_STATE_RINGING:
234 text_state = "RINGING";
alision11e8e162013-05-28 10:33:14 -0400235 break;
alisionfde875f2013-05-28 17:01:54 -0400236 case state.CALL_STATE_CURRENT:
237 text_state = "CURRENT";
alision11e8e162013-05-28 10:33:14 -0400238 break;
alisionfde875f2013-05-28 17:01:54 -0400239 case state.CALL_STATE_HUNGUP:
240 text_state = "HUNGUP";
alision11e8e162013-05-28 10:33:14 -0400241 break;
alisionfde875f2013-05-28 17:01:54 -0400242 case state.CALL_STATE_BUSY:
243 text_state = "BUSY";
alision11e8e162013-05-28 10:33:14 -0400244 break;
alisionfde875f2013-05-28 17:01:54 -0400245 case state.CALL_STATE_FAILURE:
246 text_state = "FAILURE";
alision11e8e162013-05-28 10:33:14 -0400247 break;
alisionfde875f2013-05-28 17:01:54 -0400248 case state.CALL_STATE_HOLD:
249 text_state = "HOLD";
alision11e8e162013-05-28 10:33:14 -0400250 break;
alisionfde875f2013-05-28 17:01:54 -0400251 case state.CALL_STATE_UNHOLD:
252 text_state = "UNHOLD";
alision11e8e162013-05-28 10:33:14 -0400253 break;
254 default:
alisionfde875f2013-05-28 17:01:54 -0400255 text_state = "NULL";
Alexandre Savarddf544262012-10-25 14:24:08 -0400256 }
257
alisionfde875f2013-05-28 17:01:54 -0400258 return text_state;
Alexandre Savarddf544262012-10-25 14:24:08 -0400259 }
260
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400261 public void setMediaState(int mediaState) {
alisionfde875f2013-05-28 17:01:54 -0400262 mMediaState = mediaState;
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400263 }
264
265 public int getMediaState() {
alisionfde875f2013-05-28 17:01:54 -0400266 return mMediaState;
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400267 }
268
alisiondf1dac92013-06-27 17:35:53 -0400269 public boolean isRecording() {
270 return isRecording;
271 }
272
273 public void setRecording(boolean isRecording) {
274 this.isRecording = isRecording;
275 }
276
alisionfde875f2013-05-28 17:01:54 -0400277 public static class SipCallBuilder {
278
279 private String bCallID = "";
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400280 private Account bAccount = null;
alision907bde72013-06-20 14:40:37 -0400281 private CallContact bContact = null;
alisionfde875f2013-05-28 17:01:54 -0400282
283 private int bCallType = state.CALL_TYPE_UNDETERMINED;
284 private int bCallState = state.CALL_STATE_NONE;
285 private int bMediaState = state.MEDIA_STATE_NONE;
286
alisionfde875f2013-05-28 17:01:54 -0400287 public SipCallBuilder setCallType(int bCallType) {
288 this.bCallType = bCallType;
289 return this;
290 }
291
292 public SipCallBuilder setMediaState(int state) {
293 this.bMediaState = state;
294 return this;
295 }
296
297 public SipCallBuilder setCallState(int state) {
298 this.bCallState = state;
299 return this;
300 }
alision85704182013-05-29 15:23:03 -0400301
alisionfde875f2013-05-28 17:01:54 -0400302 public SipCallBuilder startCallCreation(String id) {
303 bCallID = id;
alisionfde875f2013-05-28 17:01:54 -0400304 bCallType = SipCall.state.CALL_TYPE_INCOMING;
305 return this;
306 }
307
308 public SipCallBuilder startCallCreation() {
309 Random random = new Random();
Tristan Matthews1a4962d2013-07-18 16:27:10 -0400310 bCallID = Integer.toString(Math.abs(random.nextInt()));
alisionfde875f2013-05-28 17:01:54 -0400311 return this;
312 }
313
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400314 public SipCallBuilder setAccount(Account a) {
315 bAccount = a;
alisionfde875f2013-05-28 17:01:54 -0400316 return this;
317 }
318
alision907bde72013-06-20 14:40:37 -0400319 public SipCallBuilder setContact(CallContact c) {
320 bContact = c;
alisionfde875f2013-05-28 17:01:54 -0400321 return this;
322 }
323
Alexandre Lision5ed2c972013-10-11 15:36:33 -0400324 public SipCall build() throws InvalidObjectException {
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400325 if (bCallID.contentEquals("") || bAccount == null || bContact == null) {
Alexandre Lision5ed2c972013-10-11 15:36:33 -0400326 throw new InvalidObjectException("SipCallBuilder's parameters missing");
alisionfde875f2013-05-28 17:01:54 -0400327 }
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400328 return new SipCall(bCallID, bAccount, bCallType, bCallState, bMediaState, bContact);
alisionfde875f2013-05-28 17:01:54 -0400329 }
330
331 public static SipCallBuilder getInstance() {
332 return new SipCallBuilder();
333 }
334
alision806e18e2013-06-21 15:30:17 -0400335 public static SipCall buildMyselfCall(ContentResolver cr, String displayName) {
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400336 return new SipCall("default", null, SipCall.state.CALL_TYPE_UNDETERMINED, state.CALL_STATE_NONE, state.MEDIA_STATE_NONE,
Alexandre Lision3874e552013-11-04 17:20:12 -0500337 CallContact.ContactBuilder.buildUserContact(cr));
alision806e18e2013-06-21 15:30:17 -0400338
339 }
340
alisionfde875f2013-05-28 17:01:54 -0400341 }
342
alision85704182013-05-29 15:23:03 -0400343 public void printCallInfo() {
344 Log.i(TAG, "CallInfo: CallID: " + mCallID);
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400345 Log.i(TAG, " AccountID: " + mAccount.getAccountID());
alision85704182013-05-29 15:23:03 -0400346 Log.i(TAG, " CallState: " + mCallState);
347 Log.i(TAG, " CallType: " + mCallType);
348 }
Alexandre Savard73bc56f2012-10-25 13:35:54 -0400349
alision5f899632013-04-22 17:26:56 -0400350 /**
351 * Compare sip calls based on call ID
352 */
353 @Override
alision11e8e162013-05-28 10:33:14 -0400354 public boolean equals(Object c) {
alision465ceba2013-07-04 09:24:30 -0400355 if (c instanceof SipCall && ((SipCall) c).mCallID.contentEquals((mCallID))) {
alision5f899632013-04-22 17:26:56 -0400356 return true;
357 }
358 return false;
alision11e8e162013-05-28 10:33:14 -0400359
alision5f899632013-04-22 17:26:56 -0400360 }
alision7f18fc82013-05-01 09:37:33 -0400361
alision85704182013-05-29 15:23:03 -0400362 public boolean isOutGoing() {
363 if (mCallType == state.CALL_TYPE_OUTGOING)
364 return true;
365
366 return false;
367 }
368
369 public boolean isRinging() {
370 if (mCallState == state.CALL_STATE_RINGING || mCallState == state.CALL_STATE_NONE)
371 return true;
372
373 return false;
374 }
375
376 public boolean isIncoming() {
377 if (mCallType == state.CALL_TYPE_INCOMING)
378 return true;
379
380 return false;
381 }
382
383 public void setCallState(String newState) {
384 if (newState.equals("INCOMING")) {
385 setCallState(SipCall.state.CALL_STATE_INCOMING);
386 } else if (newState.equals("RINGING")) {
387 setCallState(SipCall.state.CALL_STATE_RINGING);
388 } else if (newState.equals("CURRENT")) {
389 setCallState(SipCall.state.CALL_STATE_CURRENT);
390 } else if (newState.equals("HUNGUP")) {
391 setCallState(SipCall.state.CALL_STATE_HUNGUP);
392 } else if (newState.equals("BUSY")) {
393 setCallState(SipCall.state.CALL_STATE_BUSY);
394 } else if (newState.equals("FAILURE")) {
395 setCallState(SipCall.state.CALL_STATE_FAILURE);
396 } else if (newState.equals("HOLD")) {
397 setCallState(SipCall.state.CALL_STATE_HOLD);
398 } else if (newState.equals("UNHOLD")) {
399 setCallState(SipCall.state.CALL_STATE_CURRENT);
400 } else {
401 setCallState(SipCall.state.CALL_STATE_NONE);
402 }
alision907bde72013-06-20 14:40:37 -0400403
alision85704182013-05-29 15:23:03 -0400404 }
405
406 public boolean isOngoing() {
alision907bde72013-06-20 14:40:37 -0400407 if (mCallState == state.CALL_STATE_RINGING || mCallState == state.CALL_STATE_NONE || mCallState == state.CALL_STATE_FAILURE
408 || mCallState == state.CALL_STATE_BUSY || mCallState == state.CALL_STATE_HUNGUP)
alision85704182013-05-29 15:23:03 -0400409 return false;
410
411 return true;
412 }
alision04a00182013-05-10 17:05:29 -0400413
alisiondf1dac92013-06-27 17:35:53 -0400414 public boolean isOnHold() {
415 return mCallState == state.CALL_STATE_HOLD;
416 }
417
Alexandre Lision6ae652d2013-09-26 16:39:20 -0400418 public boolean isCurrent() {
419 return mCallState == state.CALL_STATE_CURRENT;
420 }
421
Alexandre Lisiond5686032013-10-29 11:09:21 -0400422 public void addSipMessage(SipMessage message) {
423 messages.add(message);
424 }
425
426 public ArrayList<SipMessage> getMessages() {
427 return messages;
428 }
429
Alexandre Savard4a19d752012-09-19 13:19:24 -0400430}