Store and restore user requested audio route.

Go back to user requested route when going out of video activity.
This commit is contained in:
Guillaume Beraudo 2011-10-18 10:10:24 +02:00
parent 4a6ba5f8fd
commit 5fe6a522ba
7 changed files with 108 additions and 31 deletions

View file

@ -27,6 +27,7 @@ import java.util.Comparator;
import java.util.List; import java.util.List;
import org.linphone.LinphoneManagerWaitHelper.LinphoneManagerReadyListener; import org.linphone.LinphoneManagerWaitHelper.LinphoneManagerReadyListener;
import org.linphone.LinphoneSimpleListener.LinphoneAudioChangedListener;
import org.linphone.LinphoneSimpleListener.LinphoneOnCallStateChangedListener; import org.linphone.LinphoneSimpleListener.LinphoneOnCallStateChangedListener;
import org.linphone.core.LinphoneAddress; import org.linphone.core.LinphoneAddress;
import org.linphone.core.LinphoneCall; import org.linphone.core.LinphoneCall;
@ -64,6 +65,7 @@ import android.widget.ToggleButton;
*/ */
public class ConferenceActivity extends ListActivity implements public class ConferenceActivity extends ListActivity implements
LinphoneManagerReadyListener, LinphoneManagerReadyListener,
LinphoneAudioChangedListener,
LinphoneOnCallStateChangedListener, Comparator<LinphoneCall>, LinphoneOnCallStateChangedListener, Comparator<LinphoneCall>,
OnClickListener { OnClickListener {
@ -149,6 +151,10 @@ public class ConferenceActivity extends ListActivity implements
updateConfState(); updateConfState();
updateSimpleControlButtons(); updateSimpleControlButtons();
CalleeListAdapter adapter = (CalleeListAdapter) getListAdapter(); CalleeListAdapter adapter = (CalleeListAdapter) getListAdapter();
if (adapter.linphoneCalls.size() != lc().getCallsNb()) {
adapter.linphoneCalls.clear();
adapter.linphoneCalls.addAll(getInitialCalls());
}
adapter.notifyDataSetInvalidated(); adapter.notifyDataSetInvalidated();
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
LinphoneManager.startProximitySensorForActivity(this); LinphoneManager.startProximitySensorForActivity(this);
@ -353,9 +359,9 @@ public class ConferenceActivity extends ListActivity implements
break; break;
case R.id.toggleSpeaker: case R.id.toggleSpeaker:
if (((ToggleButton) v).isChecked()) { if (((ToggleButton) v).isChecked()) {
LinphoneManager.getInstance().routeAudioToSpeaker(); LinphoneManager.getInstance().routeAudioToSpeaker(true);
} else { } else {
LinphoneManager.getInstance().routeAudioToReceiver(); LinphoneManager.getInstance().routeAudioToReceiver(true);
} }
break; break;
default: default:
@ -422,6 +428,10 @@ public class ConferenceActivity extends ListActivity implements
case R.id.remove_from_conference: case R.id.remove_from_conference:
lc().removeFromConference(call); lc().removeFromConference(call);
break; break;
case R.id.addVideo:
VideoCallActivity.call = call;
LinphoneActivity.instance().startVideoActivity();
break;
default: default:
throw new RuntimeException("unknown id " + v.getId()); throw new RuntimeException("unknown id " + v.getId());
} }
@ -561,7 +571,8 @@ public class ConferenceActivity extends ListActivity implements
final int numberOfCalls = linphoneCalls.size(); final int numberOfCalls = linphoneCalls.size();
boolean showAddVideo = State.StreamsRunning == state && !isInConference boolean showAddVideo = State.StreamsRunning == state && !isInConference
&& Version.isVideoCapable() && LinphoneManager.getInstance().isVideoEnabled(); && Version.isVideoCapable() && LinphoneManager.getInstance().isVideoEnabled();
setVisibility(v, R.id.addVideo, showAddVideo); View addVideoButton = v.findViewById(R.id.addVideo);
setVisibility(addVideoButton, showAddVideo);
boolean statusPaused = state== State.Paused || state == State.PausedByRemote; boolean statusPaused = state== State.Paused || state == State.PausedByRemote;
setVisibility(v, R.id.callee_status_paused, statusPaused); setVisibility(v, R.id.callee_status_paused, statusPaused);
@ -575,6 +586,7 @@ public class ConferenceActivity extends ListActivity implements
resumeButton.setOnClickListener(l); resumeButton.setOnClickListener(l);
unhookCallButton.setOnClickListener(l); unhookCallButton.setOnClickListener(l);
removeFromConfButton.setOnClickListener(l); removeFromConfButton.setOnClickListener(l);
addVideoButton.setOnClickListener(l);
v.setOnClickListener(new OnClickListener() { v.setOnClickListener(new OnClickListener() {
public void onClick(View v) { public void onClick(View v) {
@ -749,6 +761,25 @@ public class ConferenceActivity extends ListActivity implements
return super.onKeyDown(keyCode, event); return super.onKeyDown(keyCode, event);
} }
@Override
public void onAudioStateChanged(final AudioState state) {
mSpeakerButton.post(new Runnable() {
@Override
public void run() {
switch (state) {
case SPEAKER:
mSpeakerButton.setChecked(true);
break;
case EARPIECE:
mSpeakerButton.setChecked(false);
break;
default:
throw new RuntimeException("Unkown audio state " + state);
}
}
});
}
/* /*
* public int compare(LinphoneCall c1, LinphoneCall c2) { if (c1 == c2) * public int compare(LinphoneCall c1, LinphoneCall c2) { if (c1 == c2)
* return 0; * return 0;

View file

@ -288,7 +288,7 @@ public class DialerActivity extends Activity implements LinphoneGuiListener, Lin
} }
private void exitCallMode() { private void exitCallMode(LinphoneCall call) {
if (getResources().getBoolean(R.bool.use_incoming_call_activity)) { if (getResources().getBoolean(R.bool.use_incoming_call_activity)) {
finishActivity(INCOMING_CALL_ACTIVITY); finishActivity(INCOMING_CALL_ACTIVITY);
} else if (getResources().getBoolean(R.bool.use_incoming_call_dialog)) { } else if (getResources().getBoolean(R.bool.use_incoming_call_dialog)) {
@ -316,7 +316,8 @@ public class DialerActivity extends Activity implements LinphoneGuiListener, Lin
mHangup.setEnabled(false); mHangup.setEnabled(false);
if (useVideoActivity && LinphoneManager.getLc().isVideoEnabled()) { if (useVideoActivity && LinphoneManager.getLc().isVideoEnabled()
&& VideoCallActivity.call == call) {
LinphoneActivity.instance().finishVideoActivity(); LinphoneActivity.instance().finishVideoActivity();
BandwidthManager.getInstance().setUserRestriction(false); BandwidthManager.getInstance().setUserRestriction(false);
LinphoneManager.getInstance().resetCameraFromPreferences(); LinphoneManager.getInstance().resetCameraFromPreferences();
@ -464,12 +465,12 @@ public class DialerActivity extends Activity implements LinphoneGuiListener, Lin
showToast(R.string.call_error, message); showToast(R.string.call_error, message);
if (lc.getCallsNb() == 0){ if (lc.getCallsNb() == 0){
if (mWakeLock.isHeld()) mWakeLock.release(); if (mWakeLock.isHeld()) mWakeLock.release();
exitCallMode(); exitCallMode(call);
LinphoneActivity.instance().stopOrientationSensor(); LinphoneActivity.instance().stopOrientationSensor();
} }
}else if (state==LinphoneCall.State.CallEnd){ }else if (state==LinphoneCall.State.CallEnd){
if (lc.getCallsNb() == 0){ if (lc.getCallsNb() == 0){
exitCallMode(); exitCallMode(call);
LinphoneActivity.instance().stopOrientationSensor(); LinphoneActivity.instance().stopOrientationSensor();
} }
} }

View file

@ -257,7 +257,8 @@ public class LinphoneActivity extends TabActivity implements SensorEventListener
if (isFinishing()) { if (isFinishing()) {
//restore audio settings //restore audio settings
LinphoneManager.getInstance().routeAudioToReceiver(); boolean isUserRequest = false;
LinphoneManager.getInstance().routeAudioToReceiver(isUserRequest);
LinphoneManager.stopProximitySensorForActivity(this); LinphoneManager.stopProximitySensorForActivity(this);
instance = null; instance = null;
} }
@ -469,7 +470,8 @@ public class LinphoneActivity extends TabActivity implements SensorEventListener
video_activity); video_activity);
} }
}); });
LinphoneManager.getInstance().routeAudioToSpeaker(); boolean isUserRequest = false;
LinphoneManager.getInstance().routeAudioToSpeaker(isUserRequest);
} }
public void startConferenceActivity() { public void startConferenceActivity() {

View file

@ -46,7 +46,9 @@ import java.util.Set;
import java.util.Timer; import java.util.Timer;
import java.util.TimerTask; import java.util.TimerTask;
import org.linphone.LinphoneSimpleListener.LinphoneAudioChangedListener;
import org.linphone.LinphoneSimpleListener.LinphoneServiceListener; import org.linphone.LinphoneSimpleListener.LinphoneServiceListener;
import org.linphone.LinphoneSimpleListener.LinphoneAudioChangedListener.AudioState;
import org.linphone.core.LinphoneAddress; import org.linphone.core.LinphoneAddress;
import org.linphone.core.LinphoneAuthInfo; import org.linphone.core.LinphoneAuthInfo;
import org.linphone.core.LinphoneCall; import org.linphone.core.LinphoneCall;
@ -177,6 +179,12 @@ public final class LinphoneManager implements LinphoneCoreListener {
getInstance().routeAudioToSpeakerHelperHelper(speakerOn); getInstance().routeAudioToSpeakerHelperHelper(speakerOn);
} }
private void routeAudioToSpeakerHelperHelper(boolean speakerOn) { private void routeAudioToSpeakerHelperHelper(boolean speakerOn) {
boolean different = isSpeakerOn() ^ speakerOn;
if (!different) {
Log.d("Skipping change audio route by the same route ",
speakerOn ? "speaker" : "earpiece");
return;
}
if (Hacks.needGalaxySAudioHack() || lpm.useGalaxySHack()) if (Hacks.needGalaxySAudioHack() || lpm.useGalaxySHack())
setAudioModeIncallForGalaxyS(); setAudioModeIncallForGalaxyS();
@ -191,6 +199,9 @@ public final class LinphoneManager implements LinphoneCoreListener {
} else { } else {
mAudioManager.setSpeakerphoneOn(speakerOn); mAudioManager.setSpeakerphoneOn(speakerOn);
} }
for (LinphoneAudioChangedListener listener : getSimpleListeners(LinphoneAudioChangedListener.class)) {
listener.onAudioStateChanged(speakerOn ? AudioState.SPEAKER : AudioState.EARPIECE);
}
} }
private synchronized void routeAudioToSpeakerHelper(boolean speakerOn) { private synchronized void routeAudioToSpeakerHelper(boolean speakerOn) {
final LinphoneCall call = mLc.getCurrentCall(); final LinphoneCall call = mLc.getCurrentCall();
@ -202,8 +213,24 @@ public final class LinphoneManager implements LinphoneCoreListener {
} }
} }
private static boolean sUserRequestedSpeaker;
public static final boolean isUserRequestedSpeaker() {return sUserRequestedSpeaker;}
public void routeAudioToSpeaker() { public void restoreUserRequestedSpeaker() {
if (sUserRequestedSpeaker) {
routeAudioToSpeaker(false);
} else {
routeAudioToReceiver(false);
}
}
/**
*
* @param isUserRequest true if the setting is permanent, otherwise it can be lost
* eg: video activity imply speaker on, which is not a request from the user.
* when the activity stops, the sound is routed to the previously user requested route.
*/
public void routeAudioToSpeaker(boolean isUserRequest) {
if (isUserRequest) sUserRequestedSpeaker = true;
routeAudioToSpeakerHelper(true); routeAudioToSpeakerHelper(true);
if (mLc.isIncall()) { if (mLc.isIncall()) {
/*disable EC, it is not efficient enough on speaker mode due to bad quality of speakers and saturation*/ /*disable EC, it is not efficient enough on speaker mode due to bad quality of speakers and saturation*/
@ -214,7 +241,14 @@ public final class LinphoneManager implements LinphoneCoreListener {
} }
public void routeAudioToReceiver() { /**
*
* @param isUserRequest true if the setting is permanent, otherwise it can be lost
* eg: video activity imply speaker on, which is not a request from the user.
* when the activity stops, the sound is routed to the previously user requested route.
*/
public void routeAudioToReceiver(boolean isUserRequest) {
if (isUserRequest) sUserRequestedSpeaker = false;
routeAudioToSpeakerHelper(false); routeAudioToSpeakerHelper(false);
if (mLc.isIncall()) { if (mLc.isIncall()) {
//Restore default value //Restore default value
@ -677,7 +711,7 @@ public final class LinphoneManager implements LinphoneCoreListener {
void onEcCalibrationStatus(EcCalibratorStatus status, int delayMs); void onEcCalibrationStatus(EcCalibratorStatus status, int delayMs);
} }
private ListenerDispatcher listenerDispatcher = new ListenerDispatcher(simpleListeners); private ListenerDispatcher listenerDispatcher = new ListenerDispatcher();
private LinphoneCall ringingCall; private LinphoneCall ringingCall;
private MediaPlayer mRingerPlayer; private MediaPlayer mRingerPlayer;
@ -746,7 +780,6 @@ public final class LinphoneManager implements LinphoneCoreListener {
} else if (call == ringingCall && isRinging) { } else if (call == ringingCall && isRinging) {
//previous state was ringing, so stop ringing //previous state was ringing, so stop ringing
stopRinging(); stopRinging();
routeAudioToReceiver();
} }
if (state == CallEnd || state == Error) { if (state == CallEnd || state == Error) {
@ -853,6 +886,8 @@ public final class LinphoneManager implements LinphoneCoreListener {
isRinging = false; isRinging = false;
// You may need to call galaxys audio hack after this method // You may need to call galaxys audio hack after this method
boolean isUserRequest = false;
routeAudioToReceiver(isUserRequest);
} }
@ -1067,13 +1102,6 @@ public final class LinphoneManager implements LinphoneCoreListener {
return getLc(); return getLc();
} }
private static class ListenerDispatcher implements LinphoneServiceListener {
private LinphoneServiceListener serviceListener;
List<LinphoneSimpleListener> simpleListeners;
public ListenerDispatcher(List<LinphoneSimpleListener> simpleListeners) {
this.simpleListeners = simpleListeners; // yes, really keeps a reference, not a copy
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private <T> List<T> getSimpleListeners(Class<T> clazz) { private <T> List<T> getSimpleListeners(Class<T> clazz) {
List<T> list = new ArrayList<T>(); List<T> list = new ArrayList<T>();
@ -1083,6 +1111,9 @@ public final class LinphoneManager implements LinphoneCoreListener {
return list; return list;
} }
private class ListenerDispatcher implements LinphoneServiceListener {
private LinphoneServiceListener serviceListener;
public void setServiceListener(LinphoneServiceListener s) { public void setServiceListener(LinphoneServiceListener s) {
this.serviceListener = s; this.serviceListener = s;
} }
@ -1098,6 +1129,9 @@ public final class LinphoneManager implements LinphoneCoreListener {
public void onCallStateChanged(LinphoneCall call, State state, public void onCallStateChanged(LinphoneCall call, State state,
String message) { String message) {
if (state == State.CallEnd && mLc.getCallsNb() == 0) {
routeAudioToReceiver(true);
}
if (serviceListener != null) serviceListener.onCallStateChanged(call, state, message); if (serviceListener != null) serviceListener.onCallStateChanged(call, state, message);
for (LinphoneOnCallStateChangedListener l : getSimpleListeners(LinphoneOnCallStateChangedListener.class)) { for (LinphoneOnCallStateChangedListener l : getSimpleListeners(LinphoneOnCallStateChangedListener.class)) {
l.onCallStateChanged(call, state, message); l.onCallStateChanged(call, state, message);

View file

@ -47,4 +47,9 @@ public interface LinphoneSimpleListener {
public static interface LinphoneOnCallStateChangedListener extends LinphoneSimpleListener { public static interface LinphoneOnCallStateChangedListener extends LinphoneSimpleListener {
void onCallStateChanged(LinphoneCall call, State state, String message); void onCallStateChanged(LinphoneCall call, State state, String message);
} }
public static interface LinphoneAudioChangedListener extends LinphoneSimpleListener {
public enum AudioState {EARPIECE, SPEAKER}
void onAudioStateChanged(AudioState state);
}
} }

View file

@ -50,6 +50,7 @@ public class VideoCallActivity extends Activity {
private SurfaceView mVideoViewReady; private SurfaceView mVideoViewReady;
private SurfaceView mVideoCaptureViewReady; private SurfaceView mVideoCaptureViewReady;
public static boolean launched = false; public static boolean launched = false;
public static LinphoneCall call;
private WakeLock mWakeLock; private WakeLock mWakeLock;
private Handler refreshHandler = new Handler(); private Handler refreshHandler = new Handler();
@ -280,7 +281,10 @@ public class VideoCallActivity extends Activity {
@Override @Override
protected void onPause() { protected void onPause() {
Log.d("onPause VideoCallActivity (isFinishing:", isFinishing(), ", inCall:", LinphoneManager.getLc().isIncall(), ", changingConf:", getChangingConfigurations()); Log.d("onPause VideoCallActivity (isFinishing:", isFinishing(), ", inCall:", LinphoneManager.getLc().isIncall(), ", changingConf:", getChangingConfigurations());
if (isFinishing()) {
call = null; // release reference
}
LinphoneManager.getInstance().restoreUserRequestedSpeaker();
launched=false; launched=false;
synchronized (androidVideoWindowImpl) { synchronized (androidVideoWindowImpl) {
/* this call will destroy native opengl renderer /* this call will destroy native opengl renderer

View file

@ -48,9 +48,9 @@ public class SpeakerButton extends ToggleImageButton implements OnCheckedChangeL
public void onCheckedChanged(ToggleImageButton button, boolean checked) { public void onCheckedChanged(ToggleImageButton button, boolean checked) {
if (checked) { if (checked) {
LinphoneManager.getInstance().routeAudioToSpeaker(); LinphoneManager.getInstance().routeAudioToSpeaker(true);
} else { } else {
LinphoneManager.getInstance().routeAudioToReceiver(); LinphoneManager.getInstance().routeAudioToReceiver(true);
} }
} }