many bug fixes + audio routing + incoming call

This commit is contained in:
Jehan Monnier 2010-02-15 18:01:06 +01:00
parent d4ef1c0957
commit 652c2e53f0
9 changed files with 131 additions and 33 deletions

View file

@ -3,7 +3,7 @@
package="org.linphone" package="org.linphone"
android:versionCode="1" android:versionCode="1"
android:versionName="1.0"> android:versionName="1.0">
<application android:icon="@drawable/linphone2" android:label="@string/app_name"> <application android:icon="@drawable/linphone2" android:label="@string/app_name" android:debuggable = "true">
<activity android:name=".Linphone" <activity android:name=".Linphone"
android:label="@string/app_name" android:label="@string/app_name"
android:theme="@android:style/Theme.NoTitleBar"> android:theme="@android:style/Theme.NoTitleBar">
@ -32,5 +32,6 @@
<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"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
</manifest> </manifest>

View file

@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<menu <menu
xmlns:android="http://schemas.android.com/apk/res/android"> xmlns:android="http://schemas.android.com/apk/res/android">
<item android:title="@string/menu_settings" android:id="@+id/menu_settings"></item> <item android:title="@string/menu_settings" android:id="@+id/menu_settings">
</item>
<item android:title="@string/menu_exit" android:id="@+id/menu_exit"></item>
</menu> </menu>

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="menu_exit">Exit</string>
<string name="pref_prefix">Prefix</string> <string name="pref_prefix">Prefix</string>
<string name="pref_advanced">Advanced</string> <string name="pref_advanced">Advanced</string>
<string name="menu_settings">Settings</string> <string name="menu_settings">Settings</string>
@ -19,4 +20,5 @@
<string name="yes">Yes</string> <string name="yes">Yes</string>
<string name="no">No</string> <string name="no">No</string>
<string name="config_error">%s, do you want to return to the settings page ?</string> <string name="config_error">%s, do you want to return to the settings page ?</string>
<string name="warning_already_incall">Cannot initiate a new call because a call is already engaged</string>
</resources> </resources>

View file

@ -8,6 +8,8 @@ import org.linphone.core.LinphoneProxyConfig;
import org.linphone.core.LinphoneCore.GeneralState; import org.linphone.core.LinphoneCore.GeneralState;
import android.app.Activity; import android.app.Activity;
import android.content.Context;
import android.media.AudioManager;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
@ -38,6 +40,8 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
private static DialerActivity theDialer; private static DialerActivity theDialer;
private String mDisplayName; private String mDisplayName;
private AudioManager mAudioManager;
/** /**
* *
* @return nul if not ready yet * @return nul if not ready yet
@ -56,6 +60,7 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.dialer); setContentView(R.layout.dialer);
mAudioManager = ((AudioManager)getSystemService(Context.AUDIO_SERVICE));
try { try {
theDialer = this; theDialer = this;
mLinphoneCore = Linphone.getLinphone().getLinphoneCore(); mLinphoneCore = Linphone.getLinphone().getLinphoneCore();
@ -64,6 +69,15 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
mCall = (ImageButton) findViewById(R.id.Call); mCall = (ImageButton) findViewById(R.id.Call);
mCall.setOnClickListener(new OnClickListener() { mCall.setOnClickListener(new OnClickListener() {
public void onClick(View v) { public void onClick(View v) {
if (mLinphoneCore.isInComingInvitePending()) {
mLinphoneCore.acceptCall();
return;
}
if (mLinphoneCore.isIncall()) {
Toast toast = Toast.makeText(DialerActivity.this, getString(R.string.warning_already_incall), Toast.LENGTH_LONG);
toast.show();
return;
}
String lRawAddress = mAddress.getText().toString(); String lRawAddress = mAddress.getText().toString();
String lCallingUri=null; String lCallingUri=null;
if (lRawAddress.startsWith("sip:")) { if (lRawAddress.startsWith("sip:")) {
@ -71,7 +85,7 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
} else { } else {
LinphoneProxyConfig lProxy = mLinphoneCore.getDefaultProxyConfig(); LinphoneProxyConfig lProxy = mLinphoneCore.getDefaultProxyConfig();
String lDomain=null; String lDomain=null;
String lNormalizedNumber=null; String lNormalizedNumber=lRawAddress;
if (lProxy!=null) { if (lProxy!=null) {
lNormalizedNumber = lProxy.normalizePhoneNumber(lNormalizedNumber); lNormalizedNumber = lProxy.normalizePhoneNumber(lNormalizedNumber);
lDomain = lProxy.getDomain(); lDomain = lProxy.getDomain();
@ -86,6 +100,7 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
}); });
mHangup = (ImageButton) findViewById(R.id.HangUp); mHangup = (ImageButton) findViewById(R.id.HangUp);
mHangup.setEnabled(false);
mHangup.setOnClickListener(new OnClickListener() { mHangup.setOnClickListener(new OnClickListener() {
public void onClick(View v) { public void onClick(View v) {
mLinphoneCore.terminateCall(); mLinphoneCore.terminateCall();
@ -165,8 +180,37 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
,String.format(getString(R.string.call_error),lc.getRemoteAddress()) ,String.format(getString(R.string.call_error),lc.getRemoteAddress())
, Toast.LENGTH_LONG); , Toast.LENGTH_LONG);
toast.show(); toast.show();
break;
}
case GSTATE_REG_OK: {
break;
}
case GSTATE_CALL_OUT_INVITE: {
//de-activate green button
mCall.setEnabled(false);
}
case GSTATE_CALL_IN_INVITE: {
// activate red button
mHangup.setEnabled(true);
mAudioManager.setSpeakerphoneOn(true);
mAudioManager.setMode(AudioManager.MODE_NORMAL);
mAudioManager.setRouting(AudioManager.MODE_NORMAL,
AudioManager.ROUTE_SPEAKER, AudioManager.ROUTE_ALL);
break;
}
case GSTATE_CALL_IN_CONNECTED:
case GSTATE_CALL_OUT_CONNECTED: {
mAudioManager.setSpeakerphoneOn(false);
mAudioManager.setMode(AudioManager.MODE_IN_CALL);
mAudioManager.setRouting(AudioManager.MODE_NORMAL,
AudioManager.ROUTE_EARPIECE, AudioManager.ROUTE_ALL);
break;
}
case GSTATE_CALL_END: {
mCall.setEnabled(true);
mHangup.setEnabled(false);
break;
} }
case GSTATE_REG_OK:
} }
} }
public void inviteReceived(LinphoneCore lc, String from) { public void inviteReceived(LinphoneCore lc, String from) {

View file

@ -142,10 +142,9 @@ public class Linphone extends TabActivity implements LinphoneCoreListener {
@Override @Override
protected void onStop() { protected void onDestroy() {
// TODO Auto-generated method stub super.onDestroy();
super.onStop(); if (isFinishing()) System.exit(0); // FIXME to destroy liblinphone
//finish();
} }
@ -221,6 +220,9 @@ public class Linphone extends TabActivity implements LinphoneCoreListener {
case R.id.menu_settings: case R.id.menu_settings:
startprefActivity(); startprefActivity();
return true; return true;
case R.id.menu_exit:
finish();
break;
default: default:
Log.e(TAG, "Unknown menu item ["+item+"]"); Log.e(TAG, "Unknown menu item ["+item+"]");
break; break;
@ -278,11 +280,15 @@ public class Linphone extends TabActivity implements LinphoneCoreListener {
} }
lDefaultProxyConfig = mLinphoneCore.getDefaultProxyConfig(); lDefaultProxyConfig = mLinphoneCore.getDefaultProxyConfig();
if (lDefaultProxyConfig !=null) {
//prefix //prefix
String lPrefix = mPref.getString(getString(R.string.pref_prefix_key), null); String lPrefix = mPref.getString(getString(R.string.pref_prefix_key), null);
if (lPrefix != null && lDefaultProxyConfig !=null) { if (lPrefix != null ) {
lDefaultProxyConfig.setDialPrefix(lPrefix); lDefaultProxyConfig.setDialPrefix(lPrefix);
} }
//escape +
lDefaultProxyConfig.setDialEscapePlus(true);
}
} }

View file

@ -94,6 +94,26 @@ public interface LinphoneCore {
* @return null if no call engaged yet * @return null if no call engaged yet
*/ */
public LinphoneAddress getRemoteAddress(); public LinphoneAddress getRemoteAddress();
/**
*
* @return TRUE if there is a call running or pending.
*/
public boolean isIncall();
/**
*
* @return Returns true if in incoming call is pending, ie waiting for being answered or declined.
*/
public boolean isInComingInvitePending();
public void iterate(); public void iterate();
/**
* Accept an incoming call.
*
* Basically the application is notified of incoming calls within the
* {@link LinphoneCoreListener#inviteReceived(LinphoneCore, String)} listener.
* The application can later respond positively to the call using
* this method.
*/
public void acceptCall();
} }

View file

@ -39,21 +39,24 @@ class LinphoneCoreImpl implements LinphoneCore {
private native void invite(long nativePtr,String uri); private native void invite(long nativePtr,String uri);
private native void terminateCall(long nativePtr); private native void terminateCall(long nativePtr);
private native long getRemoteAddress(long nativePtr); private native long getRemoteAddress(long nativePtr);
private native boolean isInCall(long nativePtr);
private native boolean isInComingInvitePending(long nativePtr);
private native void acceptCall(long nativePtr);
LinphoneCoreImpl(LinphoneCoreListener listener, File userConfig,File factoryConfig,Object userdata) throws IOException { LinphoneCoreImpl(LinphoneCoreListener listener, File userConfig,File factoryConfig,Object userdata) throws IOException {
mListener=listener; mListener=listener;
nativePtr = newLinphoneCore(listener,userConfig.getCanonicalPath(),factoryConfig.getCanonicalPath(),userdata); nativePtr = newLinphoneCore(listener,userConfig.getCanonicalPath(),factoryConfig.getCanonicalPath(),userdata);
} }
public void addAuthInfo(LinphoneAuthInfo info) { public synchronized void addAuthInfo(LinphoneAuthInfo info) {
addAuthInfo(nativePtr,((LinphoneAuthInfoImpl)info).nativePtr); addAuthInfo(nativePtr,((LinphoneAuthInfoImpl)info).nativePtr);
} }
public LinphoneProxyConfig createProxyConfig(String identity, String proxy,String route,boolean enableRegister) throws LinphoneCoreException { public synchronized LinphoneProxyConfig createProxyConfig(String identity, String proxy,String route,boolean enableRegister) throws LinphoneCoreException {
return new LinphoneProxyConfigImpl(identity, proxy, route,enableRegister); return new LinphoneProxyConfigImpl(identity, proxy, route,enableRegister);
} }
public LinphoneProxyConfig getDefaultProxyConfig() { public synchronized LinphoneProxyConfig getDefaultProxyConfig() {
long lNativePtr = getDefaultProxyConfig(nativePtr); long lNativePtr = getDefaultProxyConfig(nativePtr);
if (lNativePtr!=0) { if (lNativePtr!=0) {
return new LinphoneProxyConfigImpl(lNativePtr); return new LinphoneProxyConfigImpl(lNativePtr);
@ -62,33 +65,33 @@ class LinphoneCoreImpl implements LinphoneCore {
} }
} }
public void invite(String uri) { public synchronized void invite(String uri) {
invite(nativePtr,uri); invite(nativePtr,uri);
} }
public void iterate() { public synchronized void iterate() {
iterate(nativePtr); iterate(nativePtr);
} }
public void setDefaultProxyConfig(LinphoneProxyConfig proxyCfg) { public synchronized void setDefaultProxyConfig(LinphoneProxyConfig proxyCfg) {
setDefaultProxyConfig(nativePtr,((LinphoneProxyConfigImpl)proxyCfg).nativePtr); setDefaultProxyConfig(nativePtr,((LinphoneProxyConfigImpl)proxyCfg).nativePtr);
} }
public void addtProxyConfig(LinphoneProxyConfig proxyCfg) throws LinphoneCoreException{ public synchronized void addtProxyConfig(LinphoneProxyConfig proxyCfg) throws LinphoneCoreException{
if (addProxyConfig(nativePtr,((LinphoneProxyConfigImpl)proxyCfg).nativePtr) !=0) { if (addProxyConfig(nativePtr,((LinphoneProxyConfigImpl)proxyCfg).nativePtr) !=0) {
throw new LinphoneCoreException("bad proxy config"); throw new LinphoneCoreException("bad proxy config");
} }
} }
public void clearAuthInfos() { public synchronized void clearAuthInfos() {
clearAuthInfos(nativePtr); clearAuthInfos(nativePtr);
} }
public void clearProxyConfigs() { public synchronized void clearProxyConfigs() {
clearProxyConfigs(nativePtr); clearProxyConfigs(nativePtr);
} }
public void terminateCall() { public synchronized void terminateCall() {
terminateCall(nativePtr); terminateCall(nativePtr);
} }
public LinphoneAddress getRemoteAddress() { public synchronized LinphoneAddress getRemoteAddress() {
long ptr = getRemoteAddress(nativePtr); long ptr = getRemoteAddress(nativePtr);
if (ptr==0) { if (ptr==0) {
return null; return null;
@ -96,6 +99,14 @@ class LinphoneCoreImpl implements LinphoneCore {
return new LinphoneAddressImpl(ptr); return new LinphoneAddressImpl(ptr);
} }
} }
public synchronized boolean isIncall() {
return isInCall(nativePtr);
}
public synchronized boolean isInComingInvitePending() {
return isInComingInvitePending(nativePtr);
}
public synchronized void acceptCall() {
acceptCall(nativePtr);
} }
}

View file

@ -56,6 +56,12 @@ public interface LinphoneProxyConfig {
* @param prefix * @param prefix
*/ */
public void setDialPrefix(String prefix); public void setDialPrefix(String prefix);
/**
* * Sets whether liblinphone should replace "+" by "00" in dialed numbers (passed to
* {@link LinphoneCore#invite(String)}).
* @param value default value is false
*/
public void setDialEscapePlus(boolean value);
/** /**
* rget domain host name or ip * rget domain host name or ip

View file

@ -42,7 +42,8 @@ class LinphoneProxyConfigImpl implements LinphoneProxyConfig {
ownPtr=false; ownPtr=false;
} }
protected void finalize() throws Throwable { protected void finalize() throws Throwable {
if (ownPtr) delete(nativePtr); Log.e(Linphone.TAG,"fixme, should release underlying proxy config");
// FIXME if (ownPtr) delete(nativePtr);
} }
private native long newLinphoneProxyConfig(); private native long newLinphoneProxyConfig();
private native void delete(long ptr); private native void delete(long ptr);
@ -61,6 +62,8 @@ class LinphoneProxyConfigImpl implements LinphoneProxyConfig {
private native String getDomain(long ptr); private native String getDomain(long ptr);
private native void setDialEscapePlus(long ptr, boolean value);
public void enableRegister(boolean value) { public void enableRegister(boolean value) {
enableRegister(nativePtr,value); enableRegister(nativePtr,value);
} }
@ -91,4 +94,7 @@ class LinphoneProxyConfigImpl implements LinphoneProxyConfig {
public String getDomain() { public String getDomain() {
return getDomain(nativePtr); return getDomain(nativePtr);
} }
public void setDialEscapePlus(boolean value) {
setDialEscapePlus(nativePtr,value);
}
} }