blob: 1b1e6cbe56c30e78eca2dd78d9f1545252438baf [file] [log] [blame]
Alexandre Savard4a19d752012-09-19 13:19:24 -04001/*
Alexandre Lisionc1024c02014-01-06 11:12:53 -05002 * Copyright (C) 2004-2014 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;
alisionfde875f2013-05-28 17:01:54 -040035import java.util.Random;
alisiona4325152013-04-19 11:10:03 -040036
Alexandre Savard557a5742012-10-24 13:54:53 -040037import android.os.Parcel;
alisiona4325152013-04-19 11:10:03 -040038import android.os.Parcelable;
Alexandre Savard4a19d752012-09-19 13:19:24 -040039import android.util.Log;
Alexandre Savard4a19d752012-09-19 13:19:24 -040040
alisionfde875f2013-05-28 17:01:54 -040041public class SipCall implements Parcelable {
alision371b77e2013-04-23 14:51:26 -040042
alisionfde875f2013-05-28 17:01:54 -040043 private static final String TAG = SipCall.class.getSimpleName();
Alexandre Savard2f1ae542012-10-26 17:05:00 -040044
alisionfde875f2013-05-28 17:01:54 -040045 private String mCallID = "";
Alexandre Lision3ee516e2013-10-07 17:32:15 -040046 private Account mAccount = null;
alision907bde72013-06-20 14:40:37 -040047 private CallContact contact = null;
alisiondf1dac92013-06-27 17:35:53 -040048 private boolean isRecording = false;
Alexandre Lision945e4612014-01-15 17:40:31 -050049 private long timestampStart_ = 0;
50 private long timestampEnd_ = 0;
51
Alexandre Lision67c70b42014-01-16 13:57:15 -050052 private int mCallType;
alisionfde875f2013-05-28 17:01:54 -040053 private int mCallState = state.CALL_STATE_NONE;
54 private int mMediaState = state.MEDIA_STATE_NONE;
Alexandre Savard2b01c822012-09-20 15:00:37 -040055
Alexandre Lision945e4612014-01-15 17:40:31 -050056 /**
57 * *********************
alisionfde875f2013-05-28 17:01:54 -040058 * Construtors
Alexandre Lision945e4612014-01-15 17:40:31 -050059 * *********************
60 */
Alexandre Savard557a5742012-10-24 13:54:53 -040061
alisionfde875f2013-05-28 17:01:54 -040062 private SipCall(Parcel in) {
Alexandre Savard557a5742012-10-24 13:54:53 -040063
Alexandre Lisiond5686032013-10-29 11:09:21 -040064 mCallID = in.readString();
Alexandre Lision3ee516e2013-10-07 17:32:15 -040065 mAccount = in.readParcelable(Account.class.getClassLoader());
alision907bde72013-06-20 14:40:37 -040066 contact = in.readParcelable(CallContact.class.getClassLoader());
alisiondf1dac92013-06-27 17:35:53 -040067 isRecording = in.readByte() == 1;
alisionfde875f2013-05-28 17:01:54 -040068 mCallType = in.readInt();
69 mCallState = in.readInt();
70 mMediaState = in.readInt();
Alexandre Lision945e4612014-01-15 17:40:31 -050071 timestampStart_ = in.readLong();
72 timestampEnd_ = in.readLong();
73 }
Alexandre Savard4a19d752012-09-19 13:19:24 -040074
Alexandre Lision183bf452014-01-17 11:21:59 -050075 private SipCall(String id, Account account, int call_type, int call_state, int media_state, CallContact c) {
alisionfde875f2013-05-28 17:01:54 -040076 mCallID = id;
Alexandre Lision3ee516e2013-10-07 17:32:15 -040077 mAccount = account;
alisionfde875f2013-05-28 17:01:54 -040078 mCallType = call_type;
79 mCallState = call_state;
80 mMediaState = media_state;
alision907bde72013-06-20 14:40:37 -040081 contact = c;
Alexandre Savard4a19d752012-09-19 13:19:24 -040082 }
83
Alexandre Lision945e4612014-01-15 17:40:31 -050084 public long getTimestampEnd_() {
85 return timestampEnd_;
86 }
87
88 public String getRecordPath() {
89 return "";
90 }
91
Alexandre Lision183bf452014-01-17 11:21:59 -050092 public int getCallType() {
93 return mCallType;
94 }
95
Alexandre Lision67c70b42014-01-16 13:57:15 -050096 public interface direction {
alisionfde875f2013-05-28 17:01:54 -040097 public static final int CALL_TYPE_INCOMING = 1;
98 public static final int CALL_TYPE_OUTGOING = 2;
Alexandre Lision67c70b42014-01-16 13:57:15 -050099 }
alisionfde875f2013-05-28 17:01:54 -0400100
Alexandre Lision67c70b42014-01-16 13:57:15 -0500101 public interface state {
alisionfde875f2013-05-28 17:01:54 -0400102 public static final int CALL_STATE_NONE = 0;
alisionfde875f2013-05-28 17:01:54 -0400103 public static final int CALL_STATE_RINGING = 2;
104 public static final int CALL_STATE_CURRENT = 3;
105 public static final int CALL_STATE_HUNGUP = 4;
106 public static final int CALL_STATE_BUSY = 5;
107 public static final int CALL_STATE_FAILURE = 6;
108 public static final int CALL_STATE_HOLD = 7;
109 public static final int CALL_STATE_UNHOLD = 8;
110
111 public static final int MEDIA_STATE_NONE = 0; // No media currently
112 public static final int MEDIA_STATE_ACTIVE = 1; // Media is active
113 public static final int MEDIA_STATE_LOCAL_HOLD = 2; // Media is put on hold bu user
114 public static final int MEDIA_STATE_REMOTE_HOLD = 3; // Media is put on hold by peer
115 public static final int MEDIA_STATE_ERROR = 5; // Media is in error state
Alexandre Savard4a19d752012-09-19 13:19:24 -0400116 }
117
alisionfde875f2013-05-28 17:01:54 -0400118 @Override
119 public int describeContents() {
120 return 0;
121 }
122
123 @Override
124 public void writeToParcel(Parcel out, int flags) {
alisionfde875f2013-05-28 17:01:54 -0400125
Alexandre Lisiond5686032013-10-29 11:09:21 -0400126 out.writeString(mCallID);
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400127 out.writeParcelable(mAccount, 0);
128
alision907bde72013-06-20 14:40:37 -0400129 out.writeParcelable(contact, 0);
alisiondf1dac92013-06-27 17:35:53 -0400130 out.writeByte((byte) (isRecording ? 1 : 0));
alisionfde875f2013-05-28 17:01:54 -0400131 out.writeInt(mCallType);
132 out.writeInt(mCallState);
133 out.writeInt(mMediaState);
Alexandre Lision945e4612014-01-15 17:40:31 -0500134 out.writeLong(timestampStart_);
135 out.writeLong(timestampEnd_);
alisionfde875f2013-05-28 17:01:54 -0400136 }
137
138 public static final Parcelable.Creator<SipCall> CREATOR = new Parcelable.Creator<SipCall>() {
139 public SipCall createFromParcel(Parcel in) {
140 return new SipCall(in);
141 }
142
143 public SipCall[] newArray(int size) {
144 return new SipCall[size];
145 }
146 };
147
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400148 public void setCallID(String callID) {
alisionfde875f2013-05-28 17:01:54 -0400149 mCallID = callID;
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400150 }
151
152 public String getCallId() {
alisionfde875f2013-05-28 17:01:54 -0400153 return mCallID;
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400154 }
155
Alexandre Lision945e4612014-01-15 17:40:31 -0500156 public long getTimestampStart_() {
157 return timestampStart_;
Alexandre Lision3c6b7102013-09-16 16:56:46 -0400158 }
159
Alexandre Lision945e4612014-01-15 17:40:31 -0500160 public void setTimestampStart_(long timestampStart_) {
161 this.timestampStart_ = timestampStart_;
162 }
163
164 public void setTimestampEnd_(long timestampEnd_) {
165 this.timestampEnd_ = timestampEnd_;
Alexandre Lision3c6b7102013-09-16 16:56:46 -0400166 }
167
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400168 public void setAccount(Account account) {
169 mAccount = account;
Alexandre Savard73bc56f2012-10-25 13:35:54 -0400170 }
171
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400172 public Account getAccount() {
173 return mAccount;
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400174 }
175
alision85704182013-05-29 15:23:03 -0400176 public String getCallTypeString() {
177 switch (mCallType) {
Alexandre Lision67c70b42014-01-16 13:57:15 -0500178 case direction.CALL_TYPE_INCOMING:
Alexandre Lision945e4612014-01-15 17:40:31 -0500179 return "CALL_TYPE_INCOMING";
Alexandre Lision67c70b42014-01-16 13:57:15 -0500180 case direction.CALL_TYPE_OUTGOING:
Alexandre Lision945e4612014-01-15 17:40:31 -0500181 return "CALL_TYPE_OUTGOING";
182 default:
183 return "CALL_TYPE_UNDETERMINED";
alision85704182013-05-29 15:23:03 -0400184 }
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
alision907bde72013-06-20 14:40:37 -0400191 public CallContact getContact() {
192 return contact;
alisionfde875f2013-05-28 17:01:54 -0400193 }
194
alision907bde72013-06-20 14:40:37 -0400195 public void setContact(CallContact contacts) {
196 contact = contacts;
alisionfde875f2013-05-28 17:01:54 -0400197 }
198
Alexandre Savarddf544262012-10-25 14:24:08 -0400199 public String getCallStateString() {
Alexandre Savarddf544262012-10-25 14:24:08 -0400200
alisionfde875f2013-05-28 17:01:54 -0400201 String text_state;
202
203 switch (mCallState) {
Alexandre Lision945e4612014-01-15 17:40:31 -0500204 case state.CALL_STATE_RINGING:
205 text_state = "RINGING";
206 break;
207 case state.CALL_STATE_CURRENT:
208 text_state = "CURRENT";
209 break;
210 case state.CALL_STATE_HUNGUP:
211 text_state = "HUNGUP";
212 break;
213 case state.CALL_STATE_BUSY:
214 text_state = "BUSY";
215 break;
216 case state.CALL_STATE_FAILURE:
217 text_state = "FAILURE";
218 break;
219 case state.CALL_STATE_HOLD:
220 text_state = "HOLD";
221 break;
222 case state.CALL_STATE_UNHOLD:
223 text_state = "UNHOLD";
224 break;
225 default:
226 text_state = "NULL";
Alexandre Savarddf544262012-10-25 14:24:08 -0400227 }
228
alisionfde875f2013-05-28 17:01:54 -0400229 return text_state;
Alexandre Savarddf544262012-10-25 14:24:08 -0400230 }
231
alisiondf1dac92013-06-27 17:35:53 -0400232 public boolean isRecording() {
233 return isRecording;
234 }
235
236 public void setRecording(boolean isRecording) {
237 this.isRecording = isRecording;
238 }
239
alisionfde875f2013-05-28 17:01:54 -0400240 public static class SipCallBuilder {
241
242 private String bCallID = "";
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400243 private Account bAccount = null;
alision907bde72013-06-20 14:40:37 -0400244 private CallContact bContact = null;
alisionfde875f2013-05-28 17:01:54 -0400245
Alexandre Lision67c70b42014-01-16 13:57:15 -0500246 private int bCallType;
alisionfde875f2013-05-28 17:01:54 -0400247 private int bCallState = state.CALL_STATE_NONE;
248 private int bMediaState = state.MEDIA_STATE_NONE;
249
alisionfde875f2013-05-28 17:01:54 -0400250 public SipCallBuilder setCallType(int bCallType) {
251 this.bCallType = bCallType;
252 return this;
253 }
254
255 public SipCallBuilder setMediaState(int state) {
256 this.bMediaState = state;
257 return this;
258 }
259
260 public SipCallBuilder setCallState(int state) {
261 this.bCallState = state;
262 return this;
263 }
alision85704182013-05-29 15:23:03 -0400264
alisionfde875f2013-05-28 17:01:54 -0400265 public SipCallBuilder startCallCreation(String id) {
266 bCallID = id;
Alexandre Lision67c70b42014-01-16 13:57:15 -0500267 bCallType = direction.CALL_TYPE_INCOMING;
alisionfde875f2013-05-28 17:01:54 -0400268 return this;
269 }
270
271 public SipCallBuilder startCallCreation() {
272 Random random = new Random();
Tristan Matthews1a4962d2013-07-18 16:27:10 -0400273 bCallID = Integer.toString(Math.abs(random.nextInt()));
alisionfde875f2013-05-28 17:01:54 -0400274 return this;
275 }
276
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400277 public SipCallBuilder setAccount(Account a) {
278 bAccount = a;
alisionfde875f2013-05-28 17:01:54 -0400279 return this;
280 }
281
alision907bde72013-06-20 14:40:37 -0400282 public SipCallBuilder setContact(CallContact c) {
283 bContact = c;
alisionfde875f2013-05-28 17:01:54 -0400284 return this;
285 }
286
Alexandre Lision5ed2c972013-10-11 15:36:33 -0400287 public SipCall build() throws InvalidObjectException {
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400288 if (bCallID.contentEquals("") || bAccount == null || bContact == null) {
Alexandre Lision5ed2c972013-10-11 15:36:33 -0400289 throw new InvalidObjectException("SipCallBuilder's parameters missing");
alisionfde875f2013-05-28 17:01:54 -0400290 }
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400291 return new SipCall(bCallID, bAccount, bCallType, bCallState, bMediaState, bContact);
alisionfde875f2013-05-28 17:01:54 -0400292 }
293
294 public static SipCallBuilder getInstance() {
295 return new SipCallBuilder();
296 }
alisionfde875f2013-05-28 17:01:54 -0400297 }
298
alision85704182013-05-29 15:23:03 -0400299 public void printCallInfo() {
300 Log.i(TAG, "CallInfo: CallID: " + mCallID);
Alexandre Lision3ee516e2013-10-07 17:32:15 -0400301 Log.i(TAG, " AccountID: " + mAccount.getAccountID());
alision85704182013-05-29 15:23:03 -0400302 Log.i(TAG, " CallState: " + mCallState);
303 Log.i(TAG, " CallType: " + mCallType);
304 }
Alexandre Savard73bc56f2012-10-25 13:35:54 -0400305
alision5f899632013-04-22 17:26:56 -0400306 /**
307 * Compare sip calls based on call ID
308 */
309 @Override
alision11e8e162013-05-28 10:33:14 -0400310 public boolean equals(Object c) {
alision465ceba2013-07-04 09:24:30 -0400311 if (c instanceof SipCall && ((SipCall) c).mCallID.contentEquals((mCallID))) {
alision5f899632013-04-22 17:26:56 -0400312 return true;
313 }
314 return false;
alision11e8e162013-05-28 10:33:14 -0400315
alision5f899632013-04-22 17:26:56 -0400316 }
alision7f18fc82013-05-01 09:37:33 -0400317
alision85704182013-05-29 15:23:03 -0400318 public boolean isOutGoing() {
Alexandre Lision67c70b42014-01-16 13:57:15 -0500319 if (mCallType == direction.CALL_TYPE_OUTGOING)
alision85704182013-05-29 15:23:03 -0400320 return true;
alision85704182013-05-29 15:23:03 -0400321 return false;
322 }
323
324 public boolean isRinging() {
325 if (mCallState == state.CALL_STATE_RINGING || mCallState == state.CALL_STATE_NONE)
326 return true;
327
328 return false;
329 }
330
331 public boolean isIncoming() {
Alexandre Lision67c70b42014-01-16 13:57:15 -0500332 if (mCallType == direction.CALL_TYPE_INCOMING)
alision85704182013-05-29 15:23:03 -0400333 return true;
334
335 return false;
336 }
337
338 public void setCallState(String newState) {
Alexandre Lision707f9082014-01-16 15:09:07 -0500339 if (newState.equals("RINGING")) {
alision85704182013-05-29 15:23:03 -0400340 setCallState(SipCall.state.CALL_STATE_RINGING);
341 } else if (newState.equals("CURRENT")) {
342 setCallState(SipCall.state.CALL_STATE_CURRENT);
343 } else if (newState.equals("HUNGUP")) {
344 setCallState(SipCall.state.CALL_STATE_HUNGUP);
345 } else if (newState.equals("BUSY")) {
346 setCallState(SipCall.state.CALL_STATE_BUSY);
347 } else if (newState.equals("FAILURE")) {
348 setCallState(SipCall.state.CALL_STATE_FAILURE);
349 } else if (newState.equals("HOLD")) {
350 setCallState(SipCall.state.CALL_STATE_HOLD);
351 } else if (newState.equals("UNHOLD")) {
352 setCallState(SipCall.state.CALL_STATE_CURRENT);
353 } else {
354 setCallState(SipCall.state.CALL_STATE_NONE);
355 }
alision907bde72013-06-20 14:40:37 -0400356
alision85704182013-05-29 15:23:03 -0400357 }
358
359 public boolean isOngoing() {
alision907bde72013-06-20 14:40:37 -0400360 if (mCallState == state.CALL_STATE_RINGING || mCallState == state.CALL_STATE_NONE || mCallState == state.CALL_STATE_FAILURE
361 || mCallState == state.CALL_STATE_BUSY || mCallState == state.CALL_STATE_HUNGUP)
alision85704182013-05-29 15:23:03 -0400362 return false;
363
364 return true;
365 }
alision04a00182013-05-10 17:05:29 -0400366
alisiondf1dac92013-06-27 17:35:53 -0400367 public boolean isOnHold() {
368 return mCallState == state.CALL_STATE_HOLD;
369 }
370
Alexandre Lision6ae652d2013-09-26 16:39:20 -0400371 public boolean isCurrent() {
372 return mCallState == state.CALL_STATE_CURRENT;
373 }
Alexandre Savard4a19d752012-09-19 13:19:24 -0400374}