diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 5286ed535..2228c435e 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -36,8 +36,9 @@ - - + @@ -60,7 +61,6 @@ diff --git a/res/drawable/resume_blue.png b/res/drawable/resume_blue.png new file mode 100644 index 000000000..8274e4a8d Binary files /dev/null and b/res/drawable/resume_blue.png differ diff --git a/res/layout-land/dialer.xml b/res/layout-land/dialer.xml index b18e0dd33..9502261f6 100644 --- a/res/layout-land/dialer.xml +++ b/res/layout-land/dialer.xml @@ -40,6 +40,7 @@ + - - + + + - - + + diff --git a/res/layout/incoming.xml b/res/layout/incoming.xml index 91e53bbdd..4b0f71816 100644 --- a/res/layout/incoming.xml +++ b/res/layout/incoming.xml @@ -28,7 +28,7 @@ - - + Starting up... + An error occurred while accepting call + Canceled Error adding new call Transfer started diff --git a/src/org/linphone/ConferenceActivity.java b/src/org/linphone/ConferenceActivity.java index f201b2d7b..20fc2e9f7 100644 --- a/src/org/linphone/ConferenceActivity.java +++ b/src/org/linphone/ConferenceActivity.java @@ -32,6 +32,7 @@ import org.linphone.core.LinphoneCore; import org.linphone.core.LinphoneCoreException; import org.linphone.core.Log; import org.linphone.core.LinphoneCall.State; +import org.linphone.mediastream.Version; import org.linphone.mediastream.video.capture.hwconf.Hacks; import android.app.AlertDialog; @@ -123,6 +124,11 @@ public class ConferenceActivity extends ListActivity implements workaroundStatusBarBug(); } + @Override + protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + } + protected void registerLinphoneListener(boolean register) { if (register) LinphoneManager.getInstance().addListener(this); @@ -135,6 +141,8 @@ public class ConferenceActivity extends ListActivity implements active=true; registerLinphoneListener(true); updateConfState(); + boolean showSimpleActions = lc().getConferenceSize() == 0 && lc().getCallsNb() == 2; + findViewById(R.id.conf_simple_merge).setVisibility(showSimpleActions ? VISIBLE : GONE); super.onResume(); } @@ -205,9 +213,6 @@ public class ConferenceActivity extends ListActivity implements public void onClick(View v) { switch (v.getId()) { case R.id.addCall: - Toast.makeText(this, - "Should now finish this activity to go back to dialer", - Toast.LENGTH_LONG).show(); Intent intent = new Intent().setClass(this, UriPickerActivity.class); intent.putExtra(UriPickerActivity.EXTRA_PICKER_TYPE, UriPickerActivity.EXTRA_PICKER_TYPE_ADD); startActivityForResult(intent, ID_ADD_CALL); @@ -305,7 +310,6 @@ public class ConferenceActivity extends ListActivity implements } break; case R.id.transfer_existing: - Toast.makeText(ConferenceActivity.this, "Transfer choice selected", Toast.LENGTH_LONG).show(); @SuppressWarnings("unchecked") final List existingCalls = lc().getCalls(); existingCalls.remove(call); final List numbers = new ArrayList(existingCalls.size()); @@ -322,7 +326,6 @@ public class ConferenceActivity extends ListActivity implements new AlertDialog.Builder(ConferenceActivity.this).setAdapter(adapter, l).create().show(); break; case R.id.transfer_new: - Toast.makeText(ConferenceActivity.this, "Transfer choice selected : to do, create activity to select new call", Toast.LENGTH_LONG).show(); Intent intent = new Intent().setClass(ConferenceActivity.this, UriPickerActivity.class); intent.putExtra(UriPickerActivity.EXTRA_PICKER_TYPE, UriPickerActivity.EXTRA_PICKER_TYPE_TRANSFER); callToTransfer = call; @@ -342,7 +345,6 @@ public class ConferenceActivity extends ListActivity implements public CalleeListAdapter(List calls) { linphoneCalls = calls; - } public int getCount() { @@ -452,7 +454,9 @@ public class ConferenceActivity extends ListActivity implements setVisibility(removeFromConfButton, false); final int numberOfCalls = linphoneCalls.size(); - setVisibility(v, R.id.addVideo, !isInConference && !showUnhook && numberOfCalls == 1); + boolean showAddVideo = !isInConference && !showUnhook && numberOfCalls == 1 + && Version.isVideoCapable() && LinphoneManager.getInstance().isVideoEnabled(); + setVisibility(v, R.id.addVideo, showAddVideo); boolean statusPaused = state== State.Paused || state == State.PausedByRemote; setVisibility(v, R.id.callee_status_paused, statusPaused); @@ -553,7 +557,7 @@ public class ConferenceActivity extends ListActivity implements if (!inConfC1 && inConfC2) return 1; - int durationDiff = c1.getDuration() - c2.getDuration(); + int durationDiff = c2.getDuration() - c1.getDuration(); return durationDiff; } diff --git a/src/org/linphone/DialerActivity.java b/src/org/linphone/DialerActivity.java index 50a6b6910..9d6013d0d 100644 --- a/src/org/linphone/DialerActivity.java +++ b/src/org/linphone/DialerActivity.java @@ -63,7 +63,7 @@ import android.widget.Toast; * * */ -public class DialerActivity extends LinphoneManagerWaitActivity implements LinphoneGuiListener, NewOutgoingCallUiListener { +public class DialerActivity extends LinphoneManagerWaitActivity implements LinphoneGuiListener, NewOutgoingCallUiListener, OnClickListener { private TextView mStatus; private View mHangup; @@ -126,6 +126,7 @@ public class DialerActivity extends LinphoneManagerWaitActivity implements Linph mCallControlRow = findViewById(R.id.CallControlRow); + mCallControlRow.findViewById(R.id.BackToConference).setOnClickListener(this); mAddressLayout = findViewById(R.id.Addresslayout); mInCallControlRow = findViewById(R.id.IncallControlRow); @@ -319,7 +320,9 @@ public class DialerActivity extends LinphoneManagerWaitActivity implements Linph private void callPending(final LinphoneCall call) { if (getResources().getBoolean(R.bool.use_incoming_call_activity)) { - Intent intent = new Intent().setClass(this, IncomingCallActivity.class); + Intent intent = new Intent() + .setClass(this, IncomingCallActivity.class) + .putExtra("stringUri", call.getRemoteAddress().asStringUriOnly()); startActivityForResult(intent, INCOMING_CALL_ACTIVITY); } else if (getResources().getBoolean(R.bool.use_incoming_call_dialog)) { showDialog(incomingCallDialogId); @@ -462,6 +465,8 @@ public class DialerActivity extends LinphoneManagerWaitActivity implements Linph mCurrentCall=null; } } + + updateCallControlRow(); } private void showToast(int id, String txt) { @@ -498,6 +503,8 @@ public class DialerActivity extends LinphoneManagerWaitActivity implements Linph @Override protected void onResume() { + updateCallControlRow(); + // When coming back from a video call, if the phone orientation is different // Android will destroy the previous Dialer and create a new one. // Unfortunately the "call end" status event is received in the meanwhile @@ -510,4 +517,38 @@ public class DialerActivity extends LinphoneManagerWaitActivity implements Linph super.onResume(); } + + private void updateCallControlRow() { + if (useConferenceActivity) { + if (LinphoneManager.isInstanciated()) { + LinphoneCore lc = LinphoneManager.getLc(); + int calls = lc.getCallsNb(); + View backToConf = mCallControlRow.findViewById(R.id.BackToConference); + View callButton = mCallControlRow.findViewById(R.id.Call); + View hangButton = mCallControlRow.findViewById(R.id.Decline); + if (calls > 0) { + backToConf.setVisibility(View.VISIBLE); + callButton.setVisibility(View.GONE); + hangButton.setEnabled(true); + } else { + backToConf.setVisibility(View.GONE); + callButton.setVisibility(View.VISIBLE); + hangButton.setEnabled(false); + } + } + } + } + + + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.BackToConference: + LinphoneActivity.instance().startConferenceActivity(); + break; + default: + break; + } + + } } diff --git a/src/org/linphone/IncomingCallActivity.java b/src/org/linphone/IncomingCallActivity.java index 442be6247..d60fc20df 100644 --- a/src/org/linphone/IncomingCallActivity.java +++ b/src/org/linphone/IncomingCallActivity.java @@ -20,17 +20,17 @@ package org.linphone; import org.linphone.core.LinphoneAddress; import org.linphone.core.LinphoneCall; -import org.linphone.core.LinphoneCore; -import org.linphone.ui.CallButton; -import org.linphone.ui.HangCallButton; +import org.linphone.core.Log; import android.app.Activity; +import android.content.Intent; import android.os.Bundle; import android.view.KeyEvent; import android.view.View; import android.view.WindowManager; import android.view.View.OnClickListener; import android.widget.TextView; +import android.widget.Toast; /** * Activity displayed when a call comes in. @@ -44,11 +44,18 @@ public class IncomingCallActivity extends Activity implements OnClickListener { private TextView mNumberView; private LinphoneCall mCall; - + private void findIncomingCall(Intent intent) { + String stringUri = intent.getStringExtra("stringUri"); + mCall = LinphoneManager.getInstance().retrieveIncomingCall(stringUri); + if (mCall == null) { + Log.e("Couldn't find incoming call from ", stringUri); + Toast.makeText(this, "Error", Toast.LENGTH_SHORT); + } + } + @Override protected void onCreate(Bundle savedInstanceState) { - LinphoneCore lc = LinphoneManager.getLc(); - mCall = lc.getCurrentCall(); + findIncomingCall(getIntent()); super.onCreate(savedInstanceState); setContentView(R.layout.incoming); @@ -56,10 +63,8 @@ public class IncomingCallActivity extends Activity implements OnClickListener { mNameView = (TextView) findViewById(R.id.incoming_caller_name); mNumberView = (TextView) findViewById(R.id.incoming_caller_number); - HangCallButton hang = (HangCallButton) findViewById(R.id.Decline); - CallButton accept = (CallButton) findViewById(R.id.Answer); - hang.setExternalClickListener(this); - accept.setExternalClickListener(this); + findViewById(R.id.Decline).setOnClickListener(this); + findViewById(R.id.Answer).setOnClickListener(this); // set this flag so this activity will stay in front of the keyguard int flags = WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED; @@ -67,6 +72,12 @@ public class IncomingCallActivity extends Activity implements OnClickListener { getWindow().addFlags(flags); } + @Override + protected void onNewIntent(Intent intent) { + findIncomingCall(intent); + super.onNewIntent(intent); + } + @Override protected void onResume() { LinphoneAddress address = mCall.getRemoteAddress(); @@ -80,12 +91,26 @@ public class IncomingCallActivity extends Activity implements OnClickListener { public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_HOME) { LinphoneManager.getLc().terminateCall(mCall); + finish(); } return super.onKeyDown(keyCode, event); } @Override public void onClick(View v) { + switch (v.getId()) { + case R.id.Answer: + if (!LinphoneManager.getInstance().acceptCall(mCall)) { + // the above method takes care of Samsung Galaxy S + Toast.makeText(this, R.string.couldnt_accept_call, Toast.LENGTH_LONG); + } + break; + case R.id.Decline: + LinphoneManager.getLc().terminateCall(mCall); + break; + default: + throw new RuntimeException(); + } finish(); } } diff --git a/src/org/linphone/LinphoneActivity.java b/src/org/linphone/LinphoneActivity.java index 3f30cfda6..b88e16aa5 100644 --- a/src/org/linphone/LinphoneActivity.java +++ b/src/org/linphone/LinphoneActivity.java @@ -515,7 +515,9 @@ public class LinphoneActivity extends TabActivity implements SensorEventListener } public void startConferenceActivity() { - if (ConferenceActivity.active) return; + if (ConferenceActivity.active) { + return; + } mHandler.post(new Runnable() { public void run() { diff --git a/src/org/linphone/LinphoneManager.java b/src/org/linphone/LinphoneManager.java index 69985dec8..38131d12a 100644 --- a/src/org/linphone/LinphoneManager.java +++ b/src/org/linphone/LinphoneManager.java @@ -887,7 +887,7 @@ public final class LinphoneManager implements LinphoneCoreListener { listenerDispatcher.onAlreadyInVideoCall(); } } - + public boolean acceptCallIfIncomingPending() throws LinphoneCoreException { if (Hacks.needGalaxySAudioHack() || lpm.useGalaxySHack()) setAudioModeIncallForGalaxyS(); @@ -899,6 +899,19 @@ public final class LinphoneManager implements LinphoneCoreListener { return false; } + public boolean acceptCall(LinphoneCall call) { + if (Hacks.needGalaxySAudioHack() || lpm.useGalaxySHack()) + setAudioModeIncallForGalaxyS(); + + try { + mLc.acceptCall(call); + return true; + } catch (LinphoneCoreException e) { + Log.i(e, "Accept call failed"); + } + return false; + } + public static String extractIncomingRemoteName(Resources r, LinphoneAddress linphoneAddress) { if (!r.getBoolean(R.bool.show_full_remote_address_on_incoming_call)) return extractADisplayName(r, linphoneAddress); @@ -946,6 +959,7 @@ public final class LinphoneManager implements LinphoneCoreListener { private static class ListenerDispatcher implements LinphoneServiceListener { private LinphoneServiceListener serviceListener; + private List incomingCalls = new ArrayList(); List simpleListeners; public ListenerDispatcher(List simpleListeners) { this.simpleListeners = simpleListeners; @@ -973,8 +987,20 @@ public final class LinphoneManager implements LinphoneCoreListener { if (serviceListener != null) serviceListener.onCallEncryptionChanged(call, encrypted, authenticationToken); } + public LinphoneCall retrieveIncomingCall(String stringUri) { + for (LinphoneCall call : incomingCalls) { + if (stringUri.equals(call.getRemoteAddress().asStringUriOnly())) { + return call; + } + } + return null; + } + public void onCallStateChanged(LinphoneCall call, State state, String message) { + if (State.IncomingReceived.equals(state)) { + incomingCalls.add(call); + } if (serviceListener != null) serviceListener.onCallStateChanged(call, state, message); for (LinphoneOnCallStateChangedListener l : getSimpleListeners(LinphoneOnCallStateChangedListener.class)) { l.onCallStateChanged(call, state, message); @@ -1009,11 +1035,13 @@ public final class LinphoneManager implements LinphoneCoreListener { public void tryingNewOutgoingCallButWrongDestinationAddress() { if (serviceListener != null) serviceListener.tryingNewOutgoingCallButWrongDestinationAddress(); } - } - public static final boolean isInstanciated() { return instance != null; } + + public LinphoneCall retrieveIncomingCall(String stringUri) { + return listenerDispatcher.retrieveIncomingCall(stringUri); + } } diff --git a/src/org/linphone/core/LinphoneCallImpl.java b/src/org/linphone/core/LinphoneCallImpl.java index c96593d63..3f153e0fc 100644 --- a/src/org/linphone/core/LinphoneCallImpl.java +++ b/src/org/linphone/core/LinphoneCallImpl.java @@ -84,9 +84,21 @@ class LinphoneCallImpl implements LinphoneCall { public boolean cameraEnabled() { return cameraEnabled(nativePtr); } + + @Override public boolean equals(Object call) { + if (this == call) return true; + if (call == null) return false; + if (!(call instanceof LinphoneCallImpl)) return false; return nativePtr == ((LinphoneCallImpl)call).nativePtr; } + + @Override + public int hashCode() { + int result = 17; + result = 31 * result + (int) (nativePtr ^ (nativePtr >>> 32)); + return result; + } public void enableEchoCancellation(boolean enable) { enableEchoCancellation(nativePtr,enable);