blob: 33981f540dcd70f88287bb4b225f0f9c7d975e7e [file] [log] [blame]
alisionfde875f2013-05-28 17:01:54 -04001/*
alision2ec64f92013-06-17 17:28:58 -04002 * Copyright (C) 2004-2013 Savoir-Faire Linux Inc.
alisionfde875f2013-05-28 17:01:54 -04003 *
4 * Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com>
5 *
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 */
31
alision84813a12013-05-27 17:40:39 -040032package com.savoirfairelinux.sflphone.fragments;
33
Alexandre Lision2b237922013-09-09 16:23:02 -040034import java.util.ArrayList;
Alexandre Lision31f46fc2013-09-26 11:19:54 -040035import java.util.Locale;
Alexandre Lision2b237922013-09-09 16:23:02 -040036
alision84813a12013-05-27 17:40:39 -040037import android.app.Activity;
38import android.app.Fragment;
Alexandre Lision2b237922013-09-09 16:23:02 -040039import android.app.FragmentManager;
Alexandre Lisionf1850c02013-09-23 14:19:34 -040040import android.content.Context;
Alexandre Lision2b237922013-09-09 16:23:02 -040041import android.content.Intent;
alision84813a12013-05-27 17:40:39 -040042import android.graphics.Bitmap;
Adrien Béraud0c9bd8f2013-05-30 16:16:57 +100043import android.graphics.BitmapFactory;
alision84813a12013-05-27 17:40:39 -040044import android.graphics.PointF;
Alexandre Lisionf1850c02013-09-23 14:19:34 -040045import android.hardware.Sensor;
46import android.hardware.SensorEvent;
47import android.hardware.SensorEventListener;
48import android.hardware.SensorManager;
alision84813a12013-05-27 17:40:39 -040049import android.os.Bundle;
50import android.os.RemoteException;
alision84813a12013-05-27 17:40:39 -040051import android.util.Log;
Alexandre Lision64dc8c02013-09-25 15:32:25 -040052import android.view.KeyEvent;
alision84813a12013-05-27 17:40:39 -040053import android.view.LayoutInflater;
Adrien Béraud13cde0b2013-05-30 20:27:20 +100054import android.view.SurfaceHolder;
55import android.view.SurfaceHolder.Callback;
alision84813a12013-05-27 17:40:39 -040056import android.view.View;
Alexandre Lision84208a32013-09-25 13:18:37 -040057import android.view.View.OnClickListener;
alision84813a12013-05-27 17:40:39 -040058import android.view.ViewGroup;
Alexandre Lisionc30e8412013-09-26 15:12:59 -040059import android.view.WindowManager;
Alexandre Lision84208a32013-09-25 13:18:37 -040060import android.view.inputmethod.InputMethodManager;
61import android.widget.ImageButton;
Alexandre Lision3c6b7102013-09-16 16:56:46 -040062import android.widget.TextView;
alision84813a12013-05-27 17:40:39 -040063
64import com.savoirfairelinux.sflphone.R;
alision84813a12013-05-27 17:40:39 -040065import com.savoirfairelinux.sflphone.model.Attractor;
66import com.savoirfairelinux.sflphone.model.Bubble;
67import com.savoirfairelinux.sflphone.model.BubbleModel;
68import com.savoirfairelinux.sflphone.model.BubblesView;
alisiondf1dac92013-06-27 17:35:53 -040069import com.savoirfairelinux.sflphone.model.Conference;
alision84813a12013-05-27 17:40:39 -040070import com.savoirfairelinux.sflphone.model.SipCall;
alision84813a12013-05-27 17:40:39 -040071import com.savoirfairelinux.sflphone.service.ISipService;
72
Alexandre Lisionf1850c02013-09-23 14:19:34 -040073public class CallFragment extends Fragment implements Callback, SensorEventListener {
alision84813a12013-05-27 17:40:39 -040074
alision1005ba12013-06-19 13:52:44 -040075 static final String TAG = "CallFragment";
alision84813a12013-05-27 17:40:39 -040076
alisionf57d8a62013-07-02 09:37:12 -040077 float BUBBLE_SIZE = 75;
alision1005ba12013-06-19 13:52:44 -040078 static final float ATTRACTOR_SIZE = 40;
alision84813a12013-05-27 17:40:39 -040079
Alexandre Lision2b237922013-09-09 16:23:02 -040080 public static final int REQUEST_TRANSFER = 10;
81
alisiondf1dac92013-06-27 17:35:53 -040082 private Conference conf;
alision84813a12013-05-27 17:40:39 -040083
Alexandre Lision3c6b7102013-09-16 16:56:46 -040084 private TextView callStatusTxt;
alision1005ba12013-06-19 13:52:44 -040085 private BubblesView view;
86 private BubbleModel model;
alision84813a12013-05-27 17:40:39 -040087
alision1005ba12013-06-19 13:52:44 -040088 private Callbacks mCallbacks = sDummyCallbacks;
alision84813a12013-05-27 17:40:39 -040089
alision806e18e2013-06-21 15:30:17 -040090 private SipCall myself;
alision85704182013-05-29 15:23:03 -040091
Alexandre Lisiona764c682013-09-09 10:02:07 -040092 boolean accepted = false;
alision1005ba12013-06-19 13:52:44 -040093 private Bitmap call_icon;
alision85704182013-05-29 15:23:03 -040094
Alexandre Lisionf1850c02013-09-23 14:19:34 -040095 private SensorManager mSensorManager;
96
97 private Sensor mSensor;
98
alision1005ba12013-06-19 13:52:44 -040099 @Override
100 public void onCreate(Bundle savedBundle) {
101 super.onCreate(savedBundle);
alision1005ba12013-06-19 13:52:44 -0400102 Bundle b = getArguments();
alisioncd8fb912013-06-28 14:43:51 -0400103 conf = new Conference((Conference) b.getParcelable("conference"));
alisiondf1dac92013-06-27 17:35:53 -0400104 model = new BubbleModel(getResources().getDisplayMetrics().density);
alision729b0a22013-07-02 11:57:33 -0400105 BUBBLE_SIZE = getResources().getDimension(R.dimen.bubble_size);
Alexandre Lisiona764c682013-09-09 10:02:07 -0400106 Log.e(TAG, "BUBBLE_SIZE " + BUBBLE_SIZE);
Alexandre Lisionf1850c02013-09-23 14:19:34 -0400107 mSensorManager = (SensorManager) getActivity().getSystemService(Context.SENSOR_SERVICE);
108 mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
alision729b0a22013-07-02 11:57:33 -0400109
alision1005ba12013-06-19 13:52:44 -0400110 }
alision85992112013-05-29 12:18:08 -0400111
alision1005ba12013-06-19 13:52:44 -0400112 /**
113 * A dummy implementation of the {@link Callbacks} interface that does nothing. Used only when this fragment is not attached to an activity.
114 */
115 private static Callbacks sDummyCallbacks = new Callbacks() {
116 @Override
117 public void onSendMessage(SipCall call, String msg) {
118 }
alision85992112013-05-29 12:18:08 -0400119
alision1005ba12013-06-19 13:52:44 -0400120 @Override
121 public void callContact(SipCall call) {
122 }
alision85992112013-05-29 12:18:08 -0400123
alision1005ba12013-06-19 13:52:44 -0400124 @Override
125 public void onCallAccepted(SipCall call) {
126 }
alision85704182013-05-29 15:23:03 -0400127
alision1005ba12013-06-19 13:52:44 -0400128 @Override
129 public void onCallRejected(SipCall call) {
130 }
alision85992112013-05-29 12:18:08 -0400131
alision1005ba12013-06-19 13:52:44 -0400132 @Override
133 public void onCallEnded(SipCall call) {
134 }
alision85704182013-05-29 15:23:03 -0400135
alision1005ba12013-06-19 13:52:44 -0400136 @Override
137 public void onCallSuspended(SipCall call) {
138 }
alision85992112013-05-29 12:18:08 -0400139
alision1005ba12013-06-19 13:52:44 -0400140 @Override
141 public void onCallResumed(SipCall call) {
142 }
alision85704182013-05-29 15:23:03 -0400143
alision1005ba12013-06-19 13:52:44 -0400144 @Override
145 public void onCalltransfered(SipCall call, String to) {
146 }
alision85992112013-05-29 12:18:08 -0400147
alision1005ba12013-06-19 13:52:44 -0400148 @Override
149 public void onRecordCall(SipCall call) {
150 }
alision85704182013-05-29 15:23:03 -0400151
alision1005ba12013-06-19 13:52:44 -0400152 @Override
153 public ISipService getService() {
154 return null;
155 }
alisiondf1dac92013-06-27 17:35:53 -0400156
157 @Override
158 public void replaceCurrentCallDisplayed() {
159 }
Alexandre Lision0c384512013-09-17 17:15:57 -0400160
161 @Override
Adrien Béraude78d06f2013-09-19 13:33:44 +1000162 public void startTimer() {
Alexandre Lision0c384512013-09-17 17:15:57 -0400163 }
alision1005ba12013-06-19 13:52:44 -0400164 };
alision907bde72013-06-20 14:40:37 -0400165
alision1005ba12013-06-19 13:52:44 -0400166 /**
167 * The Activity calling this fragment has to implement this interface
168 *
169 */
170 public interface Callbacks {
alision85992112013-05-29 12:18:08 -0400171
alision1005ba12013-06-19 13:52:44 -0400172 public ISipService getService();
alision85704182013-05-29 15:23:03 -0400173
alision1005ba12013-06-19 13:52:44 -0400174 public void callContact(SipCall call);
alision85992112013-05-29 12:18:08 -0400175
alision1005ba12013-06-19 13:52:44 -0400176 public void onCallAccepted(SipCall call);
alision85704182013-05-29 15:23:03 -0400177
alision1005ba12013-06-19 13:52:44 -0400178 public void onCallRejected(SipCall call);
alision85992112013-05-29 12:18:08 -0400179
alision1005ba12013-06-19 13:52:44 -0400180 public void onCallEnded(SipCall call);
alision85704182013-05-29 15:23:03 -0400181
alision1005ba12013-06-19 13:52:44 -0400182 public void onCallSuspended(SipCall call);
alision85704182013-05-29 15:23:03 -0400183
alision1005ba12013-06-19 13:52:44 -0400184 public void onCallResumed(SipCall call);
alision84813a12013-05-27 17:40:39 -0400185
alision1005ba12013-06-19 13:52:44 -0400186 public void onCalltransfered(SipCall call, String to);
alision84813a12013-05-27 17:40:39 -0400187
alision1005ba12013-06-19 13:52:44 -0400188 public void onRecordCall(SipCall call);
alision85704182013-05-29 15:23:03 -0400189
alision1005ba12013-06-19 13:52:44 -0400190 public void onSendMessage(SipCall call, String msg);
alisiondf1dac92013-06-27 17:35:53 -0400191
192 public void replaceCurrentCallDisplayed();
Alexandre Lision0c384512013-09-17 17:15:57 -0400193
194 public void startTimer();
alision1005ba12013-06-19 13:52:44 -0400195 }
alision85992112013-05-29 12:18:08 -0400196
alision1005ba12013-06-19 13:52:44 -0400197 @Override
198 public void onAttach(Activity activity) {
199 super.onAttach(activity);
alision85992112013-05-29 12:18:08 -0400200
alision1005ba12013-06-19 13:52:44 -0400201 if (!(activity instanceof Callbacks)) {
202 throw new IllegalStateException("Activity must implement fragment's callbacks.");
203 }
alision85992112013-05-29 12:18:08 -0400204
alision1005ba12013-06-19 13:52:44 -0400205 // rootView.requestDisallowInterceptTouchEvent(true);
alision85992112013-05-29 12:18:08 -0400206
alision1005ba12013-06-19 13:52:44 -0400207 mCallbacks = (Callbacks) activity;
alision50fa0722013-06-25 17:29:44 -0400208 myself = SipCall.SipCallBuilder.buildMyselfCall(activity.getContentResolver(), "Me");
Adrien Béraude78d06f2013-09-19 13:33:44 +1000209
alision1005ba12013-06-19 13:52:44 -0400210 }
alision85992112013-05-29 12:18:08 -0400211
alision1005ba12013-06-19 13:52:44 -0400212 @Override
213 public void onDetach() {
214 super.onDetach();
215 mCallbacks = sDummyCallbacks;
Alexandre Lisionf1850c02013-09-23 14:19:34 -0400216 mSensorManager.unregisterListener(this);
alision1005ba12013-06-19 13:52:44 -0400217 }
alision907bde72013-06-20 14:40:37 -0400218
alision1005ba12013-06-19 13:52:44 -0400219 @Override
alision907bde72013-06-20 14:40:37 -0400220 public void onStop() {
alision1005ba12013-06-19 13:52:44 -0400221 super.onStop();
222 }
alision85992112013-05-29 12:18:08 -0400223
alision1005ba12013-06-19 13:52:44 -0400224 @Override
Alexandre Lisionf1850c02013-09-23 14:19:34 -0400225 public void onResume() {
226 super.onResume();
227 mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL);
228 }
229
230 @Override
231 public void onPause() {
232 super.onPause();
233 mSensorManager.unregisterListener(this);
234 }
235
236 @Override
Alexandre Lision2b237922013-09-09 16:23:02 -0400237 public void onActivityResult(int requestCode, int resultCode, Intent data) {
238 super.onActivityResult(requestCode, resultCode, data);
239 SipCall transfer = null;
240 if (requestCode == REQUEST_TRANSFER) {
241 switch (resultCode) {
Adrien Béraude78d06f2013-09-19 13:33:44 +1000242 case TransferDFragment.RESULT_TRANSFER_CONF:
Alexandre Lision2b237922013-09-09 16:23:02 -0400243 Conference c = data.getParcelableExtra("target");
244 transfer = data.getParcelableExtra("transfer");
245 try {
246
247 mCallbacks.getService().attendedTransfer(transfer.getCallId(), c.getParticipants().get(0).getCallId());
248
249 } catch (RemoteException e) {
250 // TODO Auto-generated catch block
251 e.printStackTrace();
252 }
Alexandre Lision6deda412013-09-25 13:21:22 -0400253 // Toast.makeText(getActivity(), "Transfer complete", Toast.LENGTH_LONG).show();
Alexandre Lision2b237922013-09-09 16:23:02 -0400254 break;
255
Adrien Béraude78d06f2013-09-19 13:33:44 +1000256 case TransferDFragment.RESULT_TRANSFER_NUMBER:
Alexandre Lision2b237922013-09-09 16:23:02 -0400257 String to = data.getStringExtra("to_number");
258 transfer = data.getParcelableExtra("transfer");
259 try {
Alexandre Lision6deda412013-09-25 13:21:22 -0400260 // Toast.makeText(getActivity(), "Transferring " + transfer.getContact().getmDisplayName() + " to " + to,
261 // Toast.LENGTH_SHORT).show();
Alexandre Lision2b237922013-09-09 16:23:02 -0400262 mCallbacks.getService().transfer(transfer.getCallId(), to);
263 mCallbacks.getService().hangUp(transfer.getCallId());
264 } catch (RemoteException e) {
265 // TODO Auto-generated catch block
266 e.printStackTrace();
267 }
268 break;
Adrien Béraud97512842013-09-19 13:37:19 +1000269 case Activity.RESULT_CANCELED:
Alexandre Lision2b237922013-09-09 16:23:02 -0400270 default:
Adrien Béraude78d06f2013-09-19 13:33:44 +1000271 model.clear();
272 initNormalStateDisplay();
Alexandre Lision2b237922013-09-09 16:23:02 -0400273 break;
274 }
275 }
276 }
277
278 @Override
alision1005ba12013-06-19 13:52:44 -0400279 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Alexandre Lision84208a32013-09-25 13:18:37 -0400280 final ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.frag_call, container, false);
alision85992112013-05-29 12:18:08 -0400281
alision1005ba12013-06-19 13:52:44 -0400282 view = (BubblesView) rootView.findViewById(R.id.main_view);
alision34673e62013-06-25 14:40:07 -0400283 view.setFragment(this);
alision1005ba12013-06-19 13:52:44 -0400284 view.setModel(model);
285 view.getHolder().addCallback(this);
alision84813a12013-05-27 17:40:39 -0400286
Alexandre Lision3c6b7102013-09-16 16:56:46 -0400287 callStatusTxt = (TextView) rootView.findViewById(R.id.call_status_txt);
alision1005ba12013-06-19 13:52:44 -0400288 call_icon = BitmapFactory.decodeResource(getResources(), R.drawable.ic_call);
alision84813a12013-05-27 17:40:39 -0400289
Alexandre Lision84208a32013-09-25 13:18:37 -0400290 ((ImageButton) rootView.findViewById(R.id.dialpad_btn)).setOnClickListener(new OnClickListener() {
291
292 @Override
293 public void onClick(View v) {
294 InputMethodManager lManager = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
295 lManager.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, InputMethodManager.HIDE_IMPLICIT_ONLY);
296 }
297 });
298
alision1005ba12013-06-19 13:52:44 -0400299 return rootView;
300 }
Alexandre Lisionc30e8412013-09-26 15:12:59 -0400301
alision1005ba12013-06-19 13:52:44 -0400302 private void initNormalStateDisplay() {
303 Log.i(TAG, "Start normal display");
alision84813a12013-05-27 17:40:39 -0400304
Alexandre Lision0c384512013-09-17 17:15:57 -0400305 mCallbacks.startTimer();
alision84813a12013-05-27 17:40:39 -0400306
alision1005ba12013-06-19 13:52:44 -0400307 getBubbleFor(myself, model.width / 2, model.height / 2);
alision907bde72013-06-20 14:40:37 -0400308
alisiondf1dac92013-06-27 17:35:53 -0400309 int angle_part = 360 / conf.getParticipants().size();
alision806e18e2013-06-21 15:30:17 -0400310 double dX = 0;
311 double dY = 0;
alision465ceba2013-07-04 09:24:30 -0400312 int radiusCalls = (int) (model.width / 2 - BUBBLE_SIZE);
alisiondf1dac92013-06-27 17:35:53 -0400313 for (int i = 0; i < conf.getParticipants().size(); ++i) {
314
315 if (conf.getParticipants().get(i) == null) {
316 Log.i(TAG, i + " null ");
317 continue;
318 }
alision34673e62013-06-25 14:40:07 -0400319 dX = Math.cos(Math.toRadians(angle_part * i - 90)) * radiusCalls;
320 dY = Math.sin(Math.toRadians(angle_part * i - 90)) * radiusCalls;
alisiondf1dac92013-06-27 17:35:53 -0400321 getBubbleFor(conf.getParticipants().get(i), (int) (model.width / 2 + dX), (int) (model.height / 2 + dY));
alision806e18e2013-06-21 15:30:17 -0400322 }
alision1005ba12013-06-19 13:52:44 -0400323
324 model.clearAttractors();
alision1005ba12013-06-19 13:52:44 -0400325 }
alision85704182013-05-29 15:23:03 -0400326
alision1005ba12013-06-19 13:52:44 -0400327 private void initIncomingCallDisplay() {
328 Log.i(TAG, "Start incoming display");
alision84813a12013-05-27 17:40:39 -0400329
Alexandre Lision0c384512013-09-17 17:15:57 -0400330 mCallbacks.startTimer();
alision84813a12013-05-27 17:40:39 -0400331
Alexandre Lision23628c12013-09-24 11:17:05 -0400332 int radiusCalls = (int) (model.width / 2 - BUBBLE_SIZE);
333 getBubbleFor(myself, model.width / 2, model.height / 2 + radiusCalls);
334 getBubbleFor(conf.getParticipants().get(0), model.width / 2, model.height / 2 - radiusCalls);
alision85704182013-05-29 15:23:03 -0400335
alision1005ba12013-06-19 13:52:44 -0400336 model.clearAttractors();
Alexandre Lision23628c12013-09-24 11:17:05 -0400337 model.addAttractor(new Attractor(new PointF(model.width / 2, model.height / 2), ATTRACTOR_SIZE, new Attractor.Callback() {
alision1005ba12013-06-19 13:52:44 -0400338 @Override
339 public boolean onBubbleSucked(Bubble b) {
Alexandre Lisiona764c682013-09-09 10:02:07 -0400340
341 if (!accepted) {
342 mCallbacks.onCallAccepted(conf.getParticipants().get(0));
343 accepted = true;
344 }
alision1005ba12013-06-19 13:52:44 -0400345 return false;
346 }
347 }, call_icon));
alision1005ba12013-06-19 13:52:44 -0400348 }
alision85704182013-05-29 15:23:03 -0400349
alision1005ba12013-06-19 13:52:44 -0400350 private void initOutGoingCallDisplay() {
351 Log.i(TAG, "Start outgoing display");
alision85704182013-05-29 15:23:03 -0400352
Alexandre Lision0c384512013-09-17 17:15:57 -0400353 mCallbacks.startTimer();
alision85704182013-05-29 15:23:03 -0400354
Adrien Béraude78d06f2013-09-19 13:33:44 +1000355 getBubbleFor(myself, model.width / 2, model.height / 2);
alision85704182013-05-29 15:23:03 -0400356
alisiondf1dac92013-06-27 17:35:53 -0400357 // TODO off-thread image loading
358 int angle_part = 360 / conf.getParticipants().size();
359 double dX = 0;
360 double dY = 0;
Adrien Béraude78d06f2013-09-19 13:33:44 +1000361 int radiusCalls = (int) (model.width / 2 - BUBBLE_SIZE);
alisiondf1dac92013-06-27 17:35:53 -0400362 for (int i = 0; i < conf.getParticipants().size(); ++i) {
363 dX = Math.cos(Math.toRadians(angle_part * i - 90)) * radiusCalls;
364 dY = Math.sin(Math.toRadians(angle_part * i - 90)) * radiusCalls;
365 getBubbleFor(conf.getParticipants().get(i), (int) (model.width / 2 + dX), (int) (model.height / 2 + dY));
366 }
alision907bde72013-06-20 14:40:37 -0400367
alision1005ba12013-06-19 13:52:44 -0400368 model.clearAttractors();
alision1005ba12013-06-19 13:52:44 -0400369 }
alision85704182013-05-29 15:23:03 -0400370
alision1005ba12013-06-19 13:52:44 -0400371 /**
372 * Retrieves or create a bubble for a given contact. If the bubble exists, it is moved to the new location.
373 *
alision806e18e2013-06-21 15:30:17 -0400374 * @param call
375 * The call associated to a contact
alision1005ba12013-06-19 13:52:44 -0400376 * @param x
377 * Initial or new x position.
378 * @param y
379 * Initial or new y position.
380 * @return Bubble corresponding to the contact.
381 */
alision806e18e2013-06-21 15:30:17 -0400382 private Bubble getBubbleFor(SipCall call, float x, float y) {
alisiondf1dac92013-06-27 17:35:53 -0400383 Bubble contact_bubble = model.getBubble(call);
alision1005ba12013-06-19 13:52:44 -0400384 if (contact_bubble != null) {
385 contact_bubble.attractor.set(x, y);
386 return contact_bubble;
387 }
alision84813a12013-05-27 17:40:39 -0400388
alision34673e62013-06-25 14:40:07 -0400389 contact_bubble = new Bubble(getActivity(), call, x, y, BUBBLE_SIZE);
alision84813a12013-05-27 17:40:39 -0400390
alision1005ba12013-06-19 13:52:44 -0400391 model.addBubble(contact_bubble);
alision1005ba12013-06-19 13:52:44 -0400392 return contact_bubble;
393 }
Adrien Béraud0c9bd8f2013-05-30 16:16:57 +1000394
alision1005ba12013-06-19 13:52:44 -0400395 /**
396 * Should be called when a bubble is removed from the model
397 */
398 void bubbleRemoved(Bubble b) {
alision806e18e2013-06-21 15:30:17 -0400399 if (b.associated_call == null) {
alision1005ba12013-06-19 13:52:44 -0400400 return;
401 }
alision1005ba12013-06-19 13:52:44 -0400402 }
Adrien Béraudc9c424d2013-05-30 17:47:35 +1000403
alision1005ba12013-06-19 13:52:44 -0400404 public void changeCallState(String callID, String newState) {
Alexandre Lisionf1850c02013-09-23 14:19:34 -0400405 Log.w(TAG, "Call :" + callID + " " + newState);
alisiondf1dac92013-06-27 17:35:53 -0400406 if (newState.contentEquals("FAILURE")) {
407 try {
408 mCallbacks.getService().hangUp(callID);
409 } catch (RemoteException e) {
410 e.printStackTrace();
alision806e18e2013-06-21 15:30:17 -0400411 }
alision1005ba12013-06-19 13:52:44 -0400412 }
alisiondf1dac92013-06-27 17:35:53 -0400413 for (int i = 0; i < conf.getParticipants().size(); ++i) {
alisiondf1dac92013-06-27 17:35:53 -0400414 if (callID.equals(conf.getParticipants().get(i).getCallId())) {
415 if (newState.contentEquals("HUNGUP")) {
alisiondf1dac92013-06-27 17:35:53 -0400416 model.removeBubble(conf.getParticipants().get(i));
417 conf.getParticipants().remove(i);
418 } else {
419 conf.getParticipants().get(i).setCallState(newState);
420 }
421 }
422 }
423
424 if (conf.isOnGoing())
425 initNormalStateDisplay();
426
427 if (conf.getParticipants().size() == 0) {
428 mCallbacks.replaceCurrentCallDisplayed();
429 }
alision1005ba12013-06-19 13:52:44 -0400430 }
alision84813a12013-05-27 17:40:39 -0400431
alision1005ba12013-06-19 13:52:44 -0400432 public boolean draggingBubble() {
433 return view == null ? false : view.isDraggingBubble();
434 }
Adrien Béraudc9c424d2013-05-30 17:47:35 +1000435
alision1005ba12013-06-19 13:52:44 -0400436 @Override
437 public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Adrien Béraud13cde0b2013-05-30 20:27:20 +1000438
alisiondf1dac92013-06-27 17:35:53 -0400439 if (conf.getParticipants().size() == 1) {
alisiondf1dac92013-06-27 17:35:53 -0400440 if (conf.getParticipants().get(0).isIncoming() && conf.getParticipants().get(0).isRinging()) {
alision806e18e2013-06-21 15:30:17 -0400441 initIncomingCallDisplay();
442 } else {
alisiondf1dac92013-06-27 17:35:53 -0400443 if (conf.getParticipants().get(0).isRinging()) {
alision1005ba12013-06-19 13:52:44 -0400444 initOutGoingCallDisplay();
445 }
alision806e18e2013-06-21 15:30:17 -0400446 try {
alisiondf1dac92013-06-27 17:35:53 -0400447 if (conf.getParticipants().get(0).isOutGoing()
448 && mCallbacks.getService().getCall(conf.getParticipants().get(0).getCallId()) == null) {
449 mCallbacks.getService().placeCall(conf.getParticipants().get(0));
alision806e18e2013-06-21 15:30:17 -0400450 initOutGoingCallDisplay();
alisiondf1dac92013-06-27 17:35:53 -0400451 } else if (conf.getParticipants().get(0).isOutGoing() && conf.getParticipants().get(0).isRinging()) {
alision806e18e2013-06-21 15:30:17 -0400452 initOutGoingCallDisplay();
453 }
454 } catch (RemoteException e) {
455 Log.e(TAG, e.toString());
456 }
alision1005ba12013-06-19 13:52:44 -0400457 }
alisiondf1dac92013-06-27 17:35:53 -0400458 if (conf.getParticipants().get(0).isOngoing()) {
alision806e18e2013-06-21 15:30:17 -0400459 initNormalStateDisplay();
460 }
alisiondf1dac92013-06-27 17:35:53 -0400461 } else if (conf.getParticipants().size() > 1) {
alision1005ba12013-06-19 13:52:44 -0400462 initNormalStateDisplay();
463 }
alision1005ba12013-06-19 13:52:44 -0400464 }
Adrien Béraud13cde0b2013-05-30 20:27:20 +1000465
Alexandre Lision2b237922013-09-09 16:23:02 -0400466 public void makeTransfer(Bubble contact) {
467 FragmentManager fm = getFragmentManager();
468 TransferDFragment editName = new TransferDFragment();
Alexandre Lision2b237922013-09-09 16:23:02 -0400469 Bundle b = new Bundle();
Alexandre Lision6ae652d2013-09-26 16:39:20 -0400470 try {
471 b.putParcelableArrayList("calls", (ArrayList<Conference>)mCallbacks.getService().getConcurrentCalls());
472 b.putParcelable("call_selected", contact.associated_call);
473 editName.setArguments(b);
474 editName.setTargetFragment(this, REQUEST_TRANSFER);
475 editName.show(fm, "");
476 } catch (RemoteException e) {
477 Log.e(TAG, e.toString());
478 }
479
Alexandre Lision2b237922013-09-09 16:23:02 -0400480 }
481
alision1005ba12013-06-19 13:52:44 -0400482 @Override
483 public void surfaceCreated(SurfaceHolder holder) {
Alexandre Lisionc30e8412013-09-26 15:12:59 -0400484
alision1005ba12013-06-19 13:52:44 -0400485 }
Adrien Béraud13cde0b2013-05-30 20:27:20 +1000486
alision1005ba12013-06-19 13:52:44 -0400487 @Override
488 public void surfaceDestroyed(SurfaceHolder holder) {
Alexandre Lision84208a32013-09-25 13:18:37 -0400489 // check that soft input is hidden
490 InputMethodManager lManager = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
491 lManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
alision1005ba12013-06-19 13:52:44 -0400492 }
Adrien Béraud13cde0b2013-05-30 20:27:20 +1000493
alisione38001f2013-06-04 14:14:39 -0400494 public BubblesView getBubbleView() {
495 return view;
alision1005ba12013-06-19 13:52:44 -0400496 }
Alexandre Lision0c384512013-09-17 17:15:57 -0400497
498 public void updateTime() {
Adrien Béraude78d06f2013-09-19 13:33:44 +1000499 long duration = System.currentTimeMillis() / 1000 - this.conf.getParticipants().get(0).getTimestamp_start();
Alexandre Lisionf1850c02013-09-23 14:19:34 -0400500 callStatusTxt.setText(String.format("%d:%02d:%02d", duration / 3600, duration % 3600 / 60, duration % 60));
Alexandre Lisionf1850c02013-09-23 14:19:34 -0400501 }
502
503 @Override
504 public void onAccuracyChanged(Sensor sensor, int accuracy) {
Alexandre Lisionf1850c02013-09-23 14:19:34 -0400505
506 }
507
508 @Override
509 public void onSensorChanged(SensorEvent event) {
Alexandre Lisionc30e8412013-09-26 15:12:59 -0400510 if (event.values[0] == 0) {
511 WindowManager.LayoutParams params = getActivity().getWindow().getAttributes();
512 params.flags |= WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
513 params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
514 params.screenBrightness = 0.004f;
515 getActivity().getWindow().setAttributes(params);
Adrien Béraude78d06f2013-09-19 13:33:44 +1000516
Alexandre Lisionc30e8412013-09-26 15:12:59 -0400517 } else {
518 WindowManager.LayoutParams params = getActivity().getWindow().getAttributes();
519 getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
520 params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
521 params.screenBrightness = 1.0f;
522 getActivity().getWindow().setAttributes(params);
523 }
Alexandre Lision0c384512013-09-17 17:15:57 -0400524 }
Alexandre Lision0edf18c2013-09-23 17:35:50 -0400525
526 public Conference getConference() {
527 return conf;
528 }
Alexandre Lision64dc8c02013-09-25 15:32:25 -0400529
530 public void onKeyUp(int keyCode, KeyEvent event) {
531 try {
Alexandre Lision80f0a7e2013-09-26 12:27:51 -0400532 String toSend = Character.toString(event.getDisplayLabel());
Alexandre Lision31f46fc2013-09-26 11:19:54 -0400533 toSend.toUpperCase(Locale.getDefault());
Alexandre Lisionc30e8412013-09-26 15:12:59 -0400534 Log.d(TAG, "toSend " + toSend);
Alexandre Lision64dc8c02013-09-25 15:32:25 -0400535 mCallbacks.getService().playDtmf(toSend);
536 } catch (RemoteException e) {
537 e.printStackTrace();
538 }
539 }
alision84813a12013-05-27 17:40:39 -0400540}