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 org.linphone.LinphoneManagerWaitHelper.LinphoneManagerReadyListener;
import org.linphone.LinphoneSimpleListener.LinphoneAudioChangedListener;
import org.linphone.LinphoneSimpleListener.LinphoneOnCallStateChangedListener;
import org.linphone.core.LinphoneAddress;
import org.linphone.core.LinphoneCall;
@ -64,6 +65,7 @@ import android.widget.ToggleButton;
*/
public class ConferenceActivity extends ListActivity implements
LinphoneManagerReadyListener,
LinphoneAudioChangedListener,
LinphoneOnCallStateChangedListener, Comparator<LinphoneCall>,
OnClickListener {
@ -149,6 +151,10 @@ public class ConferenceActivity extends ListActivity implements
updateConfState();
updateSimpleControlButtons();
CalleeListAdapter adapter = (CalleeListAdapter) getListAdapter();
if (adapter.linphoneCalls.size() != lc().getCallsNb()) {
adapter.linphoneCalls.clear();
adapter.linphoneCalls.addAll(getInitialCalls());
}
adapter.notifyDataSetInvalidated();
adapter.notifyDataSetChanged();
LinphoneManager.startProximitySensorForActivity(this);
@ -353,9 +359,9 @@ public class ConferenceActivity extends ListActivity implements
break;
case R.id.toggleSpeaker:
if (((ToggleButton) v).isChecked()) {
LinphoneManager.getInstance().routeAudioToSpeaker();
LinphoneManager.getInstance().routeAudioToSpeaker(true);
} else {
LinphoneManager.getInstance().routeAudioToReceiver();
LinphoneManager.getInstance().routeAudioToReceiver(true);
}
break;
default:
@ -422,6 +428,10 @@ public class ConferenceActivity extends ListActivity implements
case R.id.remove_from_conference:
lc().removeFromConference(call);
break;
case R.id.addVideo:
VideoCallActivity.call = call;
LinphoneActivity.instance().startVideoActivity();
break;
default:
throw new RuntimeException("unknown id " + v.getId());
}
@ -561,7 +571,8 @@ public class ConferenceActivity extends ListActivity implements
final int numberOfCalls = linphoneCalls.size();
boolean showAddVideo = State.StreamsRunning == state && !isInConference
&& 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;
setVisibility(v, R.id.callee_status_paused, statusPaused);
@ -575,6 +586,7 @@ public class ConferenceActivity extends ListActivity implements
resumeButton.setOnClickListener(l);
unhookCallButton.setOnClickListener(l);
removeFromConfButton.setOnClickListener(l);
addVideoButton.setOnClickListener(l);
v.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
@ -749,6 +761,25 @@ public class ConferenceActivity extends ListActivity implements
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)
* 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)) {
finishActivity(INCOMING_CALL_ACTIVITY);
} 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);
if (useVideoActivity && LinphoneManager.getLc().isVideoEnabled()) {
if (useVideoActivity && LinphoneManager.getLc().isVideoEnabled()
&& VideoCallActivity.call == call) {
LinphoneActivity.instance().finishVideoActivity();
BandwidthManager.getInstance().setUserRestriction(false);
LinphoneManager.getInstance().resetCameraFromPreferences();
@ -464,12 +465,12 @@ public class DialerActivity extends Activity implements LinphoneGuiListener, Lin
showToast(R.string.call_error, message);
if (lc.getCallsNb() == 0){
if (mWakeLock.isHeld()) mWakeLock.release();
exitCallMode();
exitCallMode(call);
LinphoneActivity.instance().stopOrientationSensor();
}
}else if (state==LinphoneCall.State.CallEnd){
if (lc.getCallsNb() == 0){
exitCallMode();
exitCallMode(call);
LinphoneActivity.instance().stopOrientationSensor();
}
}

View file

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

View file

@ -46,7 +46,9 @@ import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import org.linphone.LinphoneSimpleListener.LinphoneAudioChangedListener;
import org.linphone.LinphoneSimpleListener.LinphoneServiceListener;
import org.linphone.LinphoneSimpleListener.LinphoneAudioChangedListener.AudioState;
import org.linphone.core.LinphoneAddress;
import org.linphone.core.LinphoneAuthInfo;
import org.linphone.core.LinphoneCall;
@ -177,6 +179,12 @@ public final class LinphoneManager implements LinphoneCoreListener {
getInstance().routeAudioToSpeakerHelperHelper(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())
setAudioModeIncallForGalaxyS();
@ -191,6 +199,9 @@ public final class LinphoneManager implements LinphoneCoreListener {
} else {
mAudioManager.setSpeakerphoneOn(speakerOn);
}
for (LinphoneAudioChangedListener listener : getSimpleListeners(LinphoneAudioChangedListener.class)) {
listener.onAudioStateChanged(speakerOn ? AudioState.SPEAKER : AudioState.EARPIECE);
}
}
private synchronized void routeAudioToSpeakerHelper(boolean speakerOn) {
final LinphoneCall call = mLc.getCurrentCall();
@ -202,8 +213,24 @@ public final class LinphoneManager implements LinphoneCoreListener {
}
}
public void routeAudioToSpeaker() {
private static boolean sUserRequestedSpeaker;
public static final boolean isUserRequestedSpeaker() {return sUserRequestedSpeaker;}
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);
if (mLc.isIncall()) {
/*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);
if (mLc.isIncall()) {
//Restore default value
@ -677,7 +711,7 @@ public final class LinphoneManager implements LinphoneCoreListener {
void onEcCalibrationStatus(EcCalibratorStatus status, int delayMs);
}
private ListenerDispatcher listenerDispatcher = new ListenerDispatcher(simpleListeners);
private ListenerDispatcher listenerDispatcher = new ListenerDispatcher();
private LinphoneCall ringingCall;
private MediaPlayer mRingerPlayer;
@ -746,7 +780,6 @@ public final class LinphoneManager implements LinphoneCoreListener {
} else if (call == ringingCall && isRinging) {
//previous state was ringing, so stop ringing
stopRinging();
routeAudioToReceiver();
}
if (state == CallEnd || state == Error) {
@ -853,6 +886,8 @@ public final class LinphoneManager implements LinphoneCoreListener {
isRinging = false;
// You may need to call galaxys audio hack after this method
boolean isUserRequest = false;
routeAudioToReceiver(isUserRequest);
}
@ -1067,21 +1102,17 @@ public final class LinphoneManager implements LinphoneCoreListener {
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")
private <T> List<T> getSimpleListeners(Class<T> clazz) {
List<T> list = new ArrayList<T>();
for (LinphoneSimpleListener l : simpleListeners) {
if (clazz.isInstance(l)) list.add((T) l);
}
return list;
}
@SuppressWarnings("unchecked")
private <T> List<T> getSimpleListeners(Class<T> clazz) {
List<T> list = new ArrayList<T>();
for (LinphoneSimpleListener l : simpleListeners) {
if (clazz.isInstance(l)) list.add((T) l);
}
return list;
}
private class ListenerDispatcher implements LinphoneServiceListener {
private LinphoneServiceListener serviceListener;
public void setServiceListener(LinphoneServiceListener s) {
this.serviceListener = s;
@ -1098,6 +1129,9 @@ public final class LinphoneManager implements LinphoneCoreListener {
public void onCallStateChanged(LinphoneCall call, State state,
String message) {
if (state == State.CallEnd && mLc.getCallsNb() == 0) {
routeAudioToReceiver(true);
}
if (serviceListener != null) serviceListener.onCallStateChanged(call, state, message);
for (LinphoneOnCallStateChangedListener l : getSimpleListeners(LinphoneOnCallStateChangedListener.class)) {
l.onCallStateChanged(call, state, message);

View file

@ -47,4 +47,9 @@ public interface LinphoneSimpleListener {
public static interface LinphoneOnCallStateChangedListener extends LinphoneSimpleListener {
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 mVideoCaptureViewReady;
public static boolean launched = false;
public static LinphoneCall call;
private WakeLock mWakeLock;
private Handler refreshHandler = new Handler();
@ -280,7 +281,10 @@ public class VideoCallActivity extends Activity {
@Override
protected void onPause() {
Log.d("onPause VideoCallActivity (isFinishing:", isFinishing(), ", inCall:", LinphoneManager.getLc().isIncall(), ", changingConf:", getChangingConfigurations());
if (isFinishing()) {
call = null; // release reference
}
LinphoneManager.getInstance().restoreUserRequestedSpeaker();
launched=false;
synchronized (androidVideoWindowImpl) {
/* 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) {
if (checked) {
LinphoneManager.getInstance().routeAudioToSpeaker();
LinphoneManager.getInstance().routeAudioToSpeaker(true);
} else {
LinphoneManager.getInstance().routeAudioToReceiver();
LinphoneManager.getInstance().routeAudioToReceiver(true);
}
}