From ec3b40713878b845ed4ffeb111b04f9a09fae328 Mon Sep 17 00:00:00 2001 From: Guillaume Beraudo Date: Wed, 16 Nov 2011 15:14:04 +0100 Subject: [PATCH] LinphoneActivity launcher (synchro service ready) Due to a bug in tabhost on 1.5 devices (G1 and simulator) it was impossible to have the synchronisation code directly in LinphoneActivity. (NPE on touchmodechanged on mCurrentView). Note that since the synchronisation code rewrite, no special care is taken after a service crash. As a consequence you should always check the root cause of a "Caused by: java.lang.RuntimeException: Linphone Manager should be created before accessed" --- AndroidManifest.xml | 20 ++- .../{wait_service_dialog.xml => launcher.xml} | 9 +- src/org/linphone/LinphoneActivity.java | 138 +++--------------- .../linphone/LinphoneLauncherActivity.java | 88 +++++++++++ src/org/linphone/LinphoneService.java | 8 +- 5 files changed, 133 insertions(+), 130 deletions(-) rename res/layout/{wait_service_dialog.xml => launcher.xml} (51%) create mode 100644 src/org/linphone/LinphoneLauncherActivity.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 14cbb02d4..01b1d972e 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -8,8 +8,19 @@ - - + + + + + + + + + - @@ -86,12 +96,12 @@ - + - + diff --git a/res/layout/wait_service_dialog.xml b/res/layout/launcher.xml similarity index 51% rename from res/layout/wait_service_dialog.xml rename to res/layout/launcher.xml index ec09488c1..2e7387210 100644 --- a/res/layout/wait_service_dialog.xml +++ b/res/layout/launcher.xml @@ -1,8 +1,9 @@ - - - - + + + diff --git a/src/org/linphone/LinphoneActivity.java b/src/org/linphone/LinphoneActivity.java index 25a72314b..d51b1fafa 100644 --- a/src/org/linphone/LinphoneActivity.java +++ b/src/org/linphone/LinphoneActivity.java @@ -35,7 +35,6 @@ import org.linphone.mediastream.Version; import org.linphone.mediastream.video.AndroidVideoWindowImpl; import android.app.AlertDialog; -import android.app.Dialog; import android.app.TabActivity; import android.content.Context; import android.content.DialogInterface; @@ -56,7 +55,6 @@ import android.text.Html; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; -import android.view.View; import android.widget.TabWidget; import android.widget.TextView; import android.widget.Toast; @@ -85,9 +83,6 @@ public class LinphoneActivity extends TabActivity implements private Handler mHandler = new Handler(); - private static final int waitDialogId = 1; - private ServiceWaitThread thread; - // Customization private static boolean useFirstLoginActivity; private static boolean useMenuSettings; @@ -104,15 +99,6 @@ public class LinphoneActivity extends TabActivity implements throw new RuntimeException("LinphoneActivity not instantiated yet"); } - @Override - protected Dialog onCreateDialog(final int id) { - if (id == waitDialogId) { - View v = getLayoutInflater().inflate((R.layout.wait_service_dialog), null); - return new AlertDialog.Builder(this).setView(v).setCancelable(false).create(); - } - return super.onCreateDialog(id); - } - public void onCreate(Bundle savedInstanceState) { instance = this; super.onCreate(savedInstanceState); @@ -127,15 +113,27 @@ public class LinphoneActivity extends TabActivity implements PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK|PowerManager.ON_AFTER_RELEASE,Log.TAG+"#"+getClass().getName()); - if (LinphoneService.isReady()) { - onCreateWhenServiceReady(); + mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); + SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this); + + if (!useFirstLoginActivity || pref.getBoolean(getString(R.string.first_launch_suceeded_once_key), false)) { + fillTabHost(); } else { - // start linphone as background - startService(new Intent(ACTION_MAIN).setClass(this, LinphoneService.class)); - mDoOnCreateWhenServiceReady = true; - thread = new ServiceWaitThread(); - thread.start(); + startActivityForResult(new Intent().setClass(this, FirstLoginActivity.class), FIRST_LOGIN_ACTIVITY); } + + if (checkAccount && !useFirstLoginActivity) { + if (pref.getBoolean(PREF_FIRST_LAUNCH, true)) { + onFirstLaunch(); + } else if (!pref.getBoolean(PREF_CHECK_CONFIG, false) + && !checkDefined(pref, R.string.pref_username_key, R.string.pref_domain_key)) { + onBadSettings(pref); + } else { + checkAccount = false; + } + } + + LinphoneManager.addListener(this); } @@ -201,8 +199,8 @@ public class LinphoneActivity extends TabActivity implements protected void onNewIntent(Intent intent) { super.onNewIntent(intent); if (intent.getData() == null) { - Log.e("LinphoneActivity received an intent without data, recreating GUI if needed"); - if (!LinphoneService.isReady() || !LinphoneManager.getLc().isIncall()) return; + Log.i("LinphoneActivity received an intent without data, recreating GUI if needed"); + if (!LinphoneManager.getLc().isIncall()) return; if(LinphoneManager.getLc().isInComingInvitePending()) { gotToDialer(); } else { @@ -242,7 +240,6 @@ public class LinphoneActivity extends TabActivity implements @Override protected void onPause() { super.onPause(); - mDoResumeWhenServiceReady = false; if (isFinishing()) { //restore audio settings LinphoneManager.removeListener(this); @@ -573,36 +570,9 @@ public class LinphoneActivity extends TabActivity implements } - private boolean mWaitDialogPosted; @Override protected void onResume() { super.onResume(); - - if (LinphoneService.isReady()) { - onResumeWhenServiceReady(); - } else { - if (!mWaitDialogPosted) { - mWaitDialogPosted = true; - mHandler.postDelayed(new Runnable() { - // Delay to avoid flicker. - // Call in onResume to make sure the view (especially the tabhost) is initialized. - @Override - public void run() { - if (!LinphoneService.isReady()) { - showDialog(waitDialogId); - } - } - }, 2000); - } - mDoResumeWhenServiceReady = true; - if (thread == null) { - thread = new ServiceWaitThread(); - thread.start(); - } - } - } - - private void onResumeWhenServiceReady() { LinphoneCall pendingCall = LinphoneManager.getInstance().getPendingIncomingCall(); if (pendingCall != null) { LinphoneActivity.instance().startIncomingCallActivity(pendingCall); @@ -615,72 +585,6 @@ public class LinphoneActivity extends TabActivity implements // removing is done directly in LinphoneActivity.onPause() } } - - - - private boolean mDoOnCreateWhenServiceReady; - private void onCreateWhenServiceReady() { - mDoOnCreateWhenServiceReady = false; - mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); - SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this); - - if (!useFirstLoginActivity || pref.getBoolean(getString(R.string.first_launch_suceeded_once_key), false)) { - fillTabHost(); - } else { - startActivityForResult(new Intent().setClass(this, FirstLoginActivity.class), FIRST_LOGIN_ACTIVITY); - } - - if (checkAccount && !useFirstLoginActivity) { - if (pref.getBoolean(PREF_FIRST_LAUNCH, true)) { - onFirstLaunch(); - } else if (!pref.getBoolean(PREF_CHECK_CONFIG, false) - && !checkDefined(pref, R.string.pref_username_key, R.string.pref_domain_key)) { - onBadSettings(pref); - } else { - checkAccount = false; - } - } - - LinphoneManager.addListener(this); - } - - private boolean mDoResumeWhenServiceReady; - - private class ServiceWaitThread extends Thread { - public void run() { - while (!LinphoneService.isReady()) { - try { - sleep(30); - } catch (InterruptedException e) { - throw new RuntimeException("waiting thread sleep() has been interrupted"); - } - } - - mHandler.post(new Runnable() { - @Override - public void run() { - try { - dismissDialog(waitDialogId); - } catch (Throwable e) { - // Discarding exception which may be thrown if the dialog wasn't showing. - } - } - }); - - mHandler.post(new Runnable() { - @Override - public void run() { - if (mDoOnCreateWhenServiceReady) { - onCreateWhenServiceReady(); - } - if (mDoResumeWhenServiceReady) { - onResumeWhenServiceReady(); - } - } - }); - thread = null; - } - } } interface ContactPicked { diff --git a/src/org/linphone/LinphoneLauncherActivity.java b/src/org/linphone/LinphoneLauncherActivity.java new file mode 100644 index 000000000..bf6cd424d --- /dev/null +++ b/src/org/linphone/LinphoneLauncherActivity.java @@ -0,0 +1,88 @@ +/* +LinphoneLauncher.java +Copyright (C) 2011 Belledonne Communications, Grenoble, France + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +package org.linphone; + +import static android.content.Intent.ACTION_MAIN; +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.view.View; + +/** + * + * Launch Linphone main activity when Service is ready. + * + * @author Guillaume Beraudo + * + */ +public class LinphoneLauncherActivity extends Activity { + + private Handler mHandler; + private ServiceWaitThread mThread; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.launcher); + mHandler = new Handler(); + + if (LinphoneService.isReady()) { + onServiceReady(); + } else { + // start linphone as background + startService(new Intent(ACTION_MAIN).setClass(this, LinphoneService.class)); + mThread = new ServiceWaitThread(); + mThread.start(); + } + } + + private void onServiceReady() { + startActivity(new Intent() + .setClass(this, LinphoneActivity.class) + .setData(getIntent().getData())); + + finish(); + } + + + private class ServiceWaitThread extends Thread { + public void run() { + while (!LinphoneService.isReady()) { + try { + sleep(30); + } catch (InterruptedException e) { + throw new RuntimeException("waiting thread sleep() has been interrupted"); + } + } + + mHandler.post(new Runnable() { + @Override + public void run() { + onServiceReady(); + } + }); + mThread = null; + } + } +} + + diff --git a/src/org/linphone/LinphoneService.java b/src/org/linphone/LinphoneService.java index 161c6e1fe..30ec78ef7 100644 --- a/src/org/linphone/LinphoneService.java +++ b/src/org/linphone/LinphoneService.java @@ -47,7 +47,7 @@ import android.os.Handler; import android.os.IBinder; import android.preference.PreferenceManager; -/*** +/** * * Linphone service, reacting to Incoming calls, ...
* @@ -69,11 +69,11 @@ public final class LinphoneService extends Service implements LinphoneServiceLis private Handler mHandler = new Handler(); private static LinphoneService instance; -// private static boolean mTestDelayElapsed; // add a timer for testing - private static boolean mTestDelayElapsed = true; // no timer +// private boolean mTestDelayElapsed; // add a timer for testing + private boolean mTestDelayElapsed = true; // no timer public static boolean isReady() { - return mTestDelayElapsed && instance!=null; + return instance!=null && instance.mTestDelayElapsed; } /**