blob: 785a436290c682d759761e639533d9b921bedf47 [file] [log] [blame]
Alexandre Savard14323be2012-10-24 10:02:13 -04001/*
2 * Copyright (C) 2004-2012 Savoir-Faire Linux Inc.
3 *
4 * Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
Adrien Béraud71b2f812013-04-26 18:51:02 +10005 * Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
alisionfde875f2013-05-28 17:01:54 -04006 * Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com>
Alexandre Savard14323be2012-10-24 10:02:13 -04007 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 * Additional permission under GNU GPL version 3 section 7:
23 *
24 * If you modify this program, or any covered work, by linking or
25 * combining it with the OpenSSL project's OpenSSL library (or a
26 * modified version of that library), containing parts covered by the
27 * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
28 * grants you additional permission to convey the resulting work.
29 * Corresponding Source for a non-source form of such a combination
30 * shall include the source code for the parts of OpenSSL used as well
31 * as that of the covered work.
32 */
33
34package com.savoirfairelinux.sflphone.client;
35
Adrien Béraud33268882013-05-18 03:41:15 +100036import java.util.concurrent.ExecutorService;
37import java.util.concurrent.Executors;
38
Alexandre Savard14323be2012-10-24 10:02:13 -040039import android.app.Activity;
Alexandre Savard6d54bbc2012-10-24 11:04:23 -040040import android.content.ComponentName;
alision17052d42013-04-22 10:39:38 -040041import android.content.Context;
Alexandre Savard6d54bbc2012-10-24 11:04:23 -040042import android.content.Intent;
alision84813a12013-05-27 17:40:39 -040043import android.content.IntentFilter;
Alexandre Savard6d54bbc2012-10-24 11:04:23 -040044import android.content.ServiceConnection;
Alexandre Savard14323be2012-10-24 10:02:13 -040045import android.os.Bundle;
alision85992112013-05-29 12:18:08 -040046import android.os.Environment;
Alexandre Savard6d54bbc2012-10-24 11:04:23 -040047import android.os.IBinder;
alision85992112013-05-29 12:18:08 -040048import android.os.RemoteException;
alision84813a12013-05-27 17:40:39 -040049import android.support.v4.view.ViewPager;
alisionfde875f2013-05-28 17:01:54 -040050import android.support.v4.widget.SlidingPaneLayout;
Alexandre Savard6d54bbc2012-10-24 11:04:23 -040051import android.util.Log;
alisionfde875f2013-05-28 17:01:54 -040052import android.view.View;
Adrien Béraud33268882013-05-18 03:41:15 +100053import android.widget.Toast;
Alexandre Savard14323be2012-10-24 10:02:13 -040054
55import com.savoirfairelinux.sflphone.R;
alision84813a12013-05-27 17:40:39 -040056import com.savoirfairelinux.sflphone.client.receiver.CallReceiver;
57import com.savoirfairelinux.sflphone.fragments.CallFragment;
alisionfde875f2013-05-28 17:01:54 -040058import com.savoirfairelinux.sflphone.fragments.CallListFragment;
alision84813a12013-05-27 17:40:39 -040059import com.savoirfairelinux.sflphone.interfaces.CallInterface;
alisionf76de3b2013-04-16 15:35:22 -040060import com.savoirfairelinux.sflphone.model.SipCall;
alision85992112013-05-29 12:18:08 -040061import com.savoirfairelinux.sflphone.model.SipCall.state;
alision84813a12013-05-27 17:40:39 -040062import com.savoirfairelinux.sflphone.service.CallManagerCallBack;
Alexandre Savard6d54bbc2012-10-24 11:04:23 -040063import com.savoirfairelinux.sflphone.service.ISipService;
64import com.savoirfairelinux.sflphone.service.SipService;
Alexandre Savard14323be2012-10-24 10:02:13 -040065
alisionfde875f2013-05-28 17:01:54 -040066public class CallActivity extends Activity implements CallInterface, CallFragment.Callbacks, CallListFragment.Callbacks {
alision9f7a6ec2013-05-24 16:26:26 -040067 static final String TAG = "CallActivity";
68 private ISipService service;
alision84813a12013-05-27 17:40:39 -040069
alision9f7a6ec2013-05-24 16:26:26 -040070 private String pendingAction = null;
Adrien Béraud33268882013-05-18 03:41:15 +100071
alision9f7a6ec2013-05-24 16:26:26 -040072 private ExecutorService infos_fetcher = Executors.newCachedThreadPool();
alision84813a12013-05-27 17:40:39 -040073 CallReceiver receiver;
alision85992112013-05-29 12:18:08 -040074
alisionfde875f2013-05-28 17:01:54 -040075 CallListFragment mCallsFragment;
76 CallFragment mCurrentCallFragment;
Adrien Béraud33268882013-05-18 03:41:15 +100077
alisionfde875f2013-05-28 17:01:54 -040078 // private CallPagerAdapter mCallPagerAdapter;
79 // private ViewPager mViewPager;
Alexandre Savard4f42ade2012-10-24 18:03:31 -040080
alision9f7a6ec2013-05-24 16:26:26 -040081 /*
82 * private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
83 *
84 * @Override public void onReceive(Context context, Intent intent) { String signalName = intent.getStringExtra(CallManagerCallBack.SIGNAL_NAME);
85 * Log.d(TAG, "Signal received: " + signalName);
86 *
87 * if (signalName.equals(CallManagerCallBack.NEW_CALL_CREATED)) { } else if (signalName.equals(CallManagerCallBack.CALL_STATE_CHANGED)) {
88 * processCallStateChangedSignal(intent); } else if (signalName.equals(CallManagerCallBack.INCOMING_CALL)) { } } };
89 */
Alexandre Savard4f42ade2012-10-24 18:03:31 -040090
alision9f7a6ec2013-05-24 16:26:26 -040091 @Override
92 protected void onCreate(Bundle savedInstanceState) {
93 super.onCreate(savedInstanceState);
alision84813a12013-05-27 17:40:39 -040094 setContentView(R.layout.activity_call_layout);
Adrien Béraud33268882013-05-18 03:41:15 +100095
alision84813a12013-05-27 17:40:39 -040096 receiver = new CallReceiver(this);
Adrien Béraud33268882013-05-18 03:41:15 +100097
alisionfde875f2013-05-28 17:01:54 -040098 mCallsFragment = new CallListFragment();
alision85992112013-05-29 12:18:08 -040099
alisionfde875f2013-05-28 17:01:54 -0400100 getFragmentManager().beginTransaction().replace(R.id.calllist_pane, mCallsFragment).commit();
alision84813a12013-05-27 17:40:39 -0400101
alisionfde875f2013-05-28 17:01:54 -0400102 final SlidingPaneLayout slidingPaneLayout = (SlidingPaneLayout) findViewById(R.id.slidingpanelayout);
103 slidingPaneLayout.setPanelSlideListener(new SlidingPaneLayout.PanelSlideListener() {
104
105 @Override
106 public void onPanelSlide(View view, float offSet) {
107 }
108
109 @Override
110 public void onPanelOpened(View view) {
111
112 switch (view.getId()) {
113 case R.id.calllist_pane:
alision85992112013-05-29 12:18:08 -0400114 // getFragmentManager().findFragmentById(R.id.calllist_pane).setHasOptionsMenu(true);
115 // getFragmentManager().findFragmentById(R.id.ongoingcall_pane).setHasOptionsMenu(false);
alisionfde875f2013-05-28 17:01:54 -0400116 break;
117 default:
118 break;
119 }
120 }
121
122 @Override
123 public void onPanelClosed(View view) {
124
125 switch (view.getId()) {
126 case R.id.ongoingcall_pane:
alision85992112013-05-29 12:18:08 -0400127 // getFragmentManager().findFragmentById(R.id.calllist_pane).setHasOptionsMenu(false);
128 // getFragmentManager().findFragmentById(R.id.ongoingcall_pane).setHasOptionsMenu(true);
alisionfde875f2013-05-28 17:01:54 -0400129 break;
130 default:
131 break;
132 }
133 }
134 });
Adrien Béraud33268882013-05-18 03:41:15 +1000135
alision9f7a6ec2013-05-24 16:26:26 -0400136 Bundle b = getIntent().getExtras();
Alexandre Savard6d54bbc2012-10-24 11:04:23 -0400137
alision9f7a6ec2013-05-24 16:26:26 -0400138 Intent intent = new Intent(this, SipService.class);
Alexandre Savard6d54bbc2012-10-24 11:04:23 -0400139
alision9f7a6ec2013-05-24 16:26:26 -0400140 // setCallStateDisplay(mCall.getCallStateString());
Adrien Béraud6bbce912013-05-24 00:48:13 +1000141
alision9f7a6ec2013-05-24 16:26:26 -0400142 bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
Adrien Béraud33268882013-05-18 03:41:15 +1000143
alision9f7a6ec2013-05-24 16:26:26 -0400144 }
Adrien Béraud33268882013-05-18 03:41:15 +1000145
alision84813a12013-05-27 17:40:39 -0400146 /* activity gets back to the foreground and user input */
147 @Override
148 protected void onResume() {
149 Log.i(TAG, "onResume");
150 IntentFilter intentFilter = new IntentFilter();
151 intentFilter.addAction(CallManagerCallBack.INCOMING_CALL);
152 intentFilter.addAction(CallManagerCallBack.INCOMING_TEXT);
153 intentFilter.addAction(CallManagerCallBack.CALL_STATE_CHANGED);
154 registerReceiver(receiver, intentFilter);
155 super.onResume();
alision9f7a6ec2013-05-24 16:26:26 -0400156 }
Adrien Béraud33268882013-05-18 03:41:15 +1000157
alision84813a12013-05-27 17:40:39 -0400158 /* activity no more in foreground */
159 @Override
160 protected void onPause() {
161 super.onPause();
162 unregisterReceiver(receiver);
alision9f7a6ec2013-05-24 16:26:26 -0400163 }
Alexandre Savard6d54bbc2012-10-24 11:04:23 -0400164
alision9f7a6ec2013-05-24 16:26:26 -0400165 @Override
166 protected void onDestroy() {
167 // Log.i(TAG, "Destroying Call Activity for call " + mCall.getCallId());
168 // LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
169 unbindService(mConnection);
alisiond8c83882013-05-17 17:00:42 -0400170
alision9f7a6ec2013-05-24 16:26:26 -0400171 super.onDestroy();
172 }
Adrien Béraud6bbce912013-05-24 00:48:13 +1000173
alision9f7a6ec2013-05-24 16:26:26 -0400174 /** Defines callbacks for service binding, passed to bindService() */
175 private ServiceConnection mConnection = new ServiceConnection() {
176 @Override
177 public void onServiceConnected(ComponentName className, IBinder binder) {
178 service = ISipService.Stub.asInterface(binder);
alisionfde875f2013-05-28 17:01:54 -0400179 Log.i(TAG, "Placing call");
180 mCurrentCallFragment = new CallFragment();
181 mCurrentCallFragment.setArguments(getIntent().getExtras());
182 getIntent().getExtras();
alision85992112013-05-29 12:18:08 -0400183 // SipCall info = getIntent().getExtras().getParcelable("CallInfo");
alisionfde875f2013-05-28 17:01:54 -0400184 // mCallPagerAdapter.addCall(info.mCallID, newCall);
185 getFragmentManager().beginTransaction().replace(R.id.ongoingcall_pane, mCurrentCallFragment).commit();
Adrien Béraud6bbce912013-05-24 00:48:13 +1000186
alision9f7a6ec2013-05-24 16:26:26 -0400187 }
Alexandre Savarde41f5212012-10-26 14:23:50 -0400188
alision9f7a6ec2013-05-24 16:26:26 -0400189 @Override
190 public void onServiceDisconnected(ComponentName arg0) {
191 }
192 };
Alexandre Savarddf544262012-10-25 14:24:08 -0400193
alision84813a12013-05-27 17:40:39 -0400194 @Override
195 public void incomingCall(Intent call) {
196 Toast.makeText(this, "New Call incoming", Toast.LENGTH_LONG).show();
197
alisionfde875f2013-05-28 17:01:54 -0400198 mCallsFragment.update();
alision84813a12013-05-27 17:40:39 -0400199
200 }
201
202 @Override
203 public void callStateChanged(Intent callState) {
204
205 Bundle b = callState.getBundleExtra("com.savoirfairelinux.sflphone.service.newstate");
206 processCallStateChangedSignal(b.getString("CallID"), b.getString("State"));
207
208 }
209
210 public void processCallStateChangedSignal(String callID, String newState) {
alision9f7a6ec2013-05-24 16:26:26 -0400211 /*
212 * Bundle bundle = intent.getBundleExtra("com.savoirfairelinux.sflphone.service.newstate"); String callID = bundle.getString("CallID"); String
213 * newState = bundle.getString("State");
214 */
alision85992112013-05-29 12:18:08 -0400215 // CallFragment fr = mCurrentCallFragment;
Adrien Béraud29556042013-04-26 17:35:43 +1000216
alision85992112013-05-29 12:18:08 -0400217 mCallsFragment.update();
alision84813a12013-05-27 17:40:39 -0400218
alision85992112013-05-29 12:18:08 -0400219 // if (newState.equals("INCOMING")) {
220 // fr.changeCallState(SipCall.state.CALL_STATE_INCOMING);
221 //
222 // } else if (newState.equals("RINGING")) {
223 // fr.changeCallState(SipCall.state.CALL_STATE_RINGING);
224 //
225 // } else if (newState.equals("CURRENT")) {
226 // fr.changeCallState(SipCall.state.CALL_STATE_CURRENT);
227 //
228 // } else if (newState.equals("HUNGUP")) {
229 // // mCallPagerAdapter.remove(callID);
230 // // if (mCallPagerAdapter.getCount() == 0) {
231 // // finish();
232 // // }
233 //
234 // } else if (newState.equals("BUSY")) {
235 // // mCallPagerAdapter.remove(callID);
236 // // if (mCallPagerAdapter.getCount() == 0) {
237 // // finish();
238 // // }
239 //
240 // } else if (newState.equals("FAILURE")) {
241 // // mCallPagerAdapter.remove(callID);
242 // // if (mCallPagerAdapter.getCount() == 0) {
243 // // finish();
244 // // }
245 //
246 // } else if (newState.equals("HOLD")) {
247 // fr.changeCallState(SipCall.state.CALL_STATE_HOLD);
248 //
249 // } else if (newState.equals("UNHOLD")) {
250 // fr.changeCallState(SipCall.state.CALL_STATE_CURRENT);
251 //
252 // } else {
253 // fr.changeCallState(SipCall.state.CALL_STATE_NONE);
254 //
255 // }
Adrien Béraudc99b8432013-04-25 16:27:46 +1000256
alision9f7a6ec2013-05-24 16:26:26 -0400257 Log.w(TAG, "processCallStateChangedSignal " + newState);
Adrien Béraud29556042013-04-26 17:35:43 +1000258
alision9f7a6ec2013-05-24 16:26:26 -0400259 }
Adrien Béraud71b2f812013-04-26 18:51:02 +1000260
alision84813a12013-05-27 17:40:39 -0400261 @Override
262 public void incomingText(Intent msg) {
263 Toast.makeText(this, "New Call incoming", Toast.LENGTH_LONG).show();
Adrien Béraud29556042013-04-26 17:35:43 +1000264
alision84813a12013-05-27 17:40:39 -0400265 // TODO link text message to associate call and display it at the right place
Adrien Béraud71b2f812013-04-26 18:51:02 +1000266
alision9f7a6ec2013-05-24 16:26:26 -0400267 }
alision7f18fc82013-05-01 09:37:33 -0400268
alision84813a12013-05-27 17:40:39 -0400269 @Override
270 public ISipService getService() {
271 return service;
alision9f7a6ec2013-05-24 16:26:26 -0400272 }
alision04a00182013-05-10 17:05:29 -0400273
alision85992112013-05-29 12:18:08 -0400274 @Override
275 public void onCallSelected(SipCall call) {
276 mCurrentCallFragment = new CallFragment();
277 Bundle b = new Bundle();
278 b.putParcelable("CallInfo", call);
279 mCurrentCallFragment.setArguments(b);
280 getFragmentManager().beginTransaction().replace(R.id.ongoingcall_pane, mCurrentCallFragment).commit();
281
282 }
283
284 @Override
285 public void callContact(SipCall call) {
286 try {
287 service.placeCall(call);
288 } catch (RemoteException e) {
289 Log.e(TAG, "Cannot call service method", e);
290 }
291
292 }
293
294 @Override
295 public void onCallAccepted(SipCall call) {
296 int callState = call.getCallStateInt();
297 if ((callState != state.CALL_STATE_RINGING) && (callState != state.CALL_STATE_NONE)) {
298 return;
299 }
300
301 try {
302 service.accept(call.getCallId());
303 } catch (RemoteException e) {
304 Log.e(TAG, "Cannot call service method", e);
305 }
306
307 }
308
309 @Override
310 public void onCallRejected(SipCall call) {
311 try {
312 if (call.getCallStateInt() == state.CALL_STATE_RINGING) {
313 service.refuse(call.getCallId());
314 return;
315 }
316 } catch (RemoteException e) {
317 Log.e(TAG, "Cannot call service method", e);
318 }
319 }
320
321 @Override
322 public void onCallEnded(SipCall call) {
323 try {
324 if ((call.getCallStateInt() == state.CALL_STATE_NONE) || (call.getCallStateInt() == state.CALL_STATE_CURRENT)
325 || (call.getCallStateInt() == state.CALL_STATE_HOLD)) {
326 service.hangUp(call.getCallId());
327 return;
328
329 } else if (call.getCallStateInt() == state.CALL_STATE_RINGING) {
330 if (call.getCallType() == state.CALL_TYPE_INCOMING) {
331 service.refuse(call.getCallId());
332 return;
333 } else if (call.getCallType() == state.CALL_TYPE_OUTGOING) {
334 service.hangUp(call.getCallId());
335 return;
336 }
337 }
338 } catch (RemoteException e) {
339 Log.e(TAG, "Cannot call service method", e);
340 }
341 }
342
343 @Override
344 public void onCallSuspended(SipCall call) {
345 try {
346 if (call.getCallStateInt() == state.CALL_STATE_CURRENT) {
347 service.hold(call.getCallId());
348 return;
349 }
350 } catch (RemoteException e) {
351 Log.e(TAG, "Cannot call service method", e);
352 }
353 }
354
355 @Override
356 public void onCallResumed(SipCall call) {
357 try {
358 if (call.getCallStateInt() == state.CALL_STATE_HOLD) {
359 service.unhold(call.getCallId());
360 return;
361 }
362 } catch (RemoteException e) {
363 Log.e(TAG, "Cannot call service method", e);
364 }
365
366
367 }
368
369 @Override
370 public void onCalltransfered(SipCall call,String to) {
371 try {
372 if (call.getCallStateInt() == state.CALL_STATE_CURRENT) {
373 service.transfer(call.getCallId(), to);
374 }
375 } catch (RemoteException e) {
376 Log.e(TAG, "Cannot call service method", e);
377 }
378
379 }
380
381 @Override
382 public void onRecordCall(SipCall call) {
383 try {
384 if (call.getCallStateInt() == state.CALL_STATE_CURRENT) {
385 service.setRecordPath(Environment.getExternalStorageDirectory().getAbsolutePath());
386 Log.w(TAG, "Recording path" + service.getRecordPath());
387 service.setRecordingCall(call.getCallId());
388 }
389 } catch (RemoteException e) {
390 Log.e(TAG, "Cannot call service method", e);
391 }
392
393 }
394
395 @Override
396 public void onSendMessage(SipCall call, String msg) {
397 try {
398 if (call.getCallStateInt() == state.CALL_STATE_CURRENT) {
399 service.sendTextMessage(call.getCallId(), msg, "Me");
400 }
401 } catch (RemoteException e) {
402 Log.e(TAG, "Cannot call service method", e);
403 }
404
405 }
406
Alexandre Savard14323be2012-10-24 10:02:13 -0400407}