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
This commit is contained in:
parent
de64a0918f
commit
d89d9c3a3b
21 changed files with 1218 additions and 975 deletions
|
@ -3,6 +3,8 @@
|
||||||
package="org.linphone"
|
package="org.linphone"
|
||||||
android:versionCode="1103" android:versionName="1.1.3" android:installLocation="auto">
|
android:versionCode="1103" android:versionName="1.1.3" android:installLocation="auto">
|
||||||
<uses-sdk android:minSdkVersion="3" />
|
<uses-sdk android:minSdkVersion="3" />
|
||||||
|
|
||||||
|
|
||||||
<application android:label="@string/app_name" android:debuggable ="true" android:icon="@drawable/logo_linphone_57x57">
|
<application android:label="@string/app_name" android:debuggable ="true" android:icon="@drawable/logo_linphone_57x57">
|
||||||
|
|
||||||
|
|
||||||
|
@ -10,16 +12,78 @@
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:theme="@android:style/Theme.NoTitleBar"
|
android:theme="@android:style/Theme.NoTitleBar"
|
||||||
android:launchMode="singleTask">
|
android:launchMode="singleTask">
|
||||||
|
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.CALL" />
|
<action android:name="android.intent.action.CALL" />
|
||||||
|
<action android:name="android.intent.action.CALL_PRIVILEGED" />
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
<data android:scheme="tel" />
|
<data android:scheme="tel" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<activity android:name=".LinphonePreferencesActivity">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
<activity android:name=".DialerActivity">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
<activity android:name=".VideoCallActivity" android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
<activity android:name=".ContactPickerActivity">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
<activity android:name=".HistoryActivity">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
<activity android:name=".AboutActivity">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<service android:name=".LinphoneService" />
|
||||||
|
|
||||||
|
<receiver android:name="NetworkManager">
|
||||||
|
<intent-filter><action android:name="android.net.conn.CONNECTIVITY_CHANGE"></action></intent-filter>
|
||||||
|
</receiver>
|
||||||
|
|
||||||
|
<receiver android:name="OutgoingCallReceiver">
|
||||||
|
<intent-filter android:priority="0">
|
||||||
|
<action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
|
||||||
|
</intent-filter>
|
||||||
|
</receiver>
|
||||||
|
|
||||||
|
<receiver android:name="BootReceiver">
|
||||||
|
<intent-filter><action android:name="android.intent.action.BOOT_COMPLETED"></action></intent-filter>
|
||||||
|
</receiver>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<activity android:name=".core.tutorials.TestVideoActivity"
|
<activity android:name=".core.tutorials.TestVideoActivity"
|
||||||
android:label="Video test"
|
android:label="Video test"
|
||||||
android:theme="@android:style/Theme.NoTitleBar"
|
android:theme="@android:style/Theme.NoTitleBar"
|
||||||
|
@ -70,52 +134,9 @@
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity android:name=".LinphonePreferencesActivity">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.MAIN" />
|
|
||||||
</intent-filter>
|
|
||||||
</activity>
|
|
||||||
<activity android:name=".DialerActivity">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.MAIN" />
|
|
||||||
</intent-filter>
|
|
||||||
</activity>
|
|
||||||
<activity android:name=".VideoCallActivity" android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.MAIN" />
|
|
||||||
</intent-filter>
|
|
||||||
</activity>
|
|
||||||
<activity android:name=".ContactPickerActivity">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.MAIN" />
|
|
||||||
</intent-filter>
|
|
||||||
</activity>
|
|
||||||
<activity android:name=".HistoryActivity">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.MAIN" />
|
|
||||||
</intent-filter>
|
|
||||||
</activity>
|
|
||||||
<activity android:name=".AboutActivity">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.MAIN" />
|
|
||||||
</intent-filter>
|
|
||||||
</activity>
|
|
||||||
<service android:name=".LinphoneService">
|
|
||||||
</service>
|
|
||||||
<receiver android:name="NetworkManager">
|
|
||||||
<intent-filter><action android:name="android.net.conn.CONNECTIVITY_CHANGE"></action>
|
|
||||||
</intent-filter>
|
|
||||||
</receiver>
|
|
||||||
<!-- receiver android:name="OutgoingCallReceiver" >
|
|
||||||
<intent-filter android:priority="0"><action android:name="android.intent.action.NEW_OUTGOING_CALL"></action>
|
|
||||||
</intent-filter>
|
|
||||||
</receiver-->
|
|
||||||
<receiver android:name="BootReceiver" >
|
|
||||||
<intent-filter><action android:name="android.intent.action.BOOT_COMPLETED"></action>
|
|
||||||
</intent-filter>
|
|
||||||
</receiver>
|
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
|
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
|
||||||
<uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission>
|
<uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission>
|
||||||
<uses-permission android:name="android.permission.READ_CONTACTS"/>
|
<uses-permission android:name="android.permission.READ_CONTACTS"/>
|
||||||
|
@ -128,8 +149,6 @@
|
||||||
<uses-permission android:name="android.permission.VIBRATE"></uses-permission>
|
<uses-permission android:name="android.permission.VIBRATE"></uses-permission>
|
||||||
<uses-permission android:name="android.permission.CAMERA" />
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
|
|
||||||
<uses-feature android:name="android.hardware.camera" />
|
|
||||||
<uses-feature android:name="android.hardware.camera.autofocus" />
|
|
||||||
|
|
||||||
<supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:anyDensity="true"/>
|
<supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:anyDensity="true"/>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|
|
@ -35,7 +35,7 @@ public class AboutActivity extends Activity {
|
||||||
try {
|
try {
|
||||||
aboutText.setText(String.format(getString(R.string.about_text), getPackageManager().getPackageInfo(getPackageName(), 0).versionName));
|
aboutText.setText(String.format(getString(R.string.about_text), getPackageManager().getPackageInfo(getPackageName(), 0).versionName));
|
||||||
} catch (NameNotFoundException e) {
|
} catch (NameNotFoundException e) {
|
||||||
Log.e(LinphoneService.TAG, "cannot get version name", e);
|
Log.e(LinphoneManager.TAG, "cannot get version name", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,7 @@ public class BandwidthManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onProfileChanged(int newProfile) {
|
private void onProfileChanged(int newProfile) {
|
||||||
LinphoneCore lc = LinphoneService.instance().getLinphoneCore();
|
LinphoneCore lc = LinphoneManager.getLc();
|
||||||
lc.setUploadBandwidth(bandwidthes[newProfile][0]);
|
lc.setUploadBandwidth(bandwidthes[newProfile][0]);
|
||||||
lc.setDownloadBandwidth(bandwidthes[newProfile][1]);
|
lc.setDownloadBandwidth(bandwidthes[newProfile][1]);
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ import org.linphone.core.LinphoneCoreException;
|
||||||
* @author Guillaume Beraudo
|
* @author Guillaume Beraudo
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class CallManager {
|
class CallManager {
|
||||||
|
|
||||||
private static CallManager instance;
|
private static CallManager instance;
|
||||||
|
|
||||||
|
@ -41,9 +41,6 @@ public class CallManager {
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
private LinphoneCore lc() {
|
|
||||||
return LinphoneService.instance().getLinphoneCore();
|
|
||||||
}
|
|
||||||
private AndroidCameraRecordManager videoManager() {
|
private AndroidCameraRecordManager videoManager() {
|
||||||
return AndroidCameraRecordManager.getInstance();
|
return AndroidCameraRecordManager.getInstance();
|
||||||
}
|
}
|
||||||
|
@ -54,8 +51,8 @@ public class CallManager {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void inviteAddress(LinphoneAddress lAddress, boolean videoEnabled) throws LinphoneCoreException {
|
void inviteAddress(LinphoneAddress lAddress, boolean videoEnabled) throws LinphoneCoreException {
|
||||||
LinphoneCore lc = lc();
|
LinphoneCore lc = LinphoneManager.getLc();
|
||||||
|
|
||||||
LinphoneCallParams params = lc.createDefaultCallParameters();
|
LinphoneCallParams params = lc.createDefaultCallParameters();
|
||||||
bm().updateWithProfileSettings(lc, params);
|
bm().updateWithProfileSettings(lc, params);
|
||||||
|
@ -79,8 +76,8 @@ public class CallManager {
|
||||||
* or if the bandwidth settings are too low.
|
* or if the bandwidth settings are too low.
|
||||||
* @return if updateCall called
|
* @return if updateCall called
|
||||||
*/
|
*/
|
||||||
public boolean reinviteWithVideo() {
|
boolean reinviteWithVideo() {
|
||||||
LinphoneCore lc = lc();
|
LinphoneCore lc = LinphoneManager.getLc();
|
||||||
LinphoneCall lCall = lc.getCurrentCall();
|
LinphoneCall lCall = lc.getCurrentCall();
|
||||||
LinphoneCallParams params = lCall.getCurrentParamsCopy();
|
LinphoneCallParams params = lCall.getCurrentParamsCopy();
|
||||||
|
|
||||||
|
@ -105,8 +102,8 @@ public class CallManager {
|
||||||
/**
|
/**
|
||||||
* Re-invite with parameters updated from profile.
|
* Re-invite with parameters updated from profile.
|
||||||
*/
|
*/
|
||||||
public void reinvite() {
|
void reinvite() {
|
||||||
LinphoneCore lc = lc();
|
LinphoneCore lc = LinphoneManager.getLc();
|
||||||
LinphoneCall lCall = lc.getCurrentCall();
|
LinphoneCall lCall = lc.getCurrentCall();
|
||||||
LinphoneCallParams params = lCall.getCurrentParamsCopy();
|
LinphoneCallParams params = lCall.getCurrentParamsCopy();
|
||||||
bm().updateWithProfileSettings(lc, params);
|
bm().updateWithProfileSettings(lc, params);
|
||||||
|
@ -117,8 +114,8 @@ public class CallManager {
|
||||||
* Update current call, without reinvite.
|
* Update current call, without reinvite.
|
||||||
* The camera will be restarted when mediastreamer chain is recreated and setParameters is called.
|
* The camera will be restarted when mediastreamer chain is recreated and setParameters is called.
|
||||||
*/
|
*/
|
||||||
public void updateCall() {
|
void updateCall() {
|
||||||
LinphoneCore lc = lc();
|
LinphoneCore lc = LinphoneManager.getLc();
|
||||||
LinphoneCall lCall = lc.getCurrentCall();
|
LinphoneCall lCall = lc.getCurrentCall();
|
||||||
LinphoneCallParams params = lCall.getCurrentParamsCopy();
|
LinphoneCallParams params = lCall.getCurrentParamsCopy();
|
||||||
bm().updateWithProfileSettings(lc, params);
|
bm().updateWithProfileSettings(lc, params);
|
||||||
|
|
|
@ -63,7 +63,7 @@ public class ContactPickerActivity extends Activity {
|
||||||
// Get the field values
|
// Get the field values
|
||||||
lName = lCur.getString(lCur.getColumnIndex(People.NAME));
|
lName = lCur.getString(lCur.getColumnIndex(People.NAME));
|
||||||
lPhoneNo = lCur.getString(lCur.getColumnIndex(People.NUMBER));
|
lPhoneNo = lCur.getString(lCur.getColumnIndex(People.NUMBER));
|
||||||
DialerActivity.getDialer().setContactAddress(lPhoneNo, lName);
|
DialerActivity.instance().setContactAddress(lPhoneNo, lName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,16 +19,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
package org.linphone;
|
package org.linphone;
|
||||||
|
|
||||||
import org.linphone.LinphoneManager.NewOutgoingCallUiListener;
|
import org.linphone.LinphoneManager.NewOutgoingCallUiListener;
|
||||||
|
import org.linphone.LinphoneService.LinphoneGuiListener;
|
||||||
import org.linphone.core.AndroidCameraRecordManager;
|
import org.linphone.core.AndroidCameraRecordManager;
|
||||||
import org.linphone.core.LinphoneAddress;
|
|
||||||
import org.linphone.core.LinphoneCall;
|
import org.linphone.core.LinphoneCall;
|
||||||
import org.linphone.core.LinphoneChatRoom;
|
|
||||||
import org.linphone.core.LinphoneCore;
|
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.LinphoneCall.State;
|
||||||
import org.linphone.core.LinphoneCore.EcCalibratorStatus;
|
|
||||||
import org.linphone.ui.AddVideoButton;
|
import org.linphone.ui.AddVideoButton;
|
||||||
import org.linphone.ui.AddressText;
|
import org.linphone.ui.AddressText;
|
||||||
import org.linphone.ui.CallButton;
|
import org.linphone.ui.CallButton;
|
||||||
|
@ -37,7 +32,6 @@ import org.linphone.ui.EraseButton;
|
||||||
import org.linphone.ui.MuteMicButton;
|
import org.linphone.ui.MuteMicButton;
|
||||||
import org.linphone.ui.SpeakerButton;
|
import org.linphone.ui.SpeakerButton;
|
||||||
import org.linphone.ui.AddVideoButton.AlreadyInVideoCallListener;
|
import org.linphone.ui.AddVideoButton.AlreadyInVideoCallListener;
|
||||||
import org.linphone.ui.CallButton.CallButtonListener;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
|
@ -57,7 +51,19 @@ import android.widget.TableRow;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
public class DialerActivity extends Activity implements LinphoneCoreListener, AlreadyInVideoCallListener, CallButtonListener, NewOutgoingCallUiListener {
|
/**
|
||||||
|
*
|
||||||
|
* Dialer and main activity of Linphone Android.
|
||||||
|
*
|
||||||
|
* Roles are:<ul>
|
||||||
|
* <li>Display the numpad, call/accept, address buttons</li>
|
||||||
|
* <li>Define preferences through the menu</li>
|
||||||
|
* <li>React to bad preference / no account set</li>
|
||||||
|
* <li>Manage first launch</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class DialerActivity extends Activity implements LinphoneGuiListener, AlreadyInVideoCallListener, NewOutgoingCallUiListener {
|
||||||
|
|
||||||
private AddressText mAddress;
|
private AddressText mAddress;
|
||||||
private TextView mDisplayNameView;
|
private TextView mDisplayNameView;
|
||||||
|
@ -75,7 +81,7 @@ public class DialerActivity extends Activity implements LinphoneCoreListener, Al
|
||||||
private View mAddressLayout;
|
private View mAddressLayout;
|
||||||
private View mInCallAddressLayout;
|
private View mInCallAddressLayout;
|
||||||
|
|
||||||
private static DialerActivity theDialer;
|
private static DialerActivity instance;
|
||||||
|
|
||||||
private PowerManager.WakeLock mWakeLock;
|
private PowerManager.WakeLock mWakeLock;
|
||||||
private SharedPreferences mPref;
|
private SharedPreferences mPref;
|
||||||
|
@ -87,30 +93,31 @@ public class DialerActivity extends Activity implements LinphoneCoreListener, Al
|
||||||
private static String CURRENT_DISPLAYNAME = "org.linphone.current-displayname";
|
private static String CURRENT_DISPLAYNAME = "org.linphone.current-displayname";
|
||||||
static int VIDEO_VIEW_ACTIVITY = 100;
|
static int VIDEO_VIEW_ACTIVITY = 100;
|
||||||
|
|
||||||
private static boolean accountCheckingDone;
|
private static boolean checkAccount = true;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return null if not ready yet
|
* @return null if not ready yet
|
||||||
*/
|
*/
|
||||||
public static DialerActivity getDialer() {
|
public static DialerActivity instance() {
|
||||||
return theDialer;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.dialer);
|
setContentView(R.layout.dialer);
|
||||||
mPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
|
|
||||||
AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
|
// Don't use Linphone Manager in the onCreate as it takes time in LinphoneService to initialize it.
|
||||||
LinphoneManager.getInstance().setUsefullStuff(am, mPref, getWindowManager(), getResources());
|
|
||||||
|
mPref = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
|
PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
|
||||||
mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK|PowerManager.ON_AFTER_RELEASE,"Linphone");
|
mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK|PowerManager.ON_AFTER_RELEASE,"Linphone");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
try {
|
|
||||||
mAddress = (AddressText) findViewById(R.id.SipUri);
|
mAddress = (AddressText) findViewById(R.id.SipUri);
|
||||||
mDisplayNameView = (TextView) findViewById(R.id.DisplayNameView);
|
mDisplayNameView = (TextView) findViewById(R.id.DisplayNameView);
|
||||||
((EraseButton) findViewById(R.id.Erase)).setAddressView(mAddress);
|
((EraseButton) findViewById(R.id.Erase)).setAddressView(mAddress);
|
||||||
|
@ -120,14 +127,14 @@ public class DialerActivity extends Activity implements LinphoneCoreListener, Al
|
||||||
mAddVideo.setOnAlreadyInVideoCallListener(this);
|
mAddVideo.setOnAlreadyInVideoCallListener(this);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
mCall = (CallButton) findViewById(R.id.Call);
|
mCall = (CallButton) findViewById(R.id.Call);
|
||||||
mCall.setCallButtonListerner(this);
|
|
||||||
mCall.setAddressWidget(mAddress);
|
mCall.setAddressWidget(mAddress);
|
||||||
|
|
||||||
|
|
||||||
mDecline= findViewById(R.id.Decline);
|
mDecline= findViewById(R.id.Decline);
|
||||||
mDecline.setEnabled(false);
|
mDecline.setEnabled(false);
|
||||||
|
|
||||||
|
|
||||||
mHangup = findViewById(R.id.HangUp);
|
mHangup = findViewById(R.id.HangUp);
|
||||||
|
|
||||||
|
|
||||||
|
@ -142,13 +149,12 @@ public class DialerActivity extends Activity implements LinphoneCoreListener, Al
|
||||||
mSpeaker = (SpeakerButton)findViewById(R.id.speaker_button);
|
mSpeaker = (SpeakerButton)findViewById(R.id.speaker_button);
|
||||||
|
|
||||||
|
|
||||||
if (LinphoneService.isready() && getIntent().getData() != null && !LinphoneService.getLc().isIncall()) {
|
try {
|
||||||
newOutgoingCall(getIntent().getData().toString().substring("tel://".length()));
|
|
||||||
getIntent().setData(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (LinphoneService.isready()) {
|
outgoingCallIntentReceived();
|
||||||
LinphoneCore lc = LinphoneService.getLc();
|
|
||||||
|
if (LinphoneService.isReady()) {
|
||||||
|
LinphoneCore lc = LinphoneManager.getLc();
|
||||||
if (lc.isIncall()) {
|
if (lc.isIncall()) {
|
||||||
if(lc.isInComingInvitePending()) {
|
if(lc.isInComingInvitePending()) {
|
||||||
callPending(lc.getCurrentCall());
|
callPending(lc.getCurrentCall());
|
||||||
|
@ -160,20 +166,21 @@ public class DialerActivity extends Activity implements LinphoneCoreListener, Al
|
||||||
mInCallControlRow.setVisibility(View.VISIBLE);
|
mInCallControlRow.setVisibility(View.VISIBLE);
|
||||||
mAddressLayout.setVisibility(View.GONE);
|
mAddressLayout.setVisibility(View.GONE);
|
||||||
mInCallAddressLayout.setVisibility(View.VISIBLE);
|
mInCallAddressLayout.setVisibility(View.VISIBLE);
|
||||||
|
mDisplayNameView.setText(LinphoneManager.getInstance().extractADisplayName());
|
||||||
String DisplayName = lc.getRemoteAddress().getDisplayName();
|
loadMicAndSpeakerUiStateFromManager();
|
||||||
if (DisplayName!=null) {
|
|
||||||
mDisplayNameView.setText(DisplayName);
|
|
||||||
} else {
|
|
||||||
mDisplayNameView.setText(lc.getRemoteAddress().getUserName());
|
|
||||||
}
|
|
||||||
loadMicAndSpeakerUiStateFromLibrary();
|
|
||||||
LinphoneActivity.instance().startProxymitySensor();
|
LinphoneActivity.instance().startProxymitySensor();
|
||||||
mWakeLock.acquire();
|
mWakeLock.acquire();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
instance = this;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(LinphoneManager.TAG,"Cannot start linphone",e);
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (findViewById(R.id.Digit00) != null) { // In landscape view, no keyboard
|
if (findViewById(R.id.Digit00) != null) { // In landscape view, no keyboard
|
||||||
((Digit) findViewById(R.id.Digit00)).setAddressWidget(mAddress);
|
((Digit) findViewById(R.id.Digit00)).setAddressWidget(mAddress);
|
||||||
|
@ -189,25 +196,17 @@ public class DialerActivity extends Activity implements LinphoneCoreListener, Al
|
||||||
((Digit) findViewById(R.id.DigitStar)).setAddressWidget(mAddress);
|
((Digit) findViewById(R.id.DigitStar)).setAddressWidget(mAddress);
|
||||||
((Digit) findViewById(R.id.DigitHash)).setAddressWidget(mAddress);
|
((Digit) findViewById(R.id.DigitHash)).setAddressWidget(mAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
mStatus = (TextView) findViewById(R.id.status_label);
|
mStatus = (TextView) findViewById(R.id.status_label);
|
||||||
theDialer = this;
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(LinphoneService.TAG,"Cannot start linphone",e);
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (!accountCheckingDone) {
|
if (checkAccount) {
|
||||||
if (mPref.getBoolean(PREF_FIRST_LAUNCH, true)) {
|
if (mPref.getBoolean(PREF_FIRST_LAUNCH, true)) {
|
||||||
onFirstLaunch();
|
onFirstLaunch();
|
||||||
} else if (!mPref.getBoolean(PREF_CHECK_CONFIG, false)
|
} else if (!mPref.getBoolean(PREF_CHECK_CONFIG, false)
|
||||||
&& !checkDefined(R.string.pref_username_key, R.string.pref_passwd_key, R.string.pref_domain_key)) {
|
&& !checkDefined(R.string.pref_username_key, R.string.pref_passwd_key, R.string.pref_domain_key)) {
|
||||||
onBadSettings();
|
onBadSettings();
|
||||||
} else {
|
} 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) {
|
private boolean checkDefined(int ... keys) {
|
||||||
for (int key : keys) {
|
for (int key : keys) {
|
||||||
String conf = mPref.getString(getString(key), null);
|
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() {
|
.setPositiveButton(getString(R.string.cont), new DialogInterface.OnClickListener() {
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
LinphoneActivity.instance().startprefActivity();
|
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() {
|
.setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() {
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
LinphoneActivity.instance().startprefActivity();
|
LinphoneActivity.instance().startprefActivity();
|
||||||
accountCheckingDone = true;
|
checkAccount = false;
|
||||||
}
|
}
|
||||||
}).setNeutralButton(getString(R.string.no), new DialogInterface.OnClickListener() {
|
}).setNeutralButton(getString(R.string.no), new DialogInterface.OnClickListener() {
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
dialog.cancel();
|
dialog.cancel();
|
||||||
accountCheckingDone = true;
|
checkAccount = false;
|
||||||
}
|
}
|
||||||
}).setNegativeButton(getString(R.string.never_remind), new DialogInterface.OnClickListener() {
|
}).setNegativeButton(getString(R.string.never_remind), new DialogInterface.OnClickListener() {
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
mPref.edit().putBoolean(PREF_CHECK_CONFIG, true).commit();
|
mPref.edit().putBoolean(PREF_CHECK_CONFIG, true).commit();
|
||||||
dialog.cancel();
|
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
|
@Override
|
||||||
public void onSaveInstanceState(Bundle savedInstanceState) {
|
public void onSaveInstanceState(Bundle savedInstanceState) {
|
||||||
super.onSaveInstanceState(savedInstanceState);
|
super.onSaveInstanceState(savedInstanceState);
|
||||||
savedInstanceState.putString(CURRENT_ADDRESS, mAddress.getText().toString());
|
savedInstanceState.putCharSequence(CURRENT_ADDRESS, mAddress.getText());
|
||||||
if (mAddress.getDisplayedName() != null)
|
if (mAddress.getDisplayedName() != null)
|
||||||
savedInstanceState.putString(CURRENT_DISPLAYNAME,mAddress.getDisplayedName());
|
savedInstanceState.putString(CURRENT_DISPLAYNAME,mAddress.getDisplayedName());
|
||||||
}
|
}
|
||||||
|
@ -300,7 +306,7 @@ public class DialerActivity extends Activity implements LinphoneCoreListener, Al
|
||||||
@Override
|
@Override
|
||||||
protected void onRestoreInstanceState(Bundle savedInstanceState) {
|
protected void onRestoreInstanceState(Bundle savedInstanceState) {
|
||||||
super.onRestoreInstanceState(savedInstanceState);
|
super.onRestoreInstanceState(savedInstanceState);
|
||||||
String lAddress = savedInstanceState.getString(CURRENT_ADDRESS);
|
CharSequence lAddress = savedInstanceState.getCharSequence(CURRENT_ADDRESS);
|
||||||
if (lAddress != null && mAddress != null) {
|
if (lAddress != null && mAddress != null) {
|
||||||
mAddress.setText(lAddress);
|
mAddress.setText(lAddress);
|
||||||
}
|
}
|
||||||
|
@ -312,7 +318,7 @@ public class DialerActivity extends Activity implements LinphoneCoreListener, Al
|
||||||
protected void onDestroy() {
|
protected void onDestroy() {
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
if (mWakeLock.isHeld()) mWakeLock.release();
|
if (mWakeLock.isHeld()) mWakeLock.release();
|
||||||
theDialer=null;
|
instance=null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -321,31 +327,9 @@ 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) {
|
private void startVideoView(int requestCode) {
|
||||||
|
@ -354,10 +338,132 @@ public class DialerActivity extends Activity implements LinphoneCoreListener, Al
|
||||||
startActivityForResult(lIntent,requestCode);
|
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();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void callState(final LinphoneCore lc,final LinphoneCall call, final State state, final String message) {
|
private void updateIncallVideoCallButton() {
|
||||||
|
boolean prefVideoEnabled = LinphoneManager.getInstance().isVideoEnabled();
|
||||||
|
if (prefVideoEnabled && !mCall.isEnabled()) {
|
||||||
|
mAddVideo.setVisibility(View.VISIBLE);
|
||||||
|
mAddVideo.setEnabled(true);
|
||||||
|
} else {
|
||||||
|
mAddVideo.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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) {
|
if (state == LinphoneCall.State.OutgoingInit) {
|
||||||
enterIncallMode(lc);
|
enterIncallMode(lc);
|
||||||
LinphoneManager.getInstance().routeAudioToReceiver();
|
LinphoneManager.getInstance().routeAudioToReceiver();
|
||||||
|
@ -376,7 +482,7 @@ public class DialerActivity extends Activity implements LinphoneCoreListener, Al
|
||||||
} else if (state == LinphoneCall.State.CallEnd) {
|
} else if (state == LinphoneCall.State.CallEnd) {
|
||||||
exitCallMode();
|
exitCallMode();
|
||||||
} else if (state == LinphoneCall.State.StreamsRunning) {
|
} else if (state == LinphoneCall.State.StreamsRunning) {
|
||||||
if (LinphoneService.getLc().getCurrentCall().getCurrentParamsCopy().getVideoEnabled()) {
|
if (LinphoneManager.getLc().getCurrentCall().getCurrentParamsCopy().getVideoEnabled()) {
|
||||||
if (!VideoCallActivity.launched) {
|
if (!VideoCallActivity.launched) {
|
||||||
startVideoView(VIDEO_VIEW_ACTIVITY);
|
startVideoView(VIDEO_VIEW_ACTIVITY);
|
||||||
}
|
}
|
||||||
|
@ -384,126 +490,22 @@ public class DialerActivity extends Activity implements LinphoneCoreListener, Al
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void show(LinphoneCore lc) {/*nop*/}
|
|
||||||
|
|
||||||
private void enterIncallMode(LinphoneCore lc) {
|
public void onGlobalStateChangedToOn(String message) {
|
||||||
mCallControlRow.setVisibility(View.GONE);
|
mCall.setEnabled(!LinphoneManager.getLc().isIncall());
|
||||||
mInCallControlRow.setVisibility(View.VISIBLE);
|
mHangup.setEnabled(!mCall.isEnabled());
|
||||||
mAddressLayout.setVisibility(View.GONE);
|
|
||||||
mInCallAddressLayout.setVisibility(View.VISIBLE);
|
|
||||||
mCall.setEnabled(false);
|
|
||||||
updateIncallVideoCallButton();
|
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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
loadMicAndSpeakerUiStateFromLibrary();
|
|
||||||
|
|
||||||
if (mSpeaker.isSpeakerOn()) {
|
|
||||||
LinphoneManager.getInstance().routeAudioToSpeaker();
|
|
||||||
} else {
|
|
||||||
LinphoneManager.getInstance().routeAudioToReceiver();
|
|
||||||
}
|
|
||||||
setVolumeControlStream(AudioManager.STREAM_VOICE_CALL);
|
|
||||||
LinphoneActivity.instance().startProxymitySensor();
|
|
||||||
if (!mWakeLock.isHeld()) mWakeLock.acquire();
|
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadMicAndSpeakerUiStateFromLibrary() {
|
if (getIntent().getData() != null) {
|
||||||
mMute.setChecked(LinphoneService.getLc().isMicMuted());
|
outgoingCallIntentReceived();
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,9 +59,9 @@ public class HistoryActivity extends ListActivity {
|
||||||
TextView lSecondLineView = (TextView) v.findViewById(R.id.history_cell_second_line);
|
TextView lSecondLineView = (TextView) v.findViewById(R.id.history_cell_second_line);
|
||||||
if (lSecondLineView.getVisibility() == View.GONE) {
|
if (lSecondLineView.getVisibility() == View.GONE) {
|
||||||
// no display name
|
// no display name
|
||||||
DialerActivity.getDialer().setContactAddress(lFirstLineView.getText().toString(), null);
|
DialerActivity.instance().setContactAddress(lFirstLineView.getText().toString(), null);
|
||||||
} else {
|
} else {
|
||||||
DialerActivity.getDialer().setContactAddress(lSecondLineView.getText().toString()
|
DialerActivity.instance().setContactAddress(lSecondLineView.getText().toString()
|
||||||
,lFirstLineView.getText().toString());
|
,lFirstLineView.getText().toString());
|
||||||
}
|
}
|
||||||
LinphoneActivity.instance().getTabHost().setCurrentTabByTag(LinphoneActivity.DIALER_TAB);
|
LinphoneActivity.instance().getTabHost().setCurrentTabByTag(LinphoneActivity.DIALER_TAB);
|
||||||
|
@ -86,12 +86,12 @@ public class HistoryActivity extends ListActivity {
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case R.id.menu_clear_history:
|
case R.id.menu_clear_history:
|
||||||
LinphoneService.instance().getLinphoneCore().clearCallLogs();
|
LinphoneManager.getLc().clearCallLogs();
|
||||||
setListAdapter(new CallHistoryAdapter(this));
|
setListAdapter(new CallHistoryAdapter(this));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Log.e(LinphoneService.TAG, "Unknown menu item ["+item+"]");
|
Log.e(LinphoneManager.TAG, "Unknown menu item ["+item+"]");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ public class HistoryActivity extends ListActivity {
|
||||||
class CallHistoryAdapter extends BaseAdapter {
|
class CallHistoryAdapter extends BaseAdapter {
|
||||||
final List<LinphoneCallLog> mLogs;
|
final List<LinphoneCallLog> mLogs;
|
||||||
CallHistoryAdapter(Context aContext) {
|
CallHistoryAdapter(Context aContext) {
|
||||||
mLogs = LinphoneService.instance().getLinphoneCore().getCallLogs();
|
mLogs = LinphoneManager.getLc().getCallLogs();
|
||||||
}
|
}
|
||||||
public int getCount() {
|
public int getCount() {
|
||||||
return mLogs.size();
|
return mLogs.size();
|
||||||
|
@ -142,7 +142,7 @@ public class HistoryActivity extends ListActivity {
|
||||||
lDirectionImageIn.setVisibility(View.GONE);
|
lDirectionImageIn.setVisibility(View.GONE);
|
||||||
lDirectionImageOut.setVisibility(View.VISIBLE);
|
lDirectionImageOut.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
LinphoneCore lc = LinphoneService.instance().getLinphoneCore();
|
LinphoneCore lc = LinphoneManager.getLc();
|
||||||
LinphoneProxyConfig lProxyConfig = lc.getDefaultProxyConfig();
|
LinphoneProxyConfig lProxyConfig = lc.getDefaultProxyConfig();
|
||||||
String lDetailedName=null;
|
String lDetailedName=null;
|
||||||
String lDisplayName = lAddress.getDisplayName();
|
String lDisplayName = lAddress.getDisplayName();
|
||||||
|
|
|
@ -30,14 +30,14 @@ public class KeepAliveReceiver extends BroadcastReceiver {
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
|
||||||
if (!LinphoneService.isready()) {
|
if (!LinphoneService.isReady()) {
|
||||||
Log.i(LinphoneService.TAG, "Linphone service not ready");
|
Log.i(LinphoneManager.TAG, "Keep alive broadcast received while Linphone service not ready");
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
if (intent.getAction().equalsIgnoreCase(Intent.ACTION_SCREEN_ON)) {
|
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)) {
|
} else if (intent.getAction().equalsIgnoreCase(Intent.ACTION_SCREEN_OFF)) {
|
||||||
LinphoneService.getLc().enableKeepAlive(false);
|
LinphoneManager.getLc().enableKeepAlive(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,19 +19,23 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
package org.linphone;
|
package org.linphone;
|
||||||
|
|
||||||
|
|
||||||
|
import static android.content.Intent.ACTION_MAIN;
|
||||||
|
import static android.media.AudioManager.*;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.linphone.core.Version;
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.app.TabActivity;
|
import android.app.TabActivity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
import android.hardware.Sensor;
|
import android.hardware.Sensor;
|
||||||
import android.hardware.SensorEvent;
|
import android.hardware.SensorEvent;
|
||||||
import android.hardware.SensorEventListener;
|
import android.hardware.SensorEventListener;
|
||||||
import android.hardware.SensorManager;
|
import android.hardware.SensorManager;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
|
@ -43,92 +47,92 @@ import android.widget.FrameLayout;
|
||||||
import android.widget.TabHost;
|
import android.widget.TabHost;
|
||||||
|
|
||||||
public class LinphoneActivity extends TabActivity {
|
public class LinphoneActivity extends TabActivity {
|
||||||
public static String DIALER_TAB = "dialer";
|
public static final String DIALER_TAB = "dialer";
|
||||||
private AudioManager mAudioManager;
|
private AudioManager mAudioManager;
|
||||||
private static LinphoneActivity theLinphoneActivity;
|
private static LinphoneActivity instance;
|
||||||
|
|
||||||
private FrameLayout mMainFrame;
|
private FrameLayout mMainFrame;
|
||||||
private SensorManager mSensorManager;
|
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()
|
protected static LinphoneActivity instance() {
|
||||||
{
|
if (instance != null) return instance;
|
||||||
if (theLinphoneActivity == null) {
|
|
||||||
throw new RuntimeException("LinphoneActivity not instanciated yet");
|
throw new RuntimeException("LinphoneActivity not instantiated yet");
|
||||||
} else {
|
|
||||||
return theLinphoneActivity;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onSaveInstanceState (Bundle outState) {
|
protected void onSaveInstanceState (Bundle outState) {
|
||||||
super.onSaveInstanceState(outState);
|
super.onSaveInstanceState(outState);
|
||||||
if (mMainFrame.getVisibility() == View.INVISIBLE) {
|
outState.putBoolean(SCREEN_IS_HIDDEN, mMainFrame.getVisibility() == View.INVISIBLE);
|
||||||
outState.putBoolean(SCREEN_IS_HIDDEN, true);
|
|
||||||
} else {
|
|
||||||
outState.putBoolean(SCREEN_IS_HIDDEN, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
instance = this;
|
||||||
setContentView(R.layout.main);
|
setContentView(R.layout.main);
|
||||||
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
|
|
||||||
|
|
||||||
theLinphoneActivity = this;
|
|
||||||
// start linphone as background
|
// start linphone as background
|
||||||
Intent intent = new Intent(Intent.ACTION_MAIN);
|
startService(new Intent(ACTION_MAIN).setClass(this, LinphoneService.class));
|
||||||
intent.setClass(this, LinphoneService.class);
|
|
||||||
startService(intent);
|
|
||||||
|
|
||||||
mMainFrame = (FrameLayout) findViewById(R.id.main_frame);
|
mMainFrame = (FrameLayout) findViewById(R.id.main_frame);
|
||||||
|
|
||||||
mAudioManager = ((AudioManager)getSystemService(Context.AUDIO_SERVICE));
|
mAudioManager = ((AudioManager)getSystemService(Context.AUDIO_SERVICE));
|
||||||
|
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
|
||||||
|
|
||||||
|
|
||||||
TabHost lTabHost = getTabHost(); // The activity TabHost
|
TabHost lTabHost = getTabHost(); // The activity TabHost
|
||||||
TabHost.TabSpec spec; // Reusable TabSpec for each tab
|
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
|
//Call History
|
||||||
Intent lHistoryItent = new Intent().setClass(this, HistoryActivity.class);
|
tabIntent = new Intent().setClass(this, HistoryActivity.class);
|
||||||
|
tabDrawable = getResources().getDrawable(R.drawable.history_orange);
|
||||||
spec = lTabHost.newTabSpec("history").setIndicator(getString(R.string.tab_history),
|
indicator = getString(R.string.tab_history);
|
||||||
getResources().getDrawable(R.drawable.history_orange))
|
spec = lTabHost.newTabSpec("history")
|
||||||
.setContent(lHistoryItent);
|
.setIndicator(indicator, tabDrawable)
|
||||||
|
.setContent(tabIntent);
|
||||||
lTabHost.addTab(spec);
|
lTabHost.addTab(spec);
|
||||||
|
|
||||||
// dialer
|
// Dialer
|
||||||
Intent lDialerIntent = new Intent().setClass(this, DialerActivity.class);
|
tabIntent = new Intent().setClass(this, DialerActivity.class).setData(getIntent().getData());
|
||||||
lDialerIntent.setData(getIntent().getData());
|
tabDrawable = getResources().getDrawable(R.drawable.dialer_orange);
|
||||||
|
indicator = getString(R.string.tab_dialer);
|
||||||
// Initialize a TabSpec for each tab and add it to the TabHost
|
tabDrawable = getResources().getDrawable(R.drawable.dialer_orange);
|
||||||
spec = lTabHost.newTabSpec("dialer").setIndicator(getString(R.string.tab_dialer),
|
spec = lTabHost.newTabSpec(DIALER_TAB)
|
||||||
getResources().getDrawable(R.drawable.dialer_orange))
|
.setIndicator(indicator, tabDrawable)
|
||||||
.setContent(lDialerIntent);
|
.setContent(tabIntent);
|
||||||
lTabHost.addTab(spec);
|
lTabHost.addTab(spec);
|
||||||
|
|
||||||
// contact pick
|
|
||||||
Intent lContactItent = new Intent().setClass(this, ContactPickerActivity.class);
|
|
||||||
|
|
||||||
spec = lTabHost.newTabSpec("contact").setIndicator(getString(R.string.tab_contact),
|
// Contact picker
|
||||||
getResources().getDrawable(R.drawable.contact_orange))
|
tabIntent = new Intent().setClass(this, ContactPickerActivity.class);
|
||||||
.setContent(lContactItent);
|
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.addTab(spec);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
lTabHost.setCurrentTabByTag("dialer");
|
lTabHost.setCurrentTabByTag("dialer");
|
||||||
|
|
||||||
|
|
||||||
if (savedInstanceState !=null && savedInstanceState.getBoolean(SCREEN_IS_HIDDEN,false)) {
|
if (savedInstanceState !=null && savedInstanceState.getBoolean(SCREEN_IS_HIDDEN,false)) {
|
||||||
hideScreen(true);
|
hideScreen(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onNewIntent(Intent intent) {
|
protected void onNewIntent(Intent intent) {
|
||||||
super.onNewIntent(intent);
|
super.onNewIntent(intent);
|
||||||
if (intent.getData() != null) {
|
if (intent.getData() != null) {
|
||||||
DialerActivity.getDialer().newOutgoingCall(intent.getData().toString().substring("tel://".length()));
|
DialerActivity.instance().newOutgoingCall(intent);
|
||||||
intent.setData(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -136,16 +140,15 @@ public class LinphoneActivity extends TabActivity {
|
||||||
protected void onPause() {
|
protected void onPause() {
|
||||||
super.onPause();
|
super.onPause();
|
||||||
if (isFinishing()) {
|
if (isFinishing()) {
|
||||||
//restaure audio settings
|
//restore audio settings
|
||||||
if (Integer.parseInt(Build.VERSION.SDK) <=4 /*<donut*/) {
|
if (Version.sdkStrictlyBelow(4) /*<donut*/) {
|
||||||
mAudioManager.setMode(AudioManager.MODE_NORMAL);
|
mAudioManager.setMode(MODE_NORMAL);
|
||||||
mAudioManager.setRouting(AudioManager.MODE_NORMAL,
|
mAudioManager.setRouting(MODE_NORMAL, ROUTE_SPEAKER, ROUTE_ALL);
|
||||||
AudioManager.ROUTE_SPEAKER, AudioManager.ROUTE_ALL);
|
|
||||||
} else {
|
} else {
|
||||||
mAudioManager.setSpeakerphoneOn(false);
|
mAudioManager.setSpeakerphoneOn(false);
|
||||||
}
|
}
|
||||||
stopProxymitySensor();//just in case
|
stopProxymitySensor();//just in case
|
||||||
theLinphoneActivity = null;
|
instance = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -166,58 +169,29 @@ public class LinphoneActivity extends TabActivity {
|
||||||
return true;
|
return true;
|
||||||
case R.id.menu_exit:
|
case R.id.menu_exit:
|
||||||
finish();
|
finish();
|
||||||
Intent exitIntent = new Intent(Intent.ACTION_MAIN);
|
stopService(new Intent(ACTION_MAIN)
|
||||||
exitIntent.setClass(this, LinphoneService.class);
|
.setClass(this, LinphoneService.class));
|
||||||
stopService(exitIntent);
|
|
||||||
break;
|
break;
|
||||||
case R.id.menu_about:
|
case R.id.menu_about:
|
||||||
Intent intent = new Intent(Intent.ACTION_MAIN);
|
startActivity(new Intent(ACTION_MAIN)
|
||||||
intent.setClass(this, AboutActivity.class);
|
.setClass(this, AboutActivity.class));
|
||||||
startActivity(intent);
|
|
||||||
default:
|
default:
|
||||||
Log.e(LinphoneService.TAG, "Unknown menu item ["+item+"]");
|
Log.e(LinphoneManager.TAG, "Unknown menu item ["+item+"]");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
protected void startprefActivity() {
|
|
||||||
Intent intent = new Intent(Intent.ACTION_MAIN);
|
void startprefActivity() {
|
||||||
|
Intent intent = new Intent(ACTION_MAIN);
|
||||||
intent.setClass(this, LinphonePreferencesActivity.class);
|
intent.setClass(this, LinphonePreferencesActivity.class);
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
}
|
}
|
||||||
public void initFromConf() throws LinphoneException {
|
|
||||||
|
|
||||||
try {
|
|
||||||
LinphoneService.instance().initFromConf();
|
|
||||||
} catch (LinphoneConfigException e) {
|
|
||||||
handleBadConfig(e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
private void handleBadConfig(String message) {
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
|
||||||
builder.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) {
|
|
||||||
startprefActivity();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.setNegativeButton(getString(R.string.no), new DialogInterface.OnClickListener() {
|
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
|
||||||
dialog.cancel();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
builder.create().show();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onAccuracyChanged(Sensor sensor, int accuracy) {
|
|
||||||
//nop
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected void hideScreen(boolean isHidden) {
|
|
||||||
|
void hideScreen(boolean isHidden) {
|
||||||
WindowManager.LayoutParams lAttrs =getWindow().getAttributes();
|
WindowManager.LayoutParams lAttrs =getWindow().getAttributes();
|
||||||
if (isHidden) {
|
if (isHidden) {
|
||||||
lAttrs.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
|
lAttrs.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
|
||||||
|
@ -228,16 +202,17 @@ public class LinphoneActivity extends TabActivity {
|
||||||
}
|
}
|
||||||
getWindow().setAttributes(lAttrs);
|
getWindow().setAttributes(lAttrs);
|
||||||
}
|
}
|
||||||
protected synchronized void startProxymitySensor() {
|
|
||||||
|
synchronized void startProxymitySensor() {
|
||||||
if (mSensorEventListener != null) {
|
if (mSensorEventListener != null) {
|
||||||
Log.i(LinphoneService.TAG, "proximity sensor already active");
|
Log.i(LinphoneManager.TAG, "proximity sensor already active");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
List<Sensor> lSensorList = mSensorManager.getSensorList(Sensor.TYPE_PROXIMITY);
|
List<Sensor> lSensorList = mSensorManager.getSensorList(Sensor.TYPE_PROXIMITY);
|
||||||
mSensorEventListener = new SensorEventListener() {
|
mSensorEventListener = new SensorEventListener() {
|
||||||
public void onSensorChanged(SensorEvent event) {
|
public void onSensorChanged(SensorEvent event) {
|
||||||
if (event.timestamp == 0) return; //just ignoring for nexus 1
|
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() ) {
|
if (event.values[0] != event.sensor.getMaximumRange() ) {
|
||||||
instance().hideScreen(true);
|
instance().hideScreen(true);
|
||||||
|
@ -250,9 +225,10 @@ public class LinphoneActivity extends TabActivity {
|
||||||
};
|
};
|
||||||
if (lSensorList.size() >0) {
|
if (lSensorList.size() >0) {
|
||||||
mSensorManager.registerListener(mSensorEventListener,lSensorList.get(0),SensorManager.SENSOR_DELAY_UI);
|
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() {
|
protected synchronized void stopProxymitySensor() {
|
||||||
if (mSensorManager!=null) {
|
if (mSensorManager!=null) {
|
||||||
mSensorManager.unregisterListener(mSensorEventListener);
|
mSensorManager.unregisterListener(mSensorEventListener);
|
||||||
|
@ -260,5 +236,26 @@ public class LinphoneActivity extends TabActivity {
|
||||||
}
|
}
|
||||||
hideScreen(false);
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,30 +18,114 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
package org.linphone;
|
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.AndroidCameraRecordManager;
|
||||||
import org.linphone.core.LinphoneAddress;
|
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.LinphoneCore;
|
||||||
import org.linphone.core.LinphoneCoreException;
|
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.ContentResolver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
|
import android.media.MediaPlayer;
|
||||||
|
import android.net.ConnectivityManager;
|
||||||
|
import android.net.NetworkInfo;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
import android.os.Vibrator;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.provider.Settings.SettingNotFoundException;
|
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.<br />
|
||||||
|
* Including:<ul>
|
||||||
|
* <li>Starting C liblinphone</li>
|
||||||
|
* <li>Reacting to C liblinphone state changes</li>
|
||||||
|
* <li>Calling Linphone android service listener methods</li>
|
||||||
|
* <li>Interacting from Android GUI/service with low level SIP stuff/</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* Add Service Listener to react to Linphone state changes.
|
||||||
|
*
|
||||||
|
* @author Guillaume Beraudo
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public final class LinphoneManager implements LinphoneCoreListener {
|
||||||
|
|
||||||
private static LinphoneManager instance;
|
private static LinphoneManager instance;
|
||||||
private AudioManager mAudioManager;
|
private AudioManager mAudioManager;
|
||||||
private NewOutgoingCallUiListener newOutgoingCallUiListener;
|
private NewOutgoingCallUiListener newOutgoingCallUiListener;
|
||||||
private SharedPreferences mPref;
|
private SharedPreferences mPref;
|
||||||
private Resources mR;
|
private Resources mR;
|
||||||
private WindowManager mWindowManager;
|
private LinphoneCore mLc;
|
||||||
|
private int mPhoneOrientation;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
|
||||||
private LinphoneManager() {}
|
|
||||||
|
|
||||||
public void routeAudioToSpeaker() {
|
public void routeAudioToSpeaker() {
|
||||||
if (Integer.parseInt(Build.VERSION.SDK) <= 4 /*<donut*/) {
|
if (Integer.parseInt(Build.VERSION.SDK) <= 4 /*<donut*/) {
|
||||||
|
@ -50,11 +134,10 @@ public class LinphoneManager {
|
||||||
} else {
|
} else {
|
||||||
mAudioManager.setSpeakerphoneOn(true);
|
mAudioManager.setSpeakerphoneOn(true);
|
||||||
}
|
}
|
||||||
LinphoneCore lc = LinphoneService.getLc();
|
if (mLc.isIncall()) {
|
||||||
if (lc.isIncall()) {
|
|
||||||
/*disable EC*/
|
/*disable EC*/
|
||||||
lc.getCurrentCall().enableEchoCancellation(false);
|
mLc.getCurrentCall().enableEchoCancellation(false);
|
||||||
lc.getCurrentCall().enableEchoLimiter(true);
|
mLc.getCurrentCall().enableEchoLimiter(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -67,30 +150,33 @@ public class LinphoneManager {
|
||||||
mAudioManager.setSpeakerphoneOn(false);
|
mAudioManager.setSpeakerphoneOn(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
LinphoneCore lc = LinphoneService.getLc();
|
if (mLc.isIncall()) {
|
||||||
if (lc.isIncall()) {
|
|
||||||
//Restore default value
|
//Restore default value
|
||||||
lc.getCurrentCall().enableEchoCancellation(lc.isEchoCancellationEnabled());
|
mLc.getCurrentCall().enableEchoCancellation(mLc.isEchoCancellationEnabled());
|
||||||
lc.getCurrentCall().enableEchoLimiter(false);
|
mLc.getCurrentCall().enableEchoLimiter(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized static final LinphoneManager getInstance() {
|
public synchronized static final LinphoneManager createAndStart(Context c, LinphoneServiceListener listener) {
|
||||||
if (instance == null) instance = new LinphoneManager();
|
if (instance != null)
|
||||||
|
throw new RuntimeException("Linphone Manager is already initialized");
|
||||||
|
|
||||||
|
instance = new LinphoneManager(c);
|
||||||
|
instance.startLibLinphone(c, listener);
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final LinphoneManager getInstance() {
|
||||||
|
if (instance != null) return instance;
|
||||||
|
|
||||||
|
throw new RuntimeException("Linphone Manager should be created before accessed");
|
||||||
|
}
|
||||||
|
|
||||||
public static final LinphoneCore getLc() {
|
public static final LinphoneCore getLc() {
|
||||||
return LinphoneService.getLc();
|
return getInstance().mLc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setUsefullStuff(AudioManager audioManager, SharedPreferences pref, WindowManager windowManager, Resources r) {
|
|
||||||
mAudioManager = audioManager;
|
|
||||||
mPref = pref;
|
|
||||||
mR = r;
|
|
||||||
mWindowManager = windowManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSpeakerOn() {
|
public boolean isSpeakerOn() {
|
||||||
return (Integer.parseInt(Build.VERSION.SDK) <=4 && mAudioManager.getRouting(AudioManager.MODE_NORMAL) == AudioManager.ROUTE_SPEAKER)
|
return (Integer.parseInt(Build.VERSION.SDK) <=4 && mAudioManager.getRouting(AudioManager.MODE_NORMAL) == AudioManager.ROUTE_SPEAKER)
|
||||||
|
@ -105,14 +191,13 @@ public class LinphoneManager {
|
||||||
address.setText(to);
|
address.setText(to);
|
||||||
}
|
}
|
||||||
|
|
||||||
LinphoneCore lLinphoneCore = LinphoneService.instance().getLinphoneCore();
|
if (mLc.isIncall()) {
|
||||||
if (lLinphoneCore.isIncall()) {
|
|
||||||
newOutgoingCallUiListener.onAlreadyInCall();
|
newOutgoingCallUiListener.onAlreadyInCall();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LinphoneAddress lAddress;
|
LinphoneAddress lAddress;
|
||||||
try {
|
try {
|
||||||
lAddress = lLinphoneCore.interpretUrl(to);
|
lAddress = mLc.interpretUrl(to);
|
||||||
} catch (LinphoneCoreException e) {
|
} catch (LinphoneCoreException e) {
|
||||||
newOutgoingCallUiListener.onWrongDestinationAddress();
|
newOutgoingCallUiListener.onWrongDestinationAddress();
|
||||||
return;
|
return;
|
||||||
|
@ -120,8 +205,7 @@ public class LinphoneManager {
|
||||||
lAddress.setDisplayName(address.getDisplayedName());
|
lAddress.setDisplayName(address.getDisplayedName());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
boolean prefVideoEnable = isVideoEnabled();
|
||||||
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);
|
boolean prefInitiateWithVideo = mPref.getBoolean(mR.getString(R.string.pref_video_initiate_call_with_video_key), false);
|
||||||
resetCameraFromPreferences();
|
resetCameraFromPreferences();
|
||||||
CallManager.getInstance().inviteAddress(lAddress, prefVideoEnable && prefInitiateWithVideo);
|
CallManager.getInstance().inviteAddress(lAddress, prefVideoEnable && prefInitiateWithVideo);
|
||||||
|
@ -136,8 +220,7 @@ public class LinphoneManager {
|
||||||
public void resetCameraFromPreferences() {
|
public void resetCameraFromPreferences() {
|
||||||
boolean useFrontCam = mPref.getBoolean(mR.getString(R.string.pref_video_use_front_camera_key), false);
|
boolean useFrontCam = mPref.getBoolean(mR.getString(R.string.pref_video_use_front_camera_key), false);
|
||||||
AndroidCameraRecordManager.getInstance().setUseFrontCamera(useFrontCam);
|
AndroidCameraRecordManager.getInstance().setUseFrontCamera(useFrontCam);
|
||||||
final int phoneOrientation = 90 * mWindowManager.getDefaultDisplay().getOrientation();
|
AndroidCameraRecordManager.getInstance().setPhoneOrientation(mPhoneOrientation);
|
||||||
AndroidCameraRecordManager.getInstance().setPhoneOrientation(phoneOrientation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNewOutgoingCallUiListener(NewOutgoingCallUiListener l) {
|
public void setNewOutgoingCallUiListener(NewOutgoingCallUiListener l) {
|
||||||
|
@ -160,41 +243,33 @@ public class LinphoneManager {
|
||||||
|
|
||||||
|
|
||||||
public void sendStaticImage(boolean send) {
|
public void sendStaticImage(boolean send) {
|
||||||
LinphoneCore lc = LinphoneService.getLc();
|
if (mLc.isIncall()) {
|
||||||
if (lc.isIncall()) {
|
mLc.getCurrentCall().enableCamera(!send);
|
||||||
lc.getCurrentCall().enableCamera(!send);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void playDtmf(char dtmf) {
|
public void playDtmf(ContentResolver r, char dtmf) {
|
||||||
if (getLc().isIncall()) {
|
boolean speaker = true;
|
||||||
// Play if in call as it will not go to speaker
|
|
||||||
getLc().playDtmf(dtmf, -1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ContentResolver r = LinphoneService.instance().getContentResolver();
|
|
||||||
try {
|
try {
|
||||||
if (Settings.System.getInt(r, Settings.System.DTMF_TONE_WHEN_DIALING) == 0) {
|
if (Settings.System.getInt(r, Settings.System.DTMF_TONE_WHEN_DIALING) == 0) {
|
||||||
// audible touch disabled: don't play
|
// audible touch disabled: don't play on speaker, only send in outgoing stream
|
||||||
return;
|
speaker = false;
|
||||||
}
|
}
|
||||||
} catch (SettingNotFoundException e) {}
|
} catch (SettingNotFoundException e) {}
|
||||||
|
|
||||||
getLc().playDtmf(dtmf, -1);
|
getLc().playDtmf(dtmf, -1, speaker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void changeResolution() {
|
public void changeResolution() {
|
||||||
BandwidthManager manager = BandwidthManager.getInstance();
|
BandwidthManager manager = BandwidthManager.getInstance();
|
||||||
manager.setUserRestriction(!manager.isUserRestriction());
|
manager.setUserRestriction(!manager.isUserRestriction());
|
||||||
LinphoneManager.getInstance().sendStaticImage(AndroidCameraRecordManager.getInstance().isMuted());
|
sendStaticImage(AndroidCameraRecordManager.getInstance().isMuted());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void terminateCall() {
|
public void terminateCall() {
|
||||||
LinphoneCore lc = LinphoneService.getLc();
|
if (mLc.isIncall()) {
|
||||||
if (lc.isIncall()) {
|
mLc.terminateCall(mLc.getCurrentCall());
|
||||||
lc.terminateCall(lc.getCurrentCall());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,6 +285,419 @@ public class LinphoneManager {
|
||||||
|
|
||||||
public void toggleCameraMuting() {
|
public void toggleCameraMuting() {
|
||||||
AndroidCameraRecordManager rm = AndroidCameraRecordManager.getInstance();
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -21,24 +21,25 @@ package org.linphone;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import static android.media.AudioManager.STREAM_VOICE_CALL;
|
||||||
|
|
||||||
import org.linphone.core.LinphoneCoreException;
|
import org.linphone.core.LinphoneCoreException;
|
||||||
|
import org.linphone.core.Version;
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.DialogInterface.OnClickListener;
|
import android.content.DialogInterface.OnClickListener;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.preference.CheckBoxPreference;
|
import android.preference.CheckBoxPreference;
|
||||||
import android.preference.Preference;
|
import android.preference.Preference;
|
||||||
import android.preference.Preference.OnPreferenceClickListener;
|
|
||||||
import android.preference.PreferenceActivity;
|
import android.preference.PreferenceActivity;
|
||||||
|
import android.preference.Preference.OnPreferenceClickListener;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
public class LinphonePreferencesActivity extends PreferenceActivity {
|
public class LinphonePreferencesActivity extends PreferenceActivity {
|
||||||
private static final int version = Integer.parseInt(Build.VERSION.SDK);
|
private boolean mIsLowEndCpu = true;
|
||||||
boolean mIsLowEndCpu = true;
|
|
||||||
private AudioManager mAudioManager;
|
private AudioManager mAudioManager;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -46,9 +47,9 @@ public class LinphonePreferencesActivity extends PreferenceActivity {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
mAudioManager = ((AudioManager)getSystemService(Context.AUDIO_SERVICE));
|
mAudioManager = ((AudioManager)getSystemService(Context.AUDIO_SERVICE));
|
||||||
boolean enableIlbc=false;
|
boolean enableIlbc=false;
|
||||||
if (LinphoneService.isready()) {
|
if (LinphoneService.isReady()) {
|
||||||
// if not ilbc, we are on low end cpu.
|
// 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;
|
mIsLowEndCpu=!enableIlbc;
|
||||||
if (!mIsLowEndCpu && !getPreferenceManager().getSharedPreferences().contains(getString(R.string.pref_echo_cancellation_key))) {
|
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();
|
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_speex16_key)).setEnabled(enableIlbc);
|
||||||
//getPreferenceScreen().findPreference(getString(R.string.pref_codec_speex32_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) {
|
public boolean onPreferenceClick(Preference preference) {
|
||||||
startEcCalibration(preference);
|
startEcCalibration(preference);
|
||||||
return false;
|
return false;
|
||||||
|
@ -76,7 +78,7 @@ public class LinphonePreferencesActivity extends PreferenceActivity {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Force disable video
|
// Force disable video
|
||||||
if (version < 5 || !enableIlbc) {
|
if (Version.sdkStrictlyBelow(5) || !enableIlbc || !LinphoneManager.getInstance().hasCamera()) {
|
||||||
disableCheckbox(R.string.pref_video_enable_key);
|
disableCheckbox(R.string.pref_video_enable_key);
|
||||||
}
|
}
|
||||||
if (getPreferenceManager().getSharedPreferences().getBoolean(DialerActivity.PREF_FIRST_LAUNCH,true)) {
|
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 {
|
try {
|
||||||
while (mAudioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL) != mAudioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL)) {
|
int oldVolume = mAudioManager.getStreamVolume(STREAM_VOICE_CALL);
|
||||||
mAudioManager.adjustStreamVolume(AudioManager.STREAM_VOICE_CALL, AudioManager.ADJUST_RAISE, 0);
|
int maxVolume = mAudioManager.getStreamMaxVolume(STREAM_VOICE_CALL);
|
||||||
}
|
mAudioManager.setStreamVolume(STREAM_VOICE_CALL, maxVolume, 0);
|
||||||
LinphoneService.getLc().startEchoCalibration(preference);
|
|
||||||
|
LinphoneManager.getLc().startEchoCalibration(preference);
|
||||||
|
|
||||||
|
mAudioManager.setStreamVolume(STREAM_VOICE_CALL, oldVolume, 0);
|
||||||
|
|
||||||
preference.setSummary(R.string.ec_calibrating);
|
preference.setSummary(R.string.ec_calibrating);
|
||||||
preference.getEditor().putBoolean(getString(R.string.pref_echo_canceller_calibration_key), false).commit();
|
preference.getEditor().putBoolean(getString(R.string.pref_echo_canceller_calibration_key), false).commit();
|
||||||
} catch (LinphoneCoreException e) {
|
} catch (LinphoneCoreException e) {
|
||||||
Log.w(LinphoneService.TAG, "Cannot calibrate EC",e);
|
Log.w(LinphoneManager.TAG, "Cannot calibrate EC",e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void disableCheckbox(int key) {
|
private void disableCheckbox(int key) {
|
||||||
getPreferenceManager().getSharedPreferences().edit().putBoolean(getString(key), false).commit();
|
getPreferenceManager().getSharedPreferences().edit().putBoolean(getString(key), false).commit();
|
||||||
CheckBoxPreference box = (CheckBoxPreference) getPreferenceScreen().findPreference(getString(key));
|
CheckBoxPreference box = (CheckBoxPreference) getPreferenceScreen().findPreference(getString(key));
|
||||||
|
@ -116,12 +123,20 @@ public class LinphonePreferencesActivity extends PreferenceActivity {
|
||||||
@Override
|
@Override
|
||||||
protected void onPause() {
|
protected void onPause() {
|
||||||
super.onPause();
|
super.onPause();
|
||||||
if (isFinishing()) {
|
|
||||||
|
if (!isFinishing()) return;
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
LinphoneActivity.instance().initFromConf();
|
LinphoneManager.getInstance().initFromConf(getApplicationContext());
|
||||||
} catch (LinphoneException e) {
|
} catch (LinphoneException e) {
|
||||||
Log.e(LinphoneService.TAG, "cannot update config",e);
|
|
||||||
|
if (! (e instanceof LinphoneConfigException)) {
|
||||||
|
Log.e(LinphoneManager.TAG, "Cannot update config",e);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LinphoneActivity.instance().showPreferenceErrorDialog(e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,446 +18,128 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
package org.linphone;
|
package org.linphone;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.Timer;
|
|
||||||
import java.util.TimerTask;
|
|
||||||
|
|
||||||
import org.linphone.core.LinphoneAddress;
|
import org.linphone.LinphoneManager.LinphoneServiceListener;
|
||||||
import org.linphone.core.LinphoneAuthInfo;
|
|
||||||
import org.linphone.core.LinphoneCall;
|
import org.linphone.core.LinphoneCall;
|
||||||
import org.linphone.core.LinphoneChatRoom;
|
|
||||||
import org.linphone.core.LinphoneCore;
|
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.LinphoneCall.State;
|
||||||
import org.linphone.core.LinphoneCore.EcCalibratorStatus;
|
import org.linphone.core.LinphoneCore.EcCalibratorStatus;
|
||||||
import org.linphone.core.LinphoneCore.FirewallPolicy;
|
|
||||||
import org.linphone.core.LinphoneCore.GlobalState;
|
import org.linphone.core.LinphoneCore.GlobalState;
|
||||||
|
import org.linphone.core.LinphoneCore.RegistrationState;
|
||||||
|
|
||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
import android.content.BroadcastReceiver;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.media.AudioManager;
|
|
||||||
import android.media.MediaPlayer;
|
import android.media.MediaPlayer;
|
||||||
import android.media.RingtoneManager;
|
import android.media.RingtoneManager;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.Uri;
|
||||||
import android.net.NetworkInfo;
|
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.Vibrator;
|
|
||||||
import android.preference.CheckBoxPreference;
|
import android.preference.CheckBoxPreference;
|
||||||
import android.preference.PreferenceManager;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
public class LinphoneService extends Service implements LinphoneCoreListener {
|
/***
|
||||||
static final public String TAG="Linphone";
|
*
|
||||||
/** Called when the activity is first created. */
|
* Linphone service, reacting to Incoming calls, ...<br />
|
||||||
private static String LINPHONE_FACTORY_RC = "/data/data/org.linphone/files/linphonerc";
|
*
|
||||||
private static String LINPHONE_RC = "/data/data/org.linphone/files/.linphonerc";
|
* Roles include:<ul>
|
||||||
private static String RING_SND = "/data/data/org.linphone/files/oldphone_mono.wav";
|
* <li>Initializing LinphoneManager</li>
|
||||||
private static String RINGBACK_SND = "/data/data/org.linphone/files/ringback.wav";
|
* <li>Starting C libLinphone through LinphoneManager</li>
|
||||||
|
* <li>Reacting to LinphoneManager state changes</li>
|
||||||
private static LinphoneService theLinphone;
|
* <li>Delegating GUI state change actions to GUI listener</li>
|
||||||
private LinphoneCore mLinphoneCore;
|
*
|
||||||
private SharedPreferences mPref;
|
*
|
||||||
Timer mTimer = new Timer("Linphone scheduler");
|
* @author Guillaume Beraudo
|
||||||
|
*
|
||||||
NotificationManager mNotificationManager;
|
*/
|
||||||
Notification mNotification;
|
public final class LinphoneService extends Service implements LinphoneServiceListener {
|
||||||
PendingIntent mNofificationContentIntent;
|
/* Listener needs to be implemented in the Service as it calls
|
||||||
final static int NOTIFICATION_ID=1;
|
* setLatestEventInfo and startActivity() which needs a context.
|
||||||
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;
|
|
||||||
|
|
||||||
MediaPlayer mRingerPlayer;
|
|
||||||
LinphoneCall.State mCurrentCallState;
|
|
||||||
Vibrator mVibrator;
|
|
||||||
private AudioManager mAudioManager;
|
|
||||||
private BroadcastReceiver mKeepAliveMgrReceiver = new KeepAliveReceiver();
|
|
||||||
private BroadcastReceiver mOutgoingCallReceiver = null;
|
|
||||||
|
|
||||||
private Handler mHandler = new Handler();
|
private Handler mHandler = new Handler();
|
||||||
static boolean isready() {
|
private static LinphoneService instance;
|
||||||
return (theLinphone!=null);
|
|
||||||
}
|
static boolean isReady() { return (instance!=null); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws RuntimeException service not instantiated
|
||||||
|
*/
|
||||||
static LinphoneService instance() {
|
static LinphoneService instance() {
|
||||||
if (theLinphone == null) {
|
if (isReady()) return instance;
|
||||||
throw new RuntimeException("LinphoneActivity not instanciated yet");
|
|
||||||
} else {
|
throw new RuntimeException("LinphoneService not instantiated yet");
|
||||||
return theLinphone;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
theLinphone = this;
|
instance = this;
|
||||||
|
|
||||||
// Dump some debugging information to the logs
|
// Dump some debugging information to the logs
|
||||||
Hacks.dumpDeviceInformation();
|
Hacks.dumpDeviceInformation();
|
||||||
|
|
||||||
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
mNotificationMgr = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
mNotification = new Notification(R.drawable.status_level
|
mNotif = new Notification(R.drawable.status_level, "", System.currentTimeMillis());
|
||||||
, ""
|
mNotif.iconLevel=IC_LEVEL_ORANGE;
|
||||||
, System.currentTimeMillis());
|
mNotif.flags |= Notification.FLAG_ONGOING_EVENT;
|
||||||
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
|
Intent notifIntent = new Intent(this, LinphoneActivity.class);
|
||||||
, LINPHONE_RC
|
mNotifContentIntent = PendingIntent.getActivity(this, 0, notifIntent, 0);
|
||||||
, LINPHONE_FACTORY_RC
|
mNotif.setLatestEventInfo(this, NOTIF_TITLE,"", mNotifContentIntent);
|
||||||
, null);
|
mNotificationMgr.notify(NOTIF_ID, mNotif);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
LinphoneManager.createAndStart(this, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private void copyAssetsFromPackage() throws IOException {
|
|
||||||
copyIfNotExist(R.raw.oldphone_mono,RING_SND);
|
private void sendNotification(int level, int text) {
|
||||||
copyIfNotExist(R.raw.ringback,RINGBACK_SND);
|
mNotif.iconLevel = level;
|
||||||
copyFromPackage(R.raw.linphonerc, new File(LINPHONE_FACTORY_RC).getName());
|
mNotif.when=System.currentTimeMillis();
|
||||||
}
|
mNotif.setLatestEventInfo(this, NOTIF_TITLE,getString(text), mNotifContentIntent);
|
||||||
private void copyIfNotExist(int ressourceId,String target) throws IOException {
|
mNotificationMgr.notify(NOTIF_ID, mNotif);
|
||||||
File lFileToCopy = new File(target);
|
|
||||||
if (!lFileToCopy.exists()) {
|
|
||||||
copyFromPackage(ressourceId,lFileToCopy.getName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
private void sendNotificationWithId(int level, int text) {
|
||||||
private void copyFromPackage(int ressourceId,String target) throws IOException{
|
mNotif.iconLevel = level;
|
||||||
FileOutputStream lOutputStream = openFileOutput (target, 0);
|
mNotif.when=System.currentTimeMillis();
|
||||||
InputStream lInputStream = getResources().openRawResource(ressourceId);
|
String id = LinphoneManager.getLc().getDefaultProxyConfig().getIdentity();
|
||||||
int readByte;
|
mNotif.setLatestEventInfo(this, NOTIF_TITLE,
|
||||||
byte[] buff = new byte[8048];
|
String.format(getString(text), id),
|
||||||
while (( readByte = lInputStream.read(buff))!=-1) {
|
mNotifContentIntent);
|
||||||
lOutputStream.write(buff,0, readByte);
|
mNotificationMgr.notify(NOTIF_ID, mNotif);
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected LinphoneCore getLinphoneCore() {
|
|
||||||
return mLinphoneCore;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBinder onBind(Intent intent) {
|
public IBinder onBind(Intent intent) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -466,66 +148,77 @@ public class LinphoneService extends Service implements LinphoneCoreListener {
|
||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
mTimer.cancel();
|
LinphoneManager.destroy(this);
|
||||||
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
|
|
||||||
|
|
||||||
}
|
mNotificationMgr.cancel(NOTIF_ID);
|
||||||
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
|
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
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 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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void onEcCalibrationStatus(final EcCalibratorStatus status, Object data,
|
||||||
|
final int delay_ms) {
|
||||||
final CheckBoxPreference pref = (CheckBoxPreference) data;
|
final CheckBoxPreference pref = (CheckBoxPreference) data;
|
||||||
|
|
||||||
mHandler.post(new Runnable() {
|
mHandler.post(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
if (status == EcCalibratorStatus.Done) {
|
if (status == EcCalibratorStatus.Done) {
|
||||||
|
@ -541,5 +234,21 @@ public class LinphoneService extends Service implements LinphoneCoreListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,27 +27,34 @@ import android.util.Log;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Intercept network state changes and update linphone core through LinphoneManager.
|
||||||
|
*
|
||||||
|
*/
|
||||||
public class NetworkManager extends BroadcastReceiver {
|
public class NetworkManager extends BroadcastReceiver {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
|
||||||
NetworkInfo lNetworkInfo = (NetworkInfo) intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
|
NetworkInfo lNetworkInfo = (NetworkInfo) intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
|
||||||
Log.i(LinphoneService.TAG, "Network info ["+lNetworkInfo+"]");
|
Log.i(LinphoneManager.TAG, "Network info ["+lNetworkInfo+"]");
|
||||||
Boolean lNoConnectivity = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY,false);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (lNoConnectivity | ((lNetworkInfo.getState() == NetworkInfo.State.DISCONNECTED) /*&& !lIsFailOver*/)) {
|
if (lNoConnectivity | ((lNetworkInfo.getState() == NetworkInfo.State.DISCONNECTED) /*&& !lIsFailOver*/)) {
|
||||||
LinphoneService.instance().getLinphoneCore().setNetworkReachable(false);
|
LinphoneManager.getLc().setNetworkReachable(false);
|
||||||
} else if (lNetworkInfo.getState() == NetworkInfo.State.CONNECTED){
|
} else if (lNetworkInfo.getState() == NetworkInfo.State.CONNECTED){
|
||||||
LinphoneService.instance().getLinphoneCore().setNetworkReachable(true);
|
LinphoneManager.getLc().setNetworkReachable(true);
|
||||||
} else {
|
} else {
|
||||||
//unhandled event
|
// Other unhandled events
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,20 +24,30 @@ import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.preference.PreferenceManager;
|
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 class OutgoingCallReceiver extends BroadcastReceiver {
|
||||||
public static String TAG = ";0000000";
|
public static final String TAG = ";0000000";
|
||||||
public static String key_off="off";
|
public static final String key_off="off";
|
||||||
public static String key_on_demand="ask_for_outcall_interception";
|
public static final String key_on_demand="ask_for_outcall_interception";
|
||||||
public static String key_always="alway_intercept_out_call";
|
public static final String key_always="alway_intercept_out_call";
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
String to = intent.getStringExtra("android.intent.extra.PHONE_NUMBER");
|
String to = intent.getStringExtra("android.intent.extra.PHONE_NUMBER");
|
||||||
|
|
||||||
//do not catch ussd codes
|
//do not catch ussd codes
|
||||||
if (to==null || to.contains("#"))
|
if (to==null || to.contains("#"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!to.contains(TAG)) {
|
if (!to.contains(TAG)) {
|
||||||
if (LinphoneService.isready() && LinphoneService.instance().getLinphoneCore().getDefaultProxyConfig()==null) {
|
if (LinphoneService.isReady() && LinphoneManager.getLc().getDefaultProxyConfig()==null) {
|
||||||
//just return
|
//just return
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -52,7 +62,7 @@ public class OutgoingCallReceiver extends BroadcastReceiver {
|
||||||
lIntent.setAction(Intent.ACTION_CALL);
|
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);
|
lIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
context.startActivity(lIntent);
|
context.startActivity(lIntent);
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ public class VideoCallActivity extends Activity {
|
||||||
setContentView(R.layout.videocall);
|
setContentView(R.layout.videocall);
|
||||||
|
|
||||||
mVideoView = (SurfaceView) findViewById(R.id.video_surface);
|
mVideoView = (SurfaceView) findViewById(R.id.video_surface);
|
||||||
LinphoneCore lc = LinphoneService.getLc();
|
LinphoneCore lc = LinphoneManager.getLc();
|
||||||
lc.setVideoWindow(mVideoView);
|
lc.setVideoWindow(mVideoView);
|
||||||
|
|
||||||
mVideoCaptureView = (SurfaceView) findViewById(R.id.video_capture_surface);
|
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 = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK|PowerManager.ON_AFTER_RELEASE,"Linphone");
|
||||||
mWakeLock.acquire();
|
mWakeLock.acquire();
|
||||||
|
|
||||||
if (Version.sdkBelow(8)) {
|
if (Version.sdkStrictlyBelow(8)) {
|
||||||
// Force to display in portrait orientation for old devices
|
// Force to display in portrait orientation for old devices
|
||||||
// as they do not support surfaceView rotation
|
// as they do not support surfaceView rotation
|
||||||
setRequestedOrientation(recordManager.isCameraOrientationPortrait() ?
|
setRequestedOrientation(recordManager.isCameraOrientationPortrait() ?
|
||||||
|
@ -87,7 +87,7 @@ public class VideoCallActivity extends Activity {
|
||||||
@Override
|
@Override
|
||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
// Update call if orientation changed
|
// Update call if orientation changed
|
||||||
if (Version.sdkAbove(8) && previousPhoneOrientation != phoneOrientation) {
|
if (Version.sdkAboveOrEqual(8) && previousPhoneOrientation != phoneOrientation) {
|
||||||
CallManager.getInstance().updateCall();
|
CallManager.getInstance().updateCall();
|
||||||
resizeCapturePreview(mVideoCaptureView);
|
resizeCapturePreview(mVideoCaptureView);
|
||||||
}
|
}
|
||||||
|
@ -137,7 +137,7 @@ public class VideoCallActivity extends Activity {
|
||||||
*/
|
*/
|
||||||
private void resizeCapturePreview(SurfaceView sv) {
|
private void resizeCapturePreview(SurfaceView sv) {
|
||||||
LayoutParams lp = sv.getLayoutParams();
|
LayoutParams lp = sv.getLayoutParams();
|
||||||
VideoSize vs = LinphoneService.getLc().getPreferredVideoSize();
|
VideoSize vs = LinphoneManager.getLc().getPreferredVideoSize();
|
||||||
|
|
||||||
float newRatio = (float) vs.width / vs.height;
|
float newRatio = (float) vs.width / vs.height;
|
||||||
|
|
||||||
|
@ -180,11 +180,11 @@ public class VideoCallActivity extends Activity {
|
||||||
resizeCapturePreview(mVideoCaptureView);
|
resizeCapturePreview(mVideoCaptureView);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Log.e(LinphoneService.TAG, "Unknown menu item ["+item+"]");
|
Log.e(LinphoneManager.TAG, "Unknown menu item ["+item+"]");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,7 @@ public class AndroidCameraRecordManager {
|
||||||
|
|
||||||
// singleton
|
// singleton
|
||||||
private AndroidCameraRecordManager() {
|
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};
|
int[] fId = {-1};int[] rId = {-1};int[] cId = {-1};
|
||||||
cc.findFrontAndRearCameraIds(fId, rId, cId);
|
cc.findFrontAndRearCameraIds(fId, rId, cId);
|
||||||
|
@ -172,11 +172,11 @@ public class AndroidCameraRecordManager {
|
||||||
parameters.rotation = bufferRotationForCorrectImageOrientation();
|
parameters.rotation = bufferRotationForCorrectImageOrientation();
|
||||||
|
|
||||||
parameters.surfaceView = surfaceView;
|
parameters.surfaceView = surfaceView;
|
||||||
if (Version.sdkAbove(9)) {
|
if (Version.sdkAboveOrEqual(9)) {
|
||||||
recorder = new AndroidCameraRecord9Impl(parameters);
|
recorder = new AndroidCameraRecord9Impl(parameters);
|
||||||
} else if (Version.sdkAbove(8)) {
|
} else if (Version.sdkAboveOrEqual(8)) {
|
||||||
recorder = new AndroidCameraRecord8Impl(parameters);
|
recorder = new AndroidCameraRecord8Impl(parameters);
|
||||||
} else if (Version.sdkAbove(5)) {
|
} else if (Version.sdkAboveOrEqual(5)) {
|
||||||
recorder = new AndroidCameraRecord5Impl(parameters);
|
recorder = new AndroidCameraRecord5Impl(parameters);
|
||||||
} else {
|
} else {
|
||||||
recorder = new AndroidCameraRecordImpl(parameters);
|
recorder = new AndroidCameraRecordImpl(parameters);
|
||||||
|
@ -208,7 +208,7 @@ public class AndroidCameraRecordManager {
|
||||||
if (supportedVideoSizes != null) return supportedVideoSizes;
|
if (supportedVideoSizes != null) return supportedVideoSizes;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Version.sdkAbove(5)) {
|
if (Version.sdkAboveOrEqual(5)) {
|
||||||
supportedVideoSizes = AndroidCameraRecord5Impl.oneShotSupportedVideoSizes();
|
supportedVideoSizes = AndroidCameraRecord5Impl.oneShotSupportedVideoSizes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,7 +253,7 @@ public class AndroidCameraRecordManager {
|
||||||
|
|
||||||
private int bufferRotationForCorrectImageOrientation() {
|
private int bufferRotationForCorrectImageOrientation() {
|
||||||
final int cameraOrientation = cc.getCameraOrientation(cameraId);
|
final int cameraOrientation = cc.getCameraOrientation(cameraId);
|
||||||
final int rotation = Version.sdkAbove(8) ?
|
final int rotation = Version.sdkAboveOrEqual(8) ?
|
||||||
(360 - cameraOrientation + 90 - phoneOrientation) % 360
|
(360 - cameraOrientation + 90 - phoneOrientation) % 360
|
||||||
: 0;
|
: 0;
|
||||||
Log.d(tag, "Capture video buffer will need a rotation of " + rotation
|
Log.d(tag, "Capture video buffer will need a rotation of " + rotation
|
||||||
|
|
|
@ -64,7 +64,7 @@ class LinphoneCoreImpl implements LinphoneCore {
|
||||||
private native void enableEchoCancellation(long nativePtr,boolean enable);
|
private native void enableEchoCancellation(long nativePtr,boolean enable);
|
||||||
private native boolean isEchoCancellationEnabled(long nativePtr);
|
private native boolean isEchoCancellationEnabled(long nativePtr);
|
||||||
private native long getCurrentCall(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 stopDtmf(long nativePtr);
|
||||||
private native void setVideoWindowId(long nativePtr, Object wid);
|
private native void setVideoWindowId(long nativePtr, Object wid);
|
||||||
private native void setPreviewWindowId(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
|
// TODO Auto-generated method stub
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
public void playDtmf(char number, int duration) {
|
public void playDtmf(char number, int duration, boolean speaker) {
|
||||||
playDtmf(nativePtr,number, duration);
|
playDtmf(nativePtr,number, duration, speaker);
|
||||||
|
|
||||||
}
|
}
|
||||||
public void stopDtmf() {
|
public void stopDtmf() {
|
||||||
|
|
|
@ -30,11 +30,11 @@ public class Version {
|
||||||
8 : Integer.parseInt(Build.VERSION.SDK); // Force versions above 9 to 8
|
8 : Integer.parseInt(Build.VERSION.SDK); // Force versions above 9 to 8
|
||||||
// 7; // 2.1
|
// 7; // 2.1
|
||||||
|
|
||||||
public static final boolean sdkAbove(int value) {
|
public static final boolean sdkAboveOrEqual(int value) {
|
||||||
return buildVersion >= value;
|
return buildVersion >= value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final boolean sdkBelow(int value) {
|
public static final boolean sdkStrictlyBelow(int value) {
|
||||||
return buildVersion < value;
|
return buildVersion < value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
package org.linphone.ui;
|
package org.linphone.ui;
|
||||||
|
|
||||||
import org.linphone.CallManager;
|
import org.linphone.LinphoneManager;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
|
@ -37,7 +37,7 @@ public class AddVideoButton extends ImageButton implements OnClickListener {
|
||||||
|
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
// If no in video call; try to reinvite with video
|
// If no in video call; try to reinvite with video
|
||||||
boolean alreadyInVideoCall = !CallManager.getInstance().reinviteWithVideo();
|
boolean alreadyInVideoCall = !LinphoneManager.reinviteWithVideo();
|
||||||
if (alreadyInVideoCall && alreadyInVideoCallListener != null) {
|
if (alreadyInVideoCall && alreadyInVideoCallListener != null) {
|
||||||
// In video call; going back to video call activity
|
// In video call; going back to video call activity
|
||||||
alreadyInVideoCallListener.onAlreadyInVideoCall();
|
alreadyInVideoCallListener.onAlreadyInVideoCall();
|
||||||
|
|
|
@ -19,6 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
package org.linphone.ui;
|
package org.linphone.ui;
|
||||||
|
|
||||||
import org.linphone.LinphoneManager;
|
import org.linphone.LinphoneManager;
|
||||||
|
import org.linphone.R;
|
||||||
import org.linphone.core.LinphoneCore;
|
import org.linphone.core.LinphoneCore;
|
||||||
import org.linphone.core.LinphoneCoreException;
|
import org.linphone.core.LinphoneCoreException;
|
||||||
|
|
||||||
|
@ -27,10 +28,10 @@ import android.util.AttributeSet;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
import android.view.View.OnClickListener;
|
||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
public class CallButton extends ImageButton implements OnClickListener, AddressAwareWidget {
|
public class CallButton extends ImageButton implements OnClickListener, AddressAwareWidget {
|
||||||
|
|
||||||
private CallButtonListener callButtonListener;
|
|
||||||
private AddressText mAddress;
|
private AddressText mAddress;
|
||||||
|
|
||||||
public CallButton(Context context, AttributeSet attrs) {
|
public CallButton(Context context, AttributeSet attrs) {
|
||||||
|
@ -45,7 +46,7 @@ public class CallButton extends ImageButton implements OnClickListener, AddressA
|
||||||
lc.acceptCall(lc.getCurrentCall());
|
lc.acceptCall(lc.getCurrentCall());
|
||||||
} catch (LinphoneCoreException e) {
|
} catch (LinphoneCoreException e) {
|
||||||
lc.terminateCall(lc.getCurrentCall());
|
lc.terminateCall(lc.getCurrentCall());
|
||||||
callButtonListener.onWrongDestinationAddress();
|
onWrongDestinationAddress();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -55,16 +56,14 @@ public class CallButton extends ImageButton implements OnClickListener, AddressA
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected void onWrongDestinationAddress() {
|
||||||
public static interface CallButtonListener {
|
Toast toast = Toast.makeText(getContext()
|
||||||
void onWrongDestinationAddress();
|
,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) {
|
public void setAddressWidget(AddressText address) {
|
||||||
mAddress = address;
|
mAddress = address;
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,7 +108,7 @@ public class Digit extends Button implements OnLongClickListener, AddressAwareWi
|
||||||
public boolean onTouch(View v, MotionEvent event) {
|
public boolean onTouch(View v, MotionEvent event) {
|
||||||
LinphoneCore lc = LinphoneManager.getLc();
|
LinphoneCore lc = LinphoneManager.getLc();
|
||||||
if (event.getAction() == MotionEvent.ACTION_DOWN && mIsDtmfStarted ==false) {
|
if (event.getAction() == MotionEvent.ACTION_DOWN && mIsDtmfStarted ==false) {
|
||||||
LinphoneManager.getInstance().playDtmf(mKeyCode.charAt(0));
|
LinphoneManager.getInstance().playDtmf(getContext().getContentResolver(), mKeyCode.charAt(0));
|
||||||
mIsDtmfStarted=true;
|
mIsDtmfStarted=true;
|
||||||
} else {
|
} else {
|
||||||
if (event.getAction() == MotionEvent.ACTION_UP)
|
if (event.getAction() == MotionEvent.ACTION_UP)
|
||||||
|
|
Loading…
Reference in a new issue