blob: 0b668313953c7c385313a24005e3042a3b59499d [file] [log] [blame]
Adrien Béraudffd32412012-08-07 18:39:23 -04001/*
2 * Copyright (C) 2004-2012 Savoir-Faire Linux Inc.
3 *
4 * Author: Adrien Beraud <adrien.beraud@gmail.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 */
31package com.savoirfairelinux.sflphone.client;
32
Emeric Vigiere89b48b2012-08-30 14:16:46 -040033import java.util.Random;
34
Adrien Béraudffd32412012-08-07 18:39:23 -040035import android.app.ActionBar;
36import android.app.Activity;
37import android.app.Fragment;
38import android.app.FragmentManager;
39import android.app.FragmentTransaction;
Alexandre Savard1bcaf532012-09-05 16:23:02 -040040import android.content.Intent;
Emeric Vigier7a255aa2012-08-29 09:49:18 -040041import android.content.pm.PackageInfo;
42import android.content.pm.PackageManager;
43import android.content.pm.PackageManager.NameNotFoundException;
Adrien Béraudffd32412012-08-07 18:39:23 -040044import android.os.Bundle;
Emeric Vigier383b2a22012-08-27 14:20:05 -040045import android.os.Handler;
46import android.os.Message;
Adrien Béraudffd32412012-08-07 18:39:23 -040047import android.support.v13.app.FragmentStatePagerAdapter;
48import android.support.v4.view.ViewPager;
Emeric Vigier05e894e2012-08-20 13:53:02 -040049import android.util.Log;
Adrien Béraudffd32412012-08-07 18:39:23 -040050import android.view.Gravity;
51import android.view.LayoutInflater;
52import android.view.Menu;
Alexandre Savard1bcaf532012-09-05 16:23:02 -040053import android.view.MenuItem;
Adrien Béraudffd32412012-08-07 18:39:23 -040054import android.view.View;
Emeric Vigier05e894e2012-08-20 13:53:02 -040055import android.view.View.OnClickListener;
Adrien Béraudffd32412012-08-07 18:39:23 -040056import android.view.ViewGroup;
Emeric Vigiera6bdb702012-08-31 15:34:53 -040057import android.view.animation.AlphaAnimation;
58import android.view.animation.Animation;
59import android.view.animation.LinearInterpolator;
Emeric Vigiereaf2c492012-09-19 14:38:20 -040060import android.widget.Button;
Emeric Vigierd5c17f52012-08-29 09:29:33 -040061import android.widget.EditText;
Emeric Vigiere89b48b2012-08-30 14:16:46 -040062import android.widget.ImageButton;
Adrien Béraudffd32412012-08-07 18:39:23 -040063import android.widget.TextView;
64
65import com.savoirfairelinux.sflphone.R;
Emeric Vigiereaf2c492012-09-19 14:38:20 -040066import com.savoirfairelinux.sflphone.service.SipService;
Adrien Béraudffd32412012-08-07 18:39:23 -040067
Emeric Vigier62ca14d2012-08-24 11:05:09 -040068public class SFLPhoneHome extends Activity implements ActionBar.TabListener, OnClickListener
Adrien Béraudffd32412012-08-07 18:39:23 -040069{
70 SectionsPagerAdapter mSectionsPagerAdapter;
Emeric Vigier62ca14d2012-08-24 11:05:09 -040071 static final String TAG = "SFLPhoneHome";
Emeric Vigiera6bdb702012-08-31 15:34:53 -040072 private ButtonSectionFragment buttonFragment;
Emeric Vigier383b2a22012-08-27 14:20:05 -040073 Handler callbackHandler;
Emeric Vigier9701e032012-09-12 12:38:01 -040074 private Manager manager;
Emeric Vigier78a53e92012-08-29 18:15:34 -040075 /* default callID */
76 static String callID = "007";
Emeric Vigiere89b48b2012-08-30 14:16:46 -040077 static boolean callOnGoing = false;
Emeric Vigiereaf2c492012-09-19 14:38:20 -040078 static boolean serviceIsOn = false;
Emeric Vigiera6bdb702012-08-31 15:34:53 -040079 private String incomingCallID = "";
Alexandre Savard1bcaf532012-09-05 16:23:02 -040080 private static final int REQUEST_CODE_PREFERENCES = 1;
Emeric Vigier090ab602012-09-17 11:09:46 -040081 ImageButton buttonCall, buttonHangup;
Emeric Vigiereaf2c492012-09-19 14:38:20 -040082 Button buttonService;
Adrien Béraudffd32412012-08-07 18:39:23 -040083
84 /**
85 * The {@link ViewPager} that will host the section contents.
86 */
87 ViewPager mViewPager;
88
Alexandre Savarda04c5202012-09-18 17:19:53 -040089 final private int[] icon_res_id = {R.drawable.ic_tab_call, R.drawable.ic_tab_call, R.drawable.ic_tab_history, R.drawable.ic_tab_play_selected};
Adrien Béraudffd32412012-08-07 18:39:23 -040090
91 @Override
92 public void onCreate(Bundle savedInstanceState)
93 {
94 super.onCreate(savedInstanceState);
95 setContentView(R.layout.activity_sflphone_home);
96
97 mSectionsPagerAdapter = new SectionsPagerAdapter(getFragmentManager());
98
99 final ActionBar actionBar = getActionBar();
100 actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
Alexandre Savarddef3bfa2012-09-12 16:20:06 -0400101 // final ActionBar actionBar = getActionBar();
Adrien Béraudffd32412012-08-07 18:39:23 -0400102
103 // Set up the ViewPager with the sections adapter.
104 mViewPager = (ViewPager) findViewById(R.id.pager);
105 mViewPager.setAdapter(mSectionsPagerAdapter);
106
107 // When swiping between different sections, select the corresponding tab.
108 // We can also use ActionBar.Tab#select() to do this if we have a reference to the
109 // Tab.
110 mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener()
111 {
112 @Override
113 public void onPageSelected(int position)
114 {
115 actionBar.setSelectedNavigationItem(position);
116 }
117 });
118
119 // For each of the sections in the app, add a tab to the action bar.
120 for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
121 // Create a tab with text corresponding to the page title defined by the adapter.
122 // Also specify this Activity object, which implements the TabListener interface, as the
123 // listener for when this tab is selected.
Alexandre Savarda04c5202012-09-18 17:19:53 -0400124 Log.i(TAG, "adding tab: " + i);
Adrien Béraudffd32412012-08-07 18:39:23 -0400125 actionBar.addTab(actionBar.newTab().setIcon(icon_res_id[i]).setText(mSectionsPagerAdapter.getPageTitle(i)).setTabListener(this));
126 }
Emeric Vigier383b2a22012-08-27 14:20:05 -0400127
128 // FIXME
129 callbackHandler = new Handler() {
130 public void handleMessage(Message msg) {
131 Bundle b = msg.getData();
132 TextView callVoidText;
133
Emeric Vigierc411ce32012-08-29 09:28:28 -0400134 Log.i(TAG, "handleMessage");
Emeric Vigier383b2a22012-08-27 14:20:05 -0400135
136 callVoidText = buttonFragment.getcallVoidText();
137 if (callVoidText == null)
138 Log.e(TAG, "SFLPhoneHome: callVoidText is " + callVoidText);
139 callVoidText.setText(b.getString("callback_string"));
140
Emeric Vigierc411ce32012-08-29 09:28:28 -0400141 Log.i(TAG, "handleMessage: " + b.getString("callback_string"));
Emeric Vigier383b2a22012-08-27 14:20:05 -0400142 }
143 };
Emeric Vigiera6bdb702012-08-31 15:34:53 -0400144
145 buttonCall = (ImageButton) findViewById(R.id.buttonCall);
146 buttonHangup = (ImageButton) findViewById(R.id.buttonHangUp);
Alexandre Savarddef3bfa2012-09-12 16:20:06 -0400147
Emeric Vigier9701e032012-09-12 12:38:01 -0400148 manager = new Manager(callbackHandler);
149 Log.i(TAG, "ManagerImpl::instance() = " + manager.managerImpl);
150 manager.setActivity(this);
151 /* set static AppPath before calling manager.init */
152 manager.managerImpl.setPath(getAppPath());
153 Log.i(TAG, "manager created with callbackHandler " + callbackHandler);
Emeric Vigiera6bdb702012-08-31 15:34:53 -0400154
Adrien Béraudffd32412012-08-07 18:39:23 -0400155 }
156
Emeric Vigier62ca14d2012-08-24 11:05:09 -0400157 // FIXME
158 static {
159 System.loadLibrary("gnustl_shared");
160 System.loadLibrary("expat");
161 System.loadLibrary("yaml");
162 System.loadLibrary("ccgnu2");
163 System.loadLibrary("crypto");
164 System.loadLibrary("ssl");
165 System.loadLibrary("ccrtp1");
166 System.loadLibrary("dbus");
167 System.loadLibrary("dbus-c++-1");
168 System.loadLibrary("samplerate");
169 System.loadLibrary("codec_ulaw");
170 System.loadLibrary("codec_alaw");
171 System.loadLibrary("speexresampler");
172 System.loadLibrary("sflphone");
173 }
Alexandre Savard1bcaf532012-09-05 16:23:02 -0400174
175 @Override
176 public boolean onOptionsItemSelected(MenuItem item) {
Alexandre Savardebc94432012-09-13 14:30:55 -0400177 Log.i("SFLphone", "onOptionsItemSelected " + item.getItemId());
Alexandre Savard1bcaf532012-09-05 16:23:02 -0400178
Alexandre Savardebc94432012-09-13 14:30:55 -0400179 if(item.getItemId() != 0) {
180 // When the button is clicked, launch an activity through this intent
181 Intent launchPreferencesIntent = new Intent().setClass(this, SFLPhonePreferenceActivity.class);
Alexandre Savard1bcaf532012-09-05 16:23:02 -0400182
Alexandre Savardebc94432012-09-13 14:30:55 -0400183 // Make it a subactivity so we know when it returns
184 startActivityForResult(launchPreferencesIntent, REQUEST_CODE_PREFERENCES);
185 }
Alexandre Savard1bcaf532012-09-05 16:23:02 -0400186
187 return super.onOptionsItemSelected(item);
188 }
Emeric Vigier62ca14d2012-08-24 11:05:09 -0400189
Adrien Béraudffd32412012-08-07 18:39:23 -0400190 @Override
191 public boolean onCreateOptionsMenu(Menu menu)
192 {
193 getMenuInflater().inflate(R.menu.activity_sflphone_home, menu);
194 return true;
195 }
196
197 @Override
198 public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction)
199 {
200 }
201
202 @Override
203 public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction)
204 {
205 // When the given tab is selected, switch to the corresponding page in the ViewPager.
206 mViewPager.setCurrentItem(tab.getPosition());
207 }
208
209 @Override
210 public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction)
211 {
Emeric Vigier05e894e2012-08-20 13:53:02 -0400212// Log.d(TAG, "onTabReselected");
Adrien Béraudffd32412012-08-07 18:39:23 -0400213 }
214
Emeric Vigiera6bdb702012-08-31 15:34:53 -0400215 public void setIncomingCallID(String id) {
216 incomingCallID = id;
217 }
218
Adrien Béraudffd32412012-08-07 18:39:23 -0400219 /**
220 * A {@link FragmentStatePagerAdapter} that returns a fragment corresponding to
221 * one of the primary sections of the app.
222 */
223 public class SectionsPagerAdapter extends FragmentStatePagerAdapter
224 {
225
226 public SectionsPagerAdapter(FragmentManager fm)
227 {
228 super(fm);
229 }
230
231 @Override
232 public Fragment getItem(int i)
233 {
234 Fragment fragment;
Emeric Vigier62ca14d2012-08-24 11:05:09 -0400235
Emeric Vigier05e894e2012-08-20 13:53:02 -0400236 switch (i) {
Alexandre Savarda04c5202012-09-18 17:19:53 -0400237 case 0:
238 fragment = new ContactListFragment();
239 break;
240 case 1:
Adrien Béraudffd32412012-08-07 18:39:23 -0400241 fragment = new CallElementList();
Emeric Vigier05e894e2012-08-20 13:53:02 -0400242 break;
Alexandre Savarda04c5202012-09-18 17:19:53 -0400243 case 2:
Adrien Béraudffd32412012-08-07 18:39:23 -0400244 fragment = new DummySectionFragment();
Emeric Vigier05e894e2012-08-20 13:53:02 -0400245 break;
Alexandre Savarda04c5202012-09-18 17:19:53 -0400246 case 3:
Alexandre Savarddef3bfa2012-09-12 16:20:06 -0400247 fragment = new ButtonSectionFragment();
248 Log.i(TAG, "getItem: fragment is " + fragment);
Emeric Vigier05e894e2012-08-20 13:53:02 -0400249 break;
250 default:
251 Log.e(TAG, "getItem: unknown tab position " + i);
252 return null;
253 }
254
Adrien Béraudffd32412012-08-07 18:39:23 -0400255 Bundle args = new Bundle();
256 args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, i + 1);
257 fragment.setArguments(args);
258 return fragment;
259 }
260
261 @Override
262 public int getCount()
263 {
Alexandre Savarda04c5202012-09-18 17:19:53 -0400264 return 4;
Adrien Béraudffd32412012-08-07 18:39:23 -0400265 }
266
267 @Override
268 public CharSequence getPageTitle(int position)
269 {
270 switch (position) {
Alexandre Savarda04c5202012-09-18 17:19:53 -0400271 case 0:
272 return getString(R.string.title_section0).toUpperCase();
Adrien Béraudffd32412012-08-07 18:39:23 -0400273 case 1:
Alexandre Savarda04c5202012-09-18 17:19:53 -0400274 return getString(R.string.title_section1).toUpperCase();
Emeric Vigier05e894e2012-08-20 13:53:02 -0400275 case 2:
Alexandre Savarda04c5202012-09-18 17:19:53 -0400276 return getString(R.string.title_section2).toUpperCase();
277 case 3:
Emeric Vigier05e894e2012-08-20 13:53:02 -0400278 return getString(R.string.title_section3).toUpperCase();
279 default:
280 Log.e(TAG, "getPageTitle: unknown tab position " + position);
281 break;
Adrien Béraudffd32412012-08-07 18:39:23 -0400282 }
283 return null;
284 }
285 }
286
287 /**
288 * A dummy fragment representing a section of the app, but that simply
289 * displays dummy text.
290 */
291 public static class DummySectionFragment extends Fragment
292 {
293 public DummySectionFragment()
294 {
295 setRetainInstance(true);
296 }
297
298 public static final String ARG_SECTION_NUMBER = "section_number";
299
300 @Override
Emeric Vigier05e894e2012-08-20 13:53:02 -0400301 public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState)
Adrien Béraudffd32412012-08-07 18:39:23 -0400302 {
303 TextView textView = new TextView(getActivity());
304 textView.setGravity(Gravity.CENTER);
305 Bundle args = getArguments();
306 textView.setText(Integer.toString(args.getInt(ARG_SECTION_NUMBER)));
Emeric Vigier05e894e2012-08-20 13:53:02 -0400307 textView.setText("java sucks");
Adrien Béraudffd32412012-08-07 18:39:23 -0400308 return textView;
309 }
Adrien Béraudffd32412012-08-07 18:39:23 -0400310 }
Emeric Vigier05e894e2012-08-20 13:53:02 -0400311
Emeric Vigier7a255aa2012-08-29 09:49:18 -0400312 public String getAppPath() {
313 PackageManager pkgMng = getPackageManager();
314 String pkgName = getPackageName();
315
316 try {
317 PackageInfo pkgInfo = pkgMng.getPackageInfo(pkgName, 0);
318 pkgName = pkgInfo.applicationInfo.dataDir;
319 } catch (NameNotFoundException e) {
320 Log.w(TAG, "Error Package name not found ", e);
321 }
322
323 Log.d(TAG, "Application path: " + pkgName);
324 return pkgName;
Emeric Vigier62ca14d2012-08-24 11:05:09 -0400325 }
Emeric Vigier05e894e2012-08-20 13:53:02 -0400326
Emeric Vigier62ca14d2012-08-24 11:05:09 -0400327 @Override
328 public void onClick(View view)
Emeric Vigiere89b48b2012-08-30 14:16:46 -0400329 {
Emeric Vigiereaf2c492012-09-19 14:38:20 -0400330 buttonService = (Button) findViewById(R.id.buttonService);
331
Emeric Vigier62ca14d2012-08-24 11:05:09 -0400332 switch (view.getId()) {
Emeric Vigierd5c17f52012-08-29 09:29:33 -0400333 case R.id.buttonCall:
Emeric Vigier39a11fa2012-08-29 15:25:09 -0400334 TextView textView = (TextView) findViewById(R.id.editAccountID);
335 String accountID = textView.getText().toString();
336 EditText editText;
Emeric Vigier78a53e92012-08-29 18:15:34 -0400337 Random random = new Random();
Emeric Vigiere89b48b2012-08-30 14:16:46 -0400338
Emeric Vigiera6bdb702012-08-31 15:34:53 -0400339 if (incomingCallID != "") {
340 buttonCall.clearAnimation();
Emeric Vigier9380ae52012-09-14 17:40:39 -0400341// manager.managerImpl.answerCall(incomingCallID);
342 manager.callmanagerJNI.accept(incomingCallID);
Emeric Vigiera6bdb702012-08-31 15:34:53 -0400343 callID = incomingCallID;
344 incomingCallID="";
Emeric Vigiere89b48b2012-08-30 14:16:46 -0400345 callOnGoing = true;
Emeric Vigiera6bdb702012-08-31 15:34:53 -0400346 buttonCall.setEnabled(false);
347 buttonHangup.setEnabled(true);
348 } else {
349 if (callOnGoing == false) {
350 editText = (EditText) findViewById(R.id.editTo);
351 String to = editText.getText().toString();
352 if (to == null) {
353 Log.e(TAG, "to string is " + to);
354 break;
355 }
356
Emeric Vigiera6bdb702012-08-31 15:34:53 -0400357 callID = Integer.toString(random.nextInt());
358
Emeric Vigier9701e032012-09-12 12:38:01 -0400359 Log.d(TAG, "manager.managerImpl.placeCall(" + accountID + ", " + callID + ", " + to + ");");
Emeric Vigier9380ae52012-09-14 17:40:39 -0400360// manager.managerImpl.outgoingCall(accountID, callID, to);
361 manager.callmanagerJNI.placeCall(accountID, callID, to);
Emeric Vigiera6bdb702012-08-31 15:34:53 -0400362 callOnGoing = true;
363 buttonCall.setEnabled(false);
364 buttonHangup.setEnabled(true);
365 }
Emeric Vigierd5c17f52012-08-29 09:29:33 -0400366 }
Emeric Vigierd5c17f52012-08-29 09:29:33 -0400367 break;
Emeric Vigier78a53e92012-08-29 18:15:34 -0400368 case R.id.buttonHangUp:
Emeric Vigiera6bdb702012-08-31 15:34:53 -0400369 if (incomingCallID != "") {
370 buttonCall.clearAnimation();
Emeric Vigier9380ae52012-09-14 17:40:39 -0400371// manager.managerImpl.refuseCall(incomingCallID);
372 manager.callmanagerJNI.refuse(incomingCallID);
Emeric Vigiera6bdb702012-08-31 15:34:53 -0400373 incomingCallID="";
374 buttonCall.setEnabled(true);
375 buttonHangup.setEnabled(true);
376 } else {
377 if (callOnGoing == true) {
Emeric Vigier9701e032012-09-12 12:38:01 -0400378 Log.d(TAG, "manager.managerImpl.hangUp(" + callID + ");");
Emeric Vigier9380ae52012-09-14 17:40:39 -0400379// manager.managerImpl.hangupCall(callID);
380 manager.callmanagerJNI.hangUp(callID);
Emeric Vigiera6bdb702012-08-31 15:34:53 -0400381 callOnGoing = false;
382 buttonCall.setEnabled(true);
383 buttonHangup.setEnabled(false);
384 }
Emeric Vigiere89b48b2012-08-30 14:16:46 -0400385 }
Emeric Vigiera6bdb702012-08-31 15:34:53 -0400386
387 buttonCall.setImageResource(R.drawable.ic_call);
Emeric Vigier78a53e92012-08-29 18:15:34 -0400388 break;
Emeric Vigier62ca14d2012-08-24 11:05:09 -0400389 case R.id.buttonInit:
Emeric Vigier9701e032012-09-12 12:38:01 -0400390 Manager.managerImpl.setPath("");
391 Manager.managerImpl.init("");
Emeric Vigier62ca14d2012-08-24 11:05:09 -0400392 break;
Emeric Vigiereaf2c492012-09-19 14:38:20 -0400393 case R.id.buttonService:
394 if (!serviceIsOn) {
395 startService(new Intent(this, SipService.class));
396 serviceIsOn = true;
397 buttonService.setText("disable Service");
398 }
399 else {
400 stopService(new Intent(this, SipService.class));
401 serviceIsOn = false;
402 buttonService.setText("enable Service");
403 }
404 break;
Emeric Vigier62ca14d2012-08-24 11:05:09 -0400405 case R.id.buttonCallVoid:
Emeric Vigier9701e032012-09-12 12:38:01 -0400406 Manager.callVoid();
Emeric Vigier62ca14d2012-08-24 11:05:09 -0400407 break;
408 case R.id.buttonGetNewData:
Emeric Vigier9701e032012-09-12 12:38:01 -0400409 Data d = Manager.getNewData(42, "foo");
Emeric Vigier62ca14d2012-08-24 11:05:09 -0400410 if (d != null)
411 buttonFragment.getNewDataText().setText("getNewData(42, \"foo\") == Data(" + d.i + ", \"" + d.s + "\")");
412 break;
413 case R.id.buttonGetDataString:
Emeric Vigier383b2a22012-08-27 14:20:05 -0400414 Data daita = new Data(43, "bar");
Emeric Vigier9701e032012-09-12 12:38:01 -0400415 String s = Manager.getDataString(daita);
Emeric Vigier62ca14d2012-08-24 11:05:09 -0400416 if (s != "") {
Emeric Vigier383b2a22012-08-27 14:20:05 -0400417 buttonFragment.getDataStringText().setText("getDataString(Data(43, \"bar\")) == \"" + s + "\"");
Emeric Vigier62ca14d2012-08-24 11:05:09 -0400418 }
419 break;
420 default:
421 Log.w(TAG, "unknown button " + view.getId());
422 break;
Emeric Vigier05e894e2012-08-20 13:53:02 -0400423 }
Emeric Vigier05e894e2012-08-20 13:53:02 -0400424 }
Adrien Béraudffd32412012-08-07 18:39:23 -0400425}