From 61e3fd3e695607c345b717790e2304472c75fd91 Mon Sep 17 00:00:00 2001 From: Guillaume Beraudo Date: Tue, 15 Feb 2011 16:18:54 +0100 Subject: [PATCH 01/53] Digit widget for dialer. --- res/layout/dialer.xml | 73 ++++------ res/values/digit_style.xml | 12 ++ src/org/linphone/DialerActivity.java | 181 ++++--------------------- src/org/linphone/LinphoneActivity.java | 13 -- src/org/linphone/LinphoneManager.java | 74 ++++++++++ src/org/linphone/LinphoneService.java | 1 - src/org/linphone/ui/Digit.java | 119 ++++++++++++++++ 7 files changed, 259 insertions(+), 214 deletions(-) create mode 100644 res/values/digit_style.xml create mode 100644 src/org/linphone/LinphoneManager.java create mode 100644 src/org/linphone/ui/Digit.java diff --git a/res/layout/dialer.xml b/res/layout/dialer.xml index 0943935bd..58d38999a 100644 --- a/res/layout/dialer.xml +++ b/res/layout/dialer.xml @@ -41,68 +41,43 @@ - - - + + + - - - + + + - - - + + + - - - + + + - diff --git a/res/values/digit_style.xml b/res/values/digit_style.xml new file mode 100644 index 000000000..400132100 --- /dev/null +++ b/res/values/digit_style.xml @@ -0,0 +1,12 @@ + + + + \ No newline at end of file diff --git a/src/org/linphone/DialerActivity.java b/src/org/linphone/DialerActivity.java index 19416a888..f7d4265ee 100644 --- a/src/org/linphone/DialerActivity.java +++ b/src/org/linphone/DialerActivity.java @@ -25,12 +25,13 @@ import org.linphone.core.LinphoneAddress; import org.linphone.core.LinphoneCall; import org.linphone.core.LinphoneChatRoom; import org.linphone.core.LinphoneCore; -import org.linphone.core.LinphoneCore.EcCalibratorStatus; import org.linphone.core.LinphoneCoreException; import org.linphone.core.LinphoneCoreListener; import org.linphone.core.LinphoneFriend; import org.linphone.core.LinphoneProxyConfig; import org.linphone.core.LinphoneCall.State; +import org.linphone.core.LinphoneCore.EcCalibratorStatus; +import org.linphone.ui.Digit; import android.app.Activity; import android.app.AlertDialog; @@ -48,11 +49,9 @@ import android.preference.PreferenceManager; import android.provider.Settings; import android.text.Html; import android.util.Log; -import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnLongClickListener; -import android.view.View.OnTouchListener; import android.widget.Button; import android.widget.ImageButton; import android.widget.LinearLayout; @@ -71,19 +70,6 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { private ImageButton mHangup; private Button mErase; - private Button mZero; - private Button mOne; - private Button mTwo; - private Button mThree ; - private Button mFour; - private Button mFive; - private Button mSix; - private Button mSeven; - private Button mEight; - private Button mNine; - private Button mStar; - private Button mHash; - private ToggleImageButton mMute; private ToggleImageButton mSpeaker; @@ -113,16 +99,12 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { private static boolean accountCheckingDone; /** - * * @return null if not ready yet */ public static DialerActivity getDialer() { - if (theDialer == null) { - return null; - } else { - return theDialer; - } + return theDialer; } + public void setContactAddress(String aContact,String aDisplayName) { mAddress.setText(aContact); mDisplayName = aDisplayName; @@ -139,8 +121,6 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { try { - - mAddress = (TextView) findViewById(R.id.SipUri); mDisplayNameView = (TextView) findViewById(R.id.DisplayNameView); mErase = (Button)findViewById(R.id.Erase); @@ -277,55 +257,17 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { mSpeaker.setOnCheckedChangeListener(new OnCheckedChangeListener() { public void onCheckedChanged(ToggleImageButton buttonView, boolean isChecked) { if (isChecked) { - routeAudioToSpeaker(); + LinphoneManager.routeAudioToSpeaker(mAudioManager); } else { - routeAudioToReceiver(); + LinphoneManager.routeAudioToReceiver(mAudioManager); } } }); - mZero = (Button) findViewById(R.id.Button00) ; - if (mZero != null) { - setDigitListener(mZero,'0'); - mZero.setOnLongClickListener(new OnLongClickListener() { - public boolean onLongClick(View arg0) { - LinphoneCore lc = LinphoneService.instance().getLinphoneCore(); - lc.stopDtmf(); - int lBegin = mAddress.getSelectionStart(); - if (lBegin == -1) { - lBegin = mAddress.getEditableText().length(); - } - if (lBegin >=0) { - mAddress.getEditableText().insert(lBegin,"+"); - } - return true; - } - - }); - mOne = (Button) findViewById(R.id.Button01) ; - setDigitListener(mOne,'1'); - mTwo = (Button) findViewById(R.id.Button02); - setDigitListener(mTwo,'2'); - mThree = (Button) findViewById(R.id.Button03); - setDigitListener(mThree,'3'); - mFour = (Button) findViewById(R.id.Button04); - setDigitListener(mFour,'4'); - mFive = (Button) findViewById(R.id.Button05); - setDigitListener(mFive,'5'); - mSix = (Button) findViewById(R.id.Button06); - setDigitListener(mSix,'6'); - mSeven = (Button) findViewById(R.id.Button07); - setDigitListener(mSeven,'7'); - mEight = (Button) findViewById(R.id.Button08); - setDigitListener(mEight,'8'); - mNine = (Button) findViewById(R.id.Button09); - setDigitListener(mNine,'9'); - mStar = (Button) findViewById(R.id.ButtonStar); - setDigitListener(mStar,'*'); - mHash = (Button) findViewById(R.id.ButtonHash); - setDigitListener(mHash,'#'); - } + initializeDigits(); + + mStatus = (TextView) findViewById(R.id.status_label); theDialer = this; @@ -338,6 +280,21 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { if (!accountCheckingDone) checkAccountsSettings(); } + private void initializeDigits() { + ((Digit) findViewById(R.id.Button00)).setWidgets(mAddress, mDisplayName); + ((Digit) findViewById(R.id.Button01)).setWidgets(mAddress, mDisplayName); + ((Digit) findViewById(R.id.Button02)).setWidgets(mAddress, mDisplayName); + ((Digit) findViewById(R.id.Button03)).setWidgets(mAddress, mDisplayName); + ((Digit) findViewById(R.id.Button04)).setWidgets(mAddress, mDisplayName); + ((Digit) findViewById(R.id.Button05)).setWidgets(mAddress, mDisplayName); + ((Digit) findViewById(R.id.Button06)).setWidgets(mAddress, mDisplayName); + ((Digit) findViewById(R.id.Button07)).setWidgets(mAddress, mDisplayName); + ((Digit) findViewById(R.id.Button08)).setWidgets(mAddress, mDisplayName); + ((Digit) findViewById(R.id.Button09)).setWidgets(mAddress, mDisplayName); + ((Digit) findViewById(R.id.ButtonStar)).setWidgets(mAddress, mDisplayName); + ((Digit) findViewById(R.id.ButtonHash)).setWidgets(mAddress, mDisplayName); + } + private boolean checkDefined(int ... keys) { for (int key : keys) { String conf = mPref.getString(getString(key), null); @@ -434,7 +391,6 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { } @Override protected void onDestroy() { - // TODO Auto-generated method stub super.onDestroy(); if (mWakeLock.isHeld()) mWakeLock.release(); theDialer=null; @@ -491,7 +447,7 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { if (state == LinphoneCall.State.OutgoingInit) { enterIncalMode(lc); - routeAudioToReceiver(); + LinphoneManager.routeAudioToReceiver(mAudioManager); } else if (state == LinphoneCall.State.IncomingReceived) { resetCameraFromPreferences(); callPending(call); @@ -543,9 +499,9 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { configureMuteAndSpeakerButtons(); if (mSpeaker.isChecked()) { - routeAudioToSpeaker(); + LinphoneManager.routeAudioToSpeaker(mAudioManager); } else { - routeAudioToReceiver(); + LinphoneManager.routeAudioToReceiver(mAudioManager); } setVolumeControlStream(AudioManager.STREAM_VOICE_CALL); LinphoneActivity.instance().startProxymitySensor(); @@ -584,41 +540,12 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { } if (mWakeLock.isHeld())mWakeLock.release(); mSpeaker.setChecked(false); - routeAudioToReceiver(); + LinphoneManager.routeAudioToReceiver(mAudioManager); BandwidthManager.getInstance().setUserRestriction(false); resetCameraFromPreferences(); LinphoneActivity.instance().stopProxymitySensor(); } - private void routeAudioToSpeaker() { - if (Integer.parseInt(Build.VERSION.SDK) <= 4 /*=0) { - mAddressView.getEditableText().insert(lBegin,mKeyCode); - } - mDisplayName=""; - } - } - public boolean onTouch(View v, MotionEvent event) { - if (event.getAction() == MotionEvent.ACTION_DOWN && mIsDtmfStarted ==false) { - LinphoneCore lc = LinphoneService.instance().getLinphoneCore(); - lc.playDtmf(mKeyCode.charAt(0), -1); - mIsDtmfStarted=true; - } else { - if (event.getAction() == MotionEvent.ACTION_UP) - stopDtmf(); - } - return false; - } - - private void stopDtmf() { - LinphoneCore lc = LinphoneService.instance().getLinphoneCore(); - lc.stopDtmf(); - mIsDtmfStarted =false; - } - - }; - DialKeyListener lListener = new DialKeyListener(mAddress,dtmf); - aButton.setOnClickListener(lListener); - aButton.setOnTouchListener(lListener); - - } + public void newSubscriptionRequest(LinphoneCore lc, LinphoneFriend lf, String url) { // TODO Auto-generated method stub diff --git a/src/org/linphone/LinphoneActivity.java b/src/org/linphone/LinphoneActivity.java index af04225d1..c21b5c72a 100644 --- a/src/org/linphone/LinphoneActivity.java +++ b/src/org/linphone/LinphoneActivity.java @@ -134,7 +134,6 @@ public class LinphoneActivity extends TabActivity { } @Override protected void onPause() { - // TODO Auto-generated method stub super.onPause(); if (isFinishing()) { //restaure audio settings @@ -151,18 +150,6 @@ public class LinphoneActivity extends TabActivity { } - @Override - protected void onStop() { - // TODO Auto-generated method stub - super.onStop(); - } - - @Override - protected void onDestroy() { - super.onDestroy(); - - - } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the currently selected menu XML resource. diff --git a/src/org/linphone/LinphoneManager.java b/src/org/linphone/LinphoneManager.java new file mode 100644 index 000000000..5e7c9e3a7 --- /dev/null +++ b/src/org/linphone/LinphoneManager.java @@ -0,0 +1,74 @@ +/* +BigManager.java +Copyright (C) 2010 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 org.linphone.core.LinphoneCore; + +import android.media.AudioManager; +import android.os.Build; + +public class LinphoneManager { + + private static LinphoneManager instance; + + public static void routeAudioToSpeaker(AudioManager mAudioManager) { + if (Integer.parseInt(Build.VERSION.SDK) <= 4 /*=0) { + mAddress.getEditableText().insert(lBegin,"+"); + } + return true; + } + }); + } + } + + public Digit(Context context, AttributeSet attrs, int style) { + super(context, attrs, style); + createWidget(context, attrs); + } + + public Digit(Context context, AttributeSet attrs) { + super(context, attrs); + createWidget(context, attrs); + } + + + + private class DialKeyListener implements OnClickListener ,OnTouchListener { + final CharSequence mKeyCode; + boolean mIsDtmfStarted=false; + DialKeyListener(String aKeyCode) { + mKeyCode = aKeyCode.subSequence(0, 1); + } + public void onClick(View v) { + LinphoneCore lc = LinphoneManager.getLc(); + stopDtmf(); + if (lc.isIncall()) { + lc.sendDtmf(mKeyCode.charAt(0)); + } else { + int lBegin = mAddress.getSelectionStart(); + if (lBegin == -1) { + lBegin = mAddress.getEditableText().length(); + } + if (lBegin >=0) { + mAddress.getEditableText().insert(lBegin,mKeyCode); + } + mDisplayName=""; + } + } + public boolean onTouch(View v, MotionEvent event) { + if (event.getAction() == MotionEvent.ACTION_DOWN && mIsDtmfStarted ==false) { + LinphoneCore lc = LinphoneManager.getLc(); + lc.playDtmf(mKeyCode.charAt(0), -1); + mIsDtmfStarted=true; + } else { + if (event.getAction() == MotionEvent.ACTION_UP) + stopDtmf(); + } + return false; + } + + private void stopDtmf() { + LinphoneCore lc = LinphoneManager.getLc(); + lc.stopDtmf(); + mIsDtmfStarted =false; + } + + }; + + public void setWidgets(TextView address, String displayName) { + mAddress = address; + mDisplayName = displayName; + } +} From 83b638abbb96ca4529350790f39e12ef48145bff Mon Sep 17 00:00:00 2001 From: Guillaume Beraudo Date: Wed, 16 Feb 2011 13:31:30 +0100 Subject: [PATCH 02/53] Add several new widgets. AddressTex, EraseButton, HangCallButton, MuteMicButton, SpeakerButton --- res/layout-land/dialer.xml | 18 +- res/layout/dialer.xml | 47 +-- src/org/linphone/DialerActivity.java | 271 +++++++----------- src/org/linphone/LinphoneManager.java | 38 ++- .../linphone/component/ToggleImageButton.java | 7 +- src/org/linphone/ui/AddressText.java | 49 ++++ src/org/linphone/ui/Digit.java | 9 +- src/org/linphone/ui/EraseButton.java | 60 ++++ src/org/linphone/ui/HangCallButton.java | 41 +++ src/org/linphone/ui/MuteMicButton.java | 52 ++++ src/org/linphone/ui/SpeakerButton.java | 54 ++++ 11 files changed, 420 insertions(+), 226 deletions(-) create mode 100644 src/org/linphone/ui/AddressText.java create mode 100644 src/org/linphone/ui/EraseButton.java create mode 100644 src/org/linphone/ui/HangCallButton.java create mode 100644 src/org/linphone/ui/MuteMicButton.java create mode 100644 src/org/linphone/ui/SpeakerButton.java diff --git a/res/layout-land/dialer.xml b/res/layout-land/dialer.xml index cc395e052..30b1d79e9 100644 --- a/res/layout-land/dialer.xml +++ b/res/layout-land/dialer.xml @@ -7,12 +7,12 @@ android:layout_height="wrap_content" android:layout_width="fill_parent"> - - + android:text="<"/> @@ -23,12 +23,12 @@ android:id="@+id/DisplayNameView" android:clickable="false" android:cursorVisible="false" android:gravity="center" android:layout_width="fill_parent"> - - - + - + - @@ -7,11 +9,11 @@ android:layout_height="wrap_content" android:layout_width="fill_parent"> - - + android:textStyle="bold" android:text="<" android:layout_gravity="top" android:textColor="@android:color/black"/> @@ -22,13 +24,12 @@ android:layout_height="wrap_content" android:layout_width="wrap_content" android:lines="1" android:id="@+id/DisplayNameView" android:clickable="false" - android:cursorVisible="false" android:layout_gravity="center" - > - + - @@ -41,39 +42,39 @@ - - - - - - - - - - - - @@ -82,14 +83,14 @@ - + - + diff --git a/src/org/linphone/DialerActivity.java b/src/org/linphone/DialerActivity.java index f7d4265ee..9ccb8cee4 100644 --- a/src/org/linphone/DialerActivity.java +++ b/src/org/linphone/DialerActivity.java @@ -18,8 +18,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package org.linphone; -import org.linphone.component.ToggleImageButton; -import org.linphone.component.ToggleImageButton.OnCheckedChangeListener; import org.linphone.core.AndroidCameraRecordManager; import org.linphone.core.LinphoneAddress; import org.linphone.core.LinphoneCall; @@ -31,7 +29,11 @@ import org.linphone.core.LinphoneFriend; import org.linphone.core.LinphoneProxyConfig; import org.linphone.core.LinphoneCall.State; import org.linphone.core.LinphoneCore.EcCalibratorStatus; +import org.linphone.ui.AddressText; import org.linphone.ui.Digit; +import org.linphone.ui.EraseButton; +import org.linphone.ui.MuteMicButton; +import org.linphone.ui.SpeakerButton; import android.app.Activity; import android.app.AlertDialog; @@ -41,7 +43,6 @@ import android.content.Intent; import android.content.SharedPreferences; import android.media.AudioManager; import android.media.MediaPlayer; -import android.os.Build; import android.os.Bundle; import android.os.PowerManager; import android.os.Vibrator; @@ -51,8 +52,6 @@ import android.text.Html; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; -import android.view.View.OnLongClickListener; -import android.widget.Button; import android.widget.ImageButton; import android.widget.LinearLayout; import android.widget.TableRow; @@ -61,17 +60,16 @@ import android.widget.Toast; public class DialerActivity extends Activity implements LinphoneCoreListener { - private TextView mAddress; + private AddressText mAddress; private TextView mDisplayNameView; private TextView mStatus; private ImageButton mCall; - private ImageButton mDecline; - private ImageButton mHangup; - private Button mErase; + private View mDecline; + private View mHangup; - private ToggleImageButton mMute; - private ToggleImageButton mSpeaker; + private MuteMicButton mMute; + private SpeakerButton mSpeaker; private LinearLayout mCallControlRow; private TableRow mInCallControlRow; @@ -80,8 +78,6 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { private static DialerActivity theDialer; - private String mDisplayName; - private AudioManager mAudioManager; private PowerManager.WakeLock mWakeLock; private SharedPreferences mPref; private ImageButton mAddVideo; @@ -105,15 +101,11 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { return theDialer; } - public void setContactAddress(String aContact,String aDisplayName) { - mAddress.setText(aContact); - mDisplayName = aDisplayName; - } public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.dialer); - mAudioManager = ((AudioManager)getSystemService(Context.AUDIO_SERVICE)); + LinphoneManager.getInstance().setAudioManager(((AudioManager)getSystemService(Context.AUDIO_SERVICE))); PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE); mVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK|PowerManager.ON_AFTER_RELEASE,"Linphone"); @@ -121,30 +113,10 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { try { - mAddress = (TextView) findViewById(R.id.SipUri); + mAddress = (AddressText) findViewById(R.id.SipUri); mDisplayNameView = (TextView) findViewById(R.id.DisplayNameView); - mErase = (Button)findViewById(R.id.Erase); + ((EraseButton) findViewById(R.id.Erase)).setAddressView(mAddress); - mErase.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - mDisplayName=null; - if (mAddress.length() >0) { - int lBegin = mAddress.getSelectionStart(); - if (lBegin == -1) { - lBegin = mAddress.getEditableText().length()-1; - } - if (lBegin >0) { - mAddress.getEditableText().delete(lBegin-1,lBegin); - } - } - } - }); - mErase.setOnLongClickListener(new OnLongClickListener() { - public boolean onLongClick(View arg0) { - mAddress.getEditableText().clear(); - return true; - } - }); mAddVideo = (ImageButton) findViewById(R.id.AddVideo); mAddVideo.setOnClickListener(new OnClickListener() { @@ -161,46 +133,21 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { mCall = (ImageButton) findViewById(R.id.Call); mCall.setOnClickListener(new OnClickListener() { public void onClick(View v) { - LinphoneCore lLinphoneCore = LinphoneService.instance().getLinphoneCore(); - if (lLinphoneCore.isInComingInvitePending()) { - try { - lLinphoneCore.acceptCall(lLinphoneCore.getCurrentCall()); - } catch (LinphoneCoreException e) { - lLinphoneCore.terminateCall(lLinphoneCore.getCurrentCall()); - Toast toast = Toast.makeText(DialerActivity.this - ,String.format(getString(R.string.warning_wrong_destination_address),mAddress.getText().toString()) - ,Toast.LENGTH_LONG); - toast.show(); - } - return; - } - if (mAddress.getText().length() >0) { - newOutgoingCall(mAddress.getText().toString(),mDisplayName); - } + callOrAcceptIncommingCall(); } - }); - mDecline= (ImageButton) findViewById(R.id.Decline); - mHangup = (ImageButton) findViewById(R.id.HangUp); - - OnClickListener lHangupListener = new OnClickListener() { - - public void onClick(View v) { - LinphoneCore lLinphoneCore = LinphoneService.instance().getLinphoneCore(); - lLinphoneCore.terminateCall(lLinphoneCore.getCurrentCall()); - } - - }; - mHangup.setOnClickListener(lHangupListener); - mDecline.setOnClickListener(lHangupListener); + mDecline= findViewById(R.id.Decline); + mDecline.setEnabled(false); + + mHangup = findViewById(R.id.HangUp); mCallControlRow = (LinearLayout) findViewById(R.id.CallControlRow); mInCallControlRow = (TableRow) findViewById(R.id.IncallControlRow); mAddressLayout = (View) findViewById(R.id.Addresslayout); mInCallAddressLayout = (View) findViewById(R.id.IncallAddressLayout); - mMute = (ToggleImageButton)findViewById(R.id.mic_mute_button); - mSpeaker = (ToggleImageButton)findViewById(R.id.speaker_button); + mMute = (MuteMicButton)findViewById(R.id.mic_mute_button); + mSpeaker = (SpeakerButton)findViewById(R.id.speaker_button); /* if (Hacks.isGalaxyS()) { // Galaxy S doesn't handle audio routing properly // so disabling it totally @@ -208,16 +155,17 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { }*/ mInCallControlRow.setVisibility(View.GONE); mInCallAddressLayout.setVisibility(View.GONE); - mDecline.setEnabled(false); - if (LinphoneService.isready() && getIntent().getData() != null && !LinphoneService.instance().getLinphoneCore().isIncall()) { + + if (LinphoneService.isready() && getIntent().getData() != null && !LinphoneService.getLc().isIncall()) { newOutgoingCall(getIntent().getData().toString().substring("tel://".length())); getIntent().setData(null); } + if (LinphoneService.isready()) { - LinphoneCore lLinphoneCore = LinphoneService.instance().getLinphoneCore(); - if (lLinphoneCore.isIncall()) { - if(lLinphoneCore.isInComingInvitePending()) { - callPending(lLinphoneCore.getCurrentCall()); + LinphoneCore lc = LinphoneService.getLc(); + if (lc.isIncall()) { + if(lc.isInComingInvitePending()) { + callPending(lc.getCurrentCall()); } else { mCall.setEnabled(false); mHangup.setEnabled(!mCall.isEnabled()); @@ -227,43 +175,19 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { mAddressLayout.setVisibility(View.GONE); mInCallAddressLayout.setVisibility(View.VISIBLE); - String DisplayName = lLinphoneCore.getRemoteAddress().getDisplayName(); + String DisplayName = lc.getRemoteAddress().getDisplayName(); if (DisplayName!=null) { mDisplayNameView.setText(DisplayName); } else { - mDisplayNameView.setText(lLinphoneCore.getRemoteAddress().getUserName()); + mDisplayNameView.setText(lc.getRemoteAddress().getUserName()); } - configureMuteAndSpeakerButtons(); + loadMicAndSpeakerUiStateFromLibrary(); LinphoneActivity.instance().startProxymitySensor(); mWakeLock.acquire(); } } } - - - mMute.setOnCheckedChangeListener(new OnCheckedChangeListener() { - public void onCheckedChanged(ToggleImageButton button, boolean isChecked) { - LinphoneCore lc = LinphoneService.instance().getLinphoneCore(); - if (isChecked) { - lc.muteMic(true); - } else { - lc.muteMic(false); - } - } - }); - - - mSpeaker.setOnCheckedChangeListener(new OnCheckedChangeListener() { - public void onCheckedChanged(ToggleImageButton buttonView, boolean isChecked) { - if (isChecked) { - LinphoneManager.routeAudioToSpeaker(mAudioManager); - } else { - LinphoneManager.routeAudioToReceiver(mAudioManager); - } - } - }); - initializeDigits(); @@ -280,19 +204,40 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { if (!accountCheckingDone) checkAccountsSettings(); } + private void callOrAcceptIncommingCall() { + LinphoneCore lLinphoneCore = LinphoneService.instance().getLinphoneCore(); + if (lLinphoneCore.isInComingInvitePending()) { + try { + lLinphoneCore.acceptCall(lLinphoneCore.getCurrentCall()); + } catch (LinphoneCoreException e) { + lLinphoneCore.terminateCall(lLinphoneCore.getCurrentCall()); + Toast toast = Toast.makeText(DialerActivity.this + ,String.format(getString(R.string.warning_wrong_destination_address),mAddress.getText().toString()) + ,Toast.LENGTH_LONG); + toast.show(); + } + return; + } + if (mAddress.getText().length() >0) { + newOutgoingCall(mAddress.getText().toString(), mAddress.getDisplayedName()); + } + } + private void initializeDigits() { - ((Digit) findViewById(R.id.Button00)).setWidgets(mAddress, mDisplayName); - ((Digit) findViewById(R.id.Button01)).setWidgets(mAddress, mDisplayName); - ((Digit) findViewById(R.id.Button02)).setWidgets(mAddress, mDisplayName); - ((Digit) findViewById(R.id.Button03)).setWidgets(mAddress, mDisplayName); - ((Digit) findViewById(R.id.Button04)).setWidgets(mAddress, mDisplayName); - ((Digit) findViewById(R.id.Button05)).setWidgets(mAddress, mDisplayName); - ((Digit) findViewById(R.id.Button06)).setWidgets(mAddress, mDisplayName); - ((Digit) findViewById(R.id.Button07)).setWidgets(mAddress, mDisplayName); - ((Digit) findViewById(R.id.Button08)).setWidgets(mAddress, mDisplayName); - ((Digit) findViewById(R.id.Button09)).setWidgets(mAddress, mDisplayName); - ((Digit) findViewById(R.id.ButtonStar)).setWidgets(mAddress, mDisplayName); - ((Digit) findViewById(R.id.ButtonHash)).setWidgets(mAddress, mDisplayName); + if (findViewById(R.id.Digit00) == null) return; // In landscape view, no keyboard + + ((Digit) findViewById(R.id.Digit00)).setAddressWidget(mAddress); + ((Digit) findViewById(R.id.Digit1)).setAddressWidget(mAddress); + ((Digit) findViewById(R.id.Digit2)).setAddressWidget(mAddress); + ((Digit) findViewById(R.id.Digit3)).setAddressWidget(mAddress); + ((Digit) findViewById(R.id.Digit4)).setAddressWidget(mAddress); + ((Digit) findViewById(R.id.Digit5)).setAddressWidget(mAddress); + ((Digit) findViewById(R.id.Digit6)).setAddressWidget(mAddress); + ((Digit) findViewById(R.id.Digit7)).setAddressWidget(mAddress); + ((Digit) findViewById(R.id.Digit8)).setAddressWidget(mAddress); + ((Digit) findViewById(R.id.Digit9)).setAddressWidget(mAddress); + ((Digit) findViewById(R.id.DigitStar)).setAddressWidget(mAddress); + ((Digit) findViewById(R.id.DigitHash)).setAddressWidget(mAddress); } private boolean checkDefined(int ... keys) { @@ -377,7 +322,8 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { public void onSaveInstanceState(Bundle savedInstanceState) { super.onSaveInstanceState(savedInstanceState); savedInstanceState.putString(CURRENT_ADDRESS, mAddress.getText().toString()); - if (mDisplayName != null) savedInstanceState.putString(CURRENT_DISPLAYNAME,mDisplayName); + if (mAddress.getDisplayedName() != null) + savedInstanceState.putString(CURRENT_DISPLAYNAME,mAddress.getDisplayedName()); } @Override @@ -387,7 +333,7 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { if (lAddress != null && mAddress != null) { mAddress.setText(lAddress); } - mDisplayName = savedInstanceState.getString(CURRENT_DISPLAYNAME); + mAddress.setDisplayedName(savedInstanceState.getString(CURRENT_DISPLAYNAME)); } @Override protected void onDestroy() { @@ -400,27 +346,17 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { protected void onResume() { super.onResume(); } - public void authInfoRequested(LinphoneCore lc, String realm, String username) { - // TODO Auto-generated method stub - - } - public void byeReceived(LinphoneCore lc, String from) { - // TODO Auto-generated method stub - - } - public void displayMessage(LinphoneCore lc, String message) { - // TODO Auto-generated method stub - - } + + public void authInfoRequested(LinphoneCore lc, String realm, String username) /*nop*/{} + public void byeReceived(LinphoneCore lc, String from) {/*nop*/} + public void displayMessage(LinphoneCore lc, String message) {/*nop*/} + public void displayWarning(LinphoneCore lc, String message) {/*nop*/} + public void displayStatus(LinphoneCore lc, String message) { mStatus.setText(message); } - public void displayWarning(LinphoneCore lc, String message) { - // TODO Auto-generated method stub - - } - public void globalState(LinphoneCore lc, LinphoneCore.GlobalState state, String message) { + public void globalState(LinphoneCore lc, LinphoneCore.GlobalState state, String message) { if (state == LinphoneCore.GlobalState.GlobalOn) { mCall.setEnabled(!lc.isIncall()); mHangup.setEnabled(!mCall.isEnabled()); @@ -436,6 +372,8 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { } } } + + private void startVideoView(int requestCode) { Intent lIntent = new Intent(); lIntent.setClass(this, VideoCallActivity.class); @@ -447,7 +385,7 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { if (state == LinphoneCall.State.OutgoingInit) { enterIncalMode(lc); - LinphoneManager.routeAudioToReceiver(mAudioManager); + LinphoneManager.getInstance().routeAudioToReceiver(); } else if (state == LinphoneCall.State.IncomingReceived) { resetCameraFromPreferences(); callPending(call); @@ -469,13 +407,9 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { } } } - } - public void show(LinphoneCore lc) { - // TODO Auto-generated method stub - - } + public void show(LinphoneCore lc) {/*nop*/} private void enterIncalMode(LinphoneCore lc) { mCallControlRow.setVisibility(View.GONE); @@ -496,26 +430,21 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { mDisplayNameView.setText(lc.getRemoteAddress().toString()); } } - configureMuteAndSpeakerButtons(); + loadMicAndSpeakerUiStateFromLibrary(); - if (mSpeaker.isChecked()) { - LinphoneManager.routeAudioToSpeaker(mAudioManager); + if (mSpeaker.isSpeakerOn()) { + LinphoneManager.getInstance().routeAudioToSpeaker(); } else { - LinphoneManager.routeAudioToReceiver(mAudioManager); + LinphoneManager.getInstance().routeAudioToReceiver(); } setVolumeControlStream(AudioManager.STREAM_VOICE_CALL); LinphoneActivity.instance().startProxymitySensor(); if (!mWakeLock.isHeld()) mWakeLock.acquire(); } - private void configureMuteAndSpeakerButtons() { - mMute.setChecked(LinphoneService.instance().getLinphoneCore().isMicMuted()); - if ((Integer.parseInt(Build.VERSION.SDK) <=4 && mAudioManager.getRouting(AudioManager.MODE_NORMAL) == AudioManager.ROUTE_SPEAKER) - || Integer.parseInt(Build.VERSION.SDK) >4 &&mAudioManager.isSpeakerphoneOn()) { - mSpeaker.setChecked(true); - } else { - mSpeaker.setChecked(false); - } + private void loadMicAndSpeakerUiStateFromLibrary() { + mMute.setChecked(LinphoneService.getLc().isMicMuted()); + mSpeaker.setSpeakerOn(LinphoneManager.getInstance().isSpeakerOn()); } private void resetCameraFromPreferences() { @@ -539,8 +468,8 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { finishActivity(VIDEO_VIEW_ACTIVITY); } if (mWakeLock.isHeld())mWakeLock.release(); - mSpeaker.setChecked(false); - LinphoneManager.routeAudioToReceiver(mAudioManager); + mSpeaker.setSpeakerOn(false); + LinphoneManager.getInstance().routeAudioToReceiver(); BandwidthManager.getInstance().setUserRestriction(false); resetCameraFromPreferences(); LinphoneActivity.instance().stopProxymitySensor(); @@ -561,13 +490,13 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { } - public synchronized void newOutgoingCall(String aTo, String displayName) { + private synchronized void newOutgoingCall(String aTo, String displayName) { String lto = aTo; if (aTo.contains(OutgoingCallReceiver.TAG)) { lto = aTo.replace(OutgoingCallReceiver.TAG, ""); } mAddress.setText(lto); - mDisplayName = displayName; + mAddress.setDisplayedName(displayName); LinphoneCore lLinphoneCore = LinphoneService.instance().getLinphoneCore(); if (lLinphoneCore.isIncall()) { Toast toast = Toast.makeText(DialerActivity.this, getString(R.string.warning_already_incall), Toast.LENGTH_LONG); @@ -584,7 +513,7 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { toast.show(); return; } - lAddress.setDisplayName(mDisplayName); + lAddress.setDisplayName(mAddress.getDisplayedName()); try { boolean prefVideoEnable = mPref.getBoolean(getString(R.string.pref_video_enable_key), false); @@ -601,28 +530,22 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { } } - public void newSubscriptionRequest(LinphoneCore lc, LinphoneFriend lf, - String url) { - // TODO Auto-generated method stub - - } - public void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf) { - // TODO Auto-generated method stub - - } + public void newSubscriptionRequest(LinphoneCore lc, LinphoneFriend lf, String url) {} + public void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf) {} public void textReceived(LinphoneCore lc, LinphoneChatRoom cr, - LinphoneAddress from, String message) { - // TODO Auto-generated method stub - - } + LinphoneAddress from, String message) {} private AndroidCameraRecordManager getVideoManager() { return AndroidCameraRecordManager.getInstance(); } public void ecCalibrationStatus(LinphoneCore lc, EcCalibratorStatus status, - int delay_ms, Object data) { - + int delay_ms, Object data) {} + + public void setContactAddress(String aContact,String aDisplayName) { + mAddress.setText(aContact); + mAddress.setDisplayedName(aDisplayName); } } + diff --git a/src/org/linphone/LinphoneManager.java b/src/org/linphone/LinphoneManager.java index 5e7c9e3a7..5e9fac29f 100644 --- a/src/org/linphone/LinphoneManager.java +++ b/src/org/linphone/LinphoneManager.java @@ -1,5 +1,5 @@ /* -BigManager.java +LinphoneManager.java Copyright (C) 2010 Belledonne Communications, Grenoble, France This program is free software; you can redistribute it and/or @@ -20,30 +20,33 @@ package org.linphone; import org.linphone.core.LinphoneCore; +import android.content.SharedPreferences; import android.media.AudioManager; import android.os.Build; public class LinphoneManager { private static LinphoneManager instance; + private AudioManager mAudioManager; - public static void routeAudioToSpeaker(AudioManager mAudioManager) { + + public void routeAudioToSpeaker() { if (Integer.parseInt(Build.VERSION.SDK) <= 4 /*4 &&mAudioManager.isSpeakerphoneOn(); + } + + + } diff --git a/src/org/linphone/component/ToggleImageButton.java b/src/org/linphone/component/ToggleImageButton.java index 8cfa1e917..21cd620f2 100644 --- a/src/org/linphone/component/ToggleImageButton.java +++ b/src/org/linphone/component/ToggleImageButton.java @@ -36,7 +36,8 @@ import android.widget.ImageButton; * */ public class ToggleImageButton extends ImageButton implements OnClickListener { - private static final String namespace = null; +// private static final String ns = "http://schemas.android.com/apk/res/linphone"; + private static final String ns = null; private boolean checked; private Drawable stateChecked; private Drawable stateUnChecked; @@ -44,8 +45,8 @@ public class ToggleImageButton extends ImageButton implements OnClickListener { public ToggleImageButton(Context context, AttributeSet attrs) { super(context, attrs); - stateChecked = getResources().getDrawable(attrs.getAttributeResourceValue(namespace, "checked", -1)); - stateUnChecked = getResources().getDrawable(attrs.getAttributeResourceValue(namespace, "unchecked", -1)); + stateChecked = getResources().getDrawable(attrs.getAttributeResourceValue(ns, "checked", -1)); + stateUnChecked = getResources().getDrawable(attrs.getAttributeResourceValue(ns, "unchecked", -1)); setBackgroundColor(Color.TRANSPARENT); setOnClickListener(this); diff --git a/src/org/linphone/ui/AddressText.java b/src/org/linphone/ui/AddressText.java new file mode 100644 index 000000000..7c70dcb5a --- /dev/null +++ b/src/org/linphone/ui/AddressText.java @@ -0,0 +1,49 @@ +/* +AddressView.java +Copyright (C) 2010 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.ui; + +import android.content.Context; +import android.util.AttributeSet; +import android.widget.EditText; + +public class AddressText extends EditText { + + private String displayedName; + + public AddressText(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public void clearDisplayedName() { + displayedName = ""; + } + + public String getDisplayedName() { + return displayedName; + } + + public void setContactAddress(String uri, String displayedName) { + this.displayedName = displayedName; + setText(uri); + } + + public void setDisplayedName(String displayedName) { + this.displayedName = displayedName; + } +} diff --git a/src/org/linphone/ui/Digit.java b/src/org/linphone/ui/Digit.java index ef93b9371..6e70d7d51 100644 --- a/src/org/linphone/ui/Digit.java +++ b/src/org/linphone/ui/Digit.java @@ -26,12 +26,10 @@ import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.widget.Button; -import android.widget.TextView; public class Digit extends Button { - private TextView mAddress; - private String mDisplayName; // FIXME not linked with dialeractivity + private AddressText mAddress; private final void createWidget(Context context, AttributeSet attrs) { String ns = "http://schemas.android.com/apk/res/android"; @@ -89,7 +87,7 @@ public class Digit extends Button { if (lBegin >=0) { mAddress.getEditableText().insert(lBegin,mKeyCode); } - mDisplayName=""; + mAddress.clearDisplayedName(); } } public boolean onTouch(View v, MotionEvent event) { @@ -112,8 +110,7 @@ public class Digit extends Button { }; - public void setWidgets(TextView address, String displayName) { + public void setAddressWidget(AddressText address) { mAddress = address; - mDisplayName = displayName; } } diff --git a/src/org/linphone/ui/EraseButton.java b/src/org/linphone/ui/EraseButton.java new file mode 100644 index 000000000..122535062 --- /dev/null +++ b/src/org/linphone/ui/EraseButton.java @@ -0,0 +1,60 @@ +/* +EraseButton.java +Copyright (C) 2010 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.ui; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.View.OnLongClickListener; +import android.widget.Button; + +public class EraseButton extends Button implements OnClickListener, OnLongClickListener{ + + private AddressText address; + + public EraseButton(Context context, AttributeSet attrs) { + super(context, attrs); + setOnClickListener(this); + setOnLongClickListener(this); + } + + public void onClick(View v) { + address.clearDisplayedName(); + if (address.getText().length() >0) { + int lBegin = address.getSelectionStart(); + if (lBegin == -1) { + lBegin = address.getEditableText().length()-1; + } + if (lBegin >0) { + address.getEditableText().delete(lBegin-1,lBegin); + } + } + } + + public boolean onLongClick(View v) { + address.getEditableText().clear(); + return true; + } + + public void setAddressView(AddressText view) { + address = view; + } + +} diff --git a/src/org/linphone/ui/HangCallButton.java b/src/org/linphone/ui/HangCallButton.java new file mode 100644 index 000000000..9f51741c2 --- /dev/null +++ b/src/org/linphone/ui/HangCallButton.java @@ -0,0 +1,41 @@ +/* +SpeakerButton.java +Copyright (C) 2010 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.ui; + +import org.linphone.LinphoneManager; +import org.linphone.core.LinphoneCore; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.ImageButton; + +public class HangCallButton extends ImageButton implements OnClickListener { + + public HangCallButton(Context context, AttributeSet attrs) { + super(context, attrs); + setOnClickListener(this); + } + + public void onClick(View v) { + LinphoneCore lc = LinphoneManager.getLc(); + lc.terminateCall(lc.getCurrentCall()); + } +} diff --git a/src/org/linphone/ui/MuteMicButton.java b/src/org/linphone/ui/MuteMicButton.java new file mode 100644 index 000000000..50e6f9dbc --- /dev/null +++ b/src/org/linphone/ui/MuteMicButton.java @@ -0,0 +1,52 @@ +/* +SpeakerButton.java +Copyright (C) 2010 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.ui; + +import org.linphone.LinphoneManager; +import org.linphone.component.ToggleImageButton; +import org.linphone.component.ToggleImageButton.OnCheckedChangeListener; + +import android.content.Context; +import android.util.AttributeSet; + +public class MuteMicButton extends ToggleImageButton implements OnCheckedChangeListener { + + public MuteMicButton(Context context, AttributeSet attrs) { + super(context, attrs); + setOnCheckedChangeListener(this); + } + + + public boolean isMicMuted() { + return isChecked(); + } + + public void setMicMuted(boolean state) { + setChecked(state); + } + + + public void onCheckedChanged(ToggleImageButton button, boolean checked) { + if (checked) { + LinphoneManager.getLc().muteMic(true); + } else { + LinphoneManager.getLc().muteMic(false); + } + } +} diff --git a/src/org/linphone/ui/SpeakerButton.java b/src/org/linphone/ui/SpeakerButton.java new file mode 100644 index 000000000..14bbb8c3c --- /dev/null +++ b/src/org/linphone/ui/SpeakerButton.java @@ -0,0 +1,54 @@ +/* +SpeakerButton.java +Copyright (C) 2010 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.ui; + +import org.linphone.LinphoneManager; +import org.linphone.component.ToggleImageButton; +import org.linphone.component.ToggleImageButton.OnCheckedChangeListener; + +import android.content.Context; +import android.util.AttributeSet; + +public class SpeakerButton extends ToggleImageButton implements OnCheckedChangeListener { + + public SpeakerButton(Context context, AttributeSet attrs) { + super(context, attrs); + setOnCheckedChangeListener(this); + } + + + public boolean isSpeakerOn() { + return isChecked(); + } + + public void setSpeakerOn(boolean state) { + setChecked(state); + } + + + public void onCheckedChanged(ToggleImageButton button, boolean checked) { + if (checked) { + LinphoneManager.getInstance().routeAudioToSpeaker(); + } else { + LinphoneManager.getInstance().routeAudioToReceiver(); + } + } + + +} From 4d79c4e6184a92ff61cbfc4001738308de997a7b Mon Sep 17 00:00:00 2001 From: Guillaume Beraudo Date: Thu, 17 Feb 2011 14:25:23 +0100 Subject: [PATCH 03/53] Add several new ui components. Cleanups. --- res/layout-land/dialer.xml | 7 +- res/layout/dialer.xml | 69 ++-- src/org/linphone/DialerActivity.java | 315 ++++++++---------- src/org/linphone/Hacks.java | 2 + ...iveManager.java => KeepAliveReceiver.java} | 4 +- src/org/linphone/LinphoneException.java | 7 +- src/org/linphone/LinphoneManager.java | 88 ++++- src/org/linphone/LinphoneService.java | 2 +- src/org/linphone/VideoCallActivity.java | 15 +- src/org/linphone/ui/AddVideoButton.java | 58 ++++ src/org/linphone/ui/AddressAwareWidget.java | 25 ++ src/org/linphone/ui/AddressText.java | 4 +- src/org/linphone/ui/CallButton.java | 72 ++++ src/org/linphone/ui/Digit.java | 64 ++-- src/org/linphone/ui/HangCallButton.java | 2 +- src/org/linphone/ui/MuteMicButton.java | 3 +- src/org/linphone/ui/SpeakerButton.java | 3 +- .../{component => ui}/ToggleImageButton.java | 2 +- 18 files changed, 459 insertions(+), 283 deletions(-) rename src/org/linphone/{KeepAliveManager.java => KeepAliveReceiver.java} (94%) create mode 100644 src/org/linphone/ui/AddVideoButton.java create mode 100644 src/org/linphone/ui/AddressAwareWidget.java create mode 100644 src/org/linphone/ui/CallButton.java rename src/org/linphone/{component => ui}/ToggleImageButton.java (98%) diff --git a/res/layout-land/dialer.xml b/res/layout-land/dialer.xml index 30b1d79e9..eb1da6ff1 100644 --- a/res/layout-land/dialer.xml +++ b/res/layout-land/dialer.xml @@ -38,15 +38,14 @@ - + - - + diff --git a/res/layout/dialer.xml b/res/layout/dialer.xml index 0a5634187..a029f42c7 100644 --- a/res/layout/dialer.xml +++ b/res/layout/dialer.xml @@ -40,56 +40,43 @@ - - - - - - - - - - - - - - - - - - - - - + android:layout_weight="1" android:id="@+id/DialerRow01" + android:layout_width="fill_parent"> + + + + + + + + + + + + + + + + + + + + - + - + diff --git a/src/org/linphone/DialerActivity.java b/src/org/linphone/DialerActivity.java index 9ccb8cee4..6503b80a3 100644 --- a/src/org/linphone/DialerActivity.java +++ b/src/org/linphone/DialerActivity.java @@ -18,22 +18,26 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package org.linphone; +import org.linphone.LinphoneManager.NewOutgoingCallUiListener; import org.linphone.core.AndroidCameraRecordManager; import org.linphone.core.LinphoneAddress; import org.linphone.core.LinphoneCall; import org.linphone.core.LinphoneChatRoom; import org.linphone.core.LinphoneCore; -import org.linphone.core.LinphoneCoreException; import org.linphone.core.LinphoneCoreListener; import org.linphone.core.LinphoneFriend; import org.linphone.core.LinphoneProxyConfig; import org.linphone.core.LinphoneCall.State; import org.linphone.core.LinphoneCore.EcCalibratorStatus; +import org.linphone.ui.AddVideoButton; import org.linphone.ui.AddressText; +import org.linphone.ui.CallButton; import org.linphone.ui.Digit; import org.linphone.ui.EraseButton; import org.linphone.ui.MuteMicButton; import org.linphone.ui.SpeakerButton; +import org.linphone.ui.AddVideoButton.AlreadyInVideoCallListener; +import org.linphone.ui.CallButton.CallButtonListener; import android.app.Activity; import android.app.AlertDialog; @@ -51,20 +55,18 @@ import android.provider.Settings; import android.text.Html; import android.util.Log; import android.view.View; -import android.view.View.OnClickListener; -import android.widget.ImageButton; import android.widget.LinearLayout; import android.widget.TableRow; import android.widget.TextView; import android.widget.Toast; -public class DialerActivity extends Activity implements LinphoneCoreListener { +public class DialerActivity extends Activity implements LinphoneCoreListener, AlreadyInVideoCallListener, CallButtonListener, NewOutgoingCallUiListener { private AddressText mAddress; private TextView mDisplayNameView; private TextView mStatus; - private ImageButton mCall; + private CallButton mCall; private View mDecline; private View mHangup; @@ -80,7 +82,7 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { private PowerManager.WakeLock mWakeLock; private SharedPreferences mPref; - private ImageButton mAddVideo; + private AddVideoButton mAddVideo; private static final String PREF_CHECK_CONFIG = "pref_check_config"; public static final String PREF_FIRST_LAUNCH = "pref_first_launch"; @@ -105,11 +107,13 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.dialer); - LinphoneManager.getInstance().setAudioManager(((AudioManager)getSystemService(Context.AUDIO_SERVICE))); + mPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); + AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE); + LinphoneManager.getInstance().setUsefullStuff(am, mPref, getWindowManager(), getResources()); PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE); mVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK|PowerManager.ON_AFTER_RELEASE,"Linphone"); - mPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); + try { @@ -118,24 +122,15 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { ((EraseButton) findViewById(R.id.Erase)).setAddressView(mAddress); - mAddVideo = (ImageButton) findViewById(R.id.AddVideo); - mAddVideo.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - // If no in video call; try to reinvite with video - boolean alreadyInVideoCall = !CallManager.getInstance().reinviteWithVideo(); - if (alreadyInVideoCall) { - // In video call; going back to video call activity - startVideoView(VIDEO_VIEW_ACTIVITY); - } - } - }); + mAddVideo = (AddVideoButton) findViewById(R.id.AddVideo); + mAddVideo.setOnAlreadyInVideoCallListener(this); + + + + mCall = (CallButton) findViewById(R.id.Call); + mCall.setCallButtonListerner(this); + mCall.setAddressWidget(mAddress); - mCall = (ImageButton) findViewById(R.id.Call); - mCall.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - callOrAcceptIncommingCall(); - } - }); mDecline= findViewById(R.id.Decline); mDecline.setEnabled(false); @@ -143,18 +138,15 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { mCallControlRow = (LinearLayout) findViewById(R.id.CallControlRow); - mInCallControlRow = (TableRow) findViewById(R.id.IncallControlRow); mAddressLayout = (View) findViewById(R.id.Addresslayout); + + mInCallControlRow = (TableRow) findViewById(R.id.IncallControlRow); + mInCallControlRow.setVisibility(View.GONE); mInCallAddressLayout = (View) findViewById(R.id.IncallAddressLayout); + mInCallAddressLayout.setVisibility(View.GONE); mMute = (MuteMicButton)findViewById(R.id.mic_mute_button); mSpeaker = (SpeakerButton)findViewById(R.id.speaker_button); -/* if (Hacks.isGalaxyS()) { - // Galaxy S doesn't handle audio routing properly - // so disabling it totally - mSpeaker.setVisibility(View.GONE); - }*/ - mInCallControlRow.setVisibility(View.GONE); - mInCallAddressLayout.setVisibility(View.GONE); + if (LinphoneService.isready() && getIntent().getData() != null && !LinphoneService.getLc().isIncall()) { newOutgoingCall(getIntent().getData().toString().substring("tel://".length())); @@ -189,8 +181,21 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { } - initializeDigits(); - + if (findViewById(R.id.Digit00) != null) { // In landscape view, no keyboard + ((Digit) findViewById(R.id.Digit00)).setAddressWidget(mAddress); + ((Digit) findViewById(R.id.Digit1)).setAddressWidget(mAddress); + ((Digit) findViewById(R.id.Digit2)).setAddressWidget(mAddress); + ((Digit) findViewById(R.id.Digit3)).setAddressWidget(mAddress); + ((Digit) findViewById(R.id.Digit4)).setAddressWidget(mAddress); + ((Digit) findViewById(R.id.Digit5)).setAddressWidget(mAddress); + ((Digit) findViewById(R.id.Digit6)).setAddressWidget(mAddress); + ((Digit) findViewById(R.id.Digit7)).setAddressWidget(mAddress); + ((Digit) findViewById(R.id.Digit8)).setAddressWidget(mAddress); + ((Digit) findViewById(R.id.Digit9)).setAddressWidget(mAddress); + ((Digit) findViewById(R.id.DigitStar)).setAddressWidget(mAddress); + ((Digit) findViewById(R.id.DigitHash)).setAddressWidget(mAddress); + } + mStatus = (TextView) findViewById(R.id.status_label); theDialer = this; @@ -201,44 +206,21 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { } - if (!accountCheckingDone) checkAccountsSettings(); - } - - private void callOrAcceptIncommingCall() { - LinphoneCore lLinphoneCore = LinphoneService.instance().getLinphoneCore(); - if (lLinphoneCore.isInComingInvitePending()) { - try { - lLinphoneCore.acceptCall(lLinphoneCore.getCurrentCall()); - } catch (LinphoneCoreException e) { - lLinphoneCore.terminateCall(lLinphoneCore.getCurrentCall()); - Toast toast = Toast.makeText(DialerActivity.this - ,String.format(getString(R.string.warning_wrong_destination_address),mAddress.getText().toString()) - ,Toast.LENGTH_LONG); - toast.show(); + if (!accountCheckingDone) { + if (mPref.getBoolean(PREF_FIRST_LAUNCH, true)) { + onFirstLaunch(); + } else if (!mPref.getBoolean(PREF_CHECK_CONFIG, false) + && !checkDefined(R.string.pref_username_key, R.string.pref_passwd_key, R.string.pref_domain_key)) { + onBadSettings(); + } else { + accountCheckingDone = true; } - return; - } - if (mAddress.getText().length() >0) { - newOutgoingCall(mAddress.getText().toString(), mAddress.getDisplayedName()); } } - private void initializeDigits() { - if (findViewById(R.id.Digit00) == null) return; // In landscape view, no keyboard - ((Digit) findViewById(R.id.Digit00)).setAddressWidget(mAddress); - ((Digit) findViewById(R.id.Digit1)).setAddressWidget(mAddress); - ((Digit) findViewById(R.id.Digit2)).setAddressWidget(mAddress); - ((Digit) findViewById(R.id.Digit3)).setAddressWidget(mAddress); - ((Digit) findViewById(R.id.Digit4)).setAddressWidget(mAddress); - ((Digit) findViewById(R.id.Digit5)).setAddressWidget(mAddress); - ((Digit) findViewById(R.id.Digit6)).setAddressWidget(mAddress); - ((Digit) findViewById(R.id.Digit7)).setAddressWidget(mAddress); - ((Digit) findViewById(R.id.Digit8)).setAddressWidget(mAddress); - ((Digit) findViewById(R.id.Digit9)).setAddressWidget(mAddress); - ((Digit) findViewById(R.id.DigitStar)).setAddressWidget(mAddress); - ((Digit) findViewById(R.id.DigitHash)).setAddressWidget(mAddress); - } + + private boolean checkDefined(int ... keys) { for (int key : keys) { @@ -249,66 +231,58 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { return true; } + private void onFirstLaunch() { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + TextView lDialogTextView = new TextView(this); + lDialogTextView.setAutoLinkMask(0x0f/*all*/); + lDialogTextView.setPadding(10, 10, 10, 10); - private void checkAccountsSettings() { - if (mPref.getBoolean(PREF_FIRST_LAUNCH, true)) { - // First launch - AlertDialog.Builder builder = new AlertDialog.Builder(this); - TextView lDialogTextView = new TextView(this); - lDialogTextView.setAutoLinkMask(0x0f/*all*/); - lDialogTextView.setPadding(10, 10, 10, 10); + lDialogTextView.setText(Html.fromHtml(getString(R.string.first_launch_message))); - lDialogTextView.setText(Html.fromHtml(getString(R.string.first_launch_message))); + builder.setCustomTitle(lDialogTextView) + .setCancelable(false) + .setPositiveButton(getString(R.string.cont), new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + LinphoneActivity.instance().startprefActivity(); + accountCheckingDone = true; + } + }); - builder.setCustomTitle(lDialogTextView) - .setCancelable(false) - .setPositiveButton(getString(R.string.cont), new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - LinphoneActivity.instance().startprefActivity(); - accountCheckingDone = true; - } - }); - - builder.create().show(); - - - } else if (!mPref.getBoolean(PREF_CHECK_CONFIG, false) - && !checkDefined(R.string.pref_username_key, R.string.pref_passwd_key, R.string.pref_domain_key)) { - // Account not set - - AlertDialog.Builder builder = new AlertDialog.Builder(this); - TextView lDialogTextView = new TextView(this); - lDialogTextView.setAutoLinkMask(0x0f/*all*/); - lDialogTextView.setPadding(10, 10, 10, 10); - - lDialogTextView.setText(Html.fromHtml(getString(R.string.initial_config_error))); - - builder.setCustomTitle(lDialogTextView) - .setCancelable(false) - .setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - LinphoneActivity.instance().startprefActivity(); - accountCheckingDone = true; - } - }).setNeutralButton(getString(R.string.no), new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - dialog.cancel(); - accountCheckingDone = true; - } - }).setNegativeButton(getString(R.string.never_remind), new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - mPref.edit().putBoolean(PREF_CHECK_CONFIG, true).commit(); - dialog.cancel(); - accountCheckingDone = true; - } - }); - - builder.create().show(); - } else { - accountCheckingDone = true; - } + builder.create().show(); } + private void onBadSettings() { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + TextView lDialogTextView = new TextView(this); + lDialogTextView.setAutoLinkMask(0x0f/*all*/); + lDialogTextView.setPadding(10, 10, 10, 10); + + lDialogTextView.setText(Html.fromHtml(getString(R.string.initial_config_error))); + + builder.setCustomTitle(lDialogTextView) + .setCancelable(false) + .setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + LinphoneActivity.instance().startprefActivity(); + accountCheckingDone = true; + } + }).setNeutralButton(getString(R.string.no), new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + dialog.cancel(); + accountCheckingDone = true; + } + }).setNegativeButton(getString(R.string.never_remind), new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + mPref.edit().putBoolean(PREF_CHECK_CONFIG, true).commit(); + dialog.cancel(); + accountCheckingDone = true; + } + }); + + builder.create().show(); + } + + private void updateIncallVideoCallButton() { boolean prefVideoEnabled = mPref.getBoolean(getString(R.string.pref_video_enable_key), false); if (prefVideoEnabled && !mCall.isEnabled()) { @@ -384,13 +358,13 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { public void callState(final LinphoneCore lc,final LinphoneCall call, final State state, final String message) { if (state == LinphoneCall.State.OutgoingInit) { - enterIncalMode(lc); + enterIncallMode(lc); LinphoneManager.getInstance().routeAudioToReceiver(); } else if (state == LinphoneCall.State.IncomingReceived) { - resetCameraFromPreferences(); + LinphoneManager.getInstance().resetCameraFromPreferences(); callPending(call); } else if (state == LinphoneCall.State.Connected) { - enterIncalMode(lc); + enterIncallMode(lc); } else if (state == LinphoneCall.State.Error) { if (mWakeLock.isHeld()) mWakeLock.release(); Toast toast = Toast.makeText(this @@ -401,7 +375,7 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { } else if (state == LinphoneCall.State.CallEnd) { exitCallMode(); } else if (state == LinphoneCall.State.StreamsRunning) { - if (LinphoneService.instance().getLinphoneCore().getCurrentCall().getCurrentParamsCopy().getVideoEnabled()) { + if (LinphoneService.getLc().getCurrentCall().getCurrentParamsCopy().getVideoEnabled()) { if (!VideoCallActivity.launched) { startVideoView(VIDEO_VIEW_ACTIVITY); } @@ -411,7 +385,7 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { public void show(LinphoneCore lc) {/*nop*/} - private void enterIncalMode(LinphoneCore lc) { + private void enterIncallMode(LinphoneCore lc) { mCallControlRow.setVisibility(View.GONE); mInCallControlRow.setVisibility(View.VISIBLE); mAddressLayout.setVisibility(View.GONE); @@ -447,12 +421,6 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { mSpeaker.setSpeakerOn(LinphoneManager.getInstance().isSpeakerOn()); } - private void resetCameraFromPreferences() { - boolean useFrontCam = mPref.getBoolean(getString(R.string.pref_video_use_front_camera_key), false); - getVideoManager().setUseFrontCamera(useFrontCam); - final int phoneOrientation = 90 * getWindowManager().getDefaultDisplay().getOrientation(); - getVideoManager().setPhoneOrientation(phoneOrientation); - } private void exitCallMode() { mCallControlRow.setVisibility(View.VISIBLE); @@ -471,7 +439,7 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { mSpeaker.setSpeakerOn(false); LinphoneManager.getInstance().routeAudioToReceiver(); BandwidthManager.getInstance().setUserRestriction(false); - resetCameraFromPreferences(); + LinphoneManager.getInstance().resetCameraFromPreferences(); LinphoneActivity.instance().stopProxymitySensor(); } @@ -482,53 +450,17 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { // Privacy setting to not share the user camera by default boolean prefVideoEnable = mPref.getBoolean(getString(R.string.pref_video_enable_key), false); boolean prefAutomaticallyShareMyCamera = mPref.getBoolean(getString(R.string.pref_video_automatically_share_my_video_key), false); - getVideoManager().setMuted(!(prefVideoEnable && prefAutomaticallyShareMyCamera)); + AndroidCameraRecordManager.getInstance().setMuted(!(prefVideoEnable && prefAutomaticallyShareMyCamera)); call.enableCamera(prefAutomaticallyShareMyCamera); } public void newOutgoingCall(String aTo) { - newOutgoingCall(aTo,null); + mAddress.setText(aTo); + mAddress.clearDisplayedName(); + LinphoneManager.getInstance().newOutgoingCall(mAddress); } - private synchronized void newOutgoingCall(String aTo, String displayName) { - String lto = aTo; - if (aTo.contains(OutgoingCallReceiver.TAG)) { - lto = aTo.replace(OutgoingCallReceiver.TAG, ""); - } - mAddress.setText(lto); - mAddress.setDisplayedName(displayName); - LinphoneCore lLinphoneCore = LinphoneService.instance().getLinphoneCore(); - if (lLinphoneCore.isIncall()) { - Toast toast = Toast.makeText(DialerActivity.this, getString(R.string.warning_already_incall), Toast.LENGTH_LONG); - toast.show(); - return; - } - LinphoneAddress lAddress; - try { - lAddress = lLinphoneCore.interpretUrl(lto); - } catch (LinphoneCoreException e) { - Toast toast = Toast.makeText(DialerActivity.this - ,String.format(getString(R.string.warning_wrong_destination_address),mAddress.getText().toString()) - , Toast.LENGTH_LONG); - toast.show(); - return; - } - lAddress.setDisplayName(mAddress.getDisplayedName()); - - try { - boolean prefVideoEnable = mPref.getBoolean(getString(R.string.pref_video_enable_key), false); - boolean prefInitiateWithVideo = mPref.getBoolean(getString(R.string.pref_video_initiate_call_with_video_key), false); - resetCameraFromPreferences(); - CallManager.getInstance().inviteAddress(lAddress, prefVideoEnable && prefInitiateWithVideo); - - } catch (LinphoneCoreException e) { - Toast toast = Toast.makeText(DialerActivity.this - ,String.format(getString(R.string.error_cannot_get_call_parameters),mAddress.getText().toString()) - ,Toast.LENGTH_LONG); - toast.show(); - return; - } - } + public void newSubscriptionRequest(LinphoneCore lc, LinphoneFriend lf, String url) {} public void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf) {} @@ -536,9 +468,6 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { LinphoneAddress from, String message) {} - private AndroidCameraRecordManager getVideoManager() { - return AndroidCameraRecordManager.getInstance(); - } public void ecCalibrationStatus(LinphoneCore lc, EcCalibratorStatus status, int delay_ms, Object data) {} @@ -546,6 +475,34 @@ public class DialerActivity extends Activity implements LinphoneCoreListener { mAddress.setText(aContact); mAddress.setDisplayedName(aDisplayName); } + + + public void onAlreadyInVideoCall() { + startVideoView(VIDEO_VIEW_ACTIVITY); + } + + + public void onWrongDestinationAddress() { + Toast toast = Toast.makeText(DialerActivity.this + ,String.format(getString(R.string.warning_wrong_destination_address),mAddress.getText().toString()) + ,Toast.LENGTH_LONG); + toast.show(); + } + + + public void onAlreadyInCall() { + Toast toast = Toast.makeText(DialerActivity.this, getString(R.string.warning_already_incall), Toast.LENGTH_LONG); + toast.show(); + } + + + public void onCannotGetCallParameters() { + Toast toast = Toast.makeText(DialerActivity.this + ,String.format(getString(R.string.error_cannot_get_call_parameters),mAddress.getText().toString()) + ,Toast.LENGTH_LONG); + toast.show(); + + } } diff --git a/src/org/linphone/Hacks.java b/src/org/linphone/Hacks.java index 0c6809048..bfc323d33 100644 --- a/src/org/linphone/Hacks.java +++ b/src/org/linphone/Hacks.java @@ -24,6 +24,8 @@ import android.util.Log; public class Hacks { + private Hacks() {} + public static boolean isGalaxyS() { return Build.DEVICE.startsWith("GT-I9000") || Build.DEVICE.startsWith("GT-P1000"); } diff --git a/src/org/linphone/KeepAliveManager.java b/src/org/linphone/KeepAliveReceiver.java similarity index 94% rename from src/org/linphone/KeepAliveManager.java rename to src/org/linphone/KeepAliveReceiver.java index 3baf685c9..fba931aa3 100644 --- a/src/org/linphone/KeepAliveManager.java +++ b/src/org/linphone/KeepAliveReceiver.java @@ -1,5 +1,5 @@ /* -ContactPickerActivity.java +KeepAliveReceiver.java Copyright (C) 2010 Belledonne Communications, Grenoble, France This program is free software; you can redistribute it and/or @@ -25,7 +25,7 @@ import android.util.Log; -public class KeepAliveManager extends BroadcastReceiver { +public class KeepAliveReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { diff --git a/src/org/linphone/LinphoneException.java b/src/org/linphone/LinphoneException.java index 61bcd1253..cc44df65a 100644 --- a/src/org/linphone/LinphoneException.java +++ b/src/org/linphone/LinphoneException.java @@ -21,22 +21,17 @@ package org.linphone; @SuppressWarnings("serial") public class LinphoneException extends Exception { - public LinphoneException() { - // TODO Auto-generated constructor stub - } + public LinphoneException() {} public LinphoneException(String detailMessage) { super(detailMessage); - // TODO Auto-generated constructor stub } public LinphoneException(Throwable throwable) { super(throwable); - // TODO Auto-generated constructor stub } public LinphoneException(String detailMessage, Throwable throwable) { super(detailMessage, throwable); - // TODO Auto-generated constructor stub } } diff --git a/src/org/linphone/LinphoneManager.java b/src/org/linphone/LinphoneManager.java index 5e9fac29f..a01ccc88f 100644 --- a/src/org/linphone/LinphoneManager.java +++ b/src/org/linphone/LinphoneManager.java @@ -18,17 +18,27 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package org.linphone; +import org.linphone.core.AndroidCameraRecordManager; +import org.linphone.core.LinphoneAddress; import org.linphone.core.LinphoneCore; +import org.linphone.core.LinphoneCoreException; import android.content.SharedPreferences; +import android.content.res.Resources; import android.media.AudioManager; import android.os.Build; +import android.view.WindowManager; public class LinphoneManager { private static LinphoneManager instance; private AudioManager mAudioManager; + private NewOutgoingCallUiListener newOutgoingCallUiListener; + private SharedPreferences mPref; + private Resources mR; + private WindowManager mWindowManager; + private LinphoneManager() {} public void routeAudioToSpeaker() { if (Integer.parseInt(Build.VERSION.SDK) <= 4 /*4 &&mAudioManager.isSpeakerphoneOn(); } + + public void newOutgoingCall(AddressType address) { + String to = address.getText().toString(); + if (to.contains(OutgoingCallReceiver.TAG)) { + to = to.replace(OutgoingCallReceiver.TAG, ""); + address.setText(to); + } + LinphoneCore lLinphoneCore = LinphoneService.instance().getLinphoneCore(); + if (lLinphoneCore.isIncall()) { + newOutgoingCallUiListener.onAlreadyInCall(); + return; + } + LinphoneAddress lAddress; + try { + lAddress = lLinphoneCore.interpretUrl(to); + } catch (LinphoneCoreException e) { + newOutgoingCallUiListener.onWrongDestinationAddress(); + return; + } + lAddress.setDisplayName(address.getDisplayedName()); + + try { + + boolean prefVideoEnable = mPref.getBoolean(mR.getString(R.string.pref_video_enable_key), false); + boolean prefInitiateWithVideo = mPref.getBoolean(mR.getString(R.string.pref_video_initiate_call_with_video_key), false); + resetCameraFromPreferences(); + CallManager.getInstance().inviteAddress(lAddress, prefVideoEnable && prefInitiateWithVideo); + + } catch (LinphoneCoreException e) { + newOutgoingCallUiListener.onCannotGetCallParameters(); + return; + } + } + + + public void resetCameraFromPreferences() { + boolean useFrontCam = mPref.getBoolean(mR.getString(R.string.pref_video_use_front_camera_key), false); + AndroidCameraRecordManager.getInstance().setUseFrontCamera(useFrontCam); + final int phoneOrientation = 90 * mWindowManager.getDefaultDisplay().getOrientation(); + AndroidCameraRecordManager.getInstance().setPhoneOrientation(phoneOrientation); + } + + public void setNewOutgoingCallUiListener(NewOutgoingCallUiListener l) { + this.newOutgoingCallUiListener = l; + } + + public static interface AddressType { + void setText(CharSequence s); + CharSequence getText(); + void setDisplayedName(String s); + String getDisplayedName(); + } + + + public static interface NewOutgoingCallUiListener { + public void onWrongDestinationAddress(); + public void onCannotGetCallParameters(); + public void onAlreadyInCall(); + } + + + public void sendStaticImage(boolean send) { + LinphoneCore lc = LinphoneService.getLc(); + if (lc.isIncall()) { + lc.getCurrentCall().enableCamera(!send); + } + } } diff --git a/src/org/linphone/LinphoneService.java b/src/org/linphone/LinphoneService.java index 071ed4c2e..22628deb2 100644 --- a/src/org/linphone/LinphoneService.java +++ b/src/org/linphone/LinphoneService.java @@ -90,7 +90,7 @@ public class LinphoneService extends Service implements LinphoneCoreListener { LinphoneCall.State mCurrentCallState; Vibrator mVibrator; private AudioManager mAudioManager; - private BroadcastReceiver mKeepAliveMgrReceiver = new KeepAliveManager(); + private BroadcastReceiver mKeepAliveMgrReceiver = new KeepAliveReceiver(); private BroadcastReceiver mOutgoingCallReceiver = null; private Handler mHandler = new Handler() ; diff --git a/src/org/linphone/VideoCallActivity.java b/src/org/linphone/VideoCallActivity.java index e7549e0b1..63cfed8b4 100644 --- a/src/org/linphone/VideoCallActivity.java +++ b/src/org/linphone/VideoCallActivity.java @@ -68,7 +68,7 @@ public class VideoCallActivity extends Activity { recordManager.setSurfaceView(mVideoCaptureView, phoneOrientation); mVideoCaptureView.setZOrderOnTop(true); - if (!recordManager.isMuted()) sendStaticImage(false); + if (!recordManager.isMuted()) LinphoneManager.getInstance().sendStaticImage(false); PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE); mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK|PowerManager.ON_AFTER_RELEASE,"Linphone"); mWakeLock.acquire(); @@ -134,12 +134,7 @@ public class VideoCallActivity extends Activity { return true; } - private void sendStaticImage(boolean send) { - LinphoneCore lc = LinphoneService.getLc(); - if (lc.isIncall()) { - lc.getCurrentCall().enableCamera(!send); - } - } + /** * @param sv capture surface view to resize the layout @@ -167,13 +162,13 @@ public class VideoCallActivity extends Activity { public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.videocall_menu_back_to_dialer: - if (!recordManager.isMuted()) sendStaticImage(true); + if (!recordManager.isMuted()) LinphoneManager.getInstance().sendStaticImage(true); finish(); break; case R.id.videocall_menu_change_resolution: BandwidthManager manager = BandwidthManager.getInstance(); manager.setUserRestriction(!manager.isUserRestriction()); - sendStaticImage(recordManager.isMuted()); + LinphoneManager.getInstance().sendStaticImage(recordManager.isMuted()); rewriteChangeResolutionItem(item); // Resize preview frame @@ -188,7 +183,7 @@ public class VideoCallActivity extends Activity { finish(); break; case R.id.videocall_menu_toggle_camera: - sendStaticImage(recordManager.toggleMute()); + LinphoneManager.getInstance().sendStaticImage(recordManager.toggleMute()); rewriteToggleCameraItem(item); break; case R.id.videocall_menu_switch_camera: diff --git a/src/org/linphone/ui/AddVideoButton.java b/src/org/linphone/ui/AddVideoButton.java new file mode 100644 index 000000000..115fc7cfc --- /dev/null +++ b/src/org/linphone/ui/AddVideoButton.java @@ -0,0 +1,58 @@ +/* +AddVideoButton.java +Copyright (C) 2010 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.ui; + +import org.linphone.CallManager; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.ImageButton; + +public class AddVideoButton extends ImageButton implements OnClickListener { + + private AlreadyInVideoCallListener alreadyInVideoCallListener; + + public AddVideoButton(Context context, AttributeSet attrs) { + super(context, attrs); + setOnClickListener(this); + } + + public void onClick(View v) { + // If no in video call; try to reinvite with video + boolean alreadyInVideoCall = !CallManager.getInstance().reinviteWithVideo(); + if (alreadyInVideoCall && alreadyInVideoCallListener != null) { + // In video call; going back to video call activity + alreadyInVideoCallListener.onAlreadyInVideoCall(); + } + } + + + public void setOnAlreadyInVideoCallListener(AlreadyInVideoCallListener listener) { + this.alreadyInVideoCallListener = listener; + } + + + + public static interface AlreadyInVideoCallListener { + void onAlreadyInVideoCall(); + } + +} diff --git a/src/org/linphone/ui/AddressAwareWidget.java b/src/org/linphone/ui/AddressAwareWidget.java new file mode 100644 index 000000000..5a46cc6db --- /dev/null +++ b/src/org/linphone/ui/AddressAwareWidget.java @@ -0,0 +1,25 @@ +/* +AddressAwareWidget.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.ui; + +public interface AddressAwareWidget { + + void setAddressWidget(AddressText address); + +} diff --git a/src/org/linphone/ui/AddressText.java b/src/org/linphone/ui/AddressText.java index 7c70dcb5a..55faf0bd3 100644 --- a/src/org/linphone/ui/AddressText.java +++ b/src/org/linphone/ui/AddressText.java @@ -18,11 +18,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package org.linphone.ui; +import org.linphone.LinphoneManager.AddressType; + import android.content.Context; import android.util.AttributeSet; import android.widget.EditText; -public class AddressText extends EditText { +public class AddressText extends EditText implements AddressType { private String displayedName; diff --git a/src/org/linphone/ui/CallButton.java b/src/org/linphone/ui/CallButton.java new file mode 100644 index 000000000..e00f3da8a --- /dev/null +++ b/src/org/linphone/ui/CallButton.java @@ -0,0 +1,72 @@ +/* +CallButton.java +Copyright (C) 2010 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.ui; + +import org.linphone.LinphoneManager; +import org.linphone.core.LinphoneCore; +import org.linphone.core.LinphoneCoreException; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.ImageButton; + +public class CallButton extends ImageButton implements OnClickListener, AddressAwareWidget { + + private CallButtonListener callButtonListener; + private AddressText mAddress; + + public CallButton(Context context, AttributeSet attrs) { + super(context, attrs); + setOnClickListener(this); + } + + public void onClick(View v) { + LinphoneCore lc = LinphoneManager.getLc(); + if (lc.isInComingInvitePending()) { + try { + lc.acceptCall(lc.getCurrentCall()); + } catch (LinphoneCoreException e) { + lc.terminateCall(lc.getCurrentCall()); + callButtonListener.onWrongDestinationAddress(); + } + return; + } + if (mAddress.getText().length() >0) { + LinphoneManager.getInstance().newOutgoingCall(mAddress); + } + } + + + + public static interface CallButtonListener { + void onWrongDestinationAddress(); + } + + + public void setCallButtonListerner(CallButtonListener listener) { + callButtonListener = listener; + } + + public void setAddressWidget(AddressText address) { + mAddress = address; + } + +} diff --git a/src/org/linphone/ui/Digit.java b/src/org/linphone/ui/Digit.java index 6e70d7d51..40673c291 100644 --- a/src/org/linphone/ui/Digit.java +++ b/src/org/linphone/ui/Digit.java @@ -25,54 +25,64 @@ import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; +import android.view.View.OnLongClickListener; import android.widget.Button; -public class Digit extends Button { +public class Digit extends Button implements OnLongClickListener, AddressAwareWidget { private AddressText mAddress; - private final void createWidget(Context context, AttributeSet attrs) { - String ns = "http://schemas.android.com/apk/res/android"; - String dtmf = attrs.getAttributeValue(ns, "text"); - DialKeyListener lListener = new DialKeyListener(dtmf); + + @Override + protected void onTextChanged(CharSequence text, int start, int before, + int after) { + super.onTextChanged(text, start, before, after); + + if (text == null || text.length() < 1) return; + + DialKeyListener lListener = new DialKeyListener(); setOnClickListener(lListener); setOnTouchListener(lListener); - if ("0+".equals(dtmf)) { - setOnLongClickListener(new OnLongClickListener() { - public boolean onLongClick(View arg0) { - LinphoneCore lc = LinphoneManager.getLc(); - lc.stopDtmf(); - int lBegin = mAddress.getSelectionStart(); - if (lBegin == -1) { - lBegin = mAddress.getEditableText().length(); - } - if (lBegin >=0) { - mAddress.getEditableText().insert(lBegin,"+"); - } - return true; - } - }); + if ("0+".equals(text)) { + setOnLongClickListener(this); } } + public boolean onLongClick(View arg0) { + // Called if "0+" dtmf + LinphoneCore lc = LinphoneManager.getLc(); + lc.stopDtmf(); + int lBegin = mAddress.getSelectionStart(); + if (lBegin == -1) { + lBegin = mAddress.getEditableText().length(); + } + if (lBegin >=0) { + mAddress.getEditableText().insert(lBegin,"+"); + } + return true; + } + public Digit(Context context, AttributeSet attrs, int style) { super(context, attrs, style); - createWidget(context, attrs); } public Digit(Context context, AttributeSet attrs) { super(context, attrs); - createWidget(context, attrs); } - - - private class DialKeyListener implements OnClickListener ,OnTouchListener { + public Digit(Context context) { + super(context); + } + + + + + private class DialKeyListener implements OnClickListener, OnTouchListener { final CharSequence mKeyCode; boolean mIsDtmfStarted=false; - DialKeyListener(String aKeyCode) { - mKeyCode = aKeyCode.subSequence(0, 1); + DialKeyListener() { + mKeyCode = Digit.this.getText().subSequence(0, 1); } public void onClick(View v) { LinphoneCore lc = LinphoneManager.getLc(); diff --git a/src/org/linphone/ui/HangCallButton.java b/src/org/linphone/ui/HangCallButton.java index 9f51741c2..d2064c82b 100644 --- a/src/org/linphone/ui/HangCallButton.java +++ b/src/org/linphone/ui/HangCallButton.java @@ -1,5 +1,5 @@ /* -SpeakerButton.java +HangCallButton.java Copyright (C) 2010 Belledonne Communications, Grenoble, France This program is free software; you can redistribute it and/or diff --git a/src/org/linphone/ui/MuteMicButton.java b/src/org/linphone/ui/MuteMicButton.java index 50e6f9dbc..090e58cb0 100644 --- a/src/org/linphone/ui/MuteMicButton.java +++ b/src/org/linphone/ui/MuteMicButton.java @@ -19,8 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. package org.linphone.ui; import org.linphone.LinphoneManager; -import org.linphone.component.ToggleImageButton; -import org.linphone.component.ToggleImageButton.OnCheckedChangeListener; +import org.linphone.ui.ToggleImageButton.OnCheckedChangeListener; import android.content.Context; import android.util.AttributeSet; diff --git a/src/org/linphone/ui/SpeakerButton.java b/src/org/linphone/ui/SpeakerButton.java index 14bbb8c3c..e1dbfb631 100644 --- a/src/org/linphone/ui/SpeakerButton.java +++ b/src/org/linphone/ui/SpeakerButton.java @@ -19,8 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. package org.linphone.ui; import org.linphone.LinphoneManager; -import org.linphone.component.ToggleImageButton; -import org.linphone.component.ToggleImageButton.OnCheckedChangeListener; +import org.linphone.ui.ToggleImageButton.OnCheckedChangeListener; import android.content.Context; import android.util.AttributeSet; diff --git a/src/org/linphone/component/ToggleImageButton.java b/src/org/linphone/ui/ToggleImageButton.java similarity index 98% rename from src/org/linphone/component/ToggleImageButton.java rename to src/org/linphone/ui/ToggleImageButton.java index 21cd620f2..d4e61006d 100644 --- a/src/org/linphone/component/ToggleImageButton.java +++ b/src/org/linphone/ui/ToggleImageButton.java @@ -16,7 +16,7 @@ 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.component; +package org.linphone.ui; import android.content.Context; From 58dc345e77e6d5f3aee834b6ac448de8381cf9cc Mon Sep 17 00:00:00 2001 From: Guillaume Beraudo Date: Thu, 17 Feb 2011 15:34:07 +0100 Subject: [PATCH 04/53] Respect user DTMF_TONE_WHEN_DIALING settings value. When not in call and audible tones disalbed, don't call linphoneCore with playdtmf. --- src/org/linphone/LinphoneManager.java | 20 ++++++++++++++++++++ src/org/linphone/LinphoneService.java | 5 ++++- src/org/linphone/ui/Digit.java | 21 ++++++++++----------- 3 files changed, 34 insertions(+), 12 deletions(-) diff --git a/src/org/linphone/LinphoneManager.java b/src/org/linphone/LinphoneManager.java index a01ccc88f..9aeaf4bd9 100644 --- a/src/org/linphone/LinphoneManager.java +++ b/src/org/linphone/LinphoneManager.java @@ -23,10 +23,13 @@ import org.linphone.core.LinphoneAddress; import org.linphone.core.LinphoneCore; import org.linphone.core.LinphoneCoreException; +import android.content.ContentResolver; import android.content.SharedPreferences; import android.content.res.Resources; import android.media.AudioManager; import android.os.Build; +import android.provider.Settings; +import android.provider.Settings.SettingNotFoundException; import android.view.WindowManager; public class LinphoneManager { @@ -163,4 +166,21 @@ public class LinphoneManager { } } + public void playDtmf(char dtmf) { + if (getLc().isIncall()) { + // Play if in call as it will not go to speaker + getLc().playDtmf(dtmf, -1); + return; + } + + ContentResolver r = LinphoneService.instance().getContentResolver(); + try { + if (Settings.System.getInt(r, Settings.System.DTMF_TONE_WHEN_DIALING) == 0) { + // audible touch disabled: don't play + return; + } + } catch (SettingNotFoundException e) {} + + getLc().playDtmf(dtmf, -1); + } } diff --git a/src/org/linphone/LinphoneService.java b/src/org/linphone/LinphoneService.java index 22628deb2..4b84d41f2 100644 --- a/src/org/linphone/LinphoneService.java +++ b/src/org/linphone/LinphoneService.java @@ -30,7 +30,6 @@ import org.linphone.core.LinphoneAuthInfo; import org.linphone.core.LinphoneCall; import org.linphone.core.LinphoneChatRoom; import org.linphone.core.LinphoneCore; -import org.linphone.core.LinphoneCore.EcCalibratorStatus; import org.linphone.core.LinphoneCoreException; import org.linphone.core.LinphoneCoreFactory; import org.linphone.core.LinphoneCoreListener; @@ -38,6 +37,7 @@ import org.linphone.core.LinphoneFriend; import org.linphone.core.LinphoneProxyConfig; import org.linphone.core.PayloadType; import org.linphone.core.LinphoneCall.State; +import org.linphone.core.LinphoneCore.EcCalibratorStatus; import org.linphone.core.LinphoneCore.FirewallPolicy; import org.linphone.core.LinphoneCore.GlobalState; @@ -46,6 +46,7 @@ import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.BroadcastReceiver; +import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; @@ -539,5 +540,7 @@ public class LinphoneService extends Service implements LinphoneCoreListener { } }); } + + } diff --git a/src/org/linphone/ui/Digit.java b/src/org/linphone/ui/Digit.java index 40673c291..8d4547150 100644 --- a/src/org/linphone/ui/Digit.java +++ b/src/org/linphone/ui/Digit.java @@ -81,12 +81,16 @@ public class Digit extends Button implements OnLongClickListener, AddressAwareWi private class DialKeyListener implements OnClickListener, OnTouchListener { final CharSequence mKeyCode; boolean mIsDtmfStarted=false; + DialKeyListener() { mKeyCode = Digit.this.getText().subSequence(0, 1); } + public void onClick(View v) { LinphoneCore lc = LinphoneManager.getLc(); - stopDtmf(); + lc.stopDtmf(); + mIsDtmfStarted =false; + if (lc.isIncall()) { lc.sendDtmf(mKeyCode.charAt(0)); } else { @@ -100,24 +104,19 @@ public class Digit extends Button implements OnLongClickListener, AddressAwareWi mAddress.clearDisplayedName(); } } + public boolean onTouch(View v, MotionEvent event) { + LinphoneCore lc = LinphoneManager.getLc(); if (event.getAction() == MotionEvent.ACTION_DOWN && mIsDtmfStarted ==false) { - LinphoneCore lc = LinphoneManager.getLc(); - lc.playDtmf(mKeyCode.charAt(0), -1); + LinphoneManager.getInstance().playDtmf(mKeyCode.charAt(0)); mIsDtmfStarted=true; } else { if (event.getAction() == MotionEvent.ACTION_UP) - stopDtmf(); + lc.stopDtmf(); + mIsDtmfStarted =false; } return false; } - - private void stopDtmf() { - LinphoneCore lc = LinphoneManager.getLc(); - lc.stopDtmf(); - mIsDtmfStarted =false; - } - }; public void setAddressWidget(AddressText address) { From ef93c28b729a35fd52aeb1d6a6f75adbe1a8b419 Mon Sep 17 00:00:00 2001 From: Guillaume Beraudo Date: Thu, 17 Feb 2011 16:02:44 +0100 Subject: [PATCH 05/53] Moved videocall activity logics to LinphoneManager. --- src/org/linphone/CallManager.java | 2 +- src/org/linphone/LinphoneManager.java | 29 +++++++++++ src/org/linphone/LinphoneService.java | 1 - src/org/linphone/VideoCallActivity.java | 64 +++++++++---------------- 4 files changed, 52 insertions(+), 44 deletions(-) diff --git a/src/org/linphone/CallManager.java b/src/org/linphone/CallManager.java index e0c39abef..63ce9c88d 100644 --- a/src/org/linphone/CallManager.java +++ b/src/org/linphone/CallManager.java @@ -115,6 +115,7 @@ public class CallManager { /** * Update current call, without reinvite. + * The camera will be restarted when mediastreamer chain is recreated and setParameters is called. */ public void updateCall() { LinphoneCore lc = lc(); @@ -122,7 +123,6 @@ public class CallManager { LinphoneCallParams params = lCall.getCurrentParamsCopy(); bm().updateWithProfileSettings(lc, params); lc.updateCall(lCall, null); - } } diff --git a/src/org/linphone/LinphoneManager.java b/src/org/linphone/LinphoneManager.java index 9aeaf4bd9..467bb63e3 100644 --- a/src/org/linphone/LinphoneManager.java +++ b/src/org/linphone/LinphoneManager.java @@ -183,4 +183,33 @@ public class LinphoneManager { getLc().playDtmf(dtmf, -1); } + + + public void changeResolution() { + BandwidthManager manager = BandwidthManager.getInstance(); + manager.setUserRestriction(!manager.isUserRestriction()); + LinphoneManager.getInstance().sendStaticImage(AndroidCameraRecordManager.getInstance().isMuted()); + } + + public void terminateCall() { + LinphoneCore lc = LinphoneService.getLc(); + if (lc.isIncall()) { + lc.terminateCall(lc.getCurrentCall()); + } + } + + /** + * Camera will be restarted when mediastreamer chain is recreated and setParameters is called. + */ + public void switchCamera() { + AndroidCameraRecordManager rm = AndroidCameraRecordManager.getInstance(); + rm.stopVideoRecording(); + rm.toggleUseFrontCamera(); + CallManager.getInstance().updateCall(); + } + + public void toggleCameraMuting() { + AndroidCameraRecordManager rm = AndroidCameraRecordManager.getInstance(); + LinphoneManager.getInstance().sendStaticImage(rm.toggleMute()); + } } diff --git a/src/org/linphone/LinphoneService.java b/src/org/linphone/LinphoneService.java index 4b84d41f2..c4baeb37b 100644 --- a/src/org/linphone/LinphoneService.java +++ b/src/org/linphone/LinphoneService.java @@ -46,7 +46,6 @@ import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.BroadcastReceiver; -import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; diff --git a/src/org/linphone/VideoCallActivity.java b/src/org/linphone/VideoCallActivity.java index 63cfed8b4..6e85ba90d 100644 --- a/src/org/linphone/VideoCallActivity.java +++ b/src/org/linphone/VideoCallActivity.java @@ -46,7 +46,6 @@ public class VideoCallActivity extends Activity { public static boolean launched = false; private WakeLock mWakeLock; private static final int capturePreviewLargestDimension = 150; -// private static final float similarRatio = 0.1f; private int previousPhoneOrientation; private int phoneOrientation; @@ -81,23 +80,17 @@ public class VideoCallActivity extends Activity { ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); } - // Base capture frame on streamed dimensions and orientation. - resizeCapturePreview(mVideoCaptureView, lc.getPreferredVideoSize()); + resizeCapturePreview(mVideoCaptureView); } - private void updateCallIfOrientationChanged() { - if (Version.sdkAbove(8) && previousPhoneOrientation != phoneOrientation) { - CallManager.getInstance().updateCall(); - // camera will be restarted when mediastreamer chain is recreated and setParameters is called - - // Base capture frame on streamed dimensions and orientation. - resizeCapturePreview(mVideoCaptureView, LinphoneService.getLc().getPreferredVideoSize()); - } - } @Override protected void onResume() { - updateCallIfOrientationChanged(); + // Update call if orientation changed + if (Version.sdkAbove(8) && previousPhoneOrientation != phoneOrientation) { + CallManager.getInstance().updateCall(); + resizeCapturePreview(mVideoCaptureView); + } super.onResume(); } @@ -110,6 +103,7 @@ public class VideoCallActivity extends Activity { } } + private void rewriteChangeResolutionItem(MenuItem item) { if (BandwidthManager.getInstance().isUserRestriction()) { item.setTitle(getString(R.string.menu_videocall_change_resolution_when_low_resolution)); @@ -137,15 +131,15 @@ public class VideoCallActivity extends Activity { /** + * Base capture frame on streamed dimensions and orientation. * @param sv capture surface view to resize the layout * @param vs video size from which to calculate the dimensions */ - private void resizeCapturePreview(SurfaceView sv, VideoSize vs) { + private void resizeCapturePreview(SurfaceView sv) { LayoutParams lp = sv.getLayoutParams(); - float newRatio = ratioWidthHeight(vs); + VideoSize vs = LinphoneService.getLc().getPreferredVideoSize(); - // float previewRatio = (float) lp.width / lp.height; -// if (Math.abs((newRatio-previewRatio)/newRatio) < similarRatio) return; + float newRatio = (float) vs.width / vs.height; if (vs.isPortrait()) { lp.height = capturePreviewLargestDimension; @@ -157,43 +151,33 @@ public class VideoCallActivity extends Activity { sv.setLayoutParams(lp); } - + + + @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.videocall_menu_back_to_dialer: - if (!recordManager.isMuted()) LinphoneManager.getInstance().sendStaticImage(true); + if (!recordManager.isMuted()) + LinphoneManager.getInstance().sendStaticImage(true); finish(); break; case R.id.videocall_menu_change_resolution: - BandwidthManager manager = BandwidthManager.getInstance(); - manager.setUserRestriction(!manager.isUserRestriction()); - LinphoneManager.getInstance().sendStaticImage(recordManager.isMuted()); + LinphoneManager.getInstance().changeResolution(); rewriteChangeResolutionItem(item); - - // Resize preview frame - VideoSize newVideoSize = LinphoneService.getLc().getPreferredVideoSize(); - resizeCapturePreview(mVideoCaptureView, newVideoSize); + resizeCapturePreview(mVideoCaptureView); break; case R.id.videocall_menu_terminate_call: - LinphoneCore lc = LinphoneService.getLc(); - if (lc.isIncall()) { - lc.terminateCall(lc.getCurrentCall()); - } + LinphoneManager.getInstance().terminateCall(); finish(); break; case R.id.videocall_menu_toggle_camera: - LinphoneManager.getInstance().sendStaticImage(recordManager.toggleMute()); + LinphoneManager.getInstance().toggleCameraMuting(); rewriteToggleCameraItem(item); break; case R.id.videocall_menu_switch_camera: - recordManager.stopVideoRecording(); - recordManager.toggleUseFrontCamera(); - CallManager.getInstance().updateCall(); - // camera will be restarted when mediastreamer chain is recreated and setParameters is called - - // Base capture frame on streamed dimensions and orientation. - resizeCapturePreview(mVideoCaptureView, LinphoneService.getLc().getPreferredVideoSize()); + LinphoneManager.getInstance().switchCamera(); + resizeCapturePreview(mVideoCaptureView); break; default: Log.e(LinphoneService.TAG, "Unknown menu item ["+item+"]"); @@ -218,8 +202,4 @@ public class VideoCallActivity extends Activity { } - public float ratioWidthHeight(VideoSize vs) { - return (float) vs.width / vs.height; - } - } From de64a0918f42923be2a39b7fb8569ae3fc161cec Mon Sep 17 00:00:00 2001 From: Guillaume Beraudo Date: Thu, 17 Feb 2011 16:26:17 +0100 Subject: [PATCH 06/53] Cleanup. --- src/org/linphone/DialerActivity.java | 29 ++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/org/linphone/DialerActivity.java b/src/org/linphone/DialerActivity.java index 6503b80a3..34097126e 100644 --- a/src/org/linphone/DialerActivity.java +++ b/src/org/linphone/DialerActivity.java @@ -46,12 +46,9 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.media.AudioManager; -import android.media.MediaPlayer; import android.os.Bundle; import android.os.PowerManager; -import android.os.Vibrator; import android.preference.PreferenceManager; -import android.provider.Settings; import android.text.Html; import android.util.Log; import android.view.View; @@ -90,12 +87,10 @@ public class DialerActivity extends Activity implements LinphoneCoreListener, Al private static String CURRENT_DISPLAYNAME = "org.linphone.current-displayname"; static int VIDEO_VIEW_ACTIVITY = 100; - Settings.System mSystemSettings = new Settings.System(); - MediaPlayer mRingerPlayer; - - Vibrator mVibrator; private static boolean accountCheckingDone; + + /** * @return null if not ready yet */ @@ -111,7 +106,6 @@ public class DialerActivity extends Activity implements LinphoneCoreListener, Al AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE); LinphoneManager.getInstance().setUsefullStuff(am, mPref, getWindowManager(), getResources()); PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE); - mVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK|PowerManager.ON_AFTER_RELEASE,"Linphone"); @@ -292,6 +286,9 @@ public class DialerActivity extends Activity implements LinphoneCoreListener, Al mAddVideo.setVisibility(View.GONE); } } + + + @Override public void onSaveInstanceState(Bundle savedInstanceState) { super.onSaveInstanceState(savedInstanceState); @@ -309,6 +306,8 @@ public class DialerActivity extends Activity implements LinphoneCoreListener, Al } mAddress.setDisplayedName(savedInstanceState.getString(CURRENT_DISPLAYNAME)); } + + @Override protected void onDestroy() { super.onDestroy(); @@ -321,6 +320,7 @@ public class DialerActivity extends Activity implements LinphoneCoreListener, Al super.onResume(); } + public void authInfoRequested(LinphoneCore lc, String realm, String username) /*nop*/{} public void byeReceived(LinphoneCore lc, String from) {/*nop*/} public void displayMessage(LinphoneCore lc, String message) {/*nop*/} @@ -355,8 +355,9 @@ public class DialerActivity extends Activity implements LinphoneCoreListener, Al } public void registrationState(final LinphoneCore lc, final LinphoneProxyConfig cfg,final LinphoneCore.RegistrationState state,final String smessage) {/*nop*/}; - public void callState(final LinphoneCore lc,final LinphoneCall call, final State state, final String message) { + + public void callState(final LinphoneCore lc,final LinphoneCall call, final State state, final String message) { if (state == LinphoneCall.State.OutgoingInit) { enterIncallMode(lc); LinphoneManager.getInstance().routeAudioToReceiver(); @@ -416,6 +417,7 @@ public class DialerActivity extends Activity implements LinphoneCoreListener, Al if (!mWakeLock.isHeld()) mWakeLock.acquire(); } + private void loadMicAndSpeakerUiStateFromLibrary() { mMute.setChecked(LinphoneService.getLc().isMicMuted()); mSpeaker.setSpeakerOn(LinphoneManager.getInstance().isSpeakerOn()); @@ -432,7 +434,7 @@ public class DialerActivity extends Activity implements LinphoneCoreListener, Al mHangup.setEnabled(false); setVolumeControlStream(AudioManager.USE_DEFAULT_STREAM_TYPE); mDecline.setEnabled(false); - if (LinphoneService.instance().getLinphoneCore().isVideoEnabled()) { + if (LinphoneService.getLc().isVideoEnabled()) { finishActivity(VIDEO_VIEW_ACTIVITY); } if (mWakeLock.isHeld())mWakeLock.release(); @@ -453,6 +455,7 @@ public class DialerActivity extends Activity implements LinphoneCoreListener, Al AndroidCameraRecordManager.getInstance().setMuted(!(prefVideoEnable && prefAutomaticallyShareMyCamera)); call.enableCamera(prefAutomaticallyShareMyCamera); } + public void newOutgoingCall(String aTo) { mAddress.setText(aTo); mAddress.clearDisplayedName(); @@ -491,7 +494,8 @@ public class DialerActivity extends Activity implements LinphoneCoreListener, Al public void onAlreadyInCall() { - Toast toast = Toast.makeText(DialerActivity.this, getString(R.string.warning_already_incall), Toast.LENGTH_LONG); + Toast toast = Toast.makeText(DialerActivity.this, + getString(R.string.warning_already_incall), Toast.LENGTH_LONG); toast.show(); } @@ -501,8 +505,5 @@ public class DialerActivity extends Activity implements LinphoneCoreListener, Al ,String.format(getString(R.string.error_cannot_get_call_parameters),mAddress.getText().toString()) ,Toast.LENGTH_LONG); toast.show(); - } } - - From d89d9c3a3ba51709fe86ce5988b8cc81a68e0a29 Mon Sep 17 00:00:00 2001 From: Guillaume Beraudo Date: Tue, 22 Feb 2011 14:41:27 +0100 Subject: [PATCH 07/53] Several enhancements: - Fix errors in start/stop linphoneManager - Fix calls to guiListener().xx when null - Fix restart of linphoneManager - Cleanup some useless code - Work on outgoingCallReceiver - Intent CALL_PRIVILEDGED --- AndroidManifest.xml | 117 ++-- src/org/linphone/AboutActivity.java | 2 +- src/org/linphone/BandwidthManager.java | 2 +- src/org/linphone/CallManager.java | 21 +- src/org/linphone/ContactPickerActivity.java | 2 +- src/org/linphone/DialerActivity.java | 486 +++++++------- src/org/linphone/HistoryActivity.java | 12 +- src/org/linphone/KeepAliveReceiver.java | 8 +- src/org/linphone/LinphoneActivity.java | 193 +++--- src/org/linphone/LinphoneManager.java | 584 +++++++++++++++-- .../linphone/LinphonePreferencesActivity.java | 53 +- src/org/linphone/LinphoneService.java | 607 +++++------------- src/org/linphone/NetworkManager.java | 27 +- src/org/linphone/OutgoingCallReceiver.java | 22 +- src/org/linphone/VideoCallActivity.java | 12 +- .../core/AndroidCameraRecordManager.java | 12 +- src/org/linphone/core/LinphoneCoreImpl.java | 6 +- src/org/linphone/core/Version.java | 4 +- src/org/linphone/ui/AddVideoButton.java | 4 +- src/org/linphone/ui/CallButton.java | 17 +- src/org/linphone/ui/Digit.java | 2 +- 21 files changed, 1218 insertions(+), 975 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index b176dff05..c44111fef 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -3,24 +3,88 @@ package="org.linphone" android:versionCode="1103" android:versionName="1.1.3" android:installLocation="auto"> - + + + + - + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -128,8 +149,6 @@ - - diff --git a/src/org/linphone/AboutActivity.java b/src/org/linphone/AboutActivity.java index 290d82656..e01c5086e 100644 --- a/src/org/linphone/AboutActivity.java +++ b/src/org/linphone/AboutActivity.java @@ -35,7 +35,7 @@ public class AboutActivity extends Activity { try { aboutText.setText(String.format(getString(R.string.about_text), getPackageManager().getPackageInfo(getPackageName(), 0).versionName)); } catch (NameNotFoundException e) { - Log.e(LinphoneService.TAG, "cannot get version name", e); + Log.e(LinphoneManager.TAG, "cannot get version name", e); } } diff --git a/src/org/linphone/BandwidthManager.java b/src/org/linphone/BandwidthManager.java index 2ebf5d112..9d0bb5bb0 100644 --- a/src/org/linphone/BandwidthManager.java +++ b/src/org/linphone/BandwidthManager.java @@ -65,7 +65,7 @@ public class BandwidthManager { } private void onProfileChanged(int newProfile) { - LinphoneCore lc = LinphoneService.instance().getLinphoneCore(); + LinphoneCore lc = LinphoneManager.getLc(); lc.setUploadBandwidth(bandwidthes[newProfile][0]); lc.setDownloadBandwidth(bandwidthes[newProfile][1]); diff --git a/src/org/linphone/CallManager.java b/src/org/linphone/CallManager.java index 63ce9c88d..a1e9a3feb 100644 --- a/src/org/linphone/CallManager.java +++ b/src/org/linphone/CallManager.java @@ -31,7 +31,7 @@ import org.linphone.core.LinphoneCoreException; * @author Guillaume Beraudo * */ -public class CallManager { +class CallManager { private static CallManager instance; @@ -41,9 +41,6 @@ public class CallManager { return instance; } - private LinphoneCore lc() { - return LinphoneService.instance().getLinphoneCore(); - } private AndroidCameraRecordManager videoManager() { return AndroidCameraRecordManager.getInstance(); } @@ -54,8 +51,8 @@ public class CallManager { - public void inviteAddress(LinphoneAddress lAddress, boolean videoEnabled) throws LinphoneCoreException { - LinphoneCore lc = lc(); + void inviteAddress(LinphoneAddress lAddress, boolean videoEnabled) throws LinphoneCoreException { + LinphoneCore lc = LinphoneManager.getLc(); LinphoneCallParams params = lc.createDefaultCallParameters(); bm().updateWithProfileSettings(lc, params); @@ -79,8 +76,8 @@ public class CallManager { * or if the bandwidth settings are too low. * @return if updateCall called */ - public boolean reinviteWithVideo() { - LinphoneCore lc = lc(); + boolean reinviteWithVideo() { + LinphoneCore lc = LinphoneManager.getLc(); LinphoneCall lCall = lc.getCurrentCall(); LinphoneCallParams params = lCall.getCurrentParamsCopy(); @@ -105,8 +102,8 @@ public class CallManager { /** * Re-invite with parameters updated from profile. */ - public void reinvite() { - LinphoneCore lc = lc(); + void reinvite() { + LinphoneCore lc = LinphoneManager.getLc(); LinphoneCall lCall = lc.getCurrentCall(); LinphoneCallParams params = lCall.getCurrentParamsCopy(); bm().updateWithProfileSettings(lc, params); @@ -117,8 +114,8 @@ public class CallManager { * Update current call, without reinvite. * The camera will be restarted when mediastreamer chain is recreated and setParameters is called. */ - public void updateCall() { - LinphoneCore lc = lc(); + void updateCall() { + LinphoneCore lc = LinphoneManager.getLc(); LinphoneCall lCall = lc.getCurrentCall(); LinphoneCallParams params = lCall.getCurrentParamsCopy(); bm().updateWithProfileSettings(lc, params); diff --git a/src/org/linphone/ContactPickerActivity.java b/src/org/linphone/ContactPickerActivity.java index ad3d0392d..99604ef6c 100644 --- a/src/org/linphone/ContactPickerActivity.java +++ b/src/org/linphone/ContactPickerActivity.java @@ -63,7 +63,7 @@ public class ContactPickerActivity extends Activity { // Get the field values lName = lCur.getString(lCur.getColumnIndex(People.NAME)); lPhoneNo = lCur.getString(lCur.getColumnIndex(People.NUMBER)); - DialerActivity.getDialer().setContactAddress(lPhoneNo, lName); + DialerActivity.instance().setContactAddress(lPhoneNo, lName); } } diff --git a/src/org/linphone/DialerActivity.java b/src/org/linphone/DialerActivity.java index 34097126e..03181ef68 100644 --- a/src/org/linphone/DialerActivity.java +++ b/src/org/linphone/DialerActivity.java @@ -19,16 +19,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. package org.linphone; import org.linphone.LinphoneManager.NewOutgoingCallUiListener; +import org.linphone.LinphoneService.LinphoneGuiListener; import org.linphone.core.AndroidCameraRecordManager; -import org.linphone.core.LinphoneAddress; import org.linphone.core.LinphoneCall; -import org.linphone.core.LinphoneChatRoom; import org.linphone.core.LinphoneCore; -import org.linphone.core.LinphoneCoreListener; -import org.linphone.core.LinphoneFriend; -import org.linphone.core.LinphoneProxyConfig; import org.linphone.core.LinphoneCall.State; -import org.linphone.core.LinphoneCore.EcCalibratorStatus; import org.linphone.ui.AddVideoButton; import org.linphone.ui.AddressText; import org.linphone.ui.CallButton; @@ -37,7 +32,6 @@ import org.linphone.ui.EraseButton; import org.linphone.ui.MuteMicButton; import org.linphone.ui.SpeakerButton; import org.linphone.ui.AddVideoButton.AlreadyInVideoCallListener; -import org.linphone.ui.CallButton.CallButtonListener; import android.app.Activity; import android.app.AlertDialog; @@ -57,7 +51,19 @@ import android.widget.TableRow; import android.widget.TextView; import android.widget.Toast; -public class DialerActivity extends Activity implements LinphoneCoreListener, AlreadyInVideoCallListener, CallButtonListener, NewOutgoingCallUiListener { +/** + * + * Dialer and main activity of Linphone Android. + * + * Roles are:
    + *
  • Display the numpad, call/accept, address buttons
  • + *
  • Define preferences through the menu
  • + *
  • React to bad preference / no account set
  • + *
  • Manage first launch
  • + *
+ * + */ +public class DialerActivity extends Activity implements LinphoneGuiListener, AlreadyInVideoCallListener, NewOutgoingCallUiListener { private AddressText mAddress; private TextView mDisplayNameView; @@ -75,7 +81,7 @@ public class DialerActivity extends Activity implements LinphoneCoreListener, Al private View mAddressLayout; private View mInCallAddressLayout; - private static DialerActivity theDialer; + private static DialerActivity instance; private PowerManager.WakeLock mWakeLock; private SharedPreferences mPref; @@ -87,68 +93,68 @@ public class DialerActivity extends Activity implements LinphoneCoreListener, Al private static String CURRENT_DISPLAYNAME = "org.linphone.current-displayname"; static int VIDEO_VIEW_ACTIVITY = 100; - private static boolean accountCheckingDone; + private static boolean checkAccount = true; /** * @return null if not ready yet */ - public static DialerActivity getDialer() { - return theDialer; + public static DialerActivity instance() { + return instance; } public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.dialer); - mPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); - AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE); - LinphoneManager.getInstance().setUsefullStuff(am, mPref, getWindowManager(), getResources()); + + // Don't use Linphone Manager in the onCreate as it takes time in LinphoneService to initialize it. + + mPref = PreferenceManager.getDefaultSharedPreferences(this); PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE); mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK|PowerManager.ON_AFTER_RELEASE,"Linphone"); + + mAddress = (AddressText) findViewById(R.id.SipUri); + mDisplayNameView = (TextView) findViewById(R.id.DisplayNameView); + ((EraseButton) findViewById(R.id.Erase)).setAddressView(mAddress); + + + mAddVideo = (AddVideoButton) findViewById(R.id.AddVideo); + mAddVideo.setOnAlreadyInVideoCallListener(this); + + + mCall = (CallButton) findViewById(R.id.Call); + mCall.setAddressWidget(mAddress); + + + mDecline= findViewById(R.id.Decline); + mDecline.setEnabled(false); + + + mHangup = findViewById(R.id.HangUp); + + + mCallControlRow = (LinearLayout) findViewById(R.id.CallControlRow); + mAddressLayout = (View) findViewById(R.id.Addresslayout); + + mInCallControlRow = (TableRow) findViewById(R.id.IncallControlRow); + mInCallControlRow.setVisibility(View.GONE); + mInCallAddressLayout = (View) findViewById(R.id.IncallAddressLayout); + mInCallAddressLayout.setVisibility(View.GONE); + mMute = (MuteMicButton)findViewById(R.id.mic_mute_button); + mSpeaker = (SpeakerButton)findViewById(R.id.speaker_button); + + try { - mAddress = (AddressText) findViewById(R.id.SipUri); - mDisplayNameView = (TextView) findViewById(R.id.DisplayNameView); - ((EraseButton) findViewById(R.id.Erase)).setAddressView(mAddress); - - mAddVideo = (AddVideoButton) findViewById(R.id.AddVideo); - mAddVideo.setOnAlreadyInVideoCallListener(this); + outgoingCallIntentReceived(); - - - mCall = (CallButton) findViewById(R.id.Call); - mCall.setCallButtonListerner(this); - mCall.setAddressWidget(mAddress); - - mDecline= findViewById(R.id.Decline); - mDecline.setEnabled(false); - - mHangup = findViewById(R.id.HangUp); - - - mCallControlRow = (LinearLayout) findViewById(R.id.CallControlRow); - mAddressLayout = (View) findViewById(R.id.Addresslayout); - - mInCallControlRow = (TableRow) findViewById(R.id.IncallControlRow); - mInCallControlRow.setVisibility(View.GONE); - mInCallAddressLayout = (View) findViewById(R.id.IncallAddressLayout); - mInCallAddressLayout.setVisibility(View.GONE); - mMute = (MuteMicButton)findViewById(R.id.mic_mute_button); - mSpeaker = (SpeakerButton)findViewById(R.id.speaker_button); - - - if (LinphoneService.isready() && getIntent().getData() != null && !LinphoneService.getLc().isIncall()) { - newOutgoingCall(getIntent().getData().toString().substring("tel://".length())); - getIntent().setData(null); - } - - if (LinphoneService.isready()) { - LinphoneCore lc = LinphoneService.getLc(); + if (LinphoneService.isReady()) { + LinphoneCore lc = LinphoneManager.getLc(); if (lc.isIncall()) { if(lc.isInComingInvitePending()) { callPending(lc.getCurrentCall()); @@ -160,54 +166,47 @@ public class DialerActivity extends Activity implements LinphoneCoreListener, Al mInCallControlRow.setVisibility(View.VISIBLE); mAddressLayout.setVisibility(View.GONE); mInCallAddressLayout.setVisibility(View.VISIBLE); - - String DisplayName = lc.getRemoteAddress().getDisplayName(); - if (DisplayName!=null) { - mDisplayNameView.setText(DisplayName); - } else { - mDisplayNameView.setText(lc.getRemoteAddress().getUserName()); - } - loadMicAndSpeakerUiStateFromLibrary(); + mDisplayNameView.setText(LinphoneManager.getInstance().extractADisplayName()); + loadMicAndSpeakerUiStateFromManager(); LinphoneActivity.instance().startProxymitySensor(); mWakeLock.acquire(); } } } - - if (findViewById(R.id.Digit00) != null) { // In landscape view, no keyboard - ((Digit) findViewById(R.id.Digit00)).setAddressWidget(mAddress); - ((Digit) findViewById(R.id.Digit1)).setAddressWidget(mAddress); - ((Digit) findViewById(R.id.Digit2)).setAddressWidget(mAddress); - ((Digit) findViewById(R.id.Digit3)).setAddressWidget(mAddress); - ((Digit) findViewById(R.id.Digit4)).setAddressWidget(mAddress); - ((Digit) findViewById(R.id.Digit5)).setAddressWidget(mAddress); - ((Digit) findViewById(R.id.Digit6)).setAddressWidget(mAddress); - ((Digit) findViewById(R.id.Digit7)).setAddressWidget(mAddress); - ((Digit) findViewById(R.id.Digit8)).setAddressWidget(mAddress); - ((Digit) findViewById(R.id.Digit9)).setAddressWidget(mAddress); - ((Digit) findViewById(R.id.DigitStar)).setAddressWidget(mAddress); - ((Digit) findViewById(R.id.DigitHash)).setAddressWidget(mAddress); - } - - - mStatus = (TextView) findViewById(R.id.status_label); - theDialer = this; + instance = this; } catch (Exception e) { - Log.e(LinphoneService.TAG,"Cannot start linphone",e); + Log.e(LinphoneManager.TAG,"Cannot start linphone",e); finish(); } - if (!accountCheckingDone) { + if (findViewById(R.id.Digit00) != null) { // In landscape view, no keyboard + ((Digit) findViewById(R.id.Digit00)).setAddressWidget(mAddress); + ((Digit) findViewById(R.id.Digit1)).setAddressWidget(mAddress); + ((Digit) findViewById(R.id.Digit2)).setAddressWidget(mAddress); + ((Digit) findViewById(R.id.Digit3)).setAddressWidget(mAddress); + ((Digit) findViewById(R.id.Digit4)).setAddressWidget(mAddress); + ((Digit) findViewById(R.id.Digit5)).setAddressWidget(mAddress); + ((Digit) findViewById(R.id.Digit6)).setAddressWidget(mAddress); + ((Digit) findViewById(R.id.Digit7)).setAddressWidget(mAddress); + ((Digit) findViewById(R.id.Digit8)).setAddressWidget(mAddress); + ((Digit) findViewById(R.id.Digit9)).setAddressWidget(mAddress); + ((Digit) findViewById(R.id.DigitStar)).setAddressWidget(mAddress); + ((Digit) findViewById(R.id.DigitHash)).setAddressWidget(mAddress); + } + mStatus = (TextView) findViewById(R.id.status_label); + + + if (checkAccount) { if (mPref.getBoolean(PREF_FIRST_LAUNCH, true)) { onFirstLaunch(); } else if (!mPref.getBoolean(PREF_CHECK_CONFIG, false) && !checkDefined(R.string.pref_username_key, R.string.pref_passwd_key, R.string.pref_domain_key)) { onBadSettings(); } else { - accountCheckingDone = true; + checkAccount = false; } } } @@ -215,7 +214,20 @@ public class DialerActivity extends Activity implements LinphoneCoreListener, Al + private void outgoingCallIntentReceived() { + if (getIntent().getData() == null) return; + if (!LinphoneService.isReady() || LinphoneManager.getLc().isIncall()) { + Log.w(LinphoneManager.TAG, "Outgoing call aborted as LinphoneService" + + " is not ready or we are already in call"); + return; + } + + newOutgoingCall(getIntent()); + } + + + /***** Check Account *******/ private boolean checkDefined(int ... keys) { for (int key : keys) { String conf = mPref.getString(getString(key), null); @@ -238,7 +250,7 @@ public class DialerActivity extends Activity implements LinphoneCoreListener, Al .setPositiveButton(getString(R.string.cont), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { LinphoneActivity.instance().startprefActivity(); - accountCheckingDone = true; + checkAccount = false; } }); @@ -258,18 +270,18 @@ public class DialerActivity extends Activity implements LinphoneCoreListener, Al .setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { LinphoneActivity.instance().startprefActivity(); - accountCheckingDone = true; + checkAccount = false; } }).setNeutralButton(getString(R.string.no), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { dialog.cancel(); - accountCheckingDone = true; + checkAccount = false; } }).setNegativeButton(getString(R.string.never_remind), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { mPref.edit().putBoolean(PREF_CHECK_CONFIG, true).commit(); dialog.cancel(); - accountCheckingDone = true; + checkAccount = false; } }); @@ -277,22 +289,16 @@ public class DialerActivity extends Activity implements LinphoneCoreListener, Al } - private void updateIncallVideoCallButton() { - boolean prefVideoEnabled = mPref.getBoolean(getString(R.string.pref_video_enable_key), false); - if (prefVideoEnabled && !mCall.isEnabled()) { - mAddVideo.setVisibility(View.VISIBLE); - mAddVideo.setEnabled(true); - } else { - mAddVideo.setVisibility(View.GONE); - } - } + + + @Override public void onSaveInstanceState(Bundle savedInstanceState) { super.onSaveInstanceState(savedInstanceState); - savedInstanceState.putString(CURRENT_ADDRESS, mAddress.getText().toString()); + savedInstanceState.putCharSequence(CURRENT_ADDRESS, mAddress.getText()); if (mAddress.getDisplayedName() != null) savedInstanceState.putString(CURRENT_DISPLAYNAME,mAddress.getDisplayedName()); } @@ -300,7 +306,7 @@ public class DialerActivity extends Activity implements LinphoneCoreListener, Al @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); - String lAddress = savedInstanceState.getString(CURRENT_ADDRESS); + CharSequence lAddress = savedInstanceState.getCharSequence(CURRENT_ADDRESS); if (lAddress != null && mAddress != null) { mAddress.setText(lAddress); } @@ -312,7 +318,7 @@ public class DialerActivity extends Activity implements LinphoneCoreListener, Al protected void onDestroy() { super.onDestroy(); if (mWakeLock.isHeld()) mWakeLock.release(); - theDialer=null; + instance=null; } @Override @@ -321,32 +327,10 @@ public class DialerActivity extends Activity implements LinphoneCoreListener, Al } - public void authInfoRequested(LinphoneCore lc, String realm, String username) /*nop*/{} - public void byeReceived(LinphoneCore lc, String from) {/*nop*/} - public void displayMessage(LinphoneCore lc, String message) {/*nop*/} - public void displayWarning(LinphoneCore lc, String message) {/*nop*/} - public void displayStatus(LinphoneCore lc, String message) { - mStatus.setText(message); - } - public void globalState(LinphoneCore lc, LinphoneCore.GlobalState state, String message) { - if (state == LinphoneCore.GlobalState.GlobalOn) { - mCall.setEnabled(!lc.isIncall()); - mHangup.setEnabled(!mCall.isEnabled()); - updateIncallVideoCallButton(); - try{ - LinphoneService.instance().initFromConf(); - } catch (Exception e) { - Log.e(LinphoneService.TAG,"Cannot get initial config", e); - } - if (getIntent().getData() != null) { - newOutgoingCall(getIntent().getData().toString().substring("tel://".length())); - getIntent().setData(null); - } - } - } + private void startVideoView(int requestCode) { Intent lIntent = new Intent(); @@ -354,10 +338,132 @@ public class DialerActivity extends Activity implements LinphoneCoreListener, Al startActivityForResult(lIntent,requestCode); } - public void registrationState(final LinphoneCore lc, final LinphoneProxyConfig cfg,final LinphoneCore.RegistrationState state,final String smessage) {/*nop*/}; + + private void enterIncallMode(LinphoneCore lc) { + LinphoneManager m = LinphoneManager.getInstance(); + mCallControlRow.setVisibility(View.GONE); + mInCallControlRow.setVisibility(View.VISIBLE); + mAddressLayout.setVisibility(View.GONE); + mInCallAddressLayout.setVisibility(View.VISIBLE); + mCall.setEnabled(false); + updateIncallVideoCallButton(); + mHangup.setEnabled(true); + mDisplayNameView.setText(m.extractADisplayName()); + + loadMicAndSpeakerUiStateFromManager(); + setVolumeControlStream(AudioManager.STREAM_VOICE_CALL); + + LinphoneActivity.instance().startProxymitySensor(); + if (!mWakeLock.isHeld()) mWakeLock.acquire(); + + } + + + private void updateIncallVideoCallButton() { + boolean prefVideoEnabled = LinphoneManager.getInstance().isVideoEnabled(); + if (prefVideoEnabled && !mCall.isEnabled()) { + mAddVideo.setVisibility(View.VISIBLE); + mAddVideo.setEnabled(true); + } else { + mAddVideo.setVisibility(View.GONE); + } + } - public void callState(final LinphoneCore lc,final LinphoneCall call, final State state, final String message) { + private void loadMicAndSpeakerUiStateFromManager() { + mMute.setChecked(LinphoneManager.getLc().isMicMuted()); + mSpeaker.setSpeakerOn(LinphoneManager.getInstance().isSpeakerOn()); + } + + + private void exitCallMode() { + mCallControlRow.setVisibility(View.VISIBLE); + mInCallControlRow.setVisibility(View.GONE); + mAddressLayout.setVisibility(View.VISIBLE); + mInCallAddressLayout.setVisibility(View.GONE); + mCall.setEnabled(true); + updateIncallVideoCallButton(); + mHangup.setEnabled(false); + setVolumeControlStream(AudioManager.USE_DEFAULT_STREAM_TYPE); + mDecline.setEnabled(false); + if (LinphoneManager.getLc().isVideoEnabled()) { + finishActivity(VIDEO_VIEW_ACTIVITY); + } + if (mWakeLock.isHeld())mWakeLock.release(); + mSpeaker.setSpeakerOn(false); + + BandwidthManager.getInstance().setUserRestriction(false); + LinphoneManager.getInstance().resetCameraFromPreferences(); + LinphoneActivity.instance().stopProxymitySensor(); + } + + private void callPending(LinphoneCall call) { + mDecline.setEnabled(true); + + // Privacy setting to not share the user camera by default + boolean prefVideoEnable = LinphoneManager.getInstance().isVideoEnabled(); + boolean prefAutomaticallyShareMyCamera = mPref.getBoolean(getString(R.string.pref_video_automatically_share_my_video_key), false); + AndroidCameraRecordManager.getInstance().setMuted(!(prefVideoEnable && prefAutomaticallyShareMyCamera)); + call.enableCamera(prefAutomaticallyShareMyCamera); + } + + + + + + public void newOutgoingCall(Intent intent) { + mAddress.setText(intent.getData().toString().substring("tel:".length())); + mAddress.clearDisplayedName(); + intent.setData(null); + + LinphoneManager.getInstance().newOutgoingCall(mAddress); + } + + + public void setContactAddress(String aContact,String aDisplayName) { + mAddress.setText(aContact); + mAddress.setDisplayedName(aDisplayName); + } + + + + + + + /***** GUI delegates for listener LinphoneServiceListener *************/ + public void onDisplayStatus(String message) { + mStatus.setText(message); + } + + public void onAlreadyInVideoCall() { + startVideoView(VIDEO_VIEW_ACTIVITY); + } + + public void onAlreadyInCall() { + Toast toast = Toast.makeText(this, + getString(R.string.warning_already_incall), Toast.LENGTH_LONG); + toast.show(); + } + + + public void onCannotGetCallParameters() { + Toast toast = Toast.makeText(this + ,String.format(getString(R.string.error_cannot_get_call_parameters),mAddress.getText().toString()) + ,Toast.LENGTH_LONG); + toast.show(); + } + + + public void onWrongDestinationAddress() { + Toast toast = Toast.makeText(this + ,String.format(getResources().getString(R.string.warning_wrong_destination_address),mAddress.getText().toString()) + ,Toast.LENGTH_LONG); + toast.show(); + } + + + public void onCallStateChanged(LinphoneCall call, State state, String message) { + LinphoneCore lc = LinphoneManager.getLc(); if (state == LinphoneCall.State.OutgoingInit) { enterIncallMode(lc); LinphoneManager.getInstance().routeAudioToReceiver(); @@ -376,134 +482,30 @@ public class DialerActivity extends Activity implements LinphoneCoreListener, Al } else if (state == LinphoneCall.State.CallEnd) { exitCallMode(); } else if (state == LinphoneCall.State.StreamsRunning) { - if (LinphoneService.getLc().getCurrentCall().getCurrentParamsCopy().getVideoEnabled()) { + if (LinphoneManager.getLc().getCurrentCall().getCurrentParamsCopy().getVideoEnabled()) { if (!VideoCallActivity.launched) { startVideoView(VIDEO_VIEW_ACTIVITY); } } - } + } } - public void show(LinphoneCore lc) {/*nop*/} - - private void enterIncallMode(LinphoneCore lc) { - mCallControlRow.setVisibility(View.GONE); - mInCallControlRow.setVisibility(View.VISIBLE); - mAddressLayout.setVisibility(View.GONE); - mInCallAddressLayout.setVisibility(View.VISIBLE); - mCall.setEnabled(false); + + public void onGlobalStateChangedToOn(String message) { + mCall.setEnabled(!LinphoneManager.getLc().isIncall()); + mHangup.setEnabled(!mCall.isEnabled()); updateIncallVideoCallButton(); - mHangup.setEnabled(true); - LinphoneAddress remote=lc.getRemoteAddress(); - if (remote!=null){ - String DisplayName = remote.getDisplayName(); - if (DisplayName!=null) { - mDisplayNameView.setText(DisplayName); - } else if (lc.getRemoteAddress().getUserName() != null){ - mDisplayNameView.setText(lc.getRemoteAddress().getUserName()); - } else { - mDisplayNameView.setText(lc.getRemoteAddress().toString()); - } + + try{ + LinphoneManager.getInstance().initFromConf(this); + } catch (LinphoneConfigException e) { + Log.w(LinphoneManager.TAG, "Cannot get initial config : " + e.getMessage()); + } catch (Exception e) { + Log.e(LinphoneManager.TAG, "Cannot get initial config", e); } - loadMicAndSpeakerUiStateFromLibrary(); - - if (mSpeaker.isSpeakerOn()) { - LinphoneManager.getInstance().routeAudioToSpeaker(); - } else { - LinphoneManager.getInstance().routeAudioToReceiver(); + + if (getIntent().getData() != null) { + outgoingCallIntentReceived(); } - setVolumeControlStream(AudioManager.STREAM_VOICE_CALL); - LinphoneActivity.instance().startProxymitySensor(); - if (!mWakeLock.isHeld()) mWakeLock.acquire(); - - } - - private void loadMicAndSpeakerUiStateFromLibrary() { - mMute.setChecked(LinphoneService.getLc().isMicMuted()); - mSpeaker.setSpeakerOn(LinphoneManager.getInstance().isSpeakerOn()); - } - - - private void exitCallMode() { - mCallControlRow.setVisibility(View.VISIBLE); - mInCallControlRow.setVisibility(View.GONE); - mAddressLayout.setVisibility(View.VISIBLE); - mInCallAddressLayout.setVisibility(View.GONE); - mCall.setEnabled(true); - updateIncallVideoCallButton(); - mHangup.setEnabled(false); - setVolumeControlStream(AudioManager.USE_DEFAULT_STREAM_TYPE); - mDecline.setEnabled(false); - if (LinphoneService.getLc().isVideoEnabled()) { - finishActivity(VIDEO_VIEW_ACTIVITY); - } - if (mWakeLock.isHeld())mWakeLock.release(); - mSpeaker.setSpeakerOn(false); - LinphoneManager.getInstance().routeAudioToReceiver(); - BandwidthManager.getInstance().setUserRestriction(false); - LinphoneManager.getInstance().resetCameraFromPreferences(); - LinphoneActivity.instance().stopProxymitySensor(); - } - - private void callPending(LinphoneCall call) { - mDecline.setEnabled(true); - //routeAudioToSpeaker(); - - // Privacy setting to not share the user camera by default - boolean prefVideoEnable = mPref.getBoolean(getString(R.string.pref_video_enable_key), false); - boolean prefAutomaticallyShareMyCamera = mPref.getBoolean(getString(R.string.pref_video_automatically_share_my_video_key), false); - AndroidCameraRecordManager.getInstance().setMuted(!(prefVideoEnable && prefAutomaticallyShareMyCamera)); - call.enableCamera(prefAutomaticallyShareMyCamera); - } - - public void newOutgoingCall(String aTo) { - mAddress.setText(aTo); - mAddress.clearDisplayedName(); - LinphoneManager.getInstance().newOutgoingCall(mAddress); - } - - - - - public void newSubscriptionRequest(LinphoneCore lc, LinphoneFriend lf, String url) {} - public void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf) {} - public void textReceived(LinphoneCore lc, LinphoneChatRoom cr, - LinphoneAddress from, String message) {} - - - public void ecCalibrationStatus(LinphoneCore lc, EcCalibratorStatus status, - int delay_ms, Object data) {} - - public void setContactAddress(String aContact,String aDisplayName) { - mAddress.setText(aContact); - mAddress.setDisplayedName(aDisplayName); - } - - - public void onAlreadyInVideoCall() { - startVideoView(VIDEO_VIEW_ACTIVITY); - } - - - public void onWrongDestinationAddress() { - Toast toast = Toast.makeText(DialerActivity.this - ,String.format(getString(R.string.warning_wrong_destination_address),mAddress.getText().toString()) - ,Toast.LENGTH_LONG); - toast.show(); - } - - - public void onAlreadyInCall() { - Toast toast = Toast.makeText(DialerActivity.this, - getString(R.string.warning_already_incall), Toast.LENGTH_LONG); - toast.show(); - } - - - public void onCannotGetCallParameters() { - Toast toast = Toast.makeText(DialerActivity.this - ,String.format(getString(R.string.error_cannot_get_call_parameters),mAddress.getText().toString()) - ,Toast.LENGTH_LONG); - toast.show(); } } diff --git a/src/org/linphone/HistoryActivity.java b/src/org/linphone/HistoryActivity.java index 6b931cd3c..86eb2bc82 100644 --- a/src/org/linphone/HistoryActivity.java +++ b/src/org/linphone/HistoryActivity.java @@ -59,9 +59,9 @@ public class HistoryActivity extends ListActivity { TextView lSecondLineView = (TextView) v.findViewById(R.id.history_cell_second_line); if (lSecondLineView.getVisibility() == View.GONE) { // no display name - DialerActivity.getDialer().setContactAddress(lFirstLineView.getText().toString(), null); + DialerActivity.instance().setContactAddress(lFirstLineView.getText().toString(), null); } else { - DialerActivity.getDialer().setContactAddress(lSecondLineView.getText().toString() + DialerActivity.instance().setContactAddress(lSecondLineView.getText().toString() ,lFirstLineView.getText().toString()); } LinphoneActivity.instance().getTabHost().setCurrentTabByTag(LinphoneActivity.DIALER_TAB); @@ -86,12 +86,12 @@ public class HistoryActivity extends ListActivity { public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.menu_clear_history: - LinphoneService.instance().getLinphoneCore().clearCallLogs(); + LinphoneManager.getLc().clearCallLogs(); setListAdapter(new CallHistoryAdapter(this)); break; default: - Log.e(LinphoneService.TAG, "Unknown menu item ["+item+"]"); + Log.e(LinphoneManager.TAG, "Unknown menu item ["+item+"]"); break; } @@ -102,7 +102,7 @@ public class HistoryActivity extends ListActivity { class CallHistoryAdapter extends BaseAdapter { final List mLogs; CallHistoryAdapter(Context aContext) { - mLogs = LinphoneService.instance().getLinphoneCore().getCallLogs(); + mLogs = LinphoneManager.getLc().getCallLogs(); } public int getCount() { return mLogs.size(); @@ -142,7 +142,7 @@ public class HistoryActivity extends ListActivity { lDirectionImageIn.setVisibility(View.GONE); lDirectionImageOut.setVisibility(View.VISIBLE); } - LinphoneCore lc = LinphoneService.instance().getLinphoneCore(); + LinphoneCore lc = LinphoneManager.getLc(); LinphoneProxyConfig lProxyConfig = lc.getDefaultProxyConfig(); String lDetailedName=null; String lDisplayName = lAddress.getDisplayName(); diff --git a/src/org/linphone/KeepAliveReceiver.java b/src/org/linphone/KeepAliveReceiver.java index fba931aa3..ff87a3d4b 100644 --- a/src/org/linphone/KeepAliveReceiver.java +++ b/src/org/linphone/KeepAliveReceiver.java @@ -30,14 +30,14 @@ public class KeepAliveReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { - if (!LinphoneService.isready()) { - Log.i(LinphoneService.TAG, "Linphone service not ready"); + if (!LinphoneService.isReady()) { + Log.i(LinphoneManager.TAG, "Keep alive broadcast received while Linphone service not ready"); return; } else { if (intent.getAction().equalsIgnoreCase(Intent.ACTION_SCREEN_ON)) { - LinphoneService.getLc().enableKeepAlive(true); + LinphoneManager.getLc().enableKeepAlive(true); } else if (intent.getAction().equalsIgnoreCase(Intent.ACTION_SCREEN_OFF)) { - LinphoneService.getLc().enableKeepAlive(false); + LinphoneManager.getLc().enableKeepAlive(false); } } diff --git a/src/org/linphone/LinphoneActivity.java b/src/org/linphone/LinphoneActivity.java index c21b5c72a..0ebe1dffb 100644 --- a/src/org/linphone/LinphoneActivity.java +++ b/src/org/linphone/LinphoneActivity.java @@ -19,19 +19,23 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. package org.linphone; +import static android.content.Intent.ACTION_MAIN; +import static android.media.AudioManager.*; import java.util.List; +import org.linphone.core.Version; + import android.app.AlertDialog; import android.app.TabActivity; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; +import android.graphics.drawable.Drawable; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.media.AudioManager; -import android.os.Build; import android.os.Bundle; import android.util.Log; import android.view.Menu; @@ -43,92 +47,92 @@ import android.widget.FrameLayout; import android.widget.TabHost; public class LinphoneActivity extends TabActivity { - public static String DIALER_TAB = "dialer"; + public static final String DIALER_TAB = "dialer"; private AudioManager mAudioManager; - private static LinphoneActivity theLinphoneActivity; + private static LinphoneActivity instance; private FrameLayout mMainFrame; private SensorManager mSensorManager; - static private SensorEventListener mSensorEventListener; + private static SensorEventListener mSensorEventListener; - private static String SCREEN_IS_HIDDEN ="screen_is_hidden"; + private static final String SCREEN_IS_HIDDEN ="screen_is_hidden"; - protected static LinphoneActivity instance() - { - if (theLinphoneActivity == null) { - throw new RuntimeException("LinphoneActivity not instanciated yet"); - } else { - return theLinphoneActivity; - } + protected static LinphoneActivity instance() { + if (instance != null) return instance; + + throw new RuntimeException("LinphoneActivity not instantiated yet"); } + protected void onSaveInstanceState (Bundle outState) { super.onSaveInstanceState(outState); - if (mMainFrame.getVisibility() == View.INVISIBLE) { - outState.putBoolean(SCREEN_IS_HIDDEN, true); - } else { - outState.putBoolean(SCREEN_IS_HIDDEN, false); - } - + outState.putBoolean(SCREEN_IS_HIDDEN, mMainFrame.getVisibility() == View.INVISIBLE); } + public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + instance = this; setContentView(R.layout.main); - mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); - theLinphoneActivity = this; + // start linphone as background - Intent intent = new Intent(Intent.ACTION_MAIN); - intent.setClass(this, LinphoneService.class); - startService(intent); + startService(new Intent(ACTION_MAIN).setClass(this, LinphoneService.class)); + mMainFrame = (FrameLayout) findViewById(R.id.main_frame); - mAudioManager = ((AudioManager)getSystemService(Context.AUDIO_SERVICE)); + mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); + TabHost lTabHost = getTabHost(); // The activity TabHost TabHost.TabSpec spec; // Reusable TabSpec for each tab - + Drawable tabDrawable; // Drawable for a tab + Intent tabIntent; // Intent for the a table + CharSequence indicator; //Call History - Intent lHistoryItent = new Intent().setClass(this, HistoryActivity.class); - - spec = lTabHost.newTabSpec("history").setIndicator(getString(R.string.tab_history), - getResources().getDrawable(R.drawable.history_orange)) - .setContent(lHistoryItent); + tabIntent = new Intent().setClass(this, HistoryActivity.class); + tabDrawable = getResources().getDrawable(R.drawable.history_orange); + indicator = getString(R.string.tab_history); + spec = lTabHost.newTabSpec("history") + .setIndicator(indicator, tabDrawable) + .setContent(tabIntent); + lTabHost.addTab(spec); + + // Dialer + tabIntent = new Intent().setClass(this, DialerActivity.class).setData(getIntent().getData()); + tabDrawable = getResources().getDrawable(R.drawable.dialer_orange); + indicator = getString(R.string.tab_dialer); + tabDrawable = getResources().getDrawable(R.drawable.dialer_orange); + spec = lTabHost.newTabSpec(DIALER_TAB) + .setIndicator(indicator, tabDrawable) + .setContent(tabIntent); lTabHost.addTab(spec); - // dialer - Intent lDialerIntent = new Intent().setClass(this, DialerActivity.class); - lDialerIntent.setData(getIntent().getData()); - // Initialize a TabSpec for each tab and add it to the TabHost - spec = lTabHost.newTabSpec("dialer").setIndicator(getString(R.string.tab_dialer), - getResources().getDrawable(R.drawable.dialer_orange)) - .setContent(lDialerIntent); - lTabHost.addTab(spec); - - // contact pick - Intent lContactItent = new Intent().setClass(this, ContactPickerActivity.class); - - spec = lTabHost.newTabSpec("contact").setIndicator(getString(R.string.tab_contact), - getResources().getDrawable(R.drawable.contact_orange)) - .setContent(lContactItent); + // Contact picker + tabIntent = new Intent().setClass(this, ContactPickerActivity.class); + indicator = getString(R.string.tab_contact); + tabDrawable = getResources().getDrawable(R.drawable.contact_orange); + spec = lTabHost.newTabSpec("contact") + .setIndicator(indicator, tabDrawable) + .setContent(tabIntent); lTabHost.addTab(spec); + + lTabHost.setCurrentTabByTag("dialer"); + + if (savedInstanceState !=null && savedInstanceState.getBoolean(SCREEN_IS_HIDDEN,false)) { hideScreen(true); } - - } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); if (intent.getData() != null) { - DialerActivity.getDialer().newOutgoingCall(intent.getData().toString().substring("tel://".length())); - intent.setData(null); + DialerActivity.instance().newOutgoingCall(intent); } } @@ -136,16 +140,15 @@ public class LinphoneActivity extends TabActivity { protected void onPause() { super.onPause(); if (isFinishing()) { - //restaure audio settings - if (Integer.parseInt(Build.VERSION.SDK) <=4 /* lSensorList = mSensorManager.getSensorList(Sensor.TYPE_PROXIMITY); mSensorEventListener = new SensorEventListener() { public void onSensorChanged(SensorEvent event) { if (event.timestamp == 0) return; //just ignoring for nexus 1 - Log.d(LinphoneService.TAG, "Proximity sensor report ["+event.values[0]+"] , for max range ["+event.sensor.getMaximumRange()+"]"); + Log.d(LinphoneManager.TAG, "Proximity sensor report ["+event.values[0]+"] , for max range ["+event.sensor.getMaximumRange()+"]"); if (event.values[0] != event.sensor.getMaximumRange() ) { instance().hideScreen(true); @@ -250,15 +225,37 @@ public class LinphoneActivity extends TabActivity { }; if (lSensorList.size() >0) { mSensorManager.registerListener(mSensorEventListener,lSensorList.get(0),SensorManager.SENSOR_DELAY_UI); - Log.i(LinphoneService.TAG, "Proximity sensor detected, registering"); + Log.i(LinphoneManager.TAG, "Proximity sensor detected, registering"); } } + protected synchronized void stopProxymitySensor() { if (mSensorManager!=null) { mSensorManager.unregisterListener(mSensorEventListener); mSensorEventListener=null; } hideScreen(false); + } + + + void showPreferenceErrorDialog(String message) { + AlertDialog.Builder builder = new AlertDialog.Builder(this) + .setMessage(String.format(getString(R.string.config_error), message)) + .setCancelable(false) + .setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + Intent intent = new Intent(ACTION_MAIN); + intent.setClass(getApplicationContext(), LinphonePreferencesActivity.class); + startActivity(intent); + } + }) + .setNegativeButton(getString(R.string.no), new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + dialog.cancel(); + } + }); + + builder.create().show(); } } diff --git a/src/org/linphone/LinphoneManager.java b/src/org/linphone/LinphoneManager.java index 467bb63e3..070fa0fd8 100644 --- a/src/org/linphone/LinphoneManager.java +++ b/src/org/linphone/LinphoneManager.java @@ -18,31 +18,115 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package org.linphone; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Timer; +import java.util.TimerTask; + import org.linphone.core.AndroidCameraRecordManager; import org.linphone.core.LinphoneAddress; +import org.linphone.core.LinphoneAuthInfo; +import org.linphone.core.LinphoneCall; +import org.linphone.core.LinphoneChatRoom; import org.linphone.core.LinphoneCore; import org.linphone.core.LinphoneCoreException; +import org.linphone.core.LinphoneCoreFactory; +import org.linphone.core.LinphoneCoreListener; +import org.linphone.core.LinphoneFriend; +import org.linphone.core.LinphoneProxyConfig; +import org.linphone.core.PayloadType; +import org.linphone.core.LinphoneCall.State; +import org.linphone.core.LinphoneCore.EcCalibratorStatus; +import org.linphone.core.LinphoneCore.FirewallPolicy; +import org.linphone.core.LinphoneCore.GlobalState; +import org.linphone.core.LinphoneCore.RegistrationState; +import android.content.BroadcastReceiver; +import android.content.ComponentName; import android.content.ContentResolver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; import android.content.SharedPreferences; +import android.content.pm.PackageManager; import android.content.res.Resources; import android.media.AudioManager; +import android.media.MediaPlayer; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; import android.os.Build; +import android.os.Vibrator; +import android.preference.PreferenceManager; import android.provider.Settings; import android.provider.Settings.SettingNotFoundException; -import android.view.WindowManager; +import android.util.Log; +import android.view.OrientationEventListener; -public class LinphoneManager { +/** + * + * Manager of the low level LibLinphone stuff.
+ * Including:
    + *
  • Starting C liblinphone
  • + *
  • Reacting to C liblinphone state changes
  • + *
  • Calling Linphone android service listener methods
  • + *
  • Interacting from Android GUI/service with low level SIP stuff/
  • + *
+ * + * Add Service Listener to react to Linphone state changes. + * + * @author Guillaume Beraudo + * + */ +public final class LinphoneManager implements LinphoneCoreListener { private static LinphoneManager instance; private AudioManager mAudioManager; private NewOutgoingCallUiListener newOutgoingCallUiListener; private SharedPreferences mPref; private Resources mR; - private WindowManager mWindowManager; + private LinphoneCore mLc; + private int mPhoneOrientation; - private LinphoneManager() {} + + private LinphoneManager(final Context c) { + mAudioManager = ((AudioManager) c.getSystemService(Context.AUDIO_SERVICE)); + mVibrator = (Vibrator) c.getSystemService(Context.VIBRATOR_SERVICE); + mPref = PreferenceManager.getDefaultSharedPreferences(c); + mPackageManager = c.getPackageManager(); + mR = c.getResources(); + + // Register a sensor to track phoneOrientation for placing new calls. + new OrientationEventListener(c) { + @Override + public void onOrientationChanged(int o) { + if (o == OrientationEventListener.ORIENTATION_UNKNOWN) return; + + o = 90 * (o / 90); + + if (Math.abs(mPhoneOrientation - o) < 90) return; + + mPhoneOrientation = o; + } + }.enable(); + } + + public static final String TAG="Linphone"; + /** Called when the activity is first created. */ + private static final String LINPHONE_FACTORY_RC = "/data/data/org.linphone/files/linphonerc"; + private static final String LINPHONE_RC = "/data/data/org.linphone/files/.linphonerc"; + private static final String RING_SND = "/data/data/org.linphone/files/oldphone_mono.wav"; + private static final String RINGBACK_SND = "/data/data/org.linphone/files/ringback.wav"; + + private Timer mTimer = new Timer("Linphone scheduler"); + + private BroadcastReceiver mKeepAliveReceiver = new KeepAliveReceiver(); + private PackageManager mPackageManager; + + + public void routeAudioToSpeaker() { if (Integer.parseInt(Build.VERSION.SDK) <= 4 /*4 &&mAudioManager.isSpeakerphoneOn(); @@ -105,14 +191,13 @@ public class LinphoneManager { address.setText(to); } - LinphoneCore lLinphoneCore = LinphoneService.instance().getLinphoneCore(); - if (lLinphoneCore.isIncall()) { + if (mLc.isIncall()) { newOutgoingCallUiListener.onAlreadyInCall(); return; } LinphoneAddress lAddress; try { - lAddress = lLinphoneCore.interpretUrl(to); + lAddress = mLc.interpretUrl(to); } catch (LinphoneCoreException e) { newOutgoingCallUiListener.onWrongDestinationAddress(); return; @@ -120,8 +205,7 @@ public class LinphoneManager { lAddress.setDisplayName(address.getDisplayedName()); try { - - boolean prefVideoEnable = mPref.getBoolean(mR.getString(R.string.pref_video_enable_key), false); + boolean prefVideoEnable = isVideoEnabled(); boolean prefInitiateWithVideo = mPref.getBoolean(mR.getString(R.string.pref_video_initiate_call_with_video_key), false); resetCameraFromPreferences(); CallManager.getInstance().inviteAddress(lAddress, prefVideoEnable && prefInitiateWithVideo); @@ -136,8 +220,7 @@ public class LinphoneManager { public void resetCameraFromPreferences() { boolean useFrontCam = mPref.getBoolean(mR.getString(R.string.pref_video_use_front_camera_key), false); AndroidCameraRecordManager.getInstance().setUseFrontCamera(useFrontCam); - final int phoneOrientation = 90 * mWindowManager.getDefaultDisplay().getOrientation(); - AndroidCameraRecordManager.getInstance().setPhoneOrientation(phoneOrientation); + AndroidCameraRecordManager.getInstance().setPhoneOrientation(mPhoneOrientation); } public void setNewOutgoingCallUiListener(NewOutgoingCallUiListener l) { @@ -160,41 +243,33 @@ public class LinphoneManager { public void sendStaticImage(boolean send) { - LinphoneCore lc = LinphoneService.getLc(); - if (lc.isIncall()) { - lc.getCurrentCall().enableCamera(!send); + if (mLc.isIncall()) { + mLc.getCurrentCall().enableCamera(!send); } } - public void playDtmf(char dtmf) { - if (getLc().isIncall()) { - // Play if in call as it will not go to speaker - getLc().playDtmf(dtmf, -1); - return; - } - - ContentResolver r = LinphoneService.instance().getContentResolver(); + public void playDtmf(ContentResolver r, char dtmf) { + boolean speaker = true; try { if (Settings.System.getInt(r, Settings.System.DTMF_TONE_WHEN_DIALING) == 0) { - // audible touch disabled: don't play - return; + // audible touch disabled: don't play on speaker, only send in outgoing stream + speaker = false; } } catch (SettingNotFoundException e) {} - getLc().playDtmf(dtmf, -1); + getLc().playDtmf(dtmf, -1, speaker); } public void changeResolution() { BandwidthManager manager = BandwidthManager.getInstance(); manager.setUserRestriction(!manager.isUserRestriction()); - LinphoneManager.getInstance().sendStaticImage(AndroidCameraRecordManager.getInstance().isMuted()); + sendStaticImage(AndroidCameraRecordManager.getInstance().isMuted()); } public void terminateCall() { - LinphoneCore lc = LinphoneService.getLc(); - if (lc.isIncall()) { - lc.terminateCall(lc.getCurrentCall()); + if (mLc.isIncall()) { + mLc.terminateCall(mLc.getCurrentCall()); } } @@ -210,6 +285,419 @@ public class LinphoneManager { public void toggleCameraMuting() { AndroidCameraRecordManager rm = AndroidCameraRecordManager.getInstance(); - LinphoneManager.getInstance().sendStaticImage(rm.toggleMute()); + sendStaticImage(rm.toggleMute()); } + + private synchronized void startLibLinphone(final Context context, final LinphoneServiceListener listener) { + try { + this.serviceListener = listener; + copyAssetsFromPackage(context); + + mLc = LinphoneCoreFactory.instance().createLinphoneCore( + this, LINPHONE_RC, LINPHONE_FACTORY_RC, null); + + mLc.setPlaybackGain(3); + mLc.setRing(null); + + try { + initFromConf(context); + } catch (LinphoneException e) { + Log.w(TAG, "no config ready yet"); + } + TimerTask lTask = new TimerTask() { + @Override + public void run() { + mLc.iterate(); + } + + }; + + mTimer.scheduleAtFixedRate(lTask, 0, 100); + + IntentFilter lFilter = new IntentFilter(Intent.ACTION_SCREEN_ON); + lFilter.addAction(Intent.ACTION_SCREEN_OFF); + context.registerReceiver(mKeepAliveReceiver, lFilter); + } + catch (Exception e) { + Log.e(TAG,"Cannot start linphone",e); + } + } + + private void copyAssetsFromPackage(Context context) throws IOException { + copyIfNotExist(context, R.raw.oldphone_mono,RING_SND); + copyIfNotExist(context, R.raw.ringback,RINGBACK_SND); + copyFromPackage(context, R.raw.linphonerc, new File(LINPHONE_FACTORY_RC).getName()); + } + private void copyIfNotExist(Context context, int ressourceId,String target) throws IOException { + File lFileToCopy = new File(target); + if (!lFileToCopy.exists()) { + copyFromPackage(context, ressourceId,lFileToCopy.getName()); + } + } + private void copyFromPackage(Context context, int ressourceId,String target) throws IOException{ + FileOutputStream lOutputStream = context.openFileOutput (target, 0); + InputStream lInputStream = mR.openRawResource(ressourceId); + int readByte; + byte[] buff = new byte[8048]; + while (( readByte = lInputStream.read(buff))!=-1) { + lOutputStream.write(buff,0, readByte); + } + lOutputStream.flush(); + lOutputStream.close(); + lInputStream.close(); + } + + + + public void initFromConf(Context context) throws LinphoneConfigException { + //traces + boolean lIsDebug = mPref.getBoolean(getString(R.string.pref_debug_key), false); + LinphoneCoreFactory.instance().setDebugMode(lIsDebug); + + try { + // Configure audio codecs + enableDisableAudioCodec("speex", 32000, R.string.pref_codec_speex32_key); + enableDisableAudioCodec("speex", 16000, R.string.pref_codec_speex16_key); + enableDisableAudioCodec("speex", 8000, R.string.pref_codec_speex8_key); + enableDisableAudioCodec("iLBC", 8000, R.string.pref_codec_ilbc_key); + enableDisableAudioCodec("GSM", 8000, R.string.pref_codec_gsm_key); + enableDisableAudioCodec("PCMU", 8000, R.string.pref_codec_pcmu_key); + enableDisableAudioCodec("PCMA", 8000, R.string.pref_codec_pcma_key); + + // Configure video codecs + for (PayloadType videoCodec : mLc.listVideoCodecs()) { + enableDisableVideoCodecs(videoCodec); + } + + + String sOutcalls = mPref.getString(getString(R.string.pref_handle_outcall_key), OutgoingCallReceiver.key_on_demand); + boolean handleOutcalls = !sOutcalls.equalsIgnoreCase(OutgoingCallReceiver.key_off); + +/* Now useless, see enablePkgComponent + * if (handleOutcalls){ + IntentFilter lFilter = new IntentFilter(Intent.ACTION_SCREEN_ON); + lFilter.setPriority(0); + lFilter.addAction(Intent.ACTION_NEW_OUTGOING_CALL); + if (mOutgoingCallReceiver == null) { + mOutgoingCallReceiver = new OutgoingCallReceiver(); + } + context.registerReceiver(mOutgoingCallReceiver,lFilter); + } else if (mOutgoingCallReceiver!=null) { + context.unregisterReceiver(mOutgoingCallReceiver); + mOutgoingCallReceiver=null; + }*/ + + // Enable/disable outgoing call receiver according to user wishes + // Could be done already once when the preference is changed in UI. + enablePkgComponent(context, OutgoingCallReceiver.class, handleOutcalls); + + + mLc.enableEchoCancellation(mPref.getBoolean(getString(R.string.pref_echo_cancellation_key),false)); + } catch (LinphoneCoreException e) { + throw new LinphoneConfigException(getString(R.string.wrong_settings),e); + } + boolean isVideoEnabled = isVideoEnabled(); + mLc.enableVideo(isVideoEnabled, isVideoEnabled); + //1 read proxy config from preferences + String lUserName = mPref.getString(getString(R.string.pref_username_key), null); + if (lUserName == null || lUserName.length()==0) { + throw new LinphoneConfigException(getString(R.string.wrong_username)); + } + + String lPasswd = mPref.getString(getString(R.string.pref_passwd_key), null); + if (lPasswd == null || lPasswd.length()==0) { + throw new LinphoneConfigException(getString(R.string.wrong_passwd)); + } + + String lDomain = mPref.getString(getString(R.string.pref_domain_key), null); + if (lDomain == null || lDomain.length()==0) { + throw new LinphoneConfigException(getString(R.string.wrong_domain)); + } + + String lStun = mPref.getString(getString(R.string.pref_stun_server_key), null); + + //stun server + mLc.setStunServer(lStun); + mLc.setFirewallPolicy((lStun!=null && lStun.length()>0) ? FirewallPolicy.UseStun : FirewallPolicy.NoFirewall); + + //auth + mLc.clearAuthInfos(); + LinphoneAuthInfo lAuthInfo = LinphoneCoreFactory.instance().createAuthInfo(lUserName, lPasswd,null); + mLc.addAuthInfo(lAuthInfo); + + + //proxy + mLc.clearProxyConfigs(); + String lProxy = mPref.getString(getString(R.string.pref_proxy_key),null); + if (lProxy == null || lProxy.length() == 0) { + lProxy = "sip:"+lDomain; + } + if (!lProxy.startsWith("sip:")) { + lProxy = "sip:"+lProxy; + } + //get Default proxy if any + LinphoneProxyConfig lDefaultProxyConfig = mLc.getDefaultProxyConfig(); + String lIdentity = "sip:"+lUserName+"@"+lDomain; + try { + if (lDefaultProxyConfig == null) { + lDefaultProxyConfig = LinphoneCoreFactory.instance().createProxyConfig(lIdentity, lProxy, null,true); + mLc.addProxyConfig(lDefaultProxyConfig); + mLc.setDefaultProxyConfig(lDefaultProxyConfig); + + } else { + lDefaultProxyConfig.edit(); + lDefaultProxyConfig.setIdentity(lIdentity); + lDefaultProxyConfig.setProxy(lProxy); + lDefaultProxyConfig.enableRegister(true); + lDefaultProxyConfig.done(); + } + lDefaultProxyConfig = mLc.getDefaultProxyConfig(); + + if (lDefaultProxyConfig !=null) { + //prefix + String lPrefix = mPref.getString(getString(R.string.pref_prefix_key), null); + if (lPrefix != null) { + lDefaultProxyConfig.setDialPrefix(lPrefix); + } + //escape + + lDefaultProxyConfig.setDialEscapePlus(mPref.getBoolean(getString(R.string.pref_escape_plus_key),false)); + //outbound proxy + if (mPref.getBoolean(getString(R.string.pref_enable_outbound_proxy_key), false)) { + lDefaultProxyConfig.setRoute(lProxy); + } else { + lDefaultProxyConfig.setRoute(null); + } + + } + //init network state + ConnectivityManager lConnectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkInfo lInfo = lConnectivityManager.getActiveNetworkInfo(); + mLc.setNetworkReachable( lInfo !=null? lConnectivityManager.getActiveNetworkInfo().getState() ==NetworkInfo.State.CONNECTED:false); + + } catch (LinphoneCoreException e) { + throw new LinphoneConfigException(getString(R.string.wrong_settings),e); + } + } + + + private void enablePkgComponent(Context context, Class clazz, boolean state) { + mPackageManager.setComponentEnabledSetting( + new ComponentName(context, clazz), + state ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED + : PackageManager.COMPONENT_ENABLED_STATE_DISABLED, + 0); + } + + private void enableDisableAudioCodec(String codec, int rate, int key) throws LinphoneCoreException { + PayloadType pt = mLc.findPayloadType(codec, rate); + if (pt !=null) { + boolean enable= mPref.getBoolean(getString(key),false); + mLc.enablePayloadType(pt, enable); + } + } + + private void enableDisableVideoCodecs(PayloadType videoCodec) throws LinphoneCoreException { + String mime = videoCodec.getMime(); + int key; + + if ("MP4V-ES".equals(mime)) { + key = R.string.pref_video_codec_mpeg4_key; + } else if ("H264".equals(mime)) { + key = R.string.pref_video_codec_h264_key; + } else if ("H263-1998".equals(mime)) { + key = R.string.pref_video_codec_h263_key; + } else { + Log.e(TAG, "Unhandled video codec " + mime); + mLc.enablePayloadType(videoCodec, false); + return; + } + + boolean enable= mPref.getBoolean(getString(key),false); + mLc.enablePayloadType(videoCodec, enable); + } + + public boolean hasCamera() { + return mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA); + } + + public static synchronized void destroy(Context context) { + if (instance == null) return; + + try { + instance.mTimer.cancel(); + instance.mLc.destroy(); + context.unregisterReceiver(instance.mKeepAliveReceiver); + } finally { + instance.mLc = null; + instance = null; + } + } + + private String getString(int key) { + return mR.getString(key); + } + + + + + + + + + + + + + + + + + + public interface LinphoneServiceListener { + void onGlobalStateChanged(GlobalState state, String message); + void onRegistrationStateChanged(RegistrationState state, String message); + void onCallStateChanged(LinphoneCall call, State state, String message); + void onEcCalibrationStatus(EcCalibratorStatus status, Object data, + int delayMs); + void onRingerPlayerCreated(MediaPlayer mRingerPlayer); + void onDisplayStatus(String message); + } + + + private LinphoneServiceListener serviceListener; + private LinphoneCall.State mCurrentCallState; + + private MediaPlayer mRingerPlayer; + private Vibrator mVibrator; + + + + public void displayWarning(LinphoneCore lc, String message) {} + public void authInfoRequested(LinphoneCore lc, String realm, String username) {} + public void byeReceived(LinphoneCore lc, String from) {} + public void displayMessage(LinphoneCore lc, String message) {} + public void show(LinphoneCore lc) {} + public void newSubscriptionRequest(LinphoneCore lc,LinphoneFriend lf,String url) {} + public void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf) {} + public void textReceived(LinphoneCore lc, LinphoneChatRoom cr, + LinphoneAddress from, String message) {} + + + + public void displayStatus(final LinphoneCore lc, final String message) { + Log.i(TAG, message); + serviceListener.onDisplayStatus(message); + } + + + public void globalState(final LinphoneCore lc, final LinphoneCore.GlobalState state, final String message) { + Log.i(TAG, "new state ["+state+"]"); + serviceListener.onGlobalStateChanged(state, message); + } + + + + public void registrationState(final LinphoneCore lc, final LinphoneProxyConfig cfg,final LinphoneCore.RegistrationState state,final String message) { + Log.i(TAG, "new state ["+state+"]"); + serviceListener.onRegistrationStateChanged(state, message); + } + + + public void callState(final LinphoneCore lc,final LinphoneCall call, final State state, final String message) { + Log.i(TAG, "new state ["+state+"]"); + if (state == LinphoneCall.State.IncomingReceived && !call.equals(lc.getCurrentCall())) { + if (call.getReplacedCall()==null){ + //no multicall support, just decline + lc.terminateCall(call); + }//otherwise it will be accepted automatically. + + return; + } + serviceListener.onCallStateChanged(call, state, message); + + if (state == LinphoneCall.State.IncomingReceived) { + startRinging(); + } + + if (mCurrentCallState == LinphoneCall.State.IncomingReceived) { + //previous state was ringing, so stop ringing + stopRinging(); + //routeAudioToReceiver(); + } + mCurrentCallState=state; + } + + + public void ecCalibrationStatus(final LinphoneCore lc,final EcCalibratorStatus status, final int delay_ms, + final Object data) { + serviceListener.onEcCalibrationStatus(status, data, delay_ms); + } + + + + + + + + + + + + + private synchronized void startRinging() { + try { + if (mAudioManager.shouldVibrate(AudioManager.VIBRATE_TYPE_RINGER) && mVibrator !=null) { + long[] patern = {0,1000,1000}; + mVibrator.vibrate(patern, 1); + } + if (mRingerPlayer == null) { + mRingerPlayer = new MediaPlayer(); + mRingerPlayer.setAudioStreamType(AudioManager.STREAM_RING); + serviceListener.onRingerPlayerCreated(mRingerPlayer); + mRingerPlayer.prepare(); + mRingerPlayer.setLooping(true); + mRingerPlayer.start(); + } else { + Log.w(LinphoneManager.TAG,"already ringing"); + } + } catch (Exception e) { + Log.e(LinphoneManager.TAG, "cannot handle incoming call",e); + } + + } + + private synchronized void stopRinging() { + if (mRingerPlayer !=null) { + mRingerPlayer.stop(); + mRingerPlayer.release(); + mRingerPlayer=null; + } + if (mVibrator!=null) { + mVibrator.cancel(); + } + } + + public String extractADisplayName() { + final LinphoneAddress remote = mLc.getRemoteAddress(); + if (remote == null) return null; + + final String displayName = remote.getDisplayName(); + if (displayName!=null) { + return displayName; + } else if (remote.getUserName() != null){ + return remote.getUserName(); + } else { + return remote.toString(); + } + } + + public static boolean reinviteWithVideo() { + return CallManager.getInstance().reinviteWithVideo(); + } + + public boolean isVideoEnabled() { + return mPref.getBoolean(getString(R.string.pref_video_enable_key), false); + } + + } diff --git a/src/org/linphone/LinphonePreferencesActivity.java b/src/org/linphone/LinphonePreferencesActivity.java index 69077ba62..9e0e8bdc3 100644 --- a/src/org/linphone/LinphonePreferencesActivity.java +++ b/src/org/linphone/LinphonePreferencesActivity.java @@ -21,24 +21,25 @@ package org.linphone; +import static android.media.AudioManager.STREAM_VOICE_CALL; + import org.linphone.core.LinphoneCoreException; +import org.linphone.core.Version; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.media.AudioManager; -import android.os.Build; import android.os.Bundle; import android.preference.CheckBoxPreference; import android.preference.Preference; -import android.preference.Preference.OnPreferenceClickListener; import android.preference.PreferenceActivity; +import android.preference.Preference.OnPreferenceClickListener; import android.util.Log; public class LinphonePreferencesActivity extends PreferenceActivity { - private static final int version = Integer.parseInt(Build.VERSION.SDK); - boolean mIsLowEndCpu = true; + private boolean mIsLowEndCpu = true; private AudioManager mAudioManager; @Override @@ -46,9 +47,9 @@ public class LinphonePreferencesActivity extends PreferenceActivity { super.onCreate(savedInstanceState); mAudioManager = ((AudioManager)getSystemService(Context.AUDIO_SERVICE)); boolean enableIlbc=false; - if (LinphoneService.isready()) { + if (LinphoneService.isReady()) { // if not ilbc, we are on low end cpu. - enableIlbc = LinphoneService.instance().getLinphoneCore().findPayloadType("iLBC", 8000)!=null?true:false; + enableIlbc = LinphoneManager.getLc().findPayloadType("iLBC", 8000)!=null?true:false; mIsLowEndCpu=!enableIlbc; if (!mIsLowEndCpu && !getPreferenceManager().getSharedPreferences().contains(getString(R.string.pref_echo_cancellation_key))) { getPreferenceManager().getSharedPreferences().edit().putBoolean(getString(R.string.pref_echo_cancellation_key), true).commit(); @@ -68,7 +69,8 @@ public class LinphonePreferencesActivity extends PreferenceActivity { getPreferenceScreen().findPreference(getString(R.string.pref_codec_speex16_key)).setEnabled(enableIlbc); //getPreferenceScreen().findPreference(getString(R.string.pref_codec_speex32_key)).setEnabled(enableIlbc); } - getPreferenceScreen().findPreference(getString(R.string.pref_echo_canceller_calibration_key)).setOnPreferenceClickListener(new OnPreferenceClickListener() { + getPreferenceScreen().findPreference(getString(R.string.pref_echo_canceller_calibration_key)) + .setOnPreferenceClickListener(new OnPreferenceClickListener() { public boolean onPreferenceClick(Preference preference) { startEcCalibration(preference); return false; @@ -76,7 +78,7 @@ public class LinphonePreferencesActivity extends PreferenceActivity { }); // Force disable video - if (version < 5 || !enableIlbc) { + if (Version.sdkStrictlyBelow(5) || !enableIlbc || !LinphoneManager.getInstance().hasCamera()) { disableCheckbox(R.string.pref_video_enable_key); } if (getPreferenceManager().getSharedPreferences().getBoolean(DialerActivity.PREF_FIRST_LAUNCH,true)) { @@ -93,18 +95,23 @@ public class LinphonePreferencesActivity extends PreferenceActivity { } } - private void startEcCalibration(Preference preference) { + private synchronized void startEcCalibration(Preference preference) { try { - while (mAudioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL) != mAudioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL)) { - mAudioManager.adjustStreamVolume(AudioManager.STREAM_VOICE_CALL, AudioManager.ADJUST_RAISE, 0); - } - LinphoneService.getLc().startEchoCalibration(preference); + int oldVolume = mAudioManager.getStreamVolume(STREAM_VOICE_CALL); + int maxVolume = mAudioManager.getStreamMaxVolume(STREAM_VOICE_CALL); + mAudioManager.setStreamVolume(STREAM_VOICE_CALL, maxVolume, 0); + + LinphoneManager.getLc().startEchoCalibration(preference); + + mAudioManager.setStreamVolume(STREAM_VOICE_CALL, oldVolume, 0); + preference.setSummary(R.string.ec_calibrating); preference.getEditor().putBoolean(getString(R.string.pref_echo_canceller_calibration_key), false).commit(); } catch (LinphoneCoreException e) { - Log.w(LinphoneService.TAG, "Cannot calibrate EC",e); + Log.w(LinphoneManager.TAG, "Cannot calibrate EC",e); } } + private void disableCheckbox(int key) { getPreferenceManager().getSharedPreferences().edit().putBoolean(getString(key), false).commit(); CheckBoxPreference box = (CheckBoxPreference) getPreferenceScreen().findPreference(getString(key)); @@ -116,12 +123,20 @@ public class LinphonePreferencesActivity extends PreferenceActivity { @Override protected void onPause() { super.onPause(); - if (isFinishing()) { - try { - LinphoneActivity.instance().initFromConf(); - } catch (LinphoneException e) { - Log.e(LinphoneService.TAG, "cannot update config",e); + + if (!isFinishing()) return; + + + try { + LinphoneManager.getInstance().initFromConf(getApplicationContext()); + } catch (LinphoneException e) { + + if (! (e instanceof LinphoneConfigException)) { + Log.e(LinphoneManager.TAG, "Cannot update config",e); + return; } + + LinphoneActivity.instance().showPreferenceErrorDialog(e.getMessage()); } } diff --git a/src/org/linphone/LinphoneService.java b/src/org/linphone/LinphoneService.java index c4baeb37b..6993df5bc 100644 --- a/src/org/linphone/LinphoneService.java +++ b/src/org/linphone/LinphoneService.java @@ -18,446 +18,128 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package org.linphone; -import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; -import java.io.InputStream; -import java.util.Timer; -import java.util.TimerTask; -import org.linphone.core.LinphoneAddress; -import org.linphone.core.LinphoneAuthInfo; +import org.linphone.LinphoneManager.LinphoneServiceListener; import org.linphone.core.LinphoneCall; -import org.linphone.core.LinphoneChatRoom; import org.linphone.core.LinphoneCore; -import org.linphone.core.LinphoneCoreException; -import org.linphone.core.LinphoneCoreFactory; -import org.linphone.core.LinphoneCoreListener; -import org.linphone.core.LinphoneFriend; -import org.linphone.core.LinphoneProxyConfig; -import org.linphone.core.PayloadType; import org.linphone.core.LinphoneCall.State; import org.linphone.core.LinphoneCore.EcCalibratorStatus; -import org.linphone.core.LinphoneCore.FirewallPolicy; import org.linphone.core.LinphoneCore.GlobalState; +import org.linphone.core.LinphoneCore.RegistrationState; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; -import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; -import android.content.IntentFilter; -import android.content.SharedPreferences; -import android.media.AudioManager; import android.media.MediaPlayer; import android.media.RingtoneManager; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; +import android.net.Uri; import android.os.Handler; import android.os.IBinder; -import android.os.Vibrator; import android.preference.CheckBoxPreference; -import android.preference.PreferenceManager; import android.util.Log; -public class LinphoneService extends Service implements LinphoneCoreListener { - static final public String TAG="Linphone"; - /** Called when the activity is first created. */ - private static String LINPHONE_FACTORY_RC = "/data/data/org.linphone/files/linphonerc"; - private static String LINPHONE_RC = "/data/data/org.linphone/files/.linphonerc"; - private static String RING_SND = "/data/data/org.linphone/files/oldphone_mono.wav"; - private static String RINGBACK_SND = "/data/data/org.linphone/files/ringback.wav"; +/*** + * + * Linphone service, reacting to Incoming calls, ...
+ * + * Roles include:
    + *
  • Initializing LinphoneManager
  • + *
  • Starting C libLinphone through LinphoneManager
  • + *
  • Reacting to LinphoneManager state changes
  • + *
  • Delegating GUI state change actions to GUI listener
  • + * + * + * @author Guillaume Beraudo + * + */ +public final class LinphoneService extends Service implements LinphoneServiceListener { + /* Listener needs to be implemented in the Service as it calls + * setLatestEventInfo and startActivity() which needs a context. + */ + + private Handler mHandler = new Handler(); + private static LinphoneService instance; - private static LinphoneService theLinphone; - private LinphoneCore mLinphoneCore; - private SharedPreferences mPref; - Timer mTimer = new Timer("Linphone scheduler"); - - NotificationManager mNotificationManager; - Notification mNotification; - PendingIntent mNofificationContentIntent; - final static int NOTIFICATION_ID=1; - final String NOTIFICATION_TITLE = "Linphone"; - - final int IC_LEVEL_OFFLINE=3; - final int IC_LEVEL_ORANGE=0; - final int IC_LEVEL_GREEN=1; - final int IC_LEVEL_RED=2; + static boolean isReady() { return (instance!=null); } - MediaPlayer mRingerPlayer; - LinphoneCall.State mCurrentCallState; - Vibrator mVibrator; - private AudioManager mAudioManager; - private BroadcastReceiver mKeepAliveMgrReceiver = new KeepAliveReceiver(); - private BroadcastReceiver mOutgoingCallReceiver = null; - - private Handler mHandler = new Handler() ; - static boolean isready() { - return (theLinphone!=null); - } + /** + * @throws RuntimeException service not instantiated + */ static LinphoneService instance() { - if (theLinphone == null) { - throw new RuntimeException("LinphoneActivity not instanciated yet"); - } else { - return theLinphone; - } + if (isReady()) return instance; + + throw new RuntimeException("LinphoneService not instantiated yet"); } + + private NotificationManager mNotificationMgr; + private final static int NOTIF_ID=1; + + private Notification mNotif; + private PendingIntent mNotifContentIntent; + private static final String NOTIF_TITLE = "Linphone"; + + + private static final int IC_LEVEL_ORANGE=0; + private static final int IC_LEVEL_GREEN=1; + private static final int IC_LEVEL_RED=2; + private static final int IC_LEVEL_OFFLINE=3; + + + + + @Override public void onCreate() { super.onCreate(); - theLinphone = this; - + instance = this; + // Dump some debugging information to the logs Hacks.dumpDeviceInformation(); - mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); - mNotification = new Notification(R.drawable.status_level - , "" - , System.currentTimeMillis()); - mNotification.iconLevel=IC_LEVEL_ORANGE; - mNotification.flags |= Notification.FLAG_ONGOING_EVENT; - Intent notificationIntent = new Intent(this, LinphoneActivity.class); - mNofificationContentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); - mNotification.setLatestEventInfo(this, NOTIFICATION_TITLE,"", mNofificationContentIntent); - mNotificationManager.notify(NOTIFICATION_ID, mNotification); - mPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); - mAudioManager = ((AudioManager)getSystemService(Context.AUDIO_SERVICE)); - mVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); - try { - copyAssetsFromPackage(); - - mLinphoneCore = LinphoneCoreFactory.instance().createLinphoneCore( this - , LINPHONE_RC - , LINPHONE_FACTORY_RC - , null); - - mLinphoneCore.setPlaybackGain(3); - mLinphoneCore.setRing(null); - - try { - initFromConf(); - } catch (LinphoneException e) { - Log.w(TAG, "no config ready yet"); - } - TimerTask lTask = new TimerTask() { - @Override - public void run() { - mLinphoneCore.iterate(); - } - - }; - - mTimer.scheduleAtFixedRate(lTask, 0, 100); - IntentFilter lFilter = new IntentFilter(Intent.ACTION_SCREEN_ON); - lFilter.addAction(Intent.ACTION_SCREEN_OFF); - registerReceiver(mKeepAliveMgrReceiver, lFilter); - - - - } - catch (Exception e) { - Log.e(TAG,"Cannot start linphone",e); - } - + mNotificationMgr = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE); + mNotif = new Notification(R.drawable.status_level, "", System.currentTimeMillis()); + mNotif.iconLevel=IC_LEVEL_ORANGE; + mNotif.flags |= Notification.FLAG_ONGOING_EVENT; + Intent notifIntent = new Intent(this, LinphoneActivity.class); + mNotifContentIntent = PendingIntent.getActivity(this, 0, notifIntent, 0); + mNotif.setLatestEventInfo(this, NOTIF_TITLE,"", mNotifContentIntent); + mNotificationMgr.notify(NOTIF_ID, mNotif); + + + LinphoneManager.createAndStart(this, this); } - private void copyAssetsFromPackage() throws IOException { - copyIfNotExist(R.raw.oldphone_mono,RING_SND); - copyIfNotExist(R.raw.ringback,RINGBACK_SND); - copyFromPackage(R.raw.linphonerc, new File(LINPHONE_FACTORY_RC).getName()); - } - private void copyIfNotExist(int ressourceId,String target) throws IOException { - File lFileToCopy = new File(target); - if (!lFileToCopy.exists()) { - copyFromPackage(ressourceId,lFileToCopy.getName()); - } - } - private void copyFromPackage(int ressourceId,String target) throws IOException{ - FileOutputStream lOutputStream = openFileOutput (target, 0); - InputStream lInputStream = getResources().openRawResource(ressourceId); - int readByte; - byte[] buff = new byte[8048]; - while (( readByte = lInputStream.read(buff))!=-1) { - lOutputStream.write(buff,0, readByte); - } - lOutputStream.flush(); - lOutputStream.close(); - lInputStream.close(); - - } - public void authInfoRequested(LinphoneCore lc, String realm, String username) { - - } - public void byeReceived(LinphoneCore lc, String from) { - // TODO Auto-generated method stub - - } - public void displayMessage(LinphoneCore lc, String message) { - // TODO Auto-generated method stub - - } - public void displayStatus(final LinphoneCore lc, final String message) { - Log.i(TAG, message); - if (DialerActivity.getDialer()!=null) { - mHandler.post(new Runnable() { - public void run() { - if (DialerActivity.getDialer()!=null) - DialerActivity.getDialer().displayStatus(lc,message); - } - - }); - - } - } - public void displayWarning(LinphoneCore lc, String message) { - // TODO Auto-generated method stub - - } - public void globalState(final LinphoneCore lc, final LinphoneCore.GlobalState state, final String message) { - Log.i(TAG, "new state ["+state+"]"); - if (state == GlobalState.GlobalOn) { - mNotification.iconLevel=IC_LEVEL_OFFLINE; - mNotification.when=System.currentTimeMillis(); - mNotification.setLatestEventInfo(this - , NOTIFICATION_TITLE - ,getString(R.string.notification_started) - , mNofificationContentIntent); - mNotificationManager.notify(NOTIFICATION_ID, mNotification); - if (DialerActivity.getDialer()!=null) { - mHandler.post(new Runnable() { - public void run() { - DialerActivity.getDialer().globalState(lc,state,message); - } - }); - } - - } - } - public void registrationState(final LinphoneCore lc, final LinphoneProxyConfig cfg,final LinphoneCore.RegistrationState state,final String smessage) { - Log.i(TAG, "new state ["+state+"]"); - if (state == LinphoneCore.RegistrationState.RegistrationOk && lc.getDefaultProxyConfig().isRegistered()) { - mNotification.iconLevel=IC_LEVEL_ORANGE; - mNotification.when=System.currentTimeMillis(); - mNotification.setLatestEventInfo(this - , NOTIFICATION_TITLE - ,String.format(getString(R.string.notification_registered),lc.getDefaultProxyConfig().getIdentity()) - , mNofificationContentIntent); - mNotificationManager.notify(NOTIFICATION_ID, mNotification); - } - if (state == LinphoneCore.RegistrationState.RegistrationFailed ) { - mNotification.iconLevel=IC_LEVEL_OFFLINE; - mNotification.when=System.currentTimeMillis(); - mNotification.setLatestEventInfo(this - , NOTIFICATION_TITLE - ,String.format(getString(R.string.notification_register_failure),lc.getDefaultProxyConfig().getIdentity()) - , mNofificationContentIntent); - mNotificationManager.notify(NOTIFICATION_ID, mNotification); - } - mHandler.post(new Runnable() { - public void run() { - if (DialerActivity.getDialer()!=null) DialerActivity.getDialer().registrationState(lc,cfg,state,smessage); - } - }); - } - public void callState(final LinphoneCore lc,final LinphoneCall call, final State state, final String message) { - Log.i(TAG, "new state ["+state+"]"); - if (state == LinphoneCall.State.IncomingReceived && !call.equals(mLinphoneCore.getCurrentCall())) { - if (call.getReplacedCall()==null){ - //no multicall support, just decline - mLinphoneCore.terminateCall(call); - }//otherwise it will be accepted automatically. - - return; - } - mHandler.post(new Runnable() { - public void run() { - if (DialerActivity.getDialer()!=null) DialerActivity.getDialer().callState(lc,call,state,message); - } - }); - if (state == LinphoneCall.State.IncomingReceived) { - //wakeup linphone - Intent lIntent = new Intent(); - lIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - lIntent.setClass(this, LinphoneActivity.class); - startActivity(lIntent); - startRinging(); - } - if (mCurrentCallState == LinphoneCall.State.IncomingReceived) { - //previous state was ringing, so stop ringing - stopRinging(); - //routeAudioToReceiver(); - } - mCurrentCallState=state; - } - public void show(LinphoneCore lc) { - // TODO Auto-generated method stub - - } - - - private void enableDisableAudioCodec(String codec, int rate, int key) throws LinphoneCoreException { - PayloadType pt = mLinphoneCore.findPayloadType(codec, rate); - if (pt !=null) { - boolean enable= mPref.getBoolean(getString(key),false); - mLinphoneCore.enablePayloadType(pt, enable); - } - } - - private void enableDisableVideoCodecs(PayloadType videoCodec) throws LinphoneCoreException { - String mime = videoCodec.getMime(); - int key; - - if ("MP4V-ES".equals(mime)) { - key = R.string.pref_video_codec_mpeg4_key; - } else if ("H264".equals(mime)) { - key = R.string.pref_video_codec_h264_key; - } else if ("H263-1998".equals(mime)) { - key = R.string.pref_video_codec_h263_key; - } else { - Log.e(TAG, "Unhandled video codec " + mime); - mLinphoneCore.enablePayloadType(videoCodec, false); - return; - } - - boolean enable= mPref.getBoolean(getString(key),false); - mLinphoneCore.enablePayloadType(videoCodec, enable); - } - - public void initFromConf() throws LinphoneConfigException, LinphoneException { - //traces - boolean lIsDebug = mPref.getBoolean(getString(R.string.pref_debug_key), false); - LinphoneCoreFactory.instance().setDebugMode(lIsDebug); - - try { - // Configure audio codecs - enableDisableAudioCodec("speex", 32000, R.string.pref_codec_speex32_key); - enableDisableAudioCodec("speex", 16000, R.string.pref_codec_speex16_key); - enableDisableAudioCodec("speex", 8000, R.string.pref_codec_speex8_key); - enableDisableAudioCodec("iLBC", 8000, R.string.pref_codec_ilbc_key); - enableDisableAudioCodec("GSM", 8000, R.string.pref_codec_gsm_key); - enableDisableAudioCodec("PCMU", 8000, R.string.pref_codec_pcmu_key); - enableDisableAudioCodec("PCMA", 8000, R.string.pref_codec_pcma_key); - - // Configure video codecs - for (PayloadType videoCodec : mLinphoneCore.listVideoCodecs()) { - enableDisableVideoCodecs(videoCodec); - } - if (!mPref.getString(getString(R.string.pref_handle_outcall_key), OutgoingCallReceiver.key_on_demand).equalsIgnoreCase(OutgoingCallReceiver.key_off)){ - IntentFilter lFilter = new IntentFilter(Intent.ACTION_SCREEN_ON); - lFilter.setPriority(0); - lFilter.addAction(Intent.ACTION_NEW_OUTGOING_CALL); - if (mOutgoingCallReceiver == null) { - mOutgoingCallReceiver = new OutgoingCallReceiver(); - } - registerReceiver(mOutgoingCallReceiver,lFilter); - } else if (mOutgoingCallReceiver!=null) { - unregisterReceiver(mOutgoingCallReceiver); - mOutgoingCallReceiver=null; - } - - mLinphoneCore.enableEchoCancellation(mPref.getBoolean(getString(R.string.pref_echo_cancellation_key),false)); - } catch (LinphoneCoreException e) { - throw new LinphoneConfigException(getString(R.string.wrong_settings),e); - } - boolean isVideoEnabled = mPref.getBoolean(getString(R.string.pref_video_enable_key),false); - mLinphoneCore.enableVideo(isVideoEnabled, isVideoEnabled); - //1 read proxy config from preferences - String lUserName = mPref.getString(getString(R.string.pref_username_key), null); - if (lUserName == null || lUserName.length()==0) { - throw new LinphoneConfigException(getString(R.string.wrong_username)); - } - - String lPasswd = mPref.getString(getString(R.string.pref_passwd_key), null); - if (lPasswd == null || lPasswd.length()==0) { - throw new LinphoneConfigException(getString(R.string.wrong_passwd)); - } - - String lDomain = mPref.getString(getString(R.string.pref_domain_key), null); - if (lDomain == null || lDomain.length()==0) { - throw new LinphoneConfigException(getString(R.string.wrong_domain)); - } - - String lStun = mPref.getString(getString(R.string.pref_stun_server_key), null); - - //stun server - mLinphoneCore.setStunServer(lStun); - mLinphoneCore.setFirewallPolicy((lStun!=null && lStun.length()>0) ? FirewallPolicy.UseStun : FirewallPolicy.NoFirewall); - - //auth - mLinphoneCore.clearAuthInfos(); - LinphoneAuthInfo lAuthInfo = LinphoneCoreFactory.instance().createAuthInfo(lUserName, lPasswd,null); - mLinphoneCore.addAuthInfo(lAuthInfo); - - - //proxy - mLinphoneCore.clearProxyConfigs(); - String lProxy = mPref.getString(getString(R.string.pref_proxy_key),null); - if (lProxy == null || lProxy.length() == 0) { - lProxy = "sip:"+lDomain; - } - if (!lProxy.startsWith("sip:")) { - lProxy = "sip:"+lProxy; - } - //get Default proxy if any - LinphoneProxyConfig lDefaultProxyConfig = mLinphoneCore.getDefaultProxyConfig(); - String lIdentity = "sip:"+lUserName+"@"+lDomain; - try { - if (lDefaultProxyConfig == null) { - lDefaultProxyConfig = LinphoneCoreFactory.instance().createProxyConfig(lIdentity, lProxy, null,true); - mLinphoneCore.addProxyConfig(lDefaultProxyConfig); - mLinphoneCore.setDefaultProxyConfig(lDefaultProxyConfig); - - } else { - lDefaultProxyConfig.edit(); - lDefaultProxyConfig.setIdentity(lIdentity); - lDefaultProxyConfig.setProxy(lProxy); - lDefaultProxyConfig.enableRegister(true); - lDefaultProxyConfig.done(); - } - lDefaultProxyConfig = mLinphoneCore.getDefaultProxyConfig(); - - if (lDefaultProxyConfig !=null) { - //prefix - String lPrefix = mPref.getString(getString(R.string.pref_prefix_key), null); - if (lPrefix != null) { - lDefaultProxyConfig.setDialPrefix(lPrefix); - } - //escape + - lDefaultProxyConfig.setDialEscapePlus(mPref.getBoolean(getString(R.string.pref_escape_plus_key),false)); - //outbound proxy - if (mPref.getBoolean(getString(R.string.pref_enable_outbound_proxy_key), false)) { - lDefaultProxyConfig.setRoute(lProxy); - } else { - lDefaultProxyConfig.setRoute(null); - } - - } - //init network state - ConnectivityManager lConnectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkInfo lInfo = lConnectivityManager.getActiveNetworkInfo(); - mLinphoneCore.setNetworkReachable( lInfo !=null? lConnectivityManager.getActiveNetworkInfo().getState() ==NetworkInfo.State.CONNECTED:false); - - } catch (LinphoneCoreException e) { - throw new LinphoneConfigException(getString(R.string.wrong_settings),e); - } + private void sendNotification(int level, int text) { + mNotif.iconLevel = level; + mNotif.when=System.currentTimeMillis(); + mNotif.setLatestEventInfo(this, NOTIF_TITLE,getString(text), mNotifContentIntent); + mNotificationMgr.notify(NOTIF_ID, mNotif); } - - - - protected LinphoneCore getLinphoneCore() { - return mLinphoneCore; + private void sendNotificationWithId(int level, int text) { + mNotif.iconLevel = level; + mNotif.when=System.currentTimeMillis(); + String id = LinphoneManager.getLc().getDefaultProxyConfig().getIdentity(); + mNotif.setLatestEventInfo(this, NOTIF_TITLE, + String.format(getString(text), id), + mNotifContentIntent); + mNotificationMgr.notify(NOTIF_ID, mNotif); } + + + @Override public IBinder onBind(Intent intent) { return null; @@ -466,66 +148,77 @@ public class LinphoneService extends Service implements LinphoneCoreListener { @Override public void onDestroy() { super.onDestroy(); - mTimer.cancel(); - mLinphoneCore.destroy(); - theLinphone=null; - mNotificationManager.cancel(NOTIFICATION_ID); - unregisterReceiver(mKeepAliveMgrReceiver); - if (mOutgoingCallReceiver != null) unregisterReceiver(mOutgoingCallReceiver); - } - public void newSubscriptionRequest(LinphoneCore lc, LinphoneFriend lf, - String url) { - // TODO Auto-generated method stub - - } - public void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf) { - // TODO Auto-generated method stub - - } - public void textReceived(LinphoneCore lc, LinphoneChatRoom cr, - LinphoneAddress from, String message) { - // TODO Auto-generated method stub - + LinphoneManager.destroy(this); + + mNotificationMgr.cancel(NOTIF_ID); + + instance=null; } - public static LinphoneCore getLc() { - return instance().getLinphoneCore(); + + private static final LinphoneGuiListener guiListener() { + return DialerActivity.instance(); } - private synchronized void startRinging() { - try { - if (mAudioManager.shouldVibrate(AudioManager.VIBRATE_TYPE_RINGER) && mVibrator !=null) { - long[] patern = {0,1000,1000}; - mVibrator.vibrate(patern, 1); + + + + + + public void onDisplayStatus(final String message) { + mHandler.post(new Runnable() { + public void run() { + if (guiListener() != null) guiListener().onDisplayStatus(message); } - if (mRingerPlayer == null) { - mRingerPlayer = new MediaPlayer(); - mRingerPlayer.setAudioStreamType(AudioManager.STREAM_RING); - mRingerPlayer.setDataSource(getApplicationContext(), RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE)); - mRingerPlayer.prepare(); - mRingerPlayer.setLooping(true); - mRingerPlayer.start(); - } else { - Log.w(LinphoneService.TAG,"already ringing"); - } - } catch (Exception e) { - Log.e(LinphoneService.TAG, "cannot handle incoming call",e); + }); + } + + public void onGlobalStateChanged(final GlobalState state, final String message) { + if (state == GlobalState.GlobalOn) { + sendNotification(IC_LEVEL_OFFLINE, R.string.notification_started); + + mHandler.post(new Runnable() { + public void run() { + if (guiListener() != null) + guiListener().onGlobalStateChangedToOn(message); + } + }); + } + } + + + public void onRegistrationStateChanged(RegistrationState state, + String message) { + if (state == LinphoneCore.RegistrationState.RegistrationOk && LinphoneManager.getLc().getDefaultProxyConfig().isRegistered()) { + sendNotificationWithId(IC_LEVEL_ORANGE, R.string.notification_registered); + } + if (state == LinphoneCore.RegistrationState.RegistrationFailed ) { + sendNotificationWithId(IC_LEVEL_OFFLINE, R.string.notification_register_failure); + } + } + + + public void onCallStateChanged(final LinphoneCall call, final State state, final String message) { + if (state == LinphoneCall.State.IncomingReceived) { + //wakeup linphone + startActivity(new Intent() + .setClass(this, LinphoneActivity.class) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); } + mHandler.post(new Runnable() { + public void run() { + if (guiListener() != null) + guiListener().onCallStateChanged(call, state, message); + } + }); } - private synchronized void stopRinging() { - if (mRingerPlayer !=null) { - mRingerPlayer.stop(); - mRingerPlayer.release(); - mRingerPlayer=null; - } - if (mVibrator!=null) { - mVibrator.cancel(); - } - } - public void ecCalibrationStatus(final LinphoneCore lc,final EcCalibratorStatus status, final int delay_ms, - final Object data) { + + + public void onEcCalibrationStatus(final EcCalibratorStatus status, Object data, + final int delay_ms) { final CheckBoxPreference pref = (CheckBoxPreference) data; + mHandler.post(new Runnable() { public void run() { if (status == EcCalibratorStatus.Done) { @@ -537,9 +230,25 @@ public class LinphoneService extends Service implements LinphoneCoreListener { pref.setChecked(false); } } - }); + }); } + - + public interface LinphoneGuiListener { + void onDisplayStatus(String message); + void onGlobalStateChangedToOn(String message); +// void onRegistrationStateChanged(RegistrationState state, String message); + void onCallStateChanged(LinphoneCall call, State state, String message); + } + + + public void onRingerPlayerCreated(MediaPlayer mRingerPlayer) { + final Uri ringtoneUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE); + try { + mRingerPlayer.setDataSource(getApplicationContext(), ringtoneUri); + } catch (IOException e) { + Log.e(LinphoneManager.TAG, "cannot set ringtone", e); + } + } } diff --git a/src/org/linphone/NetworkManager.java b/src/org/linphone/NetworkManager.java index b5b598c75..877fa72be 100644 --- a/src/org/linphone/NetworkManager.java +++ b/src/org/linphone/NetworkManager.java @@ -27,27 +27,34 @@ import android.util.Log; +/** + * + * Intercept network state changes and update linphone core through LinphoneManager. + * + */ public class NetworkManager extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { - NetworkInfo lNetworkInfo = (NetworkInfo) intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO); - Log.i(LinphoneService.TAG, "Network info ["+lNetworkInfo+"]"); + NetworkInfo lNetworkInfo = (NetworkInfo) intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO); + Log.i(LinphoneManager.TAG, "Network info ["+lNetworkInfo+"]"); Boolean lNoConnectivity = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY,false); - if (!LinphoneService.isready()) { - Log.i(LinphoneService.TAG, "Linphone service not ready"); + + + if (!LinphoneService.isReady()) { + Log.i(LinphoneManager.TAG, "Network broadcast received while Linphone service not ready"); return; } - if (lNoConnectivity| ((lNetworkInfo.getState() == NetworkInfo.State.DISCONNECTED) /*&& !lIsFailOver*/)) { - LinphoneService.instance().getLinphoneCore().setNetworkReachable(false); + + + if (lNoConnectivity | ((lNetworkInfo.getState() == NetworkInfo.State.DISCONNECTED) /*&& !lIsFailOver*/)) { + LinphoneManager.getLc().setNetworkReachable(false); } else if (lNetworkInfo.getState() == NetworkInfo.State.CONNECTED){ - LinphoneService.instance().getLinphoneCore().setNetworkReachable(true); + LinphoneManager.getLc().setNetworkReachable(true); } else { - //unhandled event + // Other unhandled events } - - } } diff --git a/src/org/linphone/OutgoingCallReceiver.java b/src/org/linphone/OutgoingCallReceiver.java index eab2e8db4..a26867f90 100644 --- a/src/org/linphone/OutgoingCallReceiver.java +++ b/src/org/linphone/OutgoingCallReceiver.java @@ -24,20 +24,30 @@ import android.content.Context; import android.content.Intent; import android.net.Uri; import android.preference.PreferenceManager; +import android.util.Log; +/** + * Intercept outgoing calls dialed through Android dialer. + * Redirect the calls through Linphone according to user preferences. + * + */ public class OutgoingCallReceiver extends BroadcastReceiver { - public static String TAG = ";0000000"; - public static String key_off="off"; - public static String key_on_demand="ask_for_outcall_interception"; - public static String key_always="alway_intercept_out_call"; + public static final String TAG = ";0000000"; + public static final String key_off="off"; + public static final String key_on_demand="ask_for_outcall_interception"; + public static final String key_always="alway_intercept_out_call"; + + @Override public void onReceive(Context context, Intent intent) { String to = intent.getStringExtra("android.intent.extra.PHONE_NUMBER"); + //do not catch ussd codes if (to==null || to.contains("#")) return; + if (!to.contains(TAG)) { - if (LinphoneService.isready() && LinphoneService.instance().getLinphoneCore().getDefaultProxyConfig()==null) { + if (LinphoneService.isReady() && LinphoneManager.getLc().getDefaultProxyConfig()==null) { //just return return; } @@ -52,7 +62,7 @@ public class OutgoingCallReceiver extends BroadcastReceiver { lIntent.setAction(Intent.ACTION_CALL); } - lIntent.setData(Uri.parse("tel://"+to+TAG)); + lIntent.setData(Uri.parse("tel:"+to+TAG)); lIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(lIntent); diff --git a/src/org/linphone/VideoCallActivity.java b/src/org/linphone/VideoCallActivity.java index 6e85ba90d..8023b2064 100644 --- a/src/org/linphone/VideoCallActivity.java +++ b/src/org/linphone/VideoCallActivity.java @@ -56,7 +56,7 @@ public class VideoCallActivity extends Activity { setContentView(R.layout.videocall); mVideoView = (SurfaceView) findViewById(R.id.video_surface); - LinphoneCore lc = LinphoneService.getLc(); + LinphoneCore lc = LinphoneManager.getLc(); lc.setVideoWindow(mVideoView); mVideoCaptureView = (SurfaceView) findViewById(R.id.video_capture_surface); @@ -72,7 +72,7 @@ public class VideoCallActivity extends Activity { mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK|PowerManager.ON_AFTER_RELEASE,"Linphone"); mWakeLock.acquire(); - if (Version.sdkBelow(8)) { + if (Version.sdkStrictlyBelow(8)) { // Force to display in portrait orientation for old devices // as they do not support surfaceView rotation setRequestedOrientation(recordManager.isCameraOrientationPortrait() ? @@ -87,7 +87,7 @@ public class VideoCallActivity extends Activity { @Override protected void onResume() { // Update call if orientation changed - if (Version.sdkAbove(8) && previousPhoneOrientation != phoneOrientation) { + if (Version.sdkAboveOrEqual(8) && previousPhoneOrientation != phoneOrientation) { CallManager.getInstance().updateCall(); resizeCapturePreview(mVideoCaptureView); } @@ -137,7 +137,7 @@ public class VideoCallActivity extends Activity { */ private void resizeCapturePreview(SurfaceView sv) { LayoutParams lp = sv.getLayoutParams(); - VideoSize vs = LinphoneService.getLc().getPreferredVideoSize(); + VideoSize vs = LinphoneManager.getLc().getPreferredVideoSize(); float newRatio = (float) vs.width / vs.height; @@ -180,11 +180,11 @@ public class VideoCallActivity extends Activity { resizeCapturePreview(mVideoCaptureView); break; default: - Log.e(LinphoneService.TAG, "Unknown menu item ["+item+"]"); + Log.e(LinphoneManager.TAG, "Unknown menu item ["+item+"]"); break; } - return false; + return true; } diff --git a/src/org/linphone/core/AndroidCameraRecordManager.java b/src/org/linphone/core/AndroidCameraRecordManager.java index 2ca3d70aa..ecf12c597 100644 --- a/src/org/linphone/core/AndroidCameraRecordManager.java +++ b/src/org/linphone/core/AndroidCameraRecordManager.java @@ -67,7 +67,7 @@ public class AndroidCameraRecordManager { // singleton private AndroidCameraRecordManager() { - cc = Version.sdkAbove(9) ? new AndroidCameraConf9() : new AndroidCameraConf(); + cc = Version.sdkAboveOrEqual(9) ? new AndroidCameraConf9() : new AndroidCameraConf(); int[] fId = {-1};int[] rId = {-1};int[] cId = {-1}; cc.findFrontAndRearCameraIds(fId, rId, cId); @@ -172,11 +172,11 @@ public class AndroidCameraRecordManager { parameters.rotation = bufferRotationForCorrectImageOrientation(); parameters.surfaceView = surfaceView; - if (Version.sdkAbove(9)) { + if (Version.sdkAboveOrEqual(9)) { recorder = new AndroidCameraRecord9Impl(parameters); - } else if (Version.sdkAbove(8)) { + } else if (Version.sdkAboveOrEqual(8)) { recorder = new AndroidCameraRecord8Impl(parameters); - } else if (Version.sdkAbove(5)) { + } else if (Version.sdkAboveOrEqual(5)) { recorder = new AndroidCameraRecord5Impl(parameters); } else { recorder = new AndroidCameraRecordImpl(parameters); @@ -208,7 +208,7 @@ public class AndroidCameraRecordManager { if (supportedVideoSizes != null) return supportedVideoSizes; } - if (Version.sdkAbove(5)) { + if (Version.sdkAboveOrEqual(5)) { supportedVideoSizes = AndroidCameraRecord5Impl.oneShotSupportedVideoSizes(); } @@ -253,7 +253,7 @@ public class AndroidCameraRecordManager { private int bufferRotationForCorrectImageOrientation() { final int cameraOrientation = cc.getCameraOrientation(cameraId); - final int rotation = Version.sdkAbove(8) ? + final int rotation = Version.sdkAboveOrEqual(8) ? (360 - cameraOrientation + 90 - phoneOrientation) % 360 : 0; Log.d(tag, "Capture video buffer will need a rotation of " + rotation diff --git a/src/org/linphone/core/LinphoneCoreImpl.java b/src/org/linphone/core/LinphoneCoreImpl.java index 1a9fc67a7..533ee8b97 100644 --- a/src/org/linphone/core/LinphoneCoreImpl.java +++ b/src/org/linphone/core/LinphoneCoreImpl.java @@ -64,7 +64,7 @@ class LinphoneCoreImpl implements LinphoneCore { private native void enableEchoCancellation(long nativePtr,boolean enable); private native boolean isEchoCancellationEnabled(long nativePtr); private native long getCurrentCall(long nativePtr) ; - private native void playDtmf(long nativePtr,char dtmf,int duration); + private native void playDtmf(long nativePtr,char dtmf,int duration, boolean speaker); private native void stopDtmf(long nativePtr); private native void setVideoWindowId(long nativePtr, Object wid); private native void setPreviewWindowId(long nativePtr, Object wid); @@ -298,8 +298,8 @@ class LinphoneCoreImpl implements LinphoneCore { // TODO Auto-generated method stub return false; } - public void playDtmf(char number, int duration) { - playDtmf(nativePtr,number, duration); + public void playDtmf(char number, int duration, boolean speaker) { + playDtmf(nativePtr,number, duration, speaker); } public void stopDtmf() { diff --git a/src/org/linphone/core/Version.java b/src/org/linphone/core/Version.java index 2b938dbea..057fb53a3 100644 --- a/src/org/linphone/core/Version.java +++ b/src/org/linphone/core/Version.java @@ -30,11 +30,11 @@ public class Version { 8 : Integer.parseInt(Build.VERSION.SDK); // Force versions above 9 to 8 // 7; // 2.1 - public static final boolean sdkAbove(int value) { + public static final boolean sdkAboveOrEqual(int value) { return buildVersion >= value; } - public static final boolean sdkBelow(int value) { + public static final boolean sdkStrictlyBelow(int value) { return buildVersion < value; } diff --git a/src/org/linphone/ui/AddVideoButton.java b/src/org/linphone/ui/AddVideoButton.java index 115fc7cfc..1d519d2ff 100644 --- a/src/org/linphone/ui/AddVideoButton.java +++ b/src/org/linphone/ui/AddVideoButton.java @@ -18,7 +18,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package org.linphone.ui; -import org.linphone.CallManager; +import org.linphone.LinphoneManager; import android.content.Context; import android.util.AttributeSet; @@ -37,7 +37,7 @@ public class AddVideoButton extends ImageButton implements OnClickListener { public void onClick(View v) { // If no in video call; try to reinvite with video - boolean alreadyInVideoCall = !CallManager.getInstance().reinviteWithVideo(); + boolean alreadyInVideoCall = !LinphoneManager.reinviteWithVideo(); if (alreadyInVideoCall && alreadyInVideoCallListener != null) { // In video call; going back to video call activity alreadyInVideoCallListener.onAlreadyInVideoCall(); diff --git a/src/org/linphone/ui/CallButton.java b/src/org/linphone/ui/CallButton.java index e00f3da8a..05a54f2b7 100644 --- a/src/org/linphone/ui/CallButton.java +++ b/src/org/linphone/ui/CallButton.java @@ -19,6 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. package org.linphone.ui; import org.linphone.LinphoneManager; +import org.linphone.R; import org.linphone.core.LinphoneCore; import org.linphone.core.LinphoneCoreException; @@ -27,10 +28,10 @@ import android.util.AttributeSet; import android.view.View; import android.view.View.OnClickListener; import android.widget.ImageButton; +import android.widget.Toast; public class CallButton extends ImageButton implements OnClickListener, AddressAwareWidget { - private CallButtonListener callButtonListener; private AddressText mAddress; public CallButton(Context context, AttributeSet attrs) { @@ -45,7 +46,7 @@ public class CallButton extends ImageButton implements OnClickListener, AddressA lc.acceptCall(lc.getCurrentCall()); } catch (LinphoneCoreException e) { lc.terminateCall(lc.getCurrentCall()); - callButtonListener.onWrongDestinationAddress(); + onWrongDestinationAddress(); } return; } @@ -55,16 +56,14 @@ public class CallButton extends ImageButton implements OnClickListener, AddressA } - - public static interface CallButtonListener { - void onWrongDestinationAddress(); + protected void onWrongDestinationAddress() { + Toast toast = Toast.makeText(getContext() + ,String.format(getResources().getString(R.string.warning_wrong_destination_address),mAddress.getText().toString()) + ,Toast.LENGTH_LONG); + toast.show(); } - public void setCallButtonListerner(CallButtonListener listener) { - callButtonListener = listener; - } - public void setAddressWidget(AddressText address) { mAddress = address; } diff --git a/src/org/linphone/ui/Digit.java b/src/org/linphone/ui/Digit.java index 8d4547150..89a52ceb0 100644 --- a/src/org/linphone/ui/Digit.java +++ b/src/org/linphone/ui/Digit.java @@ -108,7 +108,7 @@ public class Digit extends Button implements OnLongClickListener, AddressAwareWi public boolean onTouch(View v, MotionEvent event) { LinphoneCore lc = LinphoneManager.getLc(); if (event.getAction() == MotionEvent.ACTION_DOWN && mIsDtmfStarted ==false) { - LinphoneManager.getInstance().playDtmf(mKeyCode.charAt(0)); + LinphoneManager.getInstance().playDtmf(getContext().getContentResolver(), mKeyCode.charAt(0)); mIsDtmfStarted=true; } else { if (event.getAction() == MotionEvent.ACTION_UP) From 97ba73de8db19bee78c8133dc7b3d1cd3827432c Mon Sep 17 00:00:00 2001 From: Guillaume Beraudo Date: Wed, 23 Feb 2011 15:37:28 +0100 Subject: [PATCH 08/53] Enhancements: - Numpad component factorizing setAddressWidget - Digit uses style - No more NewOutgoingCallReceiver and the associated magic Now uses CALL_PRIVILEDGED - Move Video classes to core.video package and lower visibility - Merged AndroidCameraRecord5Impl and AndroidCameraRecordImpl --- AndroidManifest.xml | 10 +- res/layout-land/dialer.xml | 96 +++++++++---------- res/layout/dialer.xml | 56 +++-------- res/layout/numpad.xml | 31 ++++++ res/layout/outcall_choser.xml | 26 ----- res/values/array.xml | 8 -- res/values/strings.xml | 9 -- res/xml/preferences.xml | 1 - src/org/linphone/BandwidthManager.java | 2 +- src/org/linphone/CallManager.java | 2 +- src/org/linphone/DialerActivity.java | 39 +++----- src/org/linphone/LinphoneManager.java | 81 ++++++---------- src/org/linphone/LinphoneService.java | 30 +++++- src/org/linphone/OutgoingCallReceiver.java | 74 -------------- src/org/linphone/VideoCallActivity.java | 7 +- .../core/AndroidCameraRecord5Impl.java | 64 ------------- src/org/linphone/core/Version.java | 4 + .../tutorials/AndroidTutorialNotifier.java | 3 +- .../core/tutorials/JavaCameraRecordImpl.java | 10 +- .../core/tutorials/TestVideoActivity.java | 2 +- .../core/{ => video}/AndroidCameraConf.java | 7 +- .../core/{ => video}/AndroidCameraConf9.java | 4 +- .../core/{ => video}/AndroidCameraRecord.java | 2 +- .../AndroidCameraRecord8.java} | 6 +- .../AndroidCameraRecord9.java} | 6 +- .../{ => video}/AndroidCameraRecordImpl.java | 37 ++++++- .../AndroidCameraRecordManager.java | 15 +-- src/org/linphone/ui/AddressAwareWidget.java | 2 + src/org/linphone/ui/Digit.java | 39 ++++---- src/org/linphone/ui/Numpad.java | 64 +++++++++++++ 30 files changed, 331 insertions(+), 406 deletions(-) create mode 100644 res/layout/numpad.xml delete mode 100644 res/layout/outcall_choser.xml delete mode 100644 res/values/array.xml delete mode 100644 src/org/linphone/OutgoingCallReceiver.java delete mode 100644 src/org/linphone/core/AndroidCameraRecord5Impl.java rename src/org/linphone/core/{ => video}/AndroidCameraConf.java (94%) rename src/org/linphone/core/{ => video}/AndroidCameraConf9.java (94%) rename src/org/linphone/core/{ => video}/AndroidCameraRecord.java (99%) rename src/org/linphone/core/{AndroidCameraRecord8Impl.java => video/AndroidCameraRecord8.java} (92%) rename src/org/linphone/core/{AndroidCameraRecord9Impl.java => video/AndroidCameraRecord9.java} (86%) rename src/org/linphone/core/{ => video}/AndroidCameraRecordImpl.java (67%) rename src/org/linphone/core/{ => video}/AndroidCameraRecordManager.java (94%) create mode 100644 src/org/linphone/ui/Numpad.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index c44111fef..7eb49ab52 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -66,13 +66,7 @@ - - - - - - - + @@ -84,7 +78,7 @@ - - - - - - + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - + - + - + + + + + + + + - - - - - - - diff --git a/res/layout/dialer.xml b/res/layout/dialer.xml index a029f42c7..d79bc546b 100644 --- a/res/layout/dialer.xml +++ b/res/layout/dialer.xml @@ -5,8 +5,7 @@ android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - + + + + + + + + diff --git a/res/layout/numpad.xml b/res/layout/numpad.xml new file mode 100644 index 000000000..8ff240fa5 --- /dev/null +++ b/res/layout/numpad.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/layout/outcall_choser.xml b/res/layout/outcall_choser.xml deleted file mode 100644 index d1c116463..000000000 --- a/res/layout/outcall_choser.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - diff --git a/res/values/array.xml b/res/values/array.xml deleted file mode 100644 index 55b12f0b3..000000000 --- a/res/values/array.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - -off -ask_for_outcall_interception -alway_intercept_out_call - - diff --git a/res/values/strings.xml b/res/values/strings.xml index 99faf8fe9..9e353027e 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -37,9 +37,6 @@ iLBC might be unavailable depending on ARM processor and Android OS version. Echo cancellation pref_echo_cancellation_key - Configure how cellular calls are redirected to voip when possible - Redirect cellular calls - pref_handle_outcall_key_v2 Start at boot time pref_autostart_key Cellular @@ -109,10 +106,4 @@ Calibrating... Calibrated [%s ms] failed - - -Off -On demand -Always - diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml index 95d922f8a..ec287fb62 100644 --- a/res/xml/preferences.xml +++ b/res/xml/preferences.xml @@ -35,7 +35,6 @@ - diff --git a/src/org/linphone/BandwidthManager.java b/src/org/linphone/BandwidthManager.java index 9d0bb5bb0..7f3e4e3f5 100644 --- a/src/org/linphone/BandwidthManager.java +++ b/src/org/linphone/BandwidthManager.java @@ -18,10 +18,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package org.linphone; -import org.linphone.core.AndroidCameraRecordManager; import org.linphone.core.LinphoneCallParams; import org.linphone.core.LinphoneCore; import org.linphone.core.VideoSize; +import org.linphone.core.video.AndroidCameraRecordManager; public class BandwidthManager { diff --git a/src/org/linphone/CallManager.java b/src/org/linphone/CallManager.java index a1e9a3feb..b7138bb3e 100644 --- a/src/org/linphone/CallManager.java +++ b/src/org/linphone/CallManager.java @@ -18,12 +18,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package org.linphone; -import org.linphone.core.AndroidCameraRecordManager; import org.linphone.core.LinphoneAddress; import org.linphone.core.LinphoneCall; import org.linphone.core.LinphoneCallParams; import org.linphone.core.LinphoneCore; import org.linphone.core.LinphoneCoreException; +import org.linphone.core.video.AndroidCameraRecordManager; /** * Handle call updating, reinvites. diff --git a/src/org/linphone/DialerActivity.java b/src/org/linphone/DialerActivity.java index 03181ef68..9daff6f58 100644 --- a/src/org/linphone/DialerActivity.java +++ b/src/org/linphone/DialerActivity.java @@ -20,14 +20,14 @@ package org.linphone; import org.linphone.LinphoneManager.NewOutgoingCallUiListener; import org.linphone.LinphoneService.LinphoneGuiListener; -import org.linphone.core.AndroidCameraRecordManager; import org.linphone.core.LinphoneCall; import org.linphone.core.LinphoneCore; import org.linphone.core.LinphoneCall.State; +import org.linphone.core.video.AndroidCameraRecordManager; import org.linphone.ui.AddVideoButton; +import org.linphone.ui.AddressAwareWidget; import org.linphone.ui.AddressText; import org.linphone.ui.CallButton; -import org.linphone.ui.Digit; import org.linphone.ui.EraseButton; import org.linphone.ui.MuteMicButton; import org.linphone.ui.SpeakerButton; @@ -46,8 +46,6 @@ import android.preference.PreferenceManager; import android.text.Html; import android.util.Log; import android.view.View; -import android.widget.LinearLayout; -import android.widget.TableRow; import android.widget.TextView; import android.widget.Toast; @@ -76,8 +74,8 @@ public class DialerActivity extends Activity implements LinphoneGuiListener, Alr private MuteMicButton mMute; private SpeakerButton mSpeaker; - private LinearLayout mCallControlRow; - private TableRow mInCallControlRow; + private View mCallControlRow; + private View mInCallControlRow; private View mAddressLayout; private View mInCallAddressLayout; @@ -138,15 +136,15 @@ public class DialerActivity extends Activity implements LinphoneGuiListener, Alr mHangup = findViewById(R.id.HangUp); - mCallControlRow = (LinearLayout) findViewById(R.id.CallControlRow); - mAddressLayout = (View) findViewById(R.id.Addresslayout); + mCallControlRow = findViewById(R.id.CallControlRow); + mAddressLayout = findViewById(R.id.Addresslayout); - mInCallControlRow = (TableRow) findViewById(R.id.IncallControlRow); + mInCallControlRow = findViewById(R.id.IncallControlRow); mInCallControlRow.setVisibility(View.GONE); - mInCallAddressLayout = (View) findViewById(R.id.IncallAddressLayout); + mInCallAddressLayout = findViewById(R.id.IncallAddressLayout); mInCallAddressLayout.setVisibility(View.GONE); - mMute = (MuteMicButton)findViewById(R.id.mic_mute_button); - mSpeaker = (SpeakerButton)findViewById(R.id.speaker_button); + mMute = (MuteMicButton) findViewById(R.id.mic_mute_button); + mSpeaker = (SpeakerButton) findViewById(R.id.speaker_button); try { @@ -181,21 +179,10 @@ public class DialerActivity extends Activity implements LinphoneGuiListener, Alr finish(); } + AddressAwareWidget numpad = (AddressAwareWidget) findViewById(R.id.Dialer); + if (numpad != null) + numpad.setAddressWidget(mAddress); - if (findViewById(R.id.Digit00) != null) { // In landscape view, no keyboard - ((Digit) findViewById(R.id.Digit00)).setAddressWidget(mAddress); - ((Digit) findViewById(R.id.Digit1)).setAddressWidget(mAddress); - ((Digit) findViewById(R.id.Digit2)).setAddressWidget(mAddress); - ((Digit) findViewById(R.id.Digit3)).setAddressWidget(mAddress); - ((Digit) findViewById(R.id.Digit4)).setAddressWidget(mAddress); - ((Digit) findViewById(R.id.Digit5)).setAddressWidget(mAddress); - ((Digit) findViewById(R.id.Digit6)).setAddressWidget(mAddress); - ((Digit) findViewById(R.id.Digit7)).setAddressWidget(mAddress); - ((Digit) findViewById(R.id.Digit8)).setAddressWidget(mAddress); - ((Digit) findViewById(R.id.Digit9)).setAddressWidget(mAddress); - ((Digit) findViewById(R.id.DigitStar)).setAddressWidget(mAddress); - ((Digit) findViewById(R.id.DigitHash)).setAddressWidget(mAddress); - } mStatus = (TextView) findViewById(R.id.status_label); diff --git a/src/org/linphone/LinphoneManager.java b/src/org/linphone/LinphoneManager.java index 070fa0fd8..50b2ea57f 100644 --- a/src/org/linphone/LinphoneManager.java +++ b/src/org/linphone/LinphoneManager.java @@ -25,7 +25,6 @@ import java.io.InputStream; import java.util.Timer; import java.util.TimerTask; -import org.linphone.core.AndroidCameraRecordManager; import org.linphone.core.LinphoneAddress; import org.linphone.core.LinphoneAuthInfo; import org.linphone.core.LinphoneCall; @@ -42,16 +41,16 @@ import org.linphone.core.LinphoneCore.EcCalibratorStatus; import org.linphone.core.LinphoneCore.FirewallPolicy; import org.linphone.core.LinphoneCore.GlobalState; import org.linphone.core.LinphoneCore.RegistrationState; +import org.linphone.core.video.AndroidCameraRecordManager; import android.content.BroadcastReceiver; -import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; -import android.content.pm.PackageManager; import android.content.res.Resources; +import android.hardware.Camera; import android.media.AudioManager; import android.media.MediaPlayer; import android.net.ConnectivityManager; @@ -83,7 +82,6 @@ public final class LinphoneManager implements LinphoneCoreListener { private static LinphoneManager instance; private AudioManager mAudioManager; - private NewOutgoingCallUiListener newOutgoingCallUiListener; private SharedPreferences mPref; private Resources mR; private LinphoneCore mLc; @@ -95,7 +93,6 @@ public final class LinphoneManager implements LinphoneCoreListener { mAudioManager = ((AudioManager) c.getSystemService(Context.AUDIO_SERVICE)); mVibrator = (Vibrator) c.getSystemService(Context.VIBRATOR_SERVICE); mPref = PreferenceManager.getDefaultSharedPreferences(c); - mPackageManager = c.getPackageManager(); mR = c.getResources(); // Register a sensor to track phoneOrientation for placing new calls. @@ -111,8 +108,22 @@ public final class LinphoneManager implements LinphoneCoreListener { mPhoneOrientation = o; } }.enable(); + + detectIfHasCamera(); } + private void detectIfHasCamera() { + Log.i(TAG, "Detecting if a camera is present"); + try { + Camera camera = Camera.open(); + if (hasCamera = camera != null) { + camera.release(); + } + } catch (Throwable e) {} + Log.i(TAG, (hasCamera ? "A" : "No") + " camera is present"); + + } + public static final String TAG="Linphone"; /** Called when the activity is first created. */ private static final String LINPHONE_FACTORY_RC = "/data/data/org.linphone/files/linphonerc"; @@ -123,7 +134,7 @@ public final class LinphoneManager implements LinphoneCoreListener { private Timer mTimer = new Timer("Linphone scheduler"); private BroadcastReceiver mKeepAliveReceiver = new KeepAliveReceiver(); - private PackageManager mPackageManager; + private boolean hasCamera; @@ -157,12 +168,14 @@ public final class LinphoneManager implements LinphoneCoreListener { } } - public synchronized static final LinphoneManager createAndStart(Context c, LinphoneServiceListener listener) { + public synchronized static final LinphoneManager createAndStart( + Context c, LinphoneServiceListener listener) { if (instance != null) throw new RuntimeException("Linphone Manager is already initialized"); instance = new LinphoneManager(c); - instance.startLibLinphone(c, listener); + instance.serviceListener = listener; + instance.startLibLinphone(c); return instance; } @@ -186,20 +199,16 @@ public final class LinphoneManager implements LinphoneCoreListener { public void newOutgoingCall(AddressType address) { String to = address.getText().toString(); - if (to.contains(OutgoingCallReceiver.TAG)) { - to = to.replace(OutgoingCallReceiver.TAG, ""); - address.setText(to); - } if (mLc.isIncall()) { - newOutgoingCallUiListener.onAlreadyInCall(); + serviceListener.tryingNewOutgoingCallButAlreadyInCall(); return; } LinphoneAddress lAddress; try { lAddress = mLc.interpretUrl(to); } catch (LinphoneCoreException e) { - newOutgoingCallUiListener.onWrongDestinationAddress(); + serviceListener.tryingNewOutgoingCallButWrongDestinationAddress(); return; } lAddress.setDisplayName(address.getDisplayedName()); @@ -211,7 +220,7 @@ public final class LinphoneManager implements LinphoneCoreListener { CallManager.getInstance().inviteAddress(lAddress, prefVideoEnable && prefInitiateWithVideo); } catch (LinphoneCoreException e) { - newOutgoingCallUiListener.onCannotGetCallParameters(); + serviceListener.tryingNewOutgoingCallButCannotGetCallParameters(); return; } } @@ -223,10 +232,6 @@ public final class LinphoneManager implements LinphoneCoreListener { AndroidCameraRecordManager.getInstance().setPhoneOrientation(mPhoneOrientation); } - public void setNewOutgoingCallUiListener(NewOutgoingCallUiListener l) { - this.newOutgoingCallUiListener = l; - } - public static interface AddressType { void setText(CharSequence s); CharSequence getText(); @@ -288,9 +293,8 @@ public final class LinphoneManager implements LinphoneCoreListener { sendStaticImage(rm.toggleMute()); } - private synchronized void startLibLinphone(final Context context, final LinphoneServiceListener listener) { + private synchronized void startLibLinphone(final Context context) { try { - this.serviceListener = listener; copyAssetsFromPackage(context); mLc = LinphoneCoreFactory.instance().createLinphoneCore( @@ -370,28 +374,6 @@ public final class LinphoneManager implements LinphoneCoreListener { } - String sOutcalls = mPref.getString(getString(R.string.pref_handle_outcall_key), OutgoingCallReceiver.key_on_demand); - boolean handleOutcalls = !sOutcalls.equalsIgnoreCase(OutgoingCallReceiver.key_off); - -/* Now useless, see enablePkgComponent - * if (handleOutcalls){ - IntentFilter lFilter = new IntentFilter(Intent.ACTION_SCREEN_ON); - lFilter.setPriority(0); - lFilter.addAction(Intent.ACTION_NEW_OUTGOING_CALL); - if (mOutgoingCallReceiver == null) { - mOutgoingCallReceiver = new OutgoingCallReceiver(); - } - context.registerReceiver(mOutgoingCallReceiver,lFilter); - } else if (mOutgoingCallReceiver!=null) { - context.unregisterReceiver(mOutgoingCallReceiver); - mOutgoingCallReceiver=null; - }*/ - - // Enable/disable outgoing call receiver according to user wishes - // Could be done already once when the preference is changed in UI. - enablePkgComponent(context, OutgoingCallReceiver.class, handleOutcalls); - - mLc.enableEchoCancellation(mPref.getBoolean(getString(R.string.pref_echo_cancellation_key),false)); } catch (LinphoneCoreException e) { throw new LinphoneConfigException(getString(R.string.wrong_settings),e); @@ -480,14 +462,6 @@ public final class LinphoneManager implements LinphoneCoreListener { } - private void enablePkgComponent(Context context, Class clazz, boolean state) { - mPackageManager.setComponentEnabledSetting( - new ComponentName(context, clazz), - state ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED - : PackageManager.COMPONENT_ENABLED_STATE_DISABLED, - 0); - } - private void enableDisableAudioCodec(String codec, int rate, int key) throws LinphoneCoreException { PayloadType pt = mLc.findPayloadType(codec, rate); if (pt !=null) { @@ -517,7 +491,7 @@ public final class LinphoneManager implements LinphoneCoreListener { } public boolean hasCamera() { - return mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA); + return hasCamera; } public static synchronized void destroy(Context context) { @@ -555,6 +529,9 @@ public final class LinphoneManager implements LinphoneCoreListener { public interface LinphoneServiceListener { void onGlobalStateChanged(GlobalState state, String message); + void tryingNewOutgoingCallButCannotGetCallParameters(); + void tryingNewOutgoingCallButWrongDestinationAddress(); + void tryingNewOutgoingCallButAlreadyInCall(); void onRegistrationStateChanged(RegistrationState state, String message); void onCallStateChanged(LinphoneCall call, State state, String message); void onEcCalibrationStatus(EcCalibratorStatus status, Object data, diff --git a/src/org/linphone/LinphoneService.java b/src/org/linphone/LinphoneService.java index 6993df5bc..adeaed939 100644 --- a/src/org/linphone/LinphoneService.java +++ b/src/org/linphone/LinphoneService.java @@ -21,6 +21,7 @@ package org.linphone; import java.io.IOException; import org.linphone.LinphoneManager.LinphoneServiceListener; +import org.linphone.LinphoneManager.NewOutgoingCallUiListener; import org.linphone.core.LinphoneCall; import org.linphone.core.LinphoneCore; import org.linphone.core.LinphoneCall.State; @@ -234,7 +235,7 @@ public final class LinphoneService extends Service implements LinphoneServiceLis } - public interface LinphoneGuiListener { + public interface LinphoneGuiListener extends NewOutgoingCallUiListener { void onDisplayStatus(String message); void onGlobalStateChangedToOn(String message); // void onRegistrationStateChanged(RegistrationState state, String message); @@ -250,5 +251,32 @@ public final class LinphoneService extends Service implements LinphoneServiceLis Log.e(LinphoneManager.TAG, "cannot set ringtone", e); } } + + public void tryingNewOutgoingCallButAlreadyInCall() { + mHandler.post(new Runnable() { + public void run() { + if (guiListener() != null) + guiListener().onAlreadyInCall(); + } + }); + } + + public void tryingNewOutgoingCallButCannotGetCallParameters() { + mHandler.post(new Runnable() { + public void run() { + if (guiListener() != null) + guiListener().onCannotGetCallParameters(); + } + }); + } + + public void tryingNewOutgoingCallButWrongDestinationAddress() { + mHandler.post(new Runnable() { + public void run() { + if (guiListener() != null) + guiListener().onWrongDestinationAddress(); + } + }); + } } diff --git a/src/org/linphone/OutgoingCallReceiver.java b/src/org/linphone/OutgoingCallReceiver.java deleted file mode 100644 index a26867f90..000000000 --- a/src/org/linphone/OutgoingCallReceiver.java +++ /dev/null @@ -1,74 +0,0 @@ -/* -OutgoingCallReceiver.java -Copyright (C) 2010 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 android.app.Activity; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.net.Uri; -import android.preference.PreferenceManager; -import android.util.Log; - -/** - * Intercept outgoing calls dialed through Android dialer. - * Redirect the calls through Linphone according to user preferences. - * - */ -public class OutgoingCallReceiver extends BroadcastReceiver { - public static final String TAG = ";0000000"; - public static final String key_off="off"; - public static final String key_on_demand="ask_for_outcall_interception"; - public static final String key_always="alway_intercept_out_call"; - - - @Override - public void onReceive(Context context, Intent intent) { - String to = intent.getStringExtra("android.intent.extra.PHONE_NUMBER"); - - //do not catch ussd codes - if (to==null || to.contains("#")) - return; - - if (!to.contains(TAG)) { - if (LinphoneService.isReady() && LinphoneManager.getLc().getDefaultProxyConfig()==null) { - //just return - return; - } - setResult(Activity.RESULT_OK,null, null); - Intent lIntent = new Intent(); - // 1 check config - if (PreferenceManager.getDefaultSharedPreferences(context).getString(context.getString(R.string.pref_handle_outcall_key),key_on_demand).equals(key_always)) { - //start linphone directly - lIntent.setClass(context, LinphoneActivity.class); - } else { - //start activity chooser - lIntent.setAction(Intent.ACTION_CALL); - } - - lIntent.setData(Uri.parse("tel:"+to+TAG)); - lIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - context.startActivity(lIntent); - - } else { - setResult(Activity.RESULT_OK,to.replace(TAG, ""),null); - } - } - -} diff --git a/src/org/linphone/VideoCallActivity.java b/src/org/linphone/VideoCallActivity.java index 8023b2064..93157d837 100644 --- a/src/org/linphone/VideoCallActivity.java +++ b/src/org/linphone/VideoCallActivity.java @@ -20,10 +20,10 @@ package org.linphone; -import org.linphone.core.AndroidCameraRecordManager; import org.linphone.core.LinphoneCore; import org.linphone.core.Version; import org.linphone.core.VideoSize; +import org.linphone.core.video.AndroidCameraRecordManager; import android.app.Activity; import android.content.Context; @@ -38,6 +38,11 @@ import android.view.MenuItem; import android.view.SurfaceView; import android.view.ViewGroup.LayoutParams; +/** + * For Android SDK >= + * @author Guillaume Beraudo + * + */ public class VideoCallActivity extends Activity { private SurfaceView mVideoView; private SurfaceView mVideoCaptureView; diff --git a/src/org/linphone/core/AndroidCameraRecord5Impl.java b/src/org/linphone/core/AndroidCameraRecord5Impl.java deleted file mode 100644 index 18e487d12..000000000 --- a/src/org/linphone/core/AndroidCameraRecord5Impl.java +++ /dev/null @@ -1,64 +0,0 @@ -/* -AndroidCameraRecordImplAPI5.java -Copyright (C) 2010 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.core; - -import java.util.List; - -import android.hardware.Camera; -import android.hardware.Camera.Parameters; -import android.hardware.Camera.Size; -import android.util.Log; - - -public class AndroidCameraRecord5Impl extends AndroidCameraRecordImpl { - - public AndroidCameraRecord5Impl(RecorderParams parameters) { - super(parameters); - } - - @Override - protected void onSettingCameraParameters(Parameters parameters) { - super.onSettingCameraParameters(parameters); - - if (parameters.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_AUTO)) { - Log.w(tag, "Auto Focus supported by camera device"); - parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); - } else { - Log.w(tag, "Auto Focus not supported by camera device"); - if (parameters.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_INFINITY)) { - Log.w(tag, "Infinity Focus supported by camera device"); - parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_INFINITY); - } else { - Log.w(tag, "Infinity Focus not supported by camera device"); - } - } - } - - public static List oneShotSupportedVideoSizes() { - Camera camera = Camera.open(); - List supportedVideoSizes =camera.getParameters().getSupportedPreviewSizes(); - camera.release(); - return supportedVideoSizes; - } - - @Override - protected List getSupportedPreviewSizes(Parameters parameters) { - return parameters.getSupportedPreviewSizes(); - } -} diff --git a/src/org/linphone/core/Version.java b/src/org/linphone/core/Version.java index 057fb53a3..c06a2efea 100644 --- a/src/org/linphone/core/Version.java +++ b/src/org/linphone/core/Version.java @@ -38,4 +38,8 @@ public class Version { return buildVersion < value; } + public static int sdk() { + return buildVersion; + } + } \ No newline at end of file diff --git a/src/org/linphone/core/tutorials/AndroidTutorialNotifier.java b/src/org/linphone/core/tutorials/AndroidTutorialNotifier.java index 01e0555e2..7721f7dc1 100644 --- a/src/org/linphone/core/tutorials/AndroidTutorialNotifier.java +++ b/src/org/linphone/core/tutorials/AndroidTutorialNotifier.java @@ -23,11 +23,12 @@ import android.widget.TextView; /** * Write notifications to a TextView widget. + * This is an helper class, not a test activity. * * @author Guillaume Beraudo * */ -public class AndroidTutorialNotifier extends TutorialNotifier { +class AndroidTutorialNotifier extends TutorialNotifier { private Handler mHandler; private TextView outputTextView; diff --git a/src/org/linphone/core/tutorials/JavaCameraRecordImpl.java b/src/org/linphone/core/tutorials/JavaCameraRecordImpl.java index 33cc6b22e..a40bee238 100644 --- a/src/org/linphone/core/tutorials/JavaCameraRecordImpl.java +++ b/src/org/linphone/core/tutorials/JavaCameraRecordImpl.java @@ -18,7 +18,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package org.linphone.core.tutorials; -import org.linphone.core.AndroidCameraRecord; +import org.linphone.core.video.AndroidCameraRecord; import android.hardware.Camera; import android.hardware.Camera.PreviewCallback; @@ -26,7 +26,13 @@ import android.hardware.Camera.Size; import android.util.Log; import android.widget.TextView; -public class JavaCameraRecordImpl extends AndroidCameraRecord implements PreviewCallback { +/** + * This is an helper class, not a test activity. + * + * @author Guillaume Beraudo + * + */ +class JavaCameraRecordImpl extends AndroidCameraRecord implements PreviewCallback { private TextView debug; private long count = 0; diff --git a/src/org/linphone/core/tutorials/TestVideoActivity.java b/src/org/linphone/core/tutorials/TestVideoActivity.java index 6bbdab517..ce3a9185b 100644 --- a/src/org/linphone/core/tutorials/TestVideoActivity.java +++ b/src/org/linphone/core/tutorials/TestVideoActivity.java @@ -21,8 +21,8 @@ package org.linphone.core.tutorials; import java.util.Stack; import org.linphone.R; -import org.linphone.core.AndroidCameraRecord; import org.linphone.core.VideoSize; +import org.linphone.core.video.AndroidCameraRecord; import android.app.Activity; import android.os.Bundle; diff --git a/src/org/linphone/core/AndroidCameraConf.java b/src/org/linphone/core/video/AndroidCameraConf.java similarity index 94% rename from src/org/linphone/core/AndroidCameraConf.java rename to src/org/linphone/core/video/AndroidCameraConf.java index 523f249b0..1d430082e 100644 --- a/src/org/linphone/core/AndroidCameraConf.java +++ b/src/org/linphone/core/video/AndroidCameraConf.java @@ -16,13 +16,13 @@ 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.core; +package org.linphone.core.video; import org.linphone.Hacks; import android.util.Log; -public class AndroidCameraConf { +class AndroidCameraConf { private static final String tag = "Linphone"; public void findFrontAndRearCameraIds(int[] frontCameraId, int[] rearCameraId, int[] cameraId) { @@ -39,6 +39,7 @@ public class AndroidCameraConf { } public int getNumberOfCameras() { + Log.i(tag, "Detecting the number of cameras"); // Use hacks to guess the number of cameras if (Hacks.isGalaxyS()) { Log.d(tag, "Hack Galaxy S : has 2 cameras"); @@ -46,7 +47,7 @@ public class AndroidCameraConf { } else return 1; } - + public int getCameraOrientation(int cameraId) { diff --git a/src/org/linphone/core/AndroidCameraConf9.java b/src/org/linphone/core/video/AndroidCameraConf9.java similarity index 94% rename from src/org/linphone/core/AndroidCameraConf9.java rename to src/org/linphone/core/video/AndroidCameraConf9.java index 07e49bab0..4c3713b83 100644 --- a/src/org/linphone/core/AndroidCameraConf9.java +++ b/src/org/linphone/core/video/AndroidCameraConf9.java @@ -16,11 +16,11 @@ 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.core; +package org.linphone.core.video; import android.hardware.Camera; -public class AndroidCameraConf9 extends AndroidCameraConf { +class AndroidCameraConf9 extends AndroidCameraConf { public void findFrontAndRearCameraIds9(Integer frontCameraId, Integer rearCameraId, Integer cameraId) { for (int id=0; id < getNumberOfCameras(); id++) { diff --git a/src/org/linphone/core/AndroidCameraRecord.java b/src/org/linphone/core/video/AndroidCameraRecord.java similarity index 99% rename from src/org/linphone/core/AndroidCameraRecord.java rename to src/org/linphone/core/video/AndroidCameraRecord.java index 6feafc322..64af664f5 100644 --- a/src/org/linphone/core/AndroidCameraRecord.java +++ b/src/org/linphone/core/video/AndroidCameraRecord.java @@ -16,7 +16,7 @@ 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.core; +package org.linphone.core.video; import java.util.ArrayList; import java.util.Collections; diff --git a/src/org/linphone/core/AndroidCameraRecord8Impl.java b/src/org/linphone/core/video/AndroidCameraRecord8.java similarity index 92% rename from src/org/linphone/core/AndroidCameraRecord8Impl.java rename to src/org/linphone/core/video/AndroidCameraRecord8.java index 490d9ad97..20805bd64 100644 --- a/src/org/linphone/core/AndroidCameraRecord8Impl.java +++ b/src/org/linphone/core/video/AndroidCameraRecord8.java @@ -16,7 +16,7 @@ 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.core; +package org.linphone.core.video; import android.hardware.Camera; import android.hardware.Camera.Parameters; @@ -30,10 +30,10 @@ import android.util.Log; * @author Guillaume Beraudo * */ -public class AndroidCameraRecord8Impl extends AndroidCameraRecord5Impl { +class AndroidCameraRecord8 extends AndroidCameraRecordImpl { - public AndroidCameraRecord8Impl(RecorderParams parameters) { + public AndroidCameraRecord8(RecorderParams parameters) { super(parameters); } diff --git a/src/org/linphone/core/AndroidCameraRecord9Impl.java b/src/org/linphone/core/video/AndroidCameraRecord9.java similarity index 86% rename from src/org/linphone/core/AndroidCameraRecord9Impl.java rename to src/org/linphone/core/video/AndroidCameraRecord9.java index 0ddb283d2..d81e8103e 100644 --- a/src/org/linphone/core/AndroidCameraRecord9Impl.java +++ b/src/org/linphone/core/video/AndroidCameraRecord9.java @@ -16,7 +16,7 @@ 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.core; +package org.linphone.core.video; import android.hardware.Camera; @@ -26,10 +26,10 @@ import android.hardware.Camera; * @author Guillaume Beraudo * */ -public class AndroidCameraRecord9Impl extends AndroidCameraRecord8Impl { +class AndroidCameraRecord9 extends AndroidCameraRecord8 { - public AndroidCameraRecord9Impl(RecorderParams parameters) { + public AndroidCameraRecord9(RecorderParams parameters) { super(parameters); } diff --git a/src/org/linphone/core/AndroidCameraRecordImpl.java b/src/org/linphone/core/video/AndroidCameraRecordImpl.java similarity index 67% rename from src/org/linphone/core/AndroidCameraRecordImpl.java rename to src/org/linphone/core/video/AndroidCameraRecordImpl.java index f1a4f4844..9e30cca07 100644 --- a/src/org/linphone/core/AndroidCameraRecordImpl.java +++ b/src/org/linphone/core/video/AndroidCameraRecordImpl.java @@ -16,19 +16,24 @@ 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.core; +package org.linphone.core.video; + +import java.util.List; import android.hardware.Camera; +import android.hardware.Camera.Parameters; import android.hardware.Camera.PreviewCallback; +import android.hardware.Camera.Size; import android.util.Log; /** * Record from Android camera. + * Android >= 5 (2.0) version. * * @author Guillaume Beraudo * */ -public class AndroidCameraRecordImpl extends AndroidCameraRecord implements PreviewCallback { +class AndroidCameraRecordImpl extends AndroidCameraRecord implements PreviewCallback { private long filterCtxPtr; private double timeElapsedBetweenFrames = 0; @@ -85,7 +90,35 @@ public class AndroidCameraRecordImpl extends AndroidCameraRecord implements Prev putImage(filterCtxPtr, data, rotation); } + @Override + protected void onSettingCameraParameters(Parameters parameters) { + super.onSettingCameraParameters(parameters); + if (parameters.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_AUTO)) { + Log.w(tag, "Auto Focus supported by camera device"); + parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); + } else { + Log.w(tag, "Auto Focus not supported by camera device"); + if (parameters.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_INFINITY)) { + Log.w(tag, "Infinity Focus supported by camera device"); + parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_INFINITY); + } else { + Log.w(tag, "Infinity Focus not supported by camera device"); + } + } + } + + public static List oneShotSupportedVideoSizes() { + Camera camera = Camera.open(); + List supportedVideoSizes =camera.getParameters().getSupportedPreviewSizes(); + camera.release(); + return supportedVideoSizes; + } + + @Override + protected List getSupportedPreviewSizes(Parameters parameters) { + return parameters.getSupportedPreviewSizes(); + } @Override protected void lowLevelSetPreviewCallback(Camera camera, PreviewCallback cb) { diff --git a/src/org/linphone/core/AndroidCameraRecordManager.java b/src/org/linphone/core/video/AndroidCameraRecordManager.java similarity index 94% rename from src/org/linphone/core/AndroidCameraRecordManager.java rename to src/org/linphone/core/video/AndroidCameraRecordManager.java index ecf12c597..87c4f53ac 100644 --- a/src/org/linphone/core/AndroidCameraRecordManager.java +++ b/src/org/linphone/core/video/AndroidCameraRecordManager.java @@ -16,11 +16,12 @@ 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.core; +package org.linphone.core.video; import java.util.List; -import org.linphone.core.AndroidCameraRecord.RecorderParams; +import org.linphone.core.Version; +import org.linphone.core.video.AndroidCameraRecord.RecorderParams; import android.hardware.Camera.Size; import android.util.Log; @@ -173,13 +174,13 @@ public class AndroidCameraRecordManager { parameters.surfaceView = surfaceView; if (Version.sdkAboveOrEqual(9)) { - recorder = new AndroidCameraRecord9Impl(parameters); + recorder = new AndroidCameraRecord9(parameters); } else if (Version.sdkAboveOrEqual(8)) { - recorder = new AndroidCameraRecord8Impl(parameters); + recorder = new AndroidCameraRecord8(parameters); } else if (Version.sdkAboveOrEqual(5)) { - recorder = new AndroidCameraRecord5Impl(parameters); - } else { recorder = new AndroidCameraRecordImpl(parameters); + } else { + throw new RuntimeException("SDK version unsupported " + Version.sdk()); } recorder.startPreview(); @@ -209,7 +210,7 @@ public class AndroidCameraRecordManager { } if (Version.sdkAboveOrEqual(5)) { - supportedVideoSizes = AndroidCameraRecord5Impl.oneShotSupportedVideoSizes(); + supportedVideoSizes = AndroidCameraRecordImpl.oneShotSupportedVideoSizes(); } // eventually null diff --git a/src/org/linphone/ui/AddressAwareWidget.java b/src/org/linphone/ui/AddressAwareWidget.java index 5a46cc6db..451271e3f 100644 --- a/src/org/linphone/ui/AddressAwareWidget.java +++ b/src/org/linphone/ui/AddressAwareWidget.java @@ -18,6 +18,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package org.linphone.ui; + + public interface AddressAwareWidget { void setAddressWidget(AddressText address); diff --git a/src/org/linphone/ui/Digit.java b/src/org/linphone/ui/Digit.java index 89a52ceb0..023bbd5d0 100644 --- a/src/org/linphone/ui/Digit.java +++ b/src/org/linphone/ui/Digit.java @@ -25,10 +25,9 @@ import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; -import android.view.View.OnLongClickListener; import android.widget.Button; -public class Digit extends Button implements OnLongClickListener, AddressAwareWidget { +public class Digit extends Button implements AddressAwareWidget { private AddressText mAddress; @@ -45,40 +44,32 @@ public class Digit extends Button implements OnLongClickListener, AddressAwareWi setOnTouchListener(lListener); if ("0+".equals(text)) { - setOnLongClickListener(this); + setOnLongClickListener(lListener); + } } - public boolean onLongClick(View arg0) { - // Called if "0+" dtmf - LinphoneCore lc = LinphoneManager.getLc(); - lc.stopDtmf(); - int lBegin = mAddress.getSelectionStart(); - if (lBegin == -1) { - lBegin = mAddress.getEditableText().length(); - } - if (lBegin >=0) { - mAddress.getEditableText().insert(lBegin,"+"); - } - return true; - } public Digit(Context context, AttributeSet attrs, int style) { super(context, attrs, style); + setLongClickable(true); } public Digit(Context context, AttributeSet attrs) { super(context, attrs); + setLongClickable(true); + } public Digit(Context context) { super(context); + setLongClickable(true); } - private class DialKeyListener implements OnClickListener, OnTouchListener { + private class DialKeyListener implements OnClickListener, OnTouchListener, OnLongClickListener { final CharSequence mKeyCode; boolean mIsDtmfStarted=false; @@ -117,6 +108,20 @@ public class Digit extends Button implements OnLongClickListener, AddressAwareWi } return false; } + + public boolean onLongClick(View v) { + // Called if "0+" dtmf + LinphoneCore lc = LinphoneManager.getLc(); + lc.stopDtmf(); + int lBegin = mAddress.getSelectionStart(); + if (lBegin == -1) { + lBegin = mAddress.getEditableText().length(); + } + if (lBegin >=0) { + mAddress.getEditableText().insert(lBegin,"+"); + } + return true; + } }; public void setAddressWidget(AddressText address) { diff --git a/src/org/linphone/ui/Numpad.java b/src/org/linphone/ui/Numpad.java new file mode 100644 index 000000000..5070c4842 --- /dev/null +++ b/src/org/linphone/ui/Numpad.java @@ -0,0 +1,64 @@ +/* +NumpadView.java +Copyright (C) 2010 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.ui; + +import java.util.ArrayList; +import java.util.Collection; + +import org.linphone.R; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.LinearLayout; + +public class Numpad extends LinearLayout implements AddressAwareWidget { + + public Numpad(Context context, AttributeSet attrs) { + super(context, attrs); + LayoutInflater.from(context).inflate(R.layout.numpad, this); + setLongClickable(true); + } + + public void setAddressWidget(AddressText address) { + for (AddressAwareWidget v : retrieveChildren(this)) { + v.setAddressWidget(address); + } + } + + + private Collection retrieveChildren(ViewGroup viewGroup) { + final Collection views = new ArrayList(); + + for (int i = 0; i < viewGroup.getChildCount(); i++) { + View v = viewGroup.getChildAt(i); + if (v instanceof ViewGroup) { + views.addAll(retrieveChildren((ViewGroup) v)); + } else { + if (v instanceof AddressAwareWidget) + views.add((AddressAwareWidget) v); + } + } + + return views; + } + +} From ce08949be935b2faf752c8de5a088ce28778e086 Mon Sep 17 00:00:00 2001 From: Guillaume Beraudo Date: Wed, 23 Feb 2011 15:55:41 +0100 Subject: [PATCH 09/53] Better looking numpad preview. --- res/layout/numpad.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/layout/numpad.xml b/res/layout/numpad.xml index 8ff240fa5..c1c99e4df 100644 --- a/res/layout/numpad.xml +++ b/res/layout/numpad.xml @@ -1,7 +1,7 @@ + android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1"> From 06bcbe39988d0a609aa655f3ec61e415dfff1755 Mon Sep 17 00:00:00 2001 From: Guillaume Beraudo Date: Wed, 23 Feb 2011 16:15:36 +0100 Subject: [PATCH 10/53] Fix Linphone dependency. --- submodules/linphone | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/linphone b/submodules/linphone index aff1134b3..f515a560b 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit aff1134b38c23eccadc4ee40c7cba7b10b6d04ef +Subproject commit f515a560bcaa0d098df885fd1264ed5db46350e5 From 75a4d15ac0971bfb82c579d717f29fa095d8838e Mon Sep 17 00:00:00 2001 From: Guillaume Beraudo Date: Mon, 28 Feb 2011 11:55:52 +0100 Subject: [PATCH 11/53] Incall view. Hack for Audio with Galaxy S --- AndroidManifest.xml | 11 +- res/drawable/numpad.png | Bin 0 -> 1356 bytes res/layout-land/dialer.xml | 8 +- res/layout/incall_view.xml | 48 +++++++ res/layout/numpad.xml | 8 +- src/org/linphone/DialerActivity.java | 34 +++-- src/org/linphone/IncallActivity.java | 132 ++++++++++++++++++ src/org/linphone/LinphoneManager.java | 55 ++++++-- src/org/linphone/LinphoneService.java | 1 + src/org/linphone/{ => core}/Hacks.java | 2 +- src/org/linphone/core/LinphoneCallImpl.java | 5 + src/org/linphone/core/LinphoneCoreImpl.java | 9 +- .../core/video/AndroidCameraConf.java | 2 +- src/org/linphone/ui/AddVideoButton.java | 4 +- ...ressAwareWidget.java => AddressAware.java} | 2 +- src/org/linphone/ui/CallButton.java | 3 +- src/org/linphone/ui/Digit.java | 7 +- src/org/linphone/ui/IncallTimer.java | 93 ++++++++++++ src/org/linphone/ui/Numpad.java | 12 +- 19 files changed, 379 insertions(+), 57 deletions(-) create mode 100644 res/drawable/numpad.png create mode 100644 res/layout/incall_view.xml create mode 100644 src/org/linphone/IncallActivity.java rename src/org/linphone/{ => core}/Hacks.java (98%) rename src/org/linphone/ui/{AddressAwareWidget.java => AddressAware.java} (95%) create mode 100644 src/org/linphone/ui/IncallTimer.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 3addcdbb3..013d29c53 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -27,7 +27,12 @@ - + + + + + + @@ -143,9 +148,5 @@ -<<<<<<< HEAD - -======= ->>>>>>> e7697429c4475fb5f6ddfb800d5bbce0d4c20865 diff --git a/res/drawable/numpad.png b/res/drawable/numpad.png new file mode 100644 index 0000000000000000000000000000000000000000..f3965ef43cfa95a9952e71a54cd75ab94a6a07a2 GIT binary patch literal 1356 zcmV-S1+)5zP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2ipQ1 z3Jx-l;RMqF00hiQL_t(o!^KxgOY3YDe%>UVY>A3m6{MmrZs`>f7m8~^`BZQt2>Js= zK}1A1_k!TwpCJk&f?GEV>O!zMEF4jA0Ea4dY7>*@{T7mA(xlaIfO{b1J@0g$Gvjh&hH-OvQTO1r5ptiOae!m}vVSsZE!!U9_ zU#%O4flMZY+uK{*+}xnIw-@1Xm}D~31=rWtP*oL`m6e2&b55F=V>jNMGXZ6<8-@W* z(~wLiv9`8`zP>&J!T1MZYikSj_4Q=-e2-N#tEqGC1pvkvG)=?({XOFGIEIFXAd2FL z3lfP0YHDgogX{~k1q*@z01yNL7Z(=*fWpE;2!cQgWV^=%8Vm-JN~Q4j_6Av&KL9*G zKcld)kTl8`Y8_jH$P^9$Pft%YE+{B)2)B+s9uE{n`2@f@M<$a2V+@92U~X;>CnqO_ zIu?teySp2@uH)h10n5wFNG6jcu&JpD_4W0{FDxwJ@$r#>H#RmR7K=H8*OmpDOa=g; zC<>OAmaw|IN*8u@b)luD1pp9+zUr{og}cOy;HpePCq!$2~bgr;du3#h8< z5NuMe`R@{Ai~=|NKE^rc$H&LEV7a@yLn@Ub-skh7w6v5Cot>RQRaN4{;V?={N{HXy z-iE5GP!t83Oa?_oMUZ8g{C|Faj={k}R8&-aTEJ@N($Z4AzrW|ysJ6B?uf~x`gvM`g zZzR~XhE*(k}Pfri=Gcz;T+1Vk!wY3$)!^6ankB{5V_xARpv$NAt zT^#^S+TGp7$;k=vu~^Ke;pOEe4h{~8udc4Pt*25cyuQA|nqi_S+N!K03(U#vuhnSy>55 zl5ADgmIX&gM^IH2e!t&Q_x}xp0i(^JmOfDS!O`KTu=lt;S z5Q?H891gp-Rc0WWQT-LYyu9RW?HFU2ot?$l*qD13WH*)BHR3B$RTW;ZH)k`O_rJiJ zx7innqDXVPuIKz0Foj#sTkm0vQTIgvWLZWck+1>C_s#{t3^cbh)`FByr%9Fo0OjT7 z*xTD9KTDG2cv~N9fLg8R@p$0%dg*O_%(?yjeNI1UdF(bm?6P$=Z^ znOpyF{l;5kB-hz^JdVZ1MU0M)Qsxi3EC<-1QAE_n#zbFt0pt!gg1qB5*Yq3B5d;T{NNkf7K-;8 + android:layout_height="fill_parent" android:layout_width="fill_parent" android:layout_weight="1" android:background="@drawable/clavier_bg" android:src="@drawable/startcall_green"/> + android:layout_weight="1" android:background="@drawable/clavier_bg" android:src="@drawable/stopcall_red"/> - - + + diff --git a/res/layout/incall_view.xml b/res/layout/incall_view.xml new file mode 100644 index 000000000..74a4bd303 --- /dev/null +++ b/res/layout/incall_view.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + +
* */ -public class DialerActivity extends Activity implements LinphoneGuiListener, AlreadyInVideoCallListener, NewOutgoingCallUiListener { +public class DialerActivity extends Activity implements LinphoneGuiListener, NewOutgoingCallUiListener { private AddressText mAddress; private TextView mDisplayNameView; @@ -81,7 +80,6 @@ public class DialerActivity extends Activity implements LinphoneGuiListener, Alr private PowerManager.WakeLock mWakeLock; private SharedPreferences mPref; - private AddVideoButton mAddVideo; private boolean useIncallActivity; private boolean useVideoActivity; @@ -133,11 +131,6 @@ public class DialerActivity extends Activity implements LinphoneGuiListener, Alr mInCallControlRow.setVisibility(View.GONE); mInCallAddressLayout = findViewById(R.id.IncallAddressLayout); mInCallAddressLayout.setVisibility(View.GONE); - - if (useVideoActivity) { - mAddVideo = (AddVideoButton) findViewById(R.id.AddVideo); - mAddVideo.setOnAlreadyInVideoCallListener(this); - } } mMute = (MuteMicButton) findViewById(R.id.mic_mute_button); @@ -148,22 +141,17 @@ public class DialerActivity extends Activity implements LinphoneGuiListener, Alr if (numpad != null) numpad.setAddressWidget(mAddress); + checkIfOutgoingCallIntentReceived(); - try { - outgoingCallIntentReceived(); - if (LinphoneService.isReady()) { - LinphoneCore lc = LinphoneManager.getLc(); - if (lc.isIncall()) { - if(lc.isInComingInvitePending()) { - callPending(lc.getCurrentCall()); - } else { - enterIncallMode(lc); - } + if (LinphoneService.isReady()) { + LinphoneCore lc = LinphoneManager.getLc(); + if (lc.isIncall()) { + if(lc.isInComingInvitePending()) { + callPending(lc.getCurrentCall()); + } else { + enterIncallMode(lc); } } - } catch (Exception e) { - Log.e(LinphoneManager.TAG,"Cannot start linphone",e); - finish(); } instance = this; } @@ -171,7 +159,7 @@ public class DialerActivity extends Activity implements LinphoneGuiListener, Alr - private void outgoingCallIntentReceived() { + private void checkIfOutgoingCallIntentReceived() { if (getIntent().getData() == null) return; if (!LinphoneService.isReady() || LinphoneManager.getLc().isIncall()) { @@ -221,12 +209,6 @@ public class DialerActivity extends Activity implements LinphoneGuiListener, Alr - private void startVideoView(int requestCode) { - if (!useVideoActivity) throw new RuntimeException("internal error"); - Intent lIntent = new Intent().setClass(this, VideoCallActivity.class); - startActivityForResult(lIntent,requestCode); - } - private void enterIncallMode(LinphoneCore lc) { mDisplayNameView.setText(LinphoneManager.getInstance().extractADisplayName()); @@ -237,7 +219,7 @@ public class DialerActivity extends Activity implements LinphoneGuiListener, Alr if (!mWakeLock.isHeld()) mWakeLock.acquire(); if (useIncallActivity) { - startIncallActivity(mDisplayNameView.getText()); + LinphoneActivity.instance().startIncallActivity(mDisplayNameView.getText()); } else { loadMicAndSpeakerUiStateFromManager(); mCallControlRow.setVisibility(View.GONE); @@ -251,19 +233,13 @@ public class DialerActivity extends Activity implements LinphoneGuiListener, Alr } - private void startIncallActivity(CharSequence callerName) { - if (!useIncallActivity) throw new RuntimeException("Internal error"); - startActivityForResult(new Intent() - .setClass(this, IncallActivity.class) - .putExtra(IncallActivity.CONTACT_KEY, callerName), - LinphoneActivity.INCALL_ACTIVITY); - } - private void updateIncallVideoCallButton() { if (useIncallActivity) throw new RuntimeException("Internal error"); boolean prefVideoEnabled = LinphoneManager.getInstance().isVideoEnabled(); + AddVideoButton mAddVideo = (AddVideoButton) findViewById(R.id.AddVideo); + if (prefVideoEnabled && !mCall.isEnabled()) { mAddVideo.setVisibility(View.VISIBLE); mAddVideo.setEnabled(true); @@ -282,12 +258,13 @@ public class DialerActivity extends Activity implements LinphoneGuiListener, Alr private void exitCallMode() { - if (!useIncallActivity) { + if (useIncallActivity) { + LinphoneActivity.instance().closeIncallActivity(); + } else { mCallControlRow.setVisibility(View.VISIBLE); mInCallControlRow.setVisibility(View.GONE); mInCallAddressLayout.setVisibility(View.GONE); updateIncallVideoCallButton(); - finishActivity(LinphoneActivity.INCALL_ACTIVITY); } mAddressLayout.setVisibility(View.VISIBLE); @@ -304,7 +281,7 @@ public class DialerActivity extends Activity implements LinphoneGuiListener, Alr LinphoneManager.getInstance().resetCameraFromPreferences(); } - if (mWakeLock.isHeld())mWakeLock.release(); + if (mWakeLock.isHeld()) mWakeLock.release(); LinphoneActivity.instance().stopProxymitySensor(); setVolumeControlStream(AudioManager.USE_DEFAULT_STREAM_TYPE); @@ -356,11 +333,6 @@ public class DialerActivity extends Activity implements LinphoneGuiListener, Alr mStatus.setText(message); } - public void onAlreadyInVideoCall() { - if (useVideoActivity) { - startVideoView(LinphoneActivity.VIDEO_VIEW_ACTIVITY); - } - } public void onAlreadyInCall() { showToast(R.string.warning_already_incall); @@ -390,16 +362,11 @@ public class DialerActivity extends Activity implements LinphoneGuiListener, Alr } } else if (state == LinphoneCall.State.Error) { if (mWakeLock.isHeld()) mWakeLock.release(); - finishActivity(LinphoneActivity.INCALL_ACTIVITY); showToast(R.string.call_error, message); exitCallMode(); } else if (state == LinphoneCall.State.CallEnd) { exitCallMode(); - } else if (state == LinphoneCall.State.StreamsRunning) { - if (useVideoActivity && LinphoneManager.getLc().getCurrentCall().getCurrentParamsCopy().getVideoEnabled()) { - startVideoView(LinphoneActivity.VIDEO_VIEW_ACTIVITY); - } - } + } } private void showToast(int id, String txt) { @@ -427,7 +394,7 @@ public class DialerActivity extends Activity implements LinphoneGuiListener, Alr } if (getIntent().getData() != null) { - outgoingCallIntentReceived(); + checkIfOutgoingCallIntentReceived(); } } From 1b4d65b5a4e59d987e63df8972699001d136093c Mon Sep 17 00:00:00 2001 From: Guillaume Beraudo Date: Fri, 18 Mar 2011 11:06:46 +0100 Subject: [PATCH 47/53] Pull submodule linphone. --- submodules/linphone | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/linphone b/submodules/linphone index c6149d1f4..c1a5f6415 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit c6149d1f4e649edf4f3adf9c68094567dc9e1d9a +Subproject commit c1a5f64157d652eb7aa9454dbc8b616bdb9c5b5b From 73b3782f13a8324e037bddc1638ecee4f7f7e794 Mon Sep 17 00:00:00 2001 From: Guillaume Beraudo Date: Tue, 22 Mar 2011 13:46:06 +0100 Subject: [PATCH 48/53] Custom editable SIP address. --- res/layout-land/dialer.xml | 2 +- res/layout/dialer.xml | 2 +- res/values/custom.xml | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/res/layout-land/dialer.xml b/res/layout-land/dialer.xml index 4243d0dfb..da2a314e5 100644 --- a/res/layout-land/dialer.xml +++ b/res/layout-land/dialer.xml @@ -9,7 +9,7 @@ android:layout_width="fill_parent" android:id="@+id/Addresslayout"> + android:layout_weight="0.2" android:editable="@bool/allow_edit_in_dialer"/> diff --git a/res/layout/dialer.xml b/res/layout/dialer.xml index d79bc546b..83fc2bbf1 100644 --- a/res/layout/dialer.xml +++ b/res/layout/dialer.xml @@ -9,7 +9,7 @@ + android:lines="1" android:layout_weight="0.2" android:layout_height="fill_parent" android:padding="10px" android:maxLines="1" android:editable="@bool/allow_edit_in_dialer"/> diff --git a/res/values/custom.xml b/res/values/custom.xml index f128fa62f..be5f6a2cf 100644 --- a/res/values/custom.xml +++ b/res/values/custom.xml @@ -15,6 +15,7 @@ false Linphone + true \ No newline at end of file From 4271398147991320157cd9d474fc718c8e3531b4 Mon Sep 17 00:00:00 2001 From: Guillaume Beraudo Date: Tue, 22 Mar 2011 14:20:34 +0100 Subject: [PATCH 49/53] Hide identity in notifications if no %s in message. --- res/values/custom.xml | 5 +++-- res/values/strings.xml | 5 ++--- src/org/linphone/LinphoneService.java | 26 ++++++++++---------------- 3 files changed, 15 insertions(+), 21 deletions(-) diff --git a/res/values/custom.xml b/res/values/custom.xml index be5f6a2cf..9e67f257b 100644 --- a/res/values/custom.xml +++ b/res/values/custom.xml @@ -15,7 +15,8 @@ false Linphone - true - + true + registered to %s + fails to register to %s \ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml index a30eaff15..c35cf618d 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -93,9 +93,8 @@ Clear Cannot get call parameters Cannot create default call parameters -Cannot invite destination address [%s] -registered to %s -fails to register to %s +Cannot invite destination address [%s] + started Removes the echo heard by other end Stun server diff --git a/src/org/linphone/LinphoneService.java b/src/org/linphone/LinphoneService.java index 9525fe105..5b0038d15 100644 --- a/src/org/linphone/LinphoneService.java +++ b/src/org/linphone/LinphoneService.java @@ -119,22 +119,16 @@ public final class LinphoneService extends Service implements LinphoneServiceLis - - - private void sendNotification(int level, int text) { + private void sendNotification(int level, int textId) { mNotif.iconLevel = level; mNotif.when=System.currentTimeMillis(); - mNotif.setLatestEventInfo(this, notificationTitle,getString(text), mNotifContentIntent); - mNotificationMgr.notify(NOTIF_ID, mNotif); - } - - private void sendNotificationWithId(int level, int text) { - mNotif.iconLevel = level; - mNotif.when=System.currentTimeMillis(); - String id = LinphoneManager.getLc().getDefaultProxyConfig().getIdentity(); - mNotif.setLatestEventInfo(this, notificationTitle, - String.format(getString(text), id), - mNotifContentIntent); + String text = getString(textId); + if (text.contains("%s")) { + String id = LinphoneManager.getLc().getDefaultProxyConfig().getIdentity(); + text = String.format(text, id); + } + + mNotif.setLatestEventInfo(this, notificationTitle, text, mNotifContentIntent); mNotificationMgr.notify(NOTIF_ID, mNotif); } @@ -191,11 +185,11 @@ public final class LinphoneService extends Service implements LinphoneServiceLis public void onRegistrationStateChanged(final RegistrationState state, final String message) { if (state == RegistrationState.RegistrationOk && LinphoneManager.getLc().getDefaultProxyConfig().isRegistered()) { - sendNotificationWithId(IC_LEVEL_ORANGE, R.string.notification_registered); + sendNotification(IC_LEVEL_ORANGE, R.string.notification_registered); } if (state == RegistrationState.RegistrationFailed) { - sendNotificationWithId(IC_LEVEL_OFFLINE, R.string.notification_register_failure); + sendNotification(IC_LEVEL_OFFLINE, R.string.notification_register_failure); } if (state == RegistrationState.RegistrationOk || state == RegistrationState.RegistrationFailed) { From e71b7a5c97b4b3de146a8f1e28cdf8a62c159259 Mon Sep 17 00:00:00 2001 From: Guillaume Beraudo Date: Wed, 23 Mar 2011 12:09:27 +0100 Subject: [PATCH 50/53] Fix contact name not shown in incall Activity. --- src/org/linphone/LinphoneActivity.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/org/linphone/LinphoneActivity.java b/src/org/linphone/LinphoneActivity.java index 828a74c4c..a03e7af11 100644 --- a/src/org/linphone/LinphoneActivity.java +++ b/src/org/linphone/LinphoneActivity.java @@ -451,7 +451,8 @@ public class LinphoneActivity extends TabActivity { public void startIncallActivity(CharSequence callerName) { startActivityForResult( - new Intent().setClass(this, IncallActivity.class), + new Intent().setClass(this, IncallActivity.class) + .putExtra(IncallActivity.CONTACT_KEY, callerName), INCALL_ACTIVITY); } From 244cae924697cf8fe36e889aa5645a80f9603a29 Mon Sep 17 00:00:00 2001 From: Guillaume Beraudo Date: Thu, 24 Mar 2011 10:36:39 +0100 Subject: [PATCH 51/53] Incoming call Dialog. Fix standard ports in Manager. --- res/layout/dialer.xml | 2 +- res/layout/incoming_call.xml | 19 ++++++++++++ res/values/custom.xml | 1 + res/values/strings.xml | 6 +++- src/org/linphone/DialerActivity.java | 41 +++++++++++++++++++------ src/org/linphone/LinphoneActivity.java | 15 ++++----- src/org/linphone/LinphoneManager.java | 35 ++++++++++++++++++--- src/org/linphone/ui/CallButton.java | 33 +++++++++----------- src/org/linphone/ui/HangCallButton.java | 5 +++ 9 files changed, 116 insertions(+), 41 deletions(-) create mode 100644 res/layout/incoming_call.xml diff --git a/res/layout/dialer.xml b/res/layout/dialer.xml index 83fc2bbf1..c6fbdb473 100644 --- a/res/layout/dialer.xml +++ b/res/layout/dialer.xml @@ -40,7 +40,7 @@ - + diff --git a/res/layout/incoming_call.xml b/res/layout/incoming_call.xml new file mode 100644 index 000000000..adc5a351c --- /dev/null +++ b/res/layout/incoming_call.xml @@ -0,0 +1,19 @@ + + + + + + + + + + diff --git a/res/values/custom.xml b/res/values/custom.xml index 9e67f257b..1a2e83929 100644 --- a/res/values/custom.xml +++ b/res/values/custom.xml @@ -13,6 +13,7 @@ true true false + true Linphone true diff --git a/res/values/strings.xml b/res/values/strings.xml index c35cf618d..04fa39914 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1,7 +1,11 @@ - + Error while accepting pending call + %s is calling you + Accept + Decline + Unknown Network UDP diff --git a/src/org/linphone/DialerActivity.java b/src/org/linphone/DialerActivity.java index a62729834..b9ef47dc2 100644 --- a/src/org/linphone/DialerActivity.java +++ b/src/org/linphone/DialerActivity.java @@ -30,10 +30,13 @@ import org.linphone.ui.AddressAware; import org.linphone.ui.AddressText; import org.linphone.ui.CallButton; import org.linphone.ui.EraseButton; +import org.linphone.ui.HangCallButton; import org.linphone.ui.MuteMicButton; import org.linphone.ui.SpeakerButton; import android.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; @@ -43,6 +46,7 @@ import android.os.PowerManager; import android.preference.PreferenceManager; import android.util.Log; import android.view.View; +import android.view.View.OnClickListener; import android.widget.TextView; import android.widget.Toast; @@ -288,16 +292,36 @@ public class DialerActivity extends Activity implements LinphoneGuiListener, New mCall.setEnabled(true); } - private void callPending(LinphoneCall call) { - mDecline.setEnabled(true); - // Privacy setting to not share the user camera by default - boolean prefVideoEnable = LinphoneManager.getInstance().isVideoEnabled(); - boolean prefAutoShareMyCamera = mPref.getBoolean(getString(R.string.pref_video_automatically_share_my_video_key), false); - boolean videoMuted = !(prefVideoEnable && prefAutoShareMyCamera); - AndroidCameraRecordManager.getInstance().setMuted(videoMuted); + private void callPending(final LinphoneCall call) { + String from = LinphoneManager.getInstance().extractIncomingRemoteName(); + View incomingCallView = getLayoutInflater().inflate(R.layout.incoming_call, null); - call.enableCamera(prefAutoShareMyCamera); + final Dialog dialog = new AlertDialog.Builder(this) + .setMessage(String.format(getString(R.string.incoming_call_dialog_title), from)) + .setCancelable(false) + .setView(incomingCallView).create(); + + + ((CallButton) incomingCallView.findViewById(R.id.Call)).setExternalClickListener(new OnClickListener() { + public void onClick(View v) { + dialog.dismiss(); + LinphoneManager.getInstance().resetCameraFromPreferences(); + + // Privacy setting to not share the user camera by default + boolean prefVideoEnable = LinphoneManager.getInstance().isVideoEnabled(); + boolean prefAutoShareMyCamera = mPref.getBoolean(getString(R.string.pref_video_automatically_share_my_video_key), false); + boolean videoMuted = !(prefVideoEnable && prefAutoShareMyCamera); + AndroidCameraRecordManager.getInstance().setMuted(videoMuted); + + call.enableCamera(prefAutoShareMyCamera); + } + }); + ((HangCallButton) incomingCallView.findViewById(R.id.Decline)).setExternalClickListener(new OnClickListener() { + public void onClick(View v) {dialog.dismiss();} + }); + + dialog.show(); } @@ -354,7 +378,6 @@ public class DialerActivity extends Activity implements LinphoneGuiListener, New if (state == LinphoneCall.State.OutgoingInit) { enterIncallMode(lc); } else if (state == LinphoneCall.State.IncomingReceived) { - LinphoneManager.getInstance().resetCameraFromPreferences(); callPending(call); } else if (state == LinphoneCall.State.Connected) { if (call.getDirection() == CallDirection.Incoming) { diff --git a/src/org/linphone/LinphoneActivity.java b/src/org/linphone/LinphoneActivity.java index a03e7af11..3004633d2 100644 --- a/src/org/linphone/LinphoneActivity.java +++ b/src/org/linphone/LinphoneActivity.java @@ -65,7 +65,8 @@ public class LinphoneActivity extends TabActivity { public static final String PREF_FIRST_LAUNCH = "pref_first_launch"; static final int VIDEO_VIEW_ACTIVITY = 100; static final int FIRST_LOGIN_ACTIVITY = 101; - static final int INCALL_ACTIVITY = 102; + static final int INCALL_ACTIVITY = 102; + static final int INCOMING_CALL_ACTIVITY = 103; private static final String PREF_CHECK_CONFIG = "pref_check_config"; private static LinphoneActivity instance; @@ -203,9 +204,7 @@ public class LinphoneActivity extends TabActivity { } }*/ - getTabHost().setCurrentTabByTag(DIALER_TAB); - - + gotToDialer(); } @Override @@ -216,8 +215,7 @@ public class LinphoneActivity extends TabActivity { if (!LinphoneService.isReady() || !LinphoneManager.getLc().isIncall()) return; LinphoneCore lc = LinphoneManager.getLc(); if(lc.isInComingInvitePending()) { - // TODO - Log.e(TAG, "Not handled case: recreation while incoming invite pending"); + gotToDialer(); } else { if (getResources().getBoolean(R.bool.use_incall_activity)) { startIncallActivity(LinphoneManager.getInstance().extractADisplayName()); @@ -436,9 +434,12 @@ public class LinphoneActivity extends TabActivity { static void setAddressAndGoToDialer(String number, String name) { DialerActivity.instance().setContactAddress(number, name); - instance.getTabHost().setCurrentTabByTag(DIALER_TAB); + instance.gotToDialer(); } + private void gotToDialer() { + getTabHost().setCurrentTabByTag(DIALER_TAB); + } private void startActivityInTab(String tag, Intent intent, int indicatorId, int drawableId) { diff --git a/src/org/linphone/LinphoneManager.java b/src/org/linphone/LinphoneManager.java index 12a23cafe..cdf097f5c 100644 --- a/src/org/linphone/LinphoneManager.java +++ b/src/org/linphone/LinphoneManager.java @@ -506,19 +506,19 @@ public final class LinphoneManager implements LinphoneCoreListener { if (!getBool(R.string.pref_transport_udp_key, false)) { ports.udp = 0; } else if (useStandardPort) { - ports.udp = 5600; + ports.udp = 5060; } if (!getBool(R.string.pref_transport_tcp_key, false)) { ports.tcp = 0; } else if (useStandardPort) { - ports.tcp = 5600; + ports.tcp = 5060; } if (!getBool(R.string.pref_transport_tls_key, false)) { ports.tls = 0; } else if (useStandardPort) { - ports.tls = 5600; + ports.tls = 5060; } mLc.setSignalingTransportPorts(ports); @@ -749,9 +749,10 @@ public final class LinphoneManager implements LinphoneCoreListener { } } + public String extractADisplayName() { final LinphoneAddress remote = mLc.getRemoteAddress(); - if (remote == null) return null; + if (remote == null) return mR.getString(R.string.unknown_incoming_call_name); final String displayName = remote.getDisplayName(); if (displayName!=null) { @@ -759,7 +760,11 @@ public final class LinphoneManager implements LinphoneCoreListener { } else if (remote.getUserName() != null){ return remote.getUserName(); } else { - return remote.toString(); + String rms = remote.toString(); + if (rms != null && rms.length() > 1) + return rms; + + return mR.getString(R.string.unknown_incoming_call_name); } } @@ -811,4 +816,24 @@ public final class LinphoneManager implements LinphoneCoreListener { serviceListener.onAlreadyInVideoCall(); } } + + public boolean acceptCallIfIncomingPending() throws LinphoneCoreException { + setAudioModeIncallForGalaxyS(); + if (mLc.isInComingInvitePending()) { + mLc.acceptCall(mLc.getCurrentCall()); + return true; + } + return false; + } + + public String extractIncomingRemoteName() { + if (!mR.getBoolean(R.bool.show_full_remote_address_on_incoming_call)) + return extractADisplayName(); + + LinphoneAddress remote = mLc.getRemoteAddress(); + if (remote != null) + return remote.toString(); + + return mR.getString(R.string.unknown_incoming_call_name); + } } diff --git a/src/org/linphone/ui/CallButton.java b/src/org/linphone/ui/CallButton.java index 7f64c418e..f0223f0f7 100644 --- a/src/org/linphone/ui/CallButton.java +++ b/src/org/linphone/ui/CallButton.java @@ -20,7 +20,6 @@ package org.linphone.ui; import org.linphone.LinphoneManager; import org.linphone.R; -import org.linphone.core.LinphoneCore; import org.linphone.core.LinphoneCoreException; import android.content.Context; @@ -37,6 +36,10 @@ import android.widget.Toast; public class CallButton extends ImageButton implements OnClickListener, AddressAware { private AddressText mAddress; + public void setAddressWidget(AddressText a) {mAddress = a;} + + private OnClickListener externalClickListener; + public void setExternalClickListener(OnClickListener e) {externalClickListener = e;} public CallButton(Context context, AttributeSet attrs) { super(context, attrs); @@ -44,20 +47,18 @@ public class CallButton extends ImageButton implements OnClickListener, AddressA } public void onClick(View v) { - LinphoneManager.getInstance().setAudioModeIncallForGalaxyS(); - LinphoneCore lc = LinphoneManager.getLc(); - if (lc.isInComingInvitePending()) { - try { - lc.acceptCall(lc.getCurrentCall()); - } catch (LinphoneCoreException e) { - lc.terminateCall(lc.getCurrentCall()); - onWrongDestinationAddress(); + try { + if (!LinphoneManager.getInstance().acceptCallIfIncomingPending()) { + if (mAddress.getText().length() >0) { + LinphoneManager.getInstance().newOutgoingCall(mAddress); + } } - return; - } - if (mAddress.getText().length() >0) { - LinphoneManager.getInstance().newOutgoingCall(mAddress); - } + } catch (LinphoneCoreException e) { + LinphoneManager.getInstance().terminateCall(); + onWrongDestinationAddress(); + }; + + if (externalClickListener != null) externalClickListener.onClick(v); } @@ -69,8 +70,4 @@ public class CallButton extends ImageButton implements OnClickListener, AddressA } - public void setAddressWidget(AddressText address) { - mAddress = address; - } - } diff --git a/src/org/linphone/ui/HangCallButton.java b/src/org/linphone/ui/HangCallButton.java index d2064c82b..706df35ec 100644 --- a/src/org/linphone/ui/HangCallButton.java +++ b/src/org/linphone/ui/HangCallButton.java @@ -29,6 +29,9 @@ import android.widget.ImageButton; public class HangCallButton extends ImageButton implements OnClickListener { + private OnClickListener externalClickListener; + public void setExternalClickListener(OnClickListener e) {externalClickListener = e;} + public HangCallButton(Context context, AttributeSet attrs) { super(context, attrs); setOnClickListener(this); @@ -37,5 +40,7 @@ public class HangCallButton extends ImageButton implements OnClickListener { public void onClick(View v) { LinphoneCore lc = LinphoneManager.getLc(); lc.terminateCall(lc.getCurrentCall()); + + if (externalClickListener != null) externalClickListener.onClick(v); } } From 3cebf5910478ec1013adbe1daaa26509aba2618f Mon Sep 17 00:00:00 2001 From: Guillaume Beraudo Date: Thu, 24 Mar 2011 11:28:45 +0100 Subject: [PATCH 52/53] Fix incoming call dialog destruction on remote hang. --- src/org/linphone/DialerActivity.java | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/org/linphone/DialerActivity.java b/src/org/linphone/DialerActivity.java index b9ef47dc2..a57bcdc8f 100644 --- a/src/org/linphone/DialerActivity.java +++ b/src/org/linphone/DialerActivity.java @@ -90,6 +90,7 @@ public class DialerActivity extends Activity implements LinphoneGuiListener, New private static final String CURRENT_ADDRESS = "org.linphone.current-address"; private static final String CURRENT_DISPLAYNAME = "org.linphone.current-displayname"; + private static final int INCOMING_CALL_DIALOG_ID = 1; /** * @return null if not ready yet @@ -262,6 +263,11 @@ public class DialerActivity extends Activity implements LinphoneGuiListener, New private void exitCallMode() { + // Remove dialog if existing + try { + dismissDialog(INCOMING_CALL_DIALOG_ID); + } catch (Throwable e) {/* Exception if never created */} + if (useIncallActivity) { LinphoneActivity.instance().closeIncallActivity(); } else { @@ -294,6 +300,12 @@ public class DialerActivity extends Activity implements LinphoneGuiListener, New private void callPending(final LinphoneCall call) { + showDialog(INCOMING_CALL_DIALOG_ID); + } + + + @Override + protected Dialog onCreateDialog(int id, Bundle b) { String from = LinphoneManager.getInstance().extractIncomingRemoteName(); View incomingCallView = getLayoutInflater().inflate(R.layout.incoming_call, null); @@ -314,17 +326,15 @@ public class DialerActivity extends Activity implements LinphoneGuiListener, New boolean videoMuted = !(prefVideoEnable && prefAutoShareMyCamera); AndroidCameraRecordManager.getInstance().setMuted(videoMuted); - call.enableCamera(prefAutoShareMyCamera); + LinphoneManager.getLc().getCurrentCall().enableCamera(prefAutoShareMyCamera); } }); ((HangCallButton) incomingCallView.findViewById(R.id.Decline)).setExternalClickListener(new OnClickListener() { public void onClick(View v) {dialog.dismiss();} }); - dialog.show(); + return dialog; } - - From 2613d3c6208d8953d9552c4bee4dbc2853844f7f Mon Sep 17 00:00:00 2001 From: Guillaume Beraudo Date: Thu, 24 Mar 2011 13:47:26 +0100 Subject: [PATCH 53/53] Update submodule/linphone --- submodules/linphone | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/linphone b/submodules/linphone index c1a5f6415..2e35f52d3 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit c1a5f64157d652eb7aa9454dbc8b616bdb9c5b5b +Subproject commit 2e35f52d35dc6f2e22ffa85130ad233172a5f488