Merge branch 'master' into bellesip

Conflicts:
	submodules/linphone
This commit is contained in:
Yann Diorcet 2013-02-21 12:19:48 +01:00
commit c2857cf5fc
11 changed files with 176 additions and 16 deletions

1
.gitignore vendored
View file

@ -3,6 +3,7 @@ obj
gen
bin
doc
default.properties
local.properties
project.properties
tests/*$py.class

View file

@ -31,6 +31,9 @@
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- Needed to use our own Contact editor -->
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
<!-- Needed to route the audio to the bluetooth headset if available -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
<supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" android:anyDensity="true"/>
@ -104,6 +107,14 @@
<intent-filter><action android:name="android.net.conn.CONNECTIVITY_CHANGE"></action></intent-filter>
</receiver>
<receiver android:name="org.linphone.BluetoothManager">
<intent-filter>
<action android:name="android.bluetooth.device.action.ACL_CONNECTED"/>
<action android:name="android.bluetooth.device.action.ACL_DISCONNECTED"/>
<action android:name="android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED"/>
</intent-filter>
</receiver>
<receiver android:name="org.linphone.BootReceiver">
<intent-filter><action android:name="android.intent.action.BOOT_COMPLETED"></action></intent-filter>
</receiver>

View file

@ -55,6 +55,8 @@
<bool name="hash_images_as_name_before_upload">true</bool>
<bool name="route_audio_to_bluetooth_if_available">true</bool>
<bool name="disable_every_log">false</bool>
<bool name="disable_all_security_features_for_markets">false</bool> <!-- Disable TLS/SRTP/ZRTP -->
<bool name="disable_all_patented_codecs_for_markets">false</bool> <!-- Disable MPEG4/H264 -->

View file

@ -5,18 +5,18 @@
<string name="pref_tunnel_port_default">443</string>
<string name="default_tunnel_mode_entry_value">@string/tunnel_mode_entry_value_disabled</string>
<bool name="pref_echo_canceller_default">false</bool>
<bool name="pref_echo_canceller_default">true</bool>
<!-- Audio codecs -->
<bool name="pref_codec_speex16_default">true</bool>
<bool name="pref_codec_speex8_default">true</bool>
<bool name="pref_codec_ilbc_default">true</bool>
<bool name="pref_codec_amr_default">true</bool>
<bool name="pref_codec_amr_default">false</bool>
<bool name="pref_codec_g729_default">true</bool>
<bool name="pref_codec_amrwb_default">true</bool>
<bool name="pref_codec_amrwb_default">false</bool>
<bool name="pref_codec_gsm_default">true</bool>
<bool name="pref_codec_g722_default">true</bool>
<bool name="pref_codec_g722_default">false</bool>
<bool name="pref_codec_silk24_default">false</bool>
<bool name="pref_codec_silk16_default">false</bool>
<bool name="pref_codec_silk16_default">true</bool>
<bool name="pref_codec_pcmu_default">true</bool>
<bool name="pref_codec_pcma_default">true</bool>

View file

@ -0,0 +1,40 @@
package org.linphone;
import org.linphone.mediastream.Log;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class BluetoothManager extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
boolean routeToBT = context.getResources().getBoolean(R.bool.route_audio_to_bluetooth_if_available);
if (!routeToBT)
return;
String action = intent.getAction();
LinphoneManager lm = LinphoneManager.getInstance();
if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {
Log.e("Bluetooth Received Event" + " ACTION_ACL_DISCONNECTED" );
if (lm != null) {
lm.uninitBluetooth();
lm.routeAudioToReceiver();
}
} else if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
Log.e("Bluetooth Received Event" + " ACTION_ACL_CONNECTED" );
if (lm != null) {
lm.routeToBluetoothIfAvailable();
}
} else if (BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
Log.e("Bluetooth state changed!");
if (lm != null) {
lm.startBluetooth();
}
}
}
}

View file

@ -166,6 +166,10 @@ public class InCallActivity extends FragmentActivity implements
callFragment.setArguments(getIntent().getExtras());
getSupportFragmentManager().beginTransaction().add(R.id.fragmentContainer, callFragment).commitAllowingStateLoss();
}
boolean routeToBT = getResources().getBoolean(R.bool.route_audio_to_bluetooth_if_available);
if (routeToBT && LinphoneManager.isInstanciated() && !isSpeakerEnabled)
LinphoneManager.getInstance().routeToBluetoothIfAvailable();
}
@Override
@ -475,11 +479,15 @@ public class InCallActivity extends FragmentActivity implements
if (isSpeakerEnabled) {
LinphoneManager.getInstance().routeAudioToSpeaker();
speaker.setBackgroundResource(R.drawable.speaker_on);
LinphoneManager.getLc().enableSpeaker(isSpeakerEnabled);
} else {
LinphoneManager.getInstance().routeAudioToReceiver();
speaker.setBackgroundResource(R.drawable.speaker_off);
boolean routeToBT = getResources().getBoolean(R.bool.route_audio_to_bluetooth_if_available);
if (!routeToBT)
LinphoneManager.getLc().enableSpeaker(isSpeakerEnabled);
}
LinphoneManager.getLc().enableSpeaker(isSpeakerEnabled);
}
private void pauseOrResumeCall() {
@ -969,8 +977,13 @@ public class InCallActivity extends FragmentActivity implements
switchVideo(isVideoEnabled, false);
}
// The following should not be needed except some devices need it (e.g. Galaxy S).
LinphoneManager.getLc().enableSpeaker(isSpeakerEnabled);
boolean routeToBT = getResources().getBoolean(R.bool.route_audio_to_bluetooth_if_available);
if (routeToBT && LinphoneManager.isInstanciated() && !isSpeakerEnabled) {
LinphoneManager.getInstance().routeToBluetoothIfAvailable();
} else {
// The following should not be needed except some devices need it (e.g. Galaxy S).
LinphoneManager.getLc().enableSpeaker(isSpeakerEnabled);
}
isMicMuted = LinphoneManager.getLc().isMicMuted();
enableAndRefreshInCallActions();

View file

@ -76,7 +76,12 @@ import org.linphone.mediastream.video.capture.hwconf.AndroidCameraConfiguration.
import org.linphone.mediastream.video.capture.hwconf.Hacks;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothProfile;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
@ -141,6 +146,10 @@ public final class LinphoneManager implements LinphoneCoreListener {
private static boolean sExited;
private WakeLock mIncallWakeLock;
private BluetoothAdapter mBluetoothAdapter;
private BluetoothHeadset mBluetoothHeadset;
private BluetoothProfile.ServiceListener mProfileListener;
private static List<LinphoneSimpleListener> simpleListeners = new ArrayList<LinphoneSimpleListener>();
public static void addListener(LinphoneSimpleListener listener) {
@ -190,9 +199,23 @@ public final class LinphoneManager implements LinphoneCoreListener {
private BroadcastReceiver mKeepAliveReceiver = new KeepAliveReceiver();
private void routeAudioToSpeakerHelper(boolean speakerOn) {
mLc.enableSpeaker(speakerOn);
boolean routeToBluetoothEnabled = false;
if (!speakerOn) {
boolean routeToBT = mServiceContext.getResources().getBoolean(R.bool.route_audio_to_bluetooth_if_available);
if (!routeToBT || (routeToBT && !routeToBluetoothIfAvailable())) {
mLc.enableSpeaker(false);
uninitBluetooth();
} else {
Log.d("Routing audio to bluetooth headset");
routeToBluetoothEnabled = true;
}
} else {
mLc.enableSpeaker(true);
uninitBluetooth();
}
for (LinphoneOnAudioChangedListener listener : getSimpleListeners(LinphoneOnAudioChangedListener.class)) {
listener.onAudioStateChanged(speakerOn ? AudioState.SPEAKER : AudioState.EARPIECE);
listener.onAudioStateChanged(speakerOn ? AudioState.SPEAKER : (routeToBluetoothEnabled ? AudioState.BLUETOOTH : AudioState.EARPIECE));
}
}
public void routeAudioToSpeaker() {
@ -216,6 +239,66 @@ public final class LinphoneManager implements LinphoneCoreListener {
public void routeAudioToReceiver() {
routeAudioToSpeakerHelper(false);
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void startBluetooth() {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30) && mBluetoothAdapter.isEnabled()) {
mProfileListener = new BluetoothProfile.ServiceListener() {
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void onServiceConnected(int profile, BluetoothProfile proxy) {
if (profile == BluetoothProfile.HEADSET) {
mBluetoothHeadset = (BluetoothHeadset) proxy;
Log.d("Bluetooth headset connected");
routeToBluetoothIfAvailable();
}
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void onServiceDisconnected(int profile) {
if (profile == BluetoothProfile.HEADSET) {
mBluetoothHeadset = null;
Log.d("Bluetooth headset disconnected");
routeAudioToReceiver();
}
}
};
mBluetoothAdapter.getProfileProxy(mServiceContext, mProfileListener, BluetoothProfile.HEADSET);
} else {
routeAudioToReceiver();
}
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public boolean routeToBluetoothIfAvailable() {
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30) && mBluetoothAdapter.isEnabled() && mAudioManager.isBluetoothScoAvailableOffCall()) {
mAudioManager.setBluetoothScoOn(true);
mAudioManager.startBluetoothSco();
boolean connected = false;
if (mBluetoothHeadset != null) {
List<BluetoothDevice> devices = mBluetoothHeadset.getConnectedDevices();
for (final BluetoothDevice dev : devices) {
connected |= mBluetoothHeadset.getConnectionState(dev) == BluetoothHeadset.STATE_CONNECTED;
}
}
if (!connected) {
Log.d("No bluetooth device available");
uninitBluetooth();
}
return connected;
}
return false;
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void uninitBluetooth() {
if (Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30) && mAudioManager != null) {
mAudioManager.stopBluetoothSco();
mAudioManager.setBluetoothScoOn(false);
}
}
public synchronized static final LinphoneManager createAndStart(
Context c, LinphoneServiceListener listener) {
@ -463,6 +546,11 @@ public final class LinphoneManager implements LinphoneCoreListener {
IntentFilter lFilter = new IntentFilter(Intent.ACTION_SCREEN_ON);
lFilter.addAction(Intent.ACTION_SCREEN_OFF);
mServiceContext.registerReceiver(mKeepAliveReceiver, lFilter);
boolean routeToBT = mServiceContext.getResources().getBoolean(R.bool.route_audio_to_bluetooth_if_available);
if (routeToBT) {
startBluetooth();
}
}
catch (Exception e) {
Log.e(e, "Cannot start linphone");

View file

@ -56,7 +56,7 @@ public interface LinphoneSimpleListener {
}
public static interface LinphoneOnAudioChangedListener extends LinphoneSimpleListener {
public enum AudioState {EARPIECE, SPEAKER}
public enum AudioState {EARPIECE, SPEAKER, BLUETOOTH}
void onAudioStateChanged(AudioState state);
}

View file

@ -19,6 +19,7 @@ public class RemoteProvisioning {
String mRPAddress;
String mSchema;
String mLocalLP;
boolean value;
public RemoteProvisioningThread(final String RPAddress, final String LocalLP, final String schema) {
this.mRPAddress = RPAddress;
@ -28,6 +29,7 @@ public class RemoteProvisioning {
public void run() {
try {
value = false;
Log.i("Download remote provisioning file from " + mRPAddress);
URL url = new URL(mRPAddress);
URLConnection ucon = url.openConnection();
@ -68,6 +70,7 @@ public class RemoteProvisioning {
} else {
lp.sync();
}
value = true;
Log.i("Remote provisioning ok");
} catch (MalformedURLException e) {
Log.e("Invalid remote provisioning url: " + e.getLocalizedMessage());
@ -81,7 +84,7 @@ public class RemoteProvisioning {
}
};
static void download(String address, String lpfile, boolean check) {
static boolean download(String address, String lpfile, boolean check) {
try {
String schema = null;
if(check) {
@ -92,13 +95,15 @@ public class RemoteProvisioning {
thread.start();
thread.wait();
}
return thread.value;
} catch (InterruptedException e) {
Log.e(e);
}
return false;
}
static void download(String address, String lpfile) {
download(address, lpfile, true);
static boolean download(String address, String lpfile) {
return download(address, lpfile, true);
}
static boolean isAvailable() {

View file

@ -139,7 +139,7 @@ public class SetupActivity extends FragmentActivity implements OnClickListener {
}
private void launchEchoCancellerCalibration(boolean sendEcCalibrationResult) {
if (!Hacks.hasBuiltInEchoCanceller() && !mPref.getBoolean(getString(R.string.first_launch_suceeded_once_key), false)) {
if (LinphoneManager.getLc().needsEchoCalibration() && !mPref.getBoolean(getString(R.string.first_launch_suceeded_once_key), false)) {
EchoCancellerCalibrationFragment fragment = new EchoCancellerCalibrationFragment();
fragment.enableEcCalibrationResultSending(sendEcCalibrationResult);
changeFragment(fragment);

@ -1 +1 @@
Subproject commit 5b14c78bbd4a22494ec54531129e5ab30b4d1667
Subproject commit d8377941920f52ffbedf2b8fb90b2e884e1a0dc5