blob: 25fec632da6b55bb34c0d5ef6cdf21755021e914 [file] [log] [blame]
Alexandre Savard4a19d752012-09-19 13:19:24 -04001/*
2 * Copyright (C) 2004-2012 Savoir-Faire Linux Inc.
3 *
Alexandre Savarda1404652012-09-20 13:34:08 -04004 * Author: Alexandre Savard <alexandre.savard@gmail.com>
Alexandre Savard4a19d752012-09-19 13:19:24 -04005 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 * Additional permission under GNU GPL version 3 section 7:
21 *
22 * If you modify this program, or any covered work, by linking or
23 * combining it with the OpenSSL project's OpenSSL library (or a
24 * modified version of that library), containing parts covered by the
25 * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
26 * grants you additional permission to convey the resulting work.
27 * Corresponding Source for a non-source form of such a combination
28 * shall include the source code for the parts of OpenSSL used as well
29 * as that of the covered work.
30 */
31package com.savoirfairelinux.sflphone.client;
32
Alexandre Savard3bdce7b2012-10-24 18:27:45 -040033import android.content.Context;
34import android.content.Intent;
35import android.os.Bundle;
Alexandre Savard85936b92012-10-24 11:23:53 -040036import android.os.Parcelable;
Alexandre Savard557a5742012-10-24 13:54:53 -040037import android.os.Parcel;
Alexandre Savard74c1cad2012-10-24 16:39:00 -040038import android.os.RemoteException;
Alexandre Savard4a19d752012-09-19 13:19:24 -040039import android.util.Log;
Alexandre Savardd1976532012-10-26 15:32:45 -040040import android.view.View;
Alexandre Savard4a19d752012-09-19 13:19:24 -040041import java.util.ArrayList;
42
Alexandre Savard74c1cad2012-10-24 16:39:00 -040043import com.savoirfairelinux.sflphone.service.ISipService;
Alexandre Savard4f42ade2012-10-24 18:03:31 -040044import com.savoirfairelinux.sflphone.client.CallActivity;
Alexandre Savardd1976532012-10-26 15:32:45 -040045import com.savoirfairelinux.sflphone.client.CallElementList.CallElementView;
Alexandre Savard74c1cad2012-10-24 16:39:00 -040046
Alexandre Savard557a5742012-10-24 13:54:53 -040047public class SipCall
Alexandre Savard4a19d752012-09-19 13:19:24 -040048{
49 final static String TAG = "SipCall";
Alexandre Savard7a46f542012-09-20 11:23:33 -040050 public CallInfo mCallInfo;
Alexandre Savarda949eec2012-10-25 17:30:49 -040051 // Update UI on actions (answer, hangup)
52 static private CallElementList mCallElementList = null;
53 static private SFLPhoneHome mHome = null;
Alexandre Savardd1976532012-10-26 15:32:45 -040054 private View mRowView = null;
Alexandre Savard7a46f542012-09-20 11:23:33 -040055
Alexandre Savard2f1ae542012-10-26 17:05:00 -040056 public static final int CALL_TYPE_UNDETERMINED = 0;
57 public static final int CALL_TYPE_INCOMING = 1;
58 public static final int CALL_TYPE_OUTGOING = 2;
59
Alexandre Savard27a51132012-10-25 18:35:14 -040060 public static final int CALL_STATE_NONE = 0;
Alexandre Savarddf544262012-10-25 14:24:08 -040061 public static final int CALL_STATE_INCOMING = 1;
62 public static final int CALL_STATE_RINGING = 2;
63 public static final int CALL_STATE_CURRENT = 3;
64 public static final int CALL_STATE_HUNGUP = 4;
65 public static final int CALL_STATE_BUSY = 5;
66 public static final int CALL_STATE_FAILURE = 6;
67 public static final int CALL_STATE_HOLD = 7;
68 public static final int CALL_STATE_UNHOLD = 8;
Alexandre Savard2b01c822012-09-20 15:00:37 -040069
Alexandre Savarddf544262012-10-25 14:24:08 -040070 public static final int MEDIA_STATE_NONE = 0; // No media currently
71 public static final int MEDIA_STATE_ACTIVE = 1; // Media is active
72 public static final int MEDIA_STATE_LOCAL_HOLD = 2; // Media is put on hold bu user
73 public static final int MEDIA_STATE_REMOTE_HOLD = 3; // Media is put on hold by peer
74 public static final int MEDIA_STATE_ERROR = 5; // Media is in error state
Alexandre Savard2b01c822012-09-20 15:00:37 -040075
Alexandre Savard557a5742012-10-24 13:54:53 -040076 public static class CallInfo implements Parcelable
Alexandre Savard7a46f542012-09-20 11:23:33 -040077 {
Alexandre Savard2b01c822012-09-20 15:00:37 -040078 public String mCallID = "";
Alexandre Savard73bc56f2012-10-25 13:35:54 -040079 public String mAccountID = "";
Alexandre Savard7a46f542012-09-20 11:23:33 -040080 public String mDisplayName = "";
81 public String mPhone = "";
82 public String mEmail = "";
Alexandre Savard2b01c822012-09-20 15:00:37 -040083 public String mRemoteContact = "";
Alexandre Savard2f1ae542012-10-26 17:05:00 -040084 public int mCallType = CALL_TYPE_UNDETERMINED;
Alexandre Savard27a51132012-10-25 18:35:14 -040085 public int mCallState = CALL_STATE_NONE;
Alexandre Savard557a5742012-10-24 13:54:53 -040086 public int mMediaState = MEDIA_STATE_NONE;
87
88 @Override
89 public int describeContents() {
90 return 0;
91 }
92
93 @Override
94 public void writeToParcel(Parcel out, int flags) {
95 ArrayList<String> list = new ArrayList<String>();
Alexandre Savard74c1cad2012-10-24 16:39:00 -040096
97 // Don't mess with this order!!!
Alexandre Savard557a5742012-10-24 13:54:53 -040098 list.add(mCallID);
Alexandre Savard73bc56f2012-10-25 13:35:54 -040099 list.add(mAccountID);
Alexandre Savard557a5742012-10-24 13:54:53 -0400100 list.add(mDisplayName);
101 list.add(mPhone);
102 list.add(mEmail);
103 list.add(mRemoteContact);
104
105 out.writeStringList(list);
Alexandre Savard2f1ae542012-10-26 17:05:00 -0400106 out.writeInt(mCallType);
Alexandre Savard557a5742012-10-24 13:54:53 -0400107 out.writeInt(mCallState);
108 out.writeInt(mMediaState);
109 }
110
111 public static final Parcelable.Creator<CallInfo> CREATOR
112 = new Parcelable.Creator<CallInfo>() {
113 public CallInfo createFromParcel(Parcel in) {
114 return new CallInfo(in);
115 }
116
117 public CallInfo[] newArray(int size) {
118 return new CallInfo[size];
119 }
120 };
121
122 public CallInfo() {}
123
124 private CallInfo(Parcel in) {
125 ArrayList<String> list = in.createStringArrayList();
Alexandre Savard74c1cad2012-10-24 16:39:00 -0400126
127 // Don't mess with this order!!!
Alexandre Savard557a5742012-10-24 13:54:53 -0400128 mCallID = list.get(0);
Alexandre Savard73bc56f2012-10-25 13:35:54 -0400129 mAccountID = list.get(1);
130 mDisplayName = list.get(2);
131 mPhone = list.get(3);
132 mEmail = list.get(4);
133 mRemoteContact = list.get(5);
Alexandre Savard557a5742012-10-24 13:54:53 -0400134
Alexandre Savard2f1ae542012-10-26 17:05:00 -0400135 mCallType = in.readInt();
Alexandre Savard557a5742012-10-24 13:54:53 -0400136 mCallState = in.readInt();
137 mMediaState = in.readInt();
138 }
Alexandre Savard7a46f542012-09-20 11:23:33 -0400139 }
Alexandre Savard4a19d752012-09-19 13:19:24 -0400140
141 public SipCall()
142 {
Alexandre Savard7a46f542012-09-20 11:23:33 -0400143 mCallInfo = new CallInfo();
Alexandre Savard4a19d752012-09-19 13:19:24 -0400144 }
145
Alexandre Savard7a46f542012-09-20 11:23:33 -0400146 public SipCall(CallInfo info)
Alexandre Savard4a19d752012-09-19 13:19:24 -0400147 {
Alexandre Savard7a46f542012-09-20 11:23:33 -0400148 mCallInfo = info;
Alexandre Savard4a19d752012-09-19 13:19:24 -0400149 }
150
Alexandre Savarda1404652012-09-20 13:34:08 -0400151 public static void setCallElementList(CallElementList list)
152 {
153 mCallElementList = list;
154 }
155
Alexandre Savarda949eec2012-10-25 17:30:49 -0400156 public static void setSFLPhoneHomeContext(SFLPhoneHome home)
157 {
158 mHome = home;
159 }
160
Alexandre Savardd1976532012-10-26 15:32:45 -0400161 public void setAssociatedRowView(View view)
162 {
163 mRowView = view;
164 }
165
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400166 public void setCallID(String callID) {
167 mCallInfo.mCallID = callID;
168 }
169
170 public String getCallId() {
171 return mCallInfo.mCallID;
172 }
173
Alexandre Savard73bc56f2012-10-25 13:35:54 -0400174 public void setAccountID(String accountID) {
175 mCallInfo.mAccountID = accountID;
176 }
177
178 public String getAccountID() {
179 return mCallInfo.mAccountID;
180 }
181
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400182 public void setDisplayName(String displayName) {
183 mCallInfo.mDisplayName = displayName;
184 }
185
186 public String getDisplayName() {
187 return mCallInfo.mDisplayName;
188 }
189
190 public void setPhone(String phone) {
191 mCallInfo.mPhone = phone;
192 }
193
194 public String getPhone() {
195 return mCallInfo.mPhone;
196 }
197
198 public void setEmail(String email) {
199 mCallInfo.mEmail = email;
200 }
201
202 public String getEmail() {
203 return mCallInfo.mEmail;
204 }
205
206 public void setRemoteContact(String remoteContact) {
207 mCallInfo.mRemoteContact = remoteContact;
208 }
209
210 public String getRemoteContact() {
211 return mCallInfo.mRemoteContact;
212 }
213
Alexandre Savard2f1ae542012-10-26 17:05:00 -0400214 public void setCallType(int callType) {
215 mCallInfo.mCallType = callType;
216 }
217
218 public int getCallType() {
219 return mCallInfo.mCallType;
220 }
221
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400222 public void setCallState(int callState) {
223 mCallInfo.mCallState = callState;
Alexandre Savardde820072012-10-26 15:39:21 -0400224
225 // Check if this call is associated to a view in CallElementList
Alexandre Savardd1976532012-10-26 15:32:45 -0400226 if(mRowView == null)
227 return;
228
Alexandre Savardde820072012-10-26 15:39:21 -0400229 // Update the state to the view
Alexandre Savardd1976532012-10-26 15:32:45 -0400230 CallElementView entryView = (CallElementView) mRowView.getTag();
231 final String CURRENT_STATE_LABEL = " CURRENT STATE: ";
232 entryView.state.setText(CURRENT_STATE_LABEL + getCallStateString());
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400233 }
234
Alexandre Savarddf544262012-10-25 14:24:08 -0400235 public int getCallStateInt() {
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400236 return mCallInfo.mCallState;
237 }
238
Alexandre Savarddf544262012-10-25 14:24:08 -0400239 public String getCallStateString() {
240 String state;
241
242 switch(mCallInfo.mCallState) {
243 case CALL_STATE_INCOMING:
244 state = "INCOMING";
245 break;
246 case CALL_STATE_RINGING:
247 state = "RINGING";
248 break;
249 case CALL_STATE_CURRENT:
250 state = "CURRENT";
251 break;
252 case CALL_STATE_HUNGUP:
253 state = "HUNGUP";
254 break;
255 case CALL_STATE_BUSY:
256 state = "BUSY";
257 break;
258 case CALL_STATE_FAILURE:
259 state = "FAILURE";
260 break;
261 case CALL_STATE_HOLD:
262 state = "HOLD";
263 break;
264 case CALL_STATE_UNHOLD:
265 state = "UNHOLD";
266 break;
267 default:
268 state = "NULL";
269 }
270
271 return state;
272 }
273
274
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400275 public void setMediaState(int mediaState) {
276 mCallInfo.mMediaState = mediaState;
277 }
278
279 public int getMediaState() {
280 return mCallInfo.mMediaState;
281 }
282
Alexandre Savarda949eec2012-10-25 17:30:49 -0400283 public void placeCallUpdateUi()
284 {
285 if(mCallElementList != null)
286 mCallElementList.addCall(this);
287
288 if(mHome != null)
289 mHome.onSelectedCallAction(this);
290 }
291
Alexandre Savard27a51132012-10-25 18:35:14 -0400292 public void notifyServicePlaceCall(ISipService service)
293 {
294 try {
295 service.placeCall(mCallInfo.mAccountID, mCallInfo.mCallID, mCallInfo.mPhone);
296 } catch (RemoteException e) {
297 Log.e(TAG, "Cannot call service method", e);
298 }
299 }
300
Alexandre Savarda949eec2012-10-25 17:30:49 -0400301 public void receiveCallUpdateUi()
Alexandre Savard23240c12012-09-19 18:23:44 -0400302 {
Alexandre Savard74c1cad2012-10-24 16:39:00 -0400303 if(mCallElementList != null)
304 mCallElementList.addCall(this);
Alexandre Savarda949eec2012-10-25 17:30:49 -0400305
306 if(mHome != null)
307 mHome.onSelectedCallAction(this);
Alexandre Savard73bc56f2012-10-25 13:35:54 -0400308 }
309
Alexandre Savarda949eec2012-10-25 17:30:49 -0400310 public void answerUpdateUi()
Alexandre Savard73bc56f2012-10-25 13:35:54 -0400311 {
Alexandre Savarda949eec2012-10-25 17:30:49 -0400312 if(mHome != null)
313 mHome.onSelectedCallAction(this);
Alexandre Savardf17e3172012-10-25 16:09:09 -0400314
315 }
Alexandre Savard4a19d752012-09-19 13:19:24 -0400316
Alexandre Savard08545ae2012-10-26 16:11:42 -0400317 public boolean notifyServiceAnswer(ISipService service)
Alexandre Savardf17e3172012-10-25 16:09:09 -0400318 {
Alexandre Savard27a51132012-10-25 18:35:14 -0400319 int callState = getCallStateInt();
320 if((callState != CALL_STATE_RINGING) &&
321 (callState != CALL_STATE_NONE)) {
Alexandre Savard08545ae2012-10-26 16:11:42 -0400322 return false;
Alexandre Savard27a51132012-10-25 18:35:14 -0400323 }
Alexandre Savardf17e3172012-10-25 16:09:09 -0400324
325 try {
326 service.accept(mCallInfo.mCallID);
327 } catch (RemoteException e) {
328 Log.e(TAG, "Cannot call service method", e);
329 }
Alexandre Savard08545ae2012-10-26 16:11:42 -0400330
331 return true;
Alexandre Savard4a19d752012-09-19 13:19:24 -0400332 }
333
Alexandre Savard4f42ade2012-10-24 18:03:31 -0400334 /**
335 * Perform hangup action without sending request to the service
Alexandre Savarda949eec2012-10-25 17:30:49 -0400336 * Used when SipService haved been notified that this call hung up
Alexandre Savard4f42ade2012-10-24 18:03:31 -0400337 */
Alexandre Savarda949eec2012-10-25 17:30:49 -0400338 public void hangupUpdateUi() {
Alexandre Savard74c1cad2012-10-24 16:39:00 -0400339 Log.i(TAG, "Hangup call " + mCallInfo.mCallID);
340
341 if(mCallElementList != null)
342 mCallElementList.removeCall(this);
Alexandre Savarda949eec2012-10-25 17:30:49 -0400343
344 if(mHome != null)
345 mHome.onUnselectedCallAction();
Alexandre Savard4f42ade2012-10-24 18:03:31 -0400346 }
347
348 /**
349 * Perform hangup action and send request to the service
350 */
Alexandre Savard08545ae2012-10-26 16:11:42 -0400351 public boolean notifyServiceHangup(ISipService service)
Alexandre Savard4f42ade2012-10-24 18:03:31 -0400352 {
Alexandre Savard74c1cad2012-10-24 16:39:00 -0400353 try {
Alexandre Savard2f1ae542012-10-26 17:05:00 -0400354 if((getCallStateInt() == CALL_STATE_NONE) ||
355 (getCallStateInt() == CALL_STATE_CURRENT) ||
356 (getCallStateInt() == CALL_STATE_HOLD)) {
Alexandre Savard08545ae2012-10-26 16:11:42 -0400357 service.hangUp(mCallInfo.mCallID);
358 return true;
359
360 }
Alexandre Savard2f1ae542012-10-26 17:05:00 -0400361 else if(getCallStateInt() == CALL_STATE_RINGING) {
362 if(getCallType() == CALL_TYPE_INCOMING) {
363 service.refuse(mCallInfo.mCallID);
364 return true;
365 }
366 else if(getCallType() == CALL_TYPE_OUTGOING) {
367 service.hangUp(mCallInfo.mCallID);
368 return true;
369 }
Alexandre Savard08545ae2012-10-26 16:11:42 -0400370 }
Alexandre Savard74c1cad2012-10-24 16:39:00 -0400371 } catch (RemoteException e) {
372 Log.e(TAG, "Cannot call service method", e);
373 }
Alexandre Savard08545ae2012-10-26 16:11:42 -0400374
375 return false;
Alexandre Savard4a19d752012-09-19 13:19:24 -0400376 }
Alexandre Savardaef9d802012-09-20 17:31:32 -0400377
Alexandre Savard08545ae2012-10-26 16:11:42 -0400378 public boolean notifyServiceRefuse(ISipService service)
Alexandre Savard83869852012-10-26 09:14:12 -0400379 {
380 try {
Alexandre Savard2f1ae542012-10-26 17:05:00 -0400381 if(getCallStateInt() == CALL_STATE_RINGING) {
Alexandre Savard08545ae2012-10-26 16:11:42 -0400382 service.refuse(mCallInfo.mCallID);
383 return true;
384 }
Alexandre Savard83869852012-10-26 09:14:12 -0400385 } catch (RemoteException e) {
386 Log.e(TAG, "Cannot call service method", e);
387 }
Alexandre Savard08545ae2012-10-26 16:11:42 -0400388
389 return false;
Alexandre Savard83869852012-10-26 09:14:12 -0400390 }
391
Alexandre Savard08545ae2012-10-26 16:11:42 -0400392 public boolean notifyServiceHold(ISipService service)
Alexandre Savarde9dc8992012-10-26 12:12:27 -0400393 {
394 try {
Alexandre Savard2f1ae542012-10-26 17:05:00 -0400395 if(getCallStateInt() == CALL_STATE_CURRENT) {
Alexandre Savard08545ae2012-10-26 16:11:42 -0400396 service.hold(mCallInfo.mCallID);
397 return true;
398 }
Alexandre Savarde9dc8992012-10-26 12:12:27 -0400399 } catch (RemoteException e) {
400 Log.e(TAG, "Cannot call service method", e);
401 }
Alexandre Savard08545ae2012-10-26 16:11:42 -0400402
403 return false;
Alexandre Savarde9dc8992012-10-26 12:12:27 -0400404 }
405
Alexandre Savard08545ae2012-10-26 16:11:42 -0400406 public boolean notifyServiceUnhold(ISipService service)
Alexandre Savarde9dc8992012-10-26 12:12:27 -0400407 {
408 try {
Alexandre Savard2f1ae542012-10-26 17:05:00 -0400409 if(getCallStateInt() == CALL_STATE_HOLD) {
Alexandre Savard08545ae2012-10-26 16:11:42 -0400410 service.unhold(mCallInfo.mCallID);
411 return true;
412 }
Alexandre Savarde9dc8992012-10-26 12:12:27 -0400413 } catch (RemoteException e) {
414 Log.e(TAG, "Cannot call service method", e);
415 }
Alexandre Savard08545ae2012-10-26 16:11:42 -0400416
417 return false;
Alexandre Savarde9dc8992012-10-26 12:12:27 -0400418 }
Alexandre Savard83869852012-10-26 09:14:12 -0400419
Alexandre Savardaef9d802012-09-20 17:31:32 -0400420 public void addToConference()
421 {
422 Log.i(TAG, "Add call to conference");
423 }
424
425 public void sendTextMessage()
426 {
427 Log.i(TAG, "Send text message");
428 }
Alexandre Savard3bdce7b2012-10-24 18:27:45 -0400429
Alexandre Savard73bc56f2012-10-25 13:35:54 -0400430 public void printCallInfo()
431 {
432 Log.i(TAG, "CallInfo: CallID: " + mCallInfo.mCallID);
433 Log.i(TAG, " AccountID: " + mCallInfo.mAccountID);
434 Log.i(TAG, " Display Name: " + mCallInfo.mDisplayName);
435 Log.i(TAG, " Phone: " + mCallInfo.mPhone);
436 Log.i(TAG, " Email: " + mCallInfo.mEmail);
437 Log.i(TAG, " Contact: " + mCallInfo.mRemoteContact);
438 }
439
Alexandre Savard3bdce7b2012-10-24 18:27:45 -0400440 public void launchCallActivity(Context context)
441 {
442 Log.i(TAG, "Launch Call Activity");
443 Bundle bundle = new Bundle();
444 bundle.putParcelable("CallInfo", mCallInfo);
445 Intent intent = new Intent().setClass(context, CallActivity.class);
446 intent.putExtras(bundle);
447 context.startActivity(intent);
448 }
Alexandre Savard4a19d752012-09-19 13:19:24 -0400449}