blob: 55b6d42ca40a29dad4dc0847210e9c430fff8914 [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 Savard27a51132012-10-25 18:35:14 -040056 public static final int CALL_STATE_NONE = 0;
Alexandre Savarddf544262012-10-25 14:24:08 -040057 public static final int CALL_STATE_INCOMING = 1;
58 public static final int CALL_STATE_RINGING = 2;
59 public static final int CALL_STATE_CURRENT = 3;
60 public static final int CALL_STATE_HUNGUP = 4;
61 public static final int CALL_STATE_BUSY = 5;
62 public static final int CALL_STATE_FAILURE = 6;
63 public static final int CALL_STATE_HOLD = 7;
64 public static final int CALL_STATE_UNHOLD = 8;
Alexandre Savard2b01c822012-09-20 15:00:37 -040065
Alexandre Savarddf544262012-10-25 14:24:08 -040066 public static final int MEDIA_STATE_NONE = 0; // No media currently
67 public static final int MEDIA_STATE_ACTIVE = 1; // Media is active
68 public static final int MEDIA_STATE_LOCAL_HOLD = 2; // Media is put on hold bu user
69 public static final int MEDIA_STATE_REMOTE_HOLD = 3; // Media is put on hold by peer
70 public static final int MEDIA_STATE_ERROR = 5; // Media is in error state
Alexandre Savard2b01c822012-09-20 15:00:37 -040071
Alexandre Savard557a5742012-10-24 13:54:53 -040072 public static class CallInfo implements Parcelable
Alexandre Savard7a46f542012-09-20 11:23:33 -040073 {
Alexandre Savard2b01c822012-09-20 15:00:37 -040074 public String mCallID = "";
Alexandre Savard73bc56f2012-10-25 13:35:54 -040075 public String mAccountID = "";
Alexandre Savard7a46f542012-09-20 11:23:33 -040076 public String mDisplayName = "";
77 public String mPhone = "";
78 public String mEmail = "";
Alexandre Savard2b01c822012-09-20 15:00:37 -040079 public String mRemoteContact = "";
Alexandre Savard27a51132012-10-25 18:35:14 -040080 public int mCallState = CALL_STATE_NONE;
Alexandre Savard557a5742012-10-24 13:54:53 -040081 public int mMediaState = MEDIA_STATE_NONE;
82
83 @Override
84 public int describeContents() {
85 return 0;
86 }
87
88 @Override
89 public void writeToParcel(Parcel out, int flags) {
90 ArrayList<String> list = new ArrayList<String>();
Alexandre Savard74c1cad2012-10-24 16:39:00 -040091
92 // Don't mess with this order!!!
Alexandre Savard557a5742012-10-24 13:54:53 -040093 list.add(mCallID);
Alexandre Savard73bc56f2012-10-25 13:35:54 -040094 list.add(mAccountID);
Alexandre Savard557a5742012-10-24 13:54:53 -040095 list.add(mDisplayName);
96 list.add(mPhone);
97 list.add(mEmail);
98 list.add(mRemoteContact);
99
100 out.writeStringList(list);
101 out.writeInt(mCallState);
102 out.writeInt(mMediaState);
103 }
104
105 public static final Parcelable.Creator<CallInfo> CREATOR
106 = new Parcelable.Creator<CallInfo>() {
107 public CallInfo createFromParcel(Parcel in) {
108 return new CallInfo(in);
109 }
110
111 public CallInfo[] newArray(int size) {
112 return new CallInfo[size];
113 }
114 };
115
116 public CallInfo() {}
117
118 private CallInfo(Parcel in) {
119 ArrayList<String> list = in.createStringArrayList();
Alexandre Savard74c1cad2012-10-24 16:39:00 -0400120
121 // Don't mess with this order!!!
Alexandre Savard557a5742012-10-24 13:54:53 -0400122 mCallID = list.get(0);
Alexandre Savard73bc56f2012-10-25 13:35:54 -0400123 mAccountID = list.get(1);
124 mDisplayName = list.get(2);
125 mPhone = list.get(3);
126 mEmail = list.get(4);
127 mRemoteContact = list.get(5);
Alexandre Savard557a5742012-10-24 13:54:53 -0400128
129 mCallState = in.readInt();
130 mMediaState = in.readInt();
131 }
Alexandre Savard7a46f542012-09-20 11:23:33 -0400132 }
Alexandre Savard4a19d752012-09-19 13:19:24 -0400133
134 public SipCall()
135 {
Alexandre Savard7a46f542012-09-20 11:23:33 -0400136 mCallInfo = new CallInfo();
Alexandre Savard4a19d752012-09-19 13:19:24 -0400137 }
138
Alexandre Savard7a46f542012-09-20 11:23:33 -0400139 public SipCall(CallInfo info)
Alexandre Savard4a19d752012-09-19 13:19:24 -0400140 {
Alexandre Savard7a46f542012-09-20 11:23:33 -0400141 mCallInfo = info;
Alexandre Savard4a19d752012-09-19 13:19:24 -0400142 }
143
Alexandre Savarda1404652012-09-20 13:34:08 -0400144 public static void setCallElementList(CallElementList list)
145 {
146 mCallElementList = list;
147 }
148
Alexandre Savarda949eec2012-10-25 17:30:49 -0400149 public static void setSFLPhoneHomeContext(SFLPhoneHome home)
150 {
151 mHome = home;
152 }
153
Alexandre Savardd1976532012-10-26 15:32:45 -0400154 public void setAssociatedRowView(View view)
155 {
156 mRowView = view;
157 }
158
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400159 public void setCallID(String callID) {
160 mCallInfo.mCallID = callID;
161 }
162
163 public String getCallId() {
164 return mCallInfo.mCallID;
165 }
166
Alexandre Savard73bc56f2012-10-25 13:35:54 -0400167 public void setAccountID(String accountID) {
168 mCallInfo.mAccountID = accountID;
169 }
170
171 public String getAccountID() {
172 return mCallInfo.mAccountID;
173 }
174
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400175 public void setDisplayName(String displayName) {
176 mCallInfo.mDisplayName = displayName;
177 }
178
179 public String getDisplayName() {
180 return mCallInfo.mDisplayName;
181 }
182
183 public void setPhone(String phone) {
184 mCallInfo.mPhone = phone;
185 }
186
187 public String getPhone() {
188 return mCallInfo.mPhone;
189 }
190
191 public void setEmail(String email) {
192 mCallInfo.mEmail = email;
193 }
194
195 public String getEmail() {
196 return mCallInfo.mEmail;
197 }
198
199 public void setRemoteContact(String remoteContact) {
200 mCallInfo.mRemoteContact = remoteContact;
201 }
202
203 public String getRemoteContact() {
204 return mCallInfo.mRemoteContact;
205 }
206
207 public void setCallState(int callState) {
208 mCallInfo.mCallState = callState;
Alexandre Savardd1976532012-10-26 15:32:45 -0400209
210 if(mRowView == null)
211 return;
212
213 String state;
214
215 switch(mCallInfo.mCallState) {
216 case CALL_STATE_INCOMING:
217 state = "INCOMING";
218 break;
219 case CALL_STATE_RINGING:
220 state = "RINGING";
221 break;
222 case CALL_STATE_CURRENT:
223 state = "CURRENT";
224 break;
225 case CALL_STATE_HUNGUP:
226 state = "HUNGUP";
227 break;
228 case CALL_STATE_BUSY:
229 state = "BUSY";
230 break;
231 case CALL_STATE_FAILURE:
232 state = "FAILURE";
233 break;
234 case CALL_STATE_HOLD:
235 state = "HOLD";
236 break;
237 case CALL_STATE_UNHOLD:
238 state = "UNHOLD";
239 break;
240 default:
241 state = "NULL";
242 }
243
244 CallElementView entryView = (CallElementView) mRowView.getTag();
245 final String CURRENT_STATE_LABEL = " CURRENT STATE: ";
246 entryView.state.setText(CURRENT_STATE_LABEL + getCallStateString());
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400247 }
248
Alexandre Savarddf544262012-10-25 14:24:08 -0400249 public int getCallStateInt() {
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400250 return mCallInfo.mCallState;
251 }
252
Alexandre Savarddf544262012-10-25 14:24:08 -0400253 public String getCallStateString() {
254 String state;
255
256 switch(mCallInfo.mCallState) {
257 case CALL_STATE_INCOMING:
258 state = "INCOMING";
259 break;
260 case CALL_STATE_RINGING:
261 state = "RINGING";
262 break;
263 case CALL_STATE_CURRENT:
264 state = "CURRENT";
265 break;
266 case CALL_STATE_HUNGUP:
267 state = "HUNGUP";
268 break;
269 case CALL_STATE_BUSY:
270 state = "BUSY";
271 break;
272 case CALL_STATE_FAILURE:
273 state = "FAILURE";
274 break;
275 case CALL_STATE_HOLD:
276 state = "HOLD";
277 break;
278 case CALL_STATE_UNHOLD:
279 state = "UNHOLD";
280 break;
281 default:
282 state = "NULL";
283 }
284
285 return state;
286 }
287
288
Alexandre Savardc58c0fd2012-10-25 10:44:08 -0400289 public void setMediaState(int mediaState) {
290 mCallInfo.mMediaState = mediaState;
291 }
292
293 public int getMediaState() {
294 return mCallInfo.mMediaState;
295 }
296
Alexandre Savarda949eec2012-10-25 17:30:49 -0400297 public void placeCallUpdateUi()
298 {
299 if(mCallElementList != null)
300 mCallElementList.addCall(this);
301
302 if(mHome != null)
303 mHome.onSelectedCallAction(this);
304 }
305
Alexandre Savard27a51132012-10-25 18:35:14 -0400306 public void notifyServicePlaceCall(ISipService service)
307 {
308 try {
309 service.placeCall(mCallInfo.mAccountID, mCallInfo.mCallID, mCallInfo.mPhone);
310 } catch (RemoteException e) {
311 Log.e(TAG, "Cannot call service method", e);
312 }
313 }
314
Alexandre Savarda949eec2012-10-25 17:30:49 -0400315 public void receiveCallUpdateUi()
Alexandre Savard23240c12012-09-19 18:23:44 -0400316 {
Alexandre Savard74c1cad2012-10-24 16:39:00 -0400317 if(mCallElementList != null)
318 mCallElementList.addCall(this);
Alexandre Savarda949eec2012-10-25 17:30:49 -0400319
320 if(mHome != null)
321 mHome.onSelectedCallAction(this);
Alexandre Savard73bc56f2012-10-25 13:35:54 -0400322 }
323
Alexandre Savarda949eec2012-10-25 17:30:49 -0400324 public void answerUpdateUi()
Alexandre Savard73bc56f2012-10-25 13:35:54 -0400325 {
Alexandre Savarda949eec2012-10-25 17:30:49 -0400326 if(mHome != null)
327 mHome.onSelectedCallAction(this);
Alexandre Savardf17e3172012-10-25 16:09:09 -0400328
329 }
Alexandre Savard4a19d752012-09-19 13:19:24 -0400330
Alexandre Savardf17e3172012-10-25 16:09:09 -0400331 public void notifyServiceAnswer(ISipService service)
332 {
Alexandre Savard27a51132012-10-25 18:35:14 -0400333 int callState = getCallStateInt();
334 if((callState != CALL_STATE_RINGING) &&
335 (callState != CALL_STATE_NONE)) {
Alexandre Savardf17e3172012-10-25 16:09:09 -0400336 return;
Alexandre Savard27a51132012-10-25 18:35:14 -0400337 }
Alexandre Savardf17e3172012-10-25 16:09:09 -0400338
339 try {
340 service.accept(mCallInfo.mCallID);
341 } catch (RemoteException e) {
342 Log.e(TAG, "Cannot call service method", e);
343 }
Alexandre Savard4a19d752012-09-19 13:19:24 -0400344 }
345
Alexandre Savard4f42ade2012-10-24 18:03:31 -0400346 /**
347 * Perform hangup action without sending request to the service
Alexandre Savarda949eec2012-10-25 17:30:49 -0400348 * Used when SipService haved been notified that this call hung up
Alexandre Savard4f42ade2012-10-24 18:03:31 -0400349 */
Alexandre Savarda949eec2012-10-25 17:30:49 -0400350 public void hangupUpdateUi() {
Alexandre Savard74c1cad2012-10-24 16:39:00 -0400351 Log.i(TAG, "Hangup call " + mCallInfo.mCallID);
352
353 if(mCallElementList != null)
354 mCallElementList.removeCall(this);
Alexandre Savarda949eec2012-10-25 17:30:49 -0400355
356 if(mHome != null)
357 mHome.onUnselectedCallAction();
Alexandre Savard4f42ade2012-10-24 18:03:31 -0400358 }
359
360 /**
361 * Perform hangup action and send request to the service
362 */
363 public void notifyServiceHangup(ISipService service)
364 {
Alexandre Savard74c1cad2012-10-24 16:39:00 -0400365 try {
366 service.hangUp(mCallInfo.mCallID);
367 } catch (RemoteException e) {
368 Log.e(TAG, "Cannot call service method", e);
369 }
Alexandre Savard4a19d752012-09-19 13:19:24 -0400370 }
Alexandre Savardaef9d802012-09-20 17:31:32 -0400371
Alexandre Savard83869852012-10-26 09:14:12 -0400372 public void notifyServiceRefuse(ISipService service)
373 {
374 try {
375 service.refuse(mCallInfo.mCallID);
376 } catch (RemoteException e) {
377 Log.e(TAG, "Cannot call service method", e);
378 }
379 }
380
Alexandre Savarde9dc8992012-10-26 12:12:27 -0400381 public void notifyServiceHold(ISipService service)
382 {
383 try {
384 service.hold(mCallInfo.mCallID);
385 } catch (RemoteException e) {
386 Log.e(TAG, "Cannot call service method", e);
387 }
388 }
389
390 public void notifyServiceUnhold(ISipService service)
391 {
392 try {
393 service.unhold(mCallInfo.mCallID);
394 } catch (RemoteException e) {
395 Log.e(TAG, "Cannot call service method", e);
396 }
397 }
Alexandre Savard83869852012-10-26 09:14:12 -0400398
Alexandre Savardaef9d802012-09-20 17:31:32 -0400399 public void addToConference()
400 {
401 Log.i(TAG, "Add call to conference");
402 }
403
404 public void sendTextMessage()
405 {
406 Log.i(TAG, "Send text message");
407 }
Alexandre Savard3bdce7b2012-10-24 18:27:45 -0400408
Alexandre Savard73bc56f2012-10-25 13:35:54 -0400409 public void printCallInfo()
410 {
411 Log.i(TAG, "CallInfo: CallID: " + mCallInfo.mCallID);
412 Log.i(TAG, " AccountID: " + mCallInfo.mAccountID);
413 Log.i(TAG, " Display Name: " + mCallInfo.mDisplayName);
414 Log.i(TAG, " Phone: " + mCallInfo.mPhone);
415 Log.i(TAG, " Email: " + mCallInfo.mEmail);
416 Log.i(TAG, " Contact: " + mCallInfo.mRemoteContact);
417 }
418
Alexandre Savard3bdce7b2012-10-24 18:27:45 -0400419 public void launchCallActivity(Context context)
420 {
421 Log.i(TAG, "Launch Call Activity");
422 Bundle bundle = new Bundle();
423 bundle.putParcelable("CallInfo", mCallInfo);
424 Intent intent = new Intent().setClass(context, CallActivity.class);
425 intent.putExtras(bundle);
426 context.startActivity(intent);
427 }
Alexandre Savard4a19d752012-09-19 13:19:24 -0400428}