blob: 8f664cd3933346c27d7ff2efd91b0168dd433fed [file] [log] [blame]
Adrien Béraud04d822c2015-04-02 17:44:36 -04001/*
2 * Copyright (C) 2004-2014 Savoir-Faire Linux Inc.
3 *
4 * Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
5 * Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
6 * Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com>
7 *
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 cx.ring.client;
35
36import java.util.*;
37
38import android.support.v4.app.FragmentActivity;
39import android.util.Log;
40import cx.ring.R;
41import cx.ring.fragments.CallFragment;
42import cx.ring.fragments.IMFragment;
43import cx.ring.model.account.Account;
44import cx.ring.model.CallContact;
45import cx.ring.model.Conference;
46import cx.ring.model.SipCall;
47import cx.ring.model.SipMessage;
48import cx.ring.service.ISipService;
49import cx.ring.service.SipService;
50import cx.ring.utils.CallProximityManager;
51import cx.ring.views.CallPaneLayout;
52
53import android.content.ComponentName;
54import android.content.Context;
55import android.content.Intent;
56import android.content.ServiceConnection;
57import android.graphics.Color;
58import android.graphics.PixelFormat;
59import android.net.Uri;
60import android.os.Bundle;
61import android.os.Handler;
62import android.os.IBinder;
63import android.os.RemoteException;
64import android.os.SystemClock;
65import android.support.v4.widget.SlidingPaneLayout;
66import android.view.KeyEvent;
67import android.view.View;
68import android.view.Window;
69import android.view.WindowManager;
70
71public class CallActivity extends FragmentActivity implements IMFragment.Callbacks, CallFragment.Callbacks, CallProximityManager.ProximityDirector {
72
73 @SuppressWarnings("unused")
74 static final String TAG = "CallActivity";
75 private ISipService mService;
76 CallPaneLayout mSlidingPaneLayout;
77
78 IMFragment mIMFragment;
79 CallFragment mCurrentCallFragment;
80 private Conference mDisplayedConference;
81
82 /* result code sent in case of call failure */
83 public static int RESULT_FAILURE = -10;
84 private CallProximityManager mProximityManager;
85
86 @Override
87 protected void onCreate(Bundle savedInstanceState) {
88 super.onCreate(savedInstanceState);
89 setContentView(R.layout.activity_call_layout);
90
91 Window w = getWindow();
92 w.setFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED, WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
93
94 setUpSlidingPanel();
95
96 mProximityManager = new CallProximityManager(this, this);
97 mProximityManager.startTracking();
98
99 mCurrentCallFragment = new CallFragment();
100 mIMFragment = new IMFragment();
101
102 if(!checkExternalCall()) {
103 mDisplayedConference = getIntent().getParcelableExtra("conference");
104 Bundle IMBundle = new Bundle();
105 if (getIntent().getBooleanExtra("resuming", false)) {
106 IMBundle.putParcelableArrayList("messages", mDisplayedConference.getMessages());
107 mIMFragment.setArguments(IMBundle);
108 } else {
109 IMBundle.putParcelableArrayList("messages", new ArrayList<SipMessage>());
110 mIMFragment.setArguments(IMBundle);
111 }
112 }
113
114 mSlidingPaneLayout.setCurFragment(mCurrentCallFragment);
115 getSupportFragmentManager().beginTransaction().replace(R.id.ongoingcall_pane, mCurrentCallFragment)
116 .replace(R.id.message_list_frame, mIMFragment).commit();
117 }
118
119 private void setUpSlidingPanel() {
120 mSlidingPaneLayout = (CallPaneLayout) findViewById(R.id.slidingpanelayout);
121 mSlidingPaneLayout.setParallaxDistance(500);
122 mSlidingPaneLayout.setSliderFadeColor(Color.TRANSPARENT);
123
124 mSlidingPaneLayout.setPanelSlideListener(new SlidingPaneLayout.PanelSlideListener() {
125
126 @Override
127 public void onPanelSlide(View view, float offSet) {
128 }
129
130 @Override
131 public void onPanelOpened(View view) {
132 getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
133 }
134
135 @Override
136 public void onPanelClosed(View view) {
137 mCurrentCallFragment.getBubbleView().restartDrawing();
138 getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);
139 }
140 });
141 }
142
143 @Override
144 public void onFragmentCreated() {
145 Intent intent = new Intent(this, SipService.class);
146 bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
147 }
148
149 @Override
150 public void onAttachedToWindow() {
151 super.onAttachedToWindow();
152 Window window = getWindow();
153 window.setFormat(PixelFormat.RGBA_8888);
154 }
155
156 private Handler mHandler = new Handler();
157 private Runnable mUpdateTimeTask = new Runnable() {
158 @Override
159 public void run() {
160 if (mCurrentCallFragment != null)
161 mCurrentCallFragment.updateTime();
162 mHandler.postAtTime(this, SystemClock.uptimeMillis() + 1000);
163 }
164 };
165
166 /* activity no more in foreground */
167 @Override
168 protected void onPause() {
169 super.onPause();
170 mHandler.removeCallbacks(mUpdateTimeTask);
171 }
172
173 @Override
174 public boolean onKeyUp(int keyCode, KeyEvent event) {
175
176 if (keyCode == KeyEvent.KEYCODE_BACK) {
177 return super.onKeyUp(keyCode, event);
178 }
179 mCurrentCallFragment.onKeyUp(keyCode, event);
180 return true;
181 }
182
183 @Override
184 protected void onDestroy() {
185
186 unbindService(mConnection);
187
188 mProximityManager.stopTracking();
189 mProximityManager.release(0);
190
191 super.onDestroy();
192 }
193
194 /**
195 * Defines callbacks for service binding, passed to bindService()
196 */
197 private ServiceConnection mConnection = new ServiceConnection() {
198 @SuppressWarnings("unchecked")
199 @Override
200 public void onServiceConnected(ComponentName className, IBinder binder) {
201 mService = ISipService.Stub.asInterface(binder);
202
203 if (mDisplayedConference.getState().contentEquals("NONE")) {
204 try {
205 mService.placeCall(mDisplayedConference.getParticipants().get(0));
206 } catch (RemoteException e) {
207 e.printStackTrace();
208 }
209 }
210 }
211
212 @Override
213 public void onServiceDisconnected(ComponentName arg0) {
214 }
215 };
216
217 private boolean checkExternalCall() {
218 Uri u = getIntent().getData();
219 if (u != null) {
220 CallContact c = CallContact.ContactBuilder.buildUnknownContact(u.getSchemeSpecificPart());
221 try {
222 String accountID = (String) mService.getAccountList().get(1); // We use the first account to place outgoing calls
223 HashMap<String, String> details = (HashMap<String, String>) mService.getAccountDetails(accountID);
224 ArrayList<HashMap<String, String>> credentials = (ArrayList<HashMap<String, String>>) mService.getCredentials(accountID);
225 Account acc = new Account(accountID, details, credentials);
226
227 Bundle args = new Bundle();
228 args.putString(SipCall.ID, Integer.toString(Math.abs(new Random().nextInt())));
229 args.putParcelable(SipCall.ACCOUNT, acc);
230 args.putInt(SipCall.STATE, SipCall.state.CALL_STATE_NONE);
231 args.putInt(SipCall.TYPE, SipCall.direction.CALL_TYPE_OUTGOING);
232 args.putParcelable(SipCall.CONTACT, c);
233
234 mDisplayedConference = new Conference(Conference.DEFAULT_ID);
235 mDisplayedConference.getParticipants().add(new SipCall(args));
236 } catch (RemoteException e) {
237 e.printStackTrace();
238 } catch (Exception e) {
239 e.printStackTrace();
240 }
241 return true;
242 }
243 return false;
244 }
245
246 @Override
247 public ISipService getService() {
248 return mService;
249 }
250
251 @Override
252 public Conference getDisplayedConference() {
253 return mDisplayedConference;
254 }
255
256 @Override
257 public void updateDisplayedConference(Conference c) {
258 if(mDisplayedConference.equals(c)){
259 mDisplayedConference = c;
260 }
261 }
262
263 @Override
264 public void onBackPressed() {
265 super.onBackPressed();
266 Intent launchHome = new Intent(this, HomeActivity.class);
267 launchHome.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
268 launchHome.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
269 startActivity(launchHome);
270 }
271
272 @Override
273 public void terminateCall() {
274 mHandler.removeCallbacks(mUpdateTimeTask);
275 mCurrentCallFragment.getBubbleView().stopThread();
276 TimerTask quit = new TimerTask() {
277
278 @Override
279 public void run() {
280 finish();
281 }
282 };
283
284 new Timer().schedule(quit, 1000);
285 }
286
287 @Override
288 public boolean sendIM(SipMessage msg) {
289
290 try {
291 Log.i(TAG, "Sending:"+msg.comment+"to"+mDisplayedConference.getId());
292 mService.sendTextMessage(mDisplayedConference.getId(), msg);
293 } catch (RemoteException e) {
294 e.printStackTrace();
295 return false;
296 }
297
298 return true;
299 }
300
301 @Override
302 public void startTimer() {
303 mHandler.postDelayed(mUpdateTimeTask, 0);
304 }
305
306 @Override
307 public void slideChatScreen() {
308
309 if (mSlidingPaneLayout.isOpen()) {
310 mSlidingPaneLayout.closePane();
311 } else {
312 mCurrentCallFragment.getBubbleView().stopThread();
313 mSlidingPaneLayout.openPane();
314 }
315 }
316
317 @Override
318 public boolean shouldActivateProximity() {
319 return true;
320 }
321
322 @Override
323 public void onProximityTrackingChanged(boolean acquired) {
324 // TODO Stub de la méthode généré automatiquement
325
326 }
327}