sipcall: Modify calls handling process
Integration of new security features implies modifications in call handling.
By default, when handling a call, a SipCall object is created, but if ZRTP hooks
are activated, the call is dynamically subclassed, and becomes a SecureSipCall.
Refs #40939
diff --git a/src/org/sflphone/adapters/DiscussArrayAdapter.java b/src/org/sflphone/adapters/DiscussArrayAdapter.java
index 5399c0a..f7489ae 100644
--- a/src/org/sflphone/adapters/DiscussArrayAdapter.java
+++ b/src/org/sflphone/adapters/DiscussArrayAdapter.java
@@ -82,7 +82,7 @@
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if (row == null) {
- LayoutInflater inflater = (LayoutInflater) LayoutInflater.from(mContext);
+ LayoutInflater inflater = LayoutInflater.from(mContext);
row = inflater.inflate(R.layout.item_message, parent, false);
}
@@ -100,10 +100,6 @@
return row;
}
- public Bitmap decodeToBitmap(byte[] decodedByte) {
- return BitmapFactory.decodeByteArray(decodedByte, 0, decodedByte.length);
- }
-
@Override
public long getItemId(int position) {
return 0;
diff --git a/src/org/sflphone/client/CallActivity.java b/src/org/sflphone/client/CallActivity.java
index 4242390..6e7143a 100644
--- a/src/org/sflphone/client/CallActivity.java
+++ b/src/org/sflphone/client/CallActivity.java
@@ -33,12 +33,10 @@
package org.sflphone.client;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Timer;
-import java.util.TimerTask;
+import java.util.*;
import android.support.v4.app.FragmentActivity;
+import android.util.Log;
import org.sflphone.R;
import org.sflphone.fragments.CallFragment;
import org.sflphone.fragments.IMFragment;
@@ -191,27 +189,33 @@
ArrayList<HashMap<String, String>> credentials = (ArrayList<HashMap<String, String>>) mService.getCredentials(accountID);
Account acc = new Account(accountID, details, credentials);
- SipCall call = SipCall.SipCallBuilder.getInstance().startCallCreation().setContact(c).setAccount(acc)
- .setCallType(SipCall.direction.CALL_TYPE_OUTGOING).build();
+ Bundle args = new Bundle();
+ args.putString(SipCall.ID, Integer.toString(Math.abs(new Random().nextInt())));
+ args.putParcelable(SipCall.ACCOUNT, acc);
+ args.putInt(SipCall.STATE, SipCall.state.CALL_STATE_RINGING);
+ args.putInt(SipCall.TYPE, SipCall.direction.CALL_TYPE_OUTGOING);
+ args.putParcelable(SipCall.CONTACT, c);
+
mDisplayedConference = new Conference(Conference.DEFAULT_ID);
- mDisplayedConference.getParticipants().add(call);
+ mDisplayedConference.getParticipants().add(new SipCall(args));
} catch (RemoteException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
} else {
+ mDisplayedConference = getIntent().getParcelableExtra("conference");
if (getIntent().getBooleanExtra("resuming", false)) {
-
- mDisplayedConference = getIntent().getParcelableExtra("conference");
-
Bundle IMBundle = new Bundle();
IMBundle.putParcelableArrayList("messages", mDisplayedConference.getMessages());
mIMFragment.setArguments(IMBundle);
-
} else {
- mDisplayedConference = getIntent().getParcelableExtra("conference");
Bundle IMBundle = new Bundle();
+ try {
+ mService.placeCall(mDisplayedConference.getParticipants().get(0));
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
IMBundle.putParcelableArrayList("messages", new ArrayList<SipMessage>());
mIMFragment.setArguments(IMBundle);
}
@@ -241,6 +245,15 @@
}
@Override
+ public void updateDisplayedConference(Conference c) {
+ Log.e(TAG, "toUpdate.getParticipants() :"+ c.getParticipants().size());
+ if(mDisplayedConference.equals(c)){
+ Log.e(TAG, "It's equal");
+ mDisplayedConference = c;
+ }
+ }
+
+ @Override
public void onBackPressed() {
super.onBackPressed();
Intent launchHome = new Intent(this, HomeActivity.class);
@@ -268,7 +281,8 @@
public boolean sendIM(SipMessage msg) {
try {
- mService.sendTextMessage(mCurrentCallFragment.getConference().getId(), msg);
+ Log.i(TAG, "Sending:"+msg.comment+"to"+mDisplayedConference.getId());
+ mService.sendTextMessage(mDisplayedConference.getId(), msg);
} catch (RemoteException e) {
e.printStackTrace();
return false;
diff --git a/src/org/sflphone/client/HomeActivity.java b/src/org/sflphone/client/HomeActivity.java
index 092ced0..09b77eb 100644
--- a/src/org/sflphone/client/HomeActivity.java
+++ b/src/org/sflphone/client/HomeActivity.java
@@ -37,6 +37,7 @@
import java.io.InputStream;
import java.io.InvalidObjectException;
import java.io.OutputStream;
+import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
@@ -475,30 +476,32 @@
@Override
public void run() {
- SipCall.SipCallBuilder callBuilder = SipCall.SipCallBuilder.getInstance();
- try {
- callBuilder.startCallCreation().setAccount(fMenu.getSelectedAccount()).setCallType(SipCall.direction.CALL_TYPE_OUTGOING);
- Cursor cPhones = getContentResolver().query(Phone.CONTENT_URI, CONTACTS_PHONES_PROJECTION, Phone.CONTACT_ID + " =" + c.getId(),
- null, null);
- while (cPhones.moveToNext()) {
- c.addPhoneNumber(cPhones.getString(cPhones.getColumnIndex(Phone.NUMBER)), cPhones.getInt(cPhones.getColumnIndex(Phone.TYPE)));
- }
- cPhones.close();
+ Bundle args = new Bundle();
+ args.putString(SipCall.ID, Integer.toString(Math.abs(new Random().nextInt())));
+ args.putParcelable(SipCall.ACCOUNT, fMenu.getSelectedAccount());
+ args.putInt(SipCall.STATE, SipCall.state.CALL_STATE_RINGING);
+ args.putInt(SipCall.TYPE, SipCall.direction.CALL_TYPE_OUTGOING);
- Cursor cSip = getContentResolver().query(Phone.CONTENT_URI, CONTACTS_SIP_PROJECTION, Phone.CONTACT_ID + "=" + c.getId(), null,
- null);
+ Cursor cPhones = getContentResolver().query(Phone.CONTENT_URI, CONTACTS_PHONES_PROJECTION, Phone.CONTACT_ID + " =" + c.getId(),
+ null, null);
- while (cSip.moveToNext()) {
- c.addSipNumber(cSip.getString(cSip.getColumnIndex(SipAddress.SIP_ADDRESS)), cSip.getInt(cSip.getColumnIndex(SipAddress.TYPE)));
- }
- cSip.close();
- callBuilder.setContact(c);
- launchCallActivity(callBuilder.build());
- } catch (InvalidObjectException e) {
- e.printStackTrace();
+ while (cPhones.moveToNext()) {
+ c.addPhoneNumber(cPhones.getString(cPhones.getColumnIndex(Phone.NUMBER)), cPhones.getInt(cPhones.getColumnIndex(Phone.TYPE)));
}
+ cPhones.close();
+ Cursor cSip = getContentResolver().query(Phone.CONTENT_URI, CONTACTS_SIP_PROJECTION, Phone.CONTACT_ID + "=" + c.getId(), null,
+ null);
+
+ while (cSip.moveToNext()) {
+ c.addSipNumber(cSip.getString(cSip.getColumnIndex(SipAddress.SIP_ADDRESS)), cSip.getInt(cSip.getColumnIndex(SipAddress.TYPE)));
+ }
+ cSip.close();
+
+ args.putParcelable(SipCall.CONTACT, c);
+
+ launchCallActivity(new SipCall(args));
}
});
launcher.start();
@@ -517,11 +520,15 @@
}
if (usedAccount.isRegistered()) {
- SipCall.SipCallBuilder callBuilder = SipCall.SipCallBuilder.getInstance();
- callBuilder.startCallCreation().setAccount(usedAccount).setCallType(SipCall.direction.CALL_TYPE_OUTGOING);
- callBuilder.setContact(to.getContact());
+ Bundle args = new Bundle();
+ args.putString(SipCall.ID, Integer.toString(Math.abs(new Random().nextInt())));
+ args.putParcelable(SipCall.ACCOUNT, usedAccount);
+ args.putInt(SipCall.STATE, SipCall.state.CALL_STATE_RINGING);
+ args.putInt(SipCall.TYPE, SipCall.direction.CALL_TYPE_OUTGOING);
+ args.putParcelable(SipCall.CONTACT, to.getContact());
+
try {
- launchCallActivity(callBuilder.build());
+ launchCallActivity(new SipCall(args));
} catch (Exception e) {
Log.e(TAG, e.toString());
}
@@ -532,8 +539,6 @@
@Override
public void onCallDialed(String to) {
-
-
Account usedAccount = fMenu.getSelectedAccount();
if (usedAccount == null) {
@@ -542,12 +547,15 @@
}
if (fMenu.getSelectedAccount().isRegistered()) {
- SipCall.SipCallBuilder callBuilder = SipCall.SipCallBuilder.getInstance();
- callBuilder.startCallCreation().setAccount(usedAccount).setCallType(SipCall.direction.CALL_TYPE_OUTGOING);
- callBuilder.setContact(CallContact.ContactBuilder.buildUnknownContact(to));
+ Bundle args = new Bundle();
+ args.putString(SipCall.ID, Integer.toString(Math.abs(new Random().nextInt())));
+ args.putParcelable(SipCall.ACCOUNT, usedAccount);
+ args.putInt(SipCall.STATE, SipCall.state.CALL_STATE_RINGING);
+ args.putInt(SipCall.TYPE, SipCall.direction.CALL_TYPE_OUTGOING);
+ args.putParcelable(SipCall.CONTACT, CallContact.ContactBuilder.buildUnknownContact(to));
try {
- launchCallActivity(callBuilder.build());
+ launchCallActivity(new SipCall(args));
} catch (Exception e) {
Log.e(TAG, e.toString());
}
diff --git a/src/org/sflphone/fragments/AccountWrapperFragment.java b/src/org/sflphone/fragments/AccountWrapperFragment.java
index 98dab74..646f0e0 100644
--- a/src/org/sflphone/fragments/AccountWrapperFragment.java
+++ b/src/org/sflphone/fragments/AccountWrapperFragment.java
@@ -1,3 +1,34 @@
+/*
+ * Copyright (C) 2004-2014 Savoir-Faire Linux Inc.
+ *
+ * Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Additional permission under GNU GPL version 3 section 7:
+ *
+ * If you modify this program, or any covered work, by linking or
+ * combining it with the OpenSSL project's OpenSSL library (or a
+ * modified version of that library), containing parts covered by the
+ * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
+ * grants you additional permission to convey the resulting work.
+ * Corresponding Source for a non-source form of such a combination
+ * shall include the source code for the parts of OpenSSL used as well
+ * as that of the covered work.
+ */
+
package org.sflphone.fragments;
import android.content.BroadcastReceiver;
@@ -10,10 +41,7 @@
import org.sflphone.interfaces.AccountsInterface;
import org.sflphone.service.ConfigurationManagerCallback;
-/**
- * Created by lisional on 11/02/14.
- */
-public class AccountWrapperFragment extends Fragment implements AccountsInterface {
+public abstract class AccountWrapperFragment extends Fragment implements AccountsInterface {
private AccountsReceiver mReceiver;
diff --git a/src/org/sflphone/fragments/AccountsManagementFragment.java b/src/org/sflphone/fragments/AccountsManagementFragment.java
index f6f7413..206770e 100644
--- a/src/org/sflphone/fragments/AccountsManagementFragment.java
+++ b/src/org/sflphone/fragments/AccountsManagementFragment.java
@@ -283,7 +283,7 @@
@Override
public View getView(final int pos, View convertView, ViewGroup parent) {
View rowView = convertView;
- AccountView entryView = null;
+ AccountView entryView;
if (rowView == null) {
LayoutInflater inflater = LayoutInflater.from(mContext);
diff --git a/src/org/sflphone/fragments/CallFragment.java b/src/org/sflphone/fragments/CallFragment.java
index 382b1a6..2c306a7 100644
--- a/src/org/sflphone/fragments/CallFragment.java
+++ b/src/org/sflphone/fragments/CallFragment.java
@@ -73,7 +73,6 @@
public static final int REQUEST_TRANSFER = 10;
-
private TextView callStatusTxt;
private ToggleButton speakers;
@@ -96,7 +95,7 @@
@Override
public void onReceive(Context context, Intent intent) {
WifiInfo info = wifiManager.getConnectionInfo();
- Log.i(TAG, "Level of wifi " +info.getRssi());
+ Log.i(TAG, "Level of wifi " + info.getRssi());
}
};
@@ -121,14 +120,14 @@
}
}
- private void initializeWiFiListener(){
+ private void initializeWiFiListener() {
Log.i(TAG, "executing initializeWiFiListener");
String connectivity_context = Context.WIFI_SERVICE;
wifiManager = (WifiManager) getActivity().getSystemService(connectivity_context);
- if(!wifiManager.isWifiEnabled()){
- if(wifiManager.getWifiState() != WifiManager.WIFI_STATE_ENABLING){
+ if (!wifiManager.isWifiEnabled()) {
+ if (wifiManager.getWifiState() != WifiManager.WIFI_STATE_ENABLING) {
wifiManager.setWifiEnabled(true);
}
}
@@ -156,17 +155,21 @@
}
@Override
+ public void updateDisplayedConference(Conference c) {
+ }
+
+ @Override
public void startTimer() {
}
@Override
public void slideChatScreen() {
}
+
};
/**
* The Activity calling this fragment has to implement this interface
- *
*/
public interface Callbacks {
@@ -179,6 +182,8 @@
public void terminateCall();
public Conference getDisplayedConference();
+
+ public void updateDisplayedConference(Conference c);
}
@Override
@@ -206,9 +211,9 @@
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
switch (item.getItemId()) {
- case R.id.menuitem_chat:
- mCallbacks.slideChatScreen();
- break;
+ case R.id.menuitem_chat:
+ mCallbacks.slideChatScreen();
+ break;
}
return true;
@@ -242,43 +247,63 @@
}
@Override
- public void callStateChanged(String callID, String state) {
- changeCallState(callID, state);
+ public void callStateChanged(Conference updated, String callID, String newState) {
+ mCallbacks.updateDisplayedConference(updated);
+ Log.i(TAG, "Call :" + callID + " " + newState);
+
+ if (getConference().isOnGoing()) {
+ initNormalStateDisplay();
+ } else if (getConference().isRinging()) {
+ callStatusTxt.setText(newState);
+
+ if (getConference().isIncoming()) {
+ initIncomingCallDisplay();
+ } else
+ initOutGoingCallDisplay();
+ } else {
+ callStatusTxt.setText(newState);
+ mCallbacks.terminateCall();
+ }
}
@Override
- public void recordingChanged(String callID, String filename) {
-
- }
-
- @Override
- public void secureZrtpOn(String id) {
+ public void secureZrtpOn(Conference updated, String id) {
Log.i(TAG, "secureZrtpOn");
+ mCallbacks.updateDisplayedConference(updated);
//enableSASButton();
}
@Override
- public void secureZrtpOff(String id) {
+ public void secureZrtpOff(Conference updated, String id) {
Log.i(TAG, "secureZrtpOff");
+ mCallbacks.updateDisplayedConference(updated);
}
@Override
- public void displaySAS(final String callID, String SAS, boolean verified) {
+ public void displaySAS(Conference updated, final String securedCallID) {
Log.i(TAG, "displaySAS");
- final Button sas = (Button) getView().findViewById(R.id.confirm_sas);
- sas.setText("Confirm SAS: " + SAS);
- sas.setVisibility(View.VISIBLE);
- sas.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- try {
- mCallbacks.getService().confirmSAS(callID);
- sas.setVisibility(View.INVISIBLE);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
+ mCallbacks.updateDisplayedConference(updated);
+ SecureSipCall display = (SecureSipCall) getConference().getCallById(securedCallID);
+
+ if (display != null) {
+ if (!display.isConfirmedSAS()) {
+ final Button sas = (Button) getView().findViewById(R.id.confirm_sas);
+ sas.setText("Confirm SAS: " + display.getSAS());
+ sas.setVisibility(View.VISIBLE);
+ sas.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ try {
+ mCallbacks.getService().confirmSAS(securedCallID);
+ sas.setVisibility(View.INVISIBLE);
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ }
+ });
}
- });
+ }
+
}
@Override
@@ -287,33 +312,33 @@
SipCall transfer;
if (requestCode == REQUEST_TRANSFER) {
switch (resultCode) {
- case TransferDFragment.RESULT_TRANSFER_CONF:
- Conference c = data.getParcelableExtra("target");
- transfer = data.getParcelableExtra("transfer");
- try {
+ case TransferDFragment.RESULT_TRANSFER_CONF:
+ Conference c = data.getParcelableExtra("target");
+ transfer = data.getParcelableExtra("transfer");
+ try {
- mCallbacks.getService().attendedTransfer(transfer.getCallId(), c.getParticipants().get(0).getCallId());
+ mCallbacks.getService().attendedTransfer(transfer.getCallId(), c.getParticipants().get(0).getCallId());
- } catch (RemoteException e) {
- e.printStackTrace();
- }
- break;
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ break;
- case TransferDFragment.RESULT_TRANSFER_NUMBER:
- String to = data.getStringExtra("to_number");
- transfer = data.getParcelableExtra("transfer");
- try {
- mCallbacks.getService().transfer(transfer.getCallId(), to);
- mCallbacks.getService().hangUp(transfer.getCallId());
- } catch (RemoteException e) {
- e.printStackTrace();
- }
- break;
- case Activity.RESULT_CANCELED:
- default:
- model.clear();
- initNormalStateDisplay();
- break;
+ case TransferDFragment.RESULT_TRANSFER_NUMBER:
+ String to = data.getStringExtra("to_number");
+ transfer = data.getParcelableExtra("transfer");
+ try {
+ mCallbacks.getService().transfer(transfer.getCallId(), to);
+ mCallbacks.getService().hangUp(transfer.getCallId());
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ break;
+ case Activity.RESULT_CANCELED:
+ default:
+ model.clear();
+ initNormalStateDisplay();
+ break;
}
}
}
@@ -357,7 +382,7 @@
return rootView;
}
- public Conference getConference(){
+ public Conference getConference() {
return mCallbacks.getDisplayedConference();
}
@@ -387,8 +412,6 @@
private void initIncomingCallDisplay() {
Log.i(TAG, "Start incoming display");
- mCallbacks.startTimer();
-
int radiusCalls = (int) (model.width / 2 - BUBBLE_SIZE);
getBubbleForUser(getConference(), model.width / 2, model.height / 2 + radiusCalls);
getBubbleFor(getConference().getParticipants().get(0), model.width / 2, model.height / 2 - radiusCalls);
@@ -397,7 +420,6 @@
model.addAttractor(new Attractor(new PointF(model.width / 2, model.height / 2), ATTRACTOR_SIZE, new Attractor.Callback() {
@Override
public boolean onBubbleSucked(Bubble b) {
-
if (!accepted) {
try {
mCallbacks.getService().accept(b.getCallID());
@@ -422,8 +444,6 @@
private void initOutGoingCallDisplay() {
Log.i(TAG, "Start outgoing display");
- mCallbacks.startTimer();
-
getBubbleForUser(getConference(), model.width / 2, model.height / 2);
// TODO off-thread image loading
@@ -441,13 +461,10 @@
/**
* Retrieves or create a bubble for a given contact. If the bubble exists, it is moved to the new location.
- *
- * @param call
- * The call associated to a contact
- * @param x
- * Initial or new x position.
- * @param y
- * Initial or new y position.
+ *
+ * @param call The call associated to a contact
+ * @param x Initial or new x position.
+ * @param y Initial or new y position.
* @return Bubble corresponding to the contact.
*/
private Bubble getBubbleFor(SipCall call, float x, float y) {
@@ -487,39 +504,6 @@
return contact_bubble;
}
- public void changeCallState(String callID, String newState) {
- Log.i(TAG, "Call :" + callID + " " + newState);
- if (newState.contentEquals("FAILURE")) {
- try {
- mCallbacks.getService().hangUp(callID);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
- }
- if (getConference() == null) {
- return;
- }
- for (int i = 0; i < getConference().getParticipants().size(); ++i) {
- if (callID.equals(getConference().getParticipants().get(i).getCallId())) {
- if (newState.contentEquals("HUNGUP")) {
- model.removeBubble(getConference().getParticipants().get(i));
- getConference().getParticipants().remove(i);
- } else {
- getConference().getParticipants().get(i).setCallState(newState);
- }
- }
- }
-
- if (getConference().isOnGoing()) {
- initNormalStateDisplay();
- }
-
- if (getConference().getParticipants().size() == 0) {
- callStatusTxt.setText(newState);
- mCallbacks.terminateCall();
- }
- }
-
public boolean draggingBubble() {
return view == null ? false : view.isDraggingBubble();
}
@@ -530,23 +514,9 @@
if (getConference().getParticipants().size() == 1) {
if (getConference().getParticipants().get(0).isIncoming() && getConference().getParticipants().get(0).isRinging()) {
initIncomingCallDisplay();
- } else {
- if (getConference().getParticipants().get(0).isRinging()) {
- initOutGoingCallDisplay();
- }
- try {
- if (getConference().getParticipants().get(0).isOutGoing()
- && mCallbacks.getService().getConference(getConference().getId()) == null) {
- mCallbacks.getService().placeCall(getConference().getParticipants().get(0));
- initOutGoingCallDisplay();
- } else if (getConference().getParticipants().get(0).isOutGoing() && getConference().getParticipants().get(0).isRinging()) {
- initOutGoingCallDisplay();
- }
- } catch (RemoteException e) {
- Log.e(TAG, e.toString());
- }
- }
- if (getConference().getParticipants().get(0).isOngoing()) {
+ } else if (getConference().getParticipants().get(0).isRinging()) {
+ initOutGoingCallDisplay();
+ } else if (getConference().getParticipants().get(0).isOngoing()) {
initNormalStateDisplay();
}
} else if (getConference().getParticipants().size() > 1) {
@@ -590,24 +560,28 @@
}
public void updateTime() {
- long duration = System.currentTimeMillis() / 1000 - this.getConference().getParticipants().get(0).getTimestampStart_();
- if (getConference().isOnGoing())
- callStatusTxt.setText(String.format("%d:%02d:%02d", duration / 3600, duration % 3600 / 60, duration % 60));
+ if (getConference() != null) {
+ long duration = System.currentTimeMillis() - getConference().getParticipants().get(0).getTimestampStart_();
+ duration = duration / 1000;
+ if (getConference().isOnGoing())
+ callStatusTxt.setText(String.format("%d:%02d:%02d", duration / 3600, duration % 3600 / 60, duration % 60));
+ }
+
}
public void onKeyUp(int keyCode, KeyEvent event) {
try {
switch (keyCode) {
- case KeyEvent.KEYCODE_VOLUME_DOWN:
- case KeyEvent.KEYCODE_VOLUME_UP:
- break;
- default:
- String toSend = Character.toString(event.getDisplayLabel());
- toSend.toUpperCase(Locale.getDefault());
- Log.d(TAG, "toSend " + toSend);
- mCallbacks.getService().playDtmf(toSend);
- break;
+ case KeyEvent.KEYCODE_VOLUME_DOWN:
+ case KeyEvent.KEYCODE_VOLUME_UP:
+ break;
+ default:
+ String toSend = Character.toString(event.getDisplayLabel());
+ toSend.toUpperCase(Locale.getDefault());
+ Log.d(TAG, "toSend " + toSend);
+ mCallbacks.getService().playDtmf(toSend);
+ break;
}
} catch (RemoteException e) {
e.printStackTrace();
diff --git a/src/org/sflphone/fragments/CallListFragment.java b/src/org/sflphone/fragments/CallListFragment.java
index 82b357b..9934401 100644
--- a/src/org/sflphone/fragments/CallListFragment.java
+++ b/src/org/sflphone/fragments/CallListFragment.java
@@ -83,31 +83,31 @@
};
@Override
- public void callStateChanged(String callID, String state) {
+ public void callStateChanged(Conference c, String callID, String state) {
Log.i(TAG, "callStateChanged" + callID + " " + state);
updateLists();
}
@Override
- public void confCreated(String id) {
+ public void confCreated(Conference c, String id) {
Log.i(TAG, "confCreated");
updateLists();
}
@Override
- public void confRemoved(String id) {
+ public void confRemoved(Conference c, String id) {
Log.i(TAG, "confRemoved");
updateLists();
}
@Override
- public void confChanged(String id, String state) {
+ public void confChanged(Conference c, String id, String state) {
Log.i(TAG, "confChanged");
updateLists();
}
@Override
- public void recordingChanged(String callID, String filename) {
+ public void recordingChanged(Conference c, String callID, String filename) {
Log.i(TAG, "confChanged");
updateLists();
}
@@ -281,7 +281,7 @@
Conference call = calls.get(position);
if (call.getParticipants().size() == 1) {
- ((TextView) convertView.findViewById(R.id.call_title)).setText(call.getParticipants().get(0).getContact().getmDisplayName());
+ ((TextView) convertView.findViewById(R.id.call_title)).setText(call.getParticipants().get(0).getmContact().getmDisplayName());
long duration = System.currentTimeMillis() / 1000 - (call.getParticipants().get(0).getTimestampStart_());
@@ -389,7 +389,7 @@
String to = data.getStringExtra("to_number");
transfer = data.getParcelableExtra("transfer");
try {
- Toast.makeText(getActivity(), getString(R.string.home_transfering, transfer.getParticipants().get(0).getContact().getmDisplayName(), to),
+ Toast.makeText(getActivity(), getString(R.string.home_transfering, transfer.getParticipants().get(0).getmContact().getmDisplayName(), to),
Toast.LENGTH_SHORT).show();
mCallbacks.getService().transfer(transfer.getParticipants().get(0).getCallId(), to);
mCallbacks.getService().hangUp(transfer.getParticipants().get(0).getCallId());
diff --git a/src/org/sflphone/fragments/CallableWrapperFragment.java b/src/org/sflphone/fragments/CallableWrapperFragment.java
index e85f94f..0dc3c73 100644
--- a/src/org/sflphone/fragments/CallableWrapperFragment.java
+++ b/src/org/sflphone/fragments/CallableWrapperFragment.java
@@ -1,3 +1,34 @@
+/*
+ * Copyright (C) 2004-2014 Savoir-Faire Linux Inc.
+ *
+ * Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Additional permission under GNU GPL version 3 section 7:
+ *
+ * If you modify this program, or any covered work, by linking or
+ * combining it with the OpenSSL project's OpenSSL library (or a
+ * modified version of that library), containing parts covered by the
+ * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
+ * grants you additional permission to convey the resulting work.
+ * Corresponding Source for a non-source form of such a combination
+ * shall include the source code for the parts of OpenSSL used as well
+ * as that of the covered work.
+ */
+
package org.sflphone.fragments;
import android.content.BroadcastReceiver;
@@ -8,11 +39,10 @@
import android.support.v4.app.Fragment;
import android.util.Log;
import org.sflphone.interfaces.CallInterface;
+import org.sflphone.model.Conference;
+import org.sflphone.model.SipCall;
import org.sflphone.service.CallManagerCallBack;
-/**
- * Created by lisional on 10/02/14.
- */
public abstract class CallableWrapperFragment extends Fragment implements CallInterface {
@@ -50,47 +80,47 @@
}
@Override
- public void callStateChanged(String callID, String state) {
+ public void callStateChanged(Conference c, String callID, String state) {
}
@Override
- public void incomingText(String ID, String from, String msg) {
+ public void incomingText(Conference c, String ID, String from, String msg) {
}
@Override
- public void confCreated(String id) {
+ public void confCreated(Conference c, String id) {
}
@Override
- public void confRemoved(String id) {
+ public void confRemoved(Conference c, String id) {
}
@Override
- public void confChanged(String id, String state) {
+ public void confChanged(Conference c, String id, String state) {
}
@Override
- public void recordingChanged(String callID, String filename) {
+ public void recordingChanged(Conference c, String callID, String filename) {
}
@Override
- public void secureZrtpOn(String id) {
+ public void secureZrtpOn(Conference c, String id) {
}
@Override
- public void secureZrtpOff(String id) {
+ public void secureZrtpOff(Conference c, String id) {
}
@Override
- public void displaySAS(String callID, String SAS, boolean verified) {
+ public void displaySAS(Conference c, String securedCallID) {
}
@@ -101,23 +131,23 @@
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().contentEquals(CallManagerCallBack.INCOMING_TEXT)) {
- incomingText(intent.getStringExtra("CallID"), intent.getStringExtra("From"), intent.getStringExtra("Msg"));
+ incomingText((Conference) intent.getParcelableExtra("conference"), intent.getStringExtra("CallID"), intent.getStringExtra("From"), intent.getStringExtra("Msg"));
} else if (intent.getAction().contentEquals(CallManagerCallBack.CALL_STATE_CHANGED)) {
- callStateChanged(intent.getStringExtra("CallID"), intent.getStringExtra("State"));
+ callStateChanged((Conference) intent.getParcelableExtra("conference"), intent.getStringExtra("CallID"), intent.getStringExtra("State"));
} else if (intent.getAction().contentEquals(CallManagerCallBack.CONF_CREATED)) {
- confCreated(intent.getStringExtra("confID"));
+ confCreated((Conference) intent.getParcelableExtra("conference"), intent.getStringExtra("confID"));
} else if (intent.getAction().contentEquals(CallManagerCallBack.CONF_REMOVED)) {
- confRemoved(intent.getStringExtra("confID"));
+ confRemoved((Conference) intent.getParcelableExtra("conference"), intent.getStringExtra("confID"));
} else if (intent.getAction().contentEquals(CallManagerCallBack.CONF_CHANGED)) {
- confChanged(intent.getStringExtra("confID"), intent.getStringExtra("state"));
+ confChanged((Conference) intent.getParcelableExtra("conference"), intent.getStringExtra("confID"), intent.getStringExtra("state"));
} else if (intent.getAction().contentEquals(CallManagerCallBack.RECORD_STATE_CHANGED)) {
- recordingChanged(intent.getStringExtra("callID"), intent.getStringExtra("file"));
+ recordingChanged((Conference) intent.getParcelableExtra("conference"), intent.getStringExtra("callID"), intent.getStringExtra("file"));
} else if (intent.getAction().contentEquals(CallManagerCallBack.ZRTP_OFF)) {
- secureZrtpOff(intent.getStringExtra("callID"));
+ secureZrtpOff((Conference) intent.getParcelableExtra("conference"), intent.getStringExtra("callID"));
} else if (intent.getAction().contentEquals(CallManagerCallBack.ZRTP_ON)) {
- secureZrtpOn(intent.getStringExtra("callID"));
+ secureZrtpOn((Conference) intent.getParcelableExtra("conference"), intent.getStringExtra("callID"));
} else if (intent.getAction().contentEquals(CallManagerCallBack.DISPLAY_SAS)) {
- displaySAS(intent.getStringExtra("callID"), intent.getStringExtra("SAS"), intent.getBooleanExtra("verified", false));
+ displaySAS((Conference) intent.getParcelableExtra("conference"), intent.getStringExtra("callID"));
} else {
Log.e(TAG, "Unknown action: " + intent.getAction());
}
diff --git a/src/org/sflphone/fragments/ConferenceDFragment.java b/src/org/sflphone/fragments/ConferenceDFragment.java
index c7ebb17..a889ccd 100644
--- a/src/org/sflphone/fragments/ConferenceDFragment.java
+++ b/src/org/sflphone/fragments/ConferenceDFragment.java
@@ -75,7 +75,7 @@
- final AlertDialog a = new AlertDialog.Builder(getActivity()).setView(rootView).setTitle("Transfer " + call_selected.getParticipants().get(0).getContact())
+ final AlertDialog a = new AlertDialog.Builder(getActivity()).setView(rootView).setTitle("Transfer " + call_selected.getParticipants().get(0).getmContact())
.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
@@ -136,7 +136,7 @@
}
if(calls.get(position).getParticipants().size() == 1){
- tv.setText(calls.get(position).getParticipants().get(0).getContact().getmDisplayName());
+ tv.setText(calls.get(position).getParticipants().get(0).getmContact().getmDisplayName());
} else {
tv.setText("Conference with "+ calls.get(position).getParticipants().size() + " participants");
}
diff --git a/src/org/sflphone/fragments/DetailsHistoryEntryFragment.java b/src/org/sflphone/fragments/DetailsHistoryEntryFragment.java
index 06600d3..ded02b2 100644
--- a/src/org/sflphone/fragments/DetailsHistoryEntryFragment.java
+++ b/src/org/sflphone/fragments/DetailsHistoryEntryFragment.java
@@ -54,6 +54,7 @@
import java.util.ArrayList;
import java.util.HashMap;
import java.util.NavigableMap;
+import java.util.Random;
public class DetailsHistoryEntryFragment extends Fragment {
@@ -135,23 +136,20 @@
@Override
public void onClick(View v) {
try {
- SipCall.SipCallBuilder callBuilder = SipCall.SipCallBuilder.getInstance();
-
HashMap<String, String> details = (HashMap<String, String>) mCallbacks.getService().getAccountDetails(toDisplay.getAccountID());
ArrayList<HashMap<String, String>> creds = (ArrayList<HashMap<String, String>>) mCallbacks.getService().getCredentials(toDisplay.getAccountID());
+ Bundle args = new Bundle();
+ args.putString(SipCall.ID, Integer.toString(Math.abs(new Random().nextInt())));
+ args.putParcelable(SipCall.ACCOUNT, new Account(toDisplay.getAccountID(), details, creds));
+ args.putInt(SipCall.STATE, SipCall.state.CALL_STATE_RINGING);
+ args.putInt(SipCall.TYPE, SipCall.direction.CALL_TYPE_OUTGOING);
+ args.putParcelable(SipCall.CONTACT, toDisplay.getContact());
- callBuilder.startCallCreation().setAccount(new Account(toDisplay.getAccountID(), details, creds))
- .setCallType(SipCall.direction.CALL_TYPE_OUTGOING);
- callBuilder.setContact(toDisplay.getContact());
-
- mCallbacks.onCall(callBuilder.build());
+ mCallbacks.onCall(new SipCall(args));
} catch (RemoteException e) {
// TODO Bloc catch généré automatiquement
e.printStackTrace();
- } catch (InvalidObjectException e) {
- // TODO Bloc catch généré automatiquement
- e.printStackTrace();
}
}
});
diff --git a/src/org/sflphone/fragments/IMFragment.java b/src/org/sflphone/fragments/IMFragment.java
index f9e63b8..0c09181 100644
--- a/src/org/sflphone/fragments/IMFragment.java
+++ b/src/org/sflphone/fragments/IMFragment.java
@@ -68,11 +68,13 @@
}
@Override
- public void incomingText(String ID, String from, String msg) {
- if (mCallbacks.getDisplayedConference().getId().contentEquals(ID)) {
+ public void incomingText(Conference updated, String ID, String from, String msg) {
+ mCallbacks.updateDisplayedConference(updated);
+ if(updated.equals(mCallbacks.getDisplayedConference())){
SipMessage sipMsg = new SipMessage(true, msg);
putMessage(sipMsg);
}
+
}
@@ -96,6 +98,11 @@
return false;
}
+ @Override
+ public void updateDisplayedConference(Conference c) {
+
+ }
+
};
/**
@@ -107,6 +114,8 @@
public Conference getDisplayedConference();
public boolean sendIM(SipMessage msg);
+
+ public void updateDisplayedConference(Conference c);
}
@Override
diff --git a/src/org/sflphone/fragments/TransferDFragment.java b/src/org/sflphone/fragments/TransferDFragment.java
index 6c8bee9..b595241 100644
--- a/src/org/sflphone/fragments/TransferDFragment.java
+++ b/src/org/sflphone/fragments/TransferDFragment.java
@@ -124,7 +124,7 @@
mEditText.setAdapter(autoCompleteAdapter);
final AlertDialog a = new AlertDialog.Builder(getActivity()).setView(rootView)
- .setTitle("Transfer " + call_selected.getContact().getmDisplayName())
+ .setTitle("Transfer " + call_selected.getmContact().getmDisplayName())
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int whichButton) {
@@ -281,7 +281,7 @@
tv = (TextView) mInflater.inflate(android.R.layout.simple_dropdown_item_1line, parent, false);
}
- tv.setText(calls.get(position).getParticipants().get(0).getContact().getmDisplayName());
+ tv.setText(calls.get(position).getParticipants().get(0).getmContact().getmDisplayName());
return tv;
}
diff --git a/src/org/sflphone/history/HistoryCall.java b/src/org/sflphone/history/HistoryCall.java
index 972a1c4..52d81a0 100644
--- a/src/org/sflphone/history/HistoryCall.java
+++ b/src/org/sflphone/history/HistoryCall.java
@@ -36,12 +36,10 @@
import android.os.Parcelable;
import com.j256.ormlite.field.DatabaseField;
import org.sflphone.model.SipCall;
-import org.sflphone.service.ServiceConstants;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;
-import java.util.HashMap;
import java.util.Locale;
import java.util.TimeZone;
@@ -78,11 +76,11 @@
call_start = call.getTimestampStart_();
call_end = call.getTimestampEnd_();
accountID = call.getAccount().getAccountID();
- number = call.getContact().getPhones().get(0).getNumber();
+ number = call.getmContact().getPhones().get(0).getNumber();
missed = call.isRinging() && call.isIncoming();
direction = call.getCallType();
recordPath = call.getRecordPath();
- contactID = call.getContact().getId();
+ contactID = call.getmContact().getId();
callID = call.getCallId();
}
diff --git a/src/org/sflphone/history/HistoryManager.java b/src/org/sflphone/history/HistoryManager.java
index bc90274..bb6dd27 100644
--- a/src/org/sflphone/history/HistoryManager.java
+++ b/src/org/sflphone/history/HistoryManager.java
@@ -53,7 +53,7 @@
public boolean insertNewEntry(Conference toInsert){
for (SipCall call : toInsert.getParticipants()) {
- call.setTimestampEnd_(System.currentTimeMillis() * 1000);
+ call.setTimestampEnd_(System.currentTimeMillis());
HistoryCall persistent = new HistoryCall(call);
try {
getHelper().getHistoryDao().create(persistent);
diff --git a/src/org/sflphone/interfaces/CallInterface.java b/src/org/sflphone/interfaces/CallInterface.java
index 3a3fd61..3683da0 100644
--- a/src/org/sflphone/interfaces/CallInterface.java
+++ b/src/org/sflphone/interfaces/CallInterface.java
@@ -31,25 +31,27 @@
package org.sflphone.interfaces;
+import org.sflphone.model.Conference;
+
public interface CallInterface {
- public void callStateChanged(String callID, String state);
+ public void callStateChanged(Conference c, String callID, String state);
- public void incomingText(String ID, String from, String msg);
+ public void incomingText(Conference c, String ID, String from, String msg);
- public void confCreated(String id);
+ public void confCreated(Conference c, String id);
- public void confRemoved(String id);
+ public void confRemoved(Conference c, String id);
- public void confChanged(String id, String state);
+ public void confChanged(Conference c, String id, String state);
- public void recordingChanged(String callID, String filename);
+ public void recordingChanged(Conference c, String callID, String filename);
- public void secureZrtpOn(String id);
+ public void secureZrtpOn(Conference c, String id);
- public void secureZrtpOff(String id);
+ public void secureZrtpOff(Conference c, String id);
- public void displaySAS(String callID, String SAS, boolean verified);
+ public void displaySAS(Conference c, String securedCallID);
}
diff --git a/src/org/sflphone/model/BubbleContact.java b/src/org/sflphone/model/BubbleContact.java
index 8e2f0d3..3ad500d 100644
--- a/src/org/sflphone/model/BubbleContact.java
+++ b/src/org/sflphone/model/BubbleContact.java
@@ -57,7 +57,7 @@
}
public BubbleContact(Context context, SipCall call, float x, float y, float size) {
- super(context, call.getContact(), x, y, size);
+ super(context, call.getmContact(), x, y, size);
associated_call = call;
buttonMsg = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ic_action_chat);
@@ -379,7 +379,7 @@
@Override
public String getName() {
- return associated_call.getContact().getmDisplayName();
+ return associated_call.getmContact().getmDisplayName();
}
@Override
diff --git a/src/org/sflphone/model/BubblesView.java b/src/org/sflphone/model/BubblesView.java
index 0ed2e20..ca44ee3 100644
--- a/src/org/sflphone/model/BubblesView.java
+++ b/src/org/sflphone/model/BubblesView.java
@@ -302,7 +302,7 @@
canvas.drawBitmap(first_plan.getDrawerBitmap(), null, first_plan.getDrawerBounds(), null);
}
canvas.drawBitmap(first_plan.getBitmap(), null, first_plan.getBounds(), null);
- // canvas.drawText(first_plan.associated_call.getContact().getmDisplayName(), first_plan.getPosX(),
+ // canvas.drawText(first_plan.associated_call.getmContact().getmDisplayName(), first_plan.getPosX(),
// (float) (first_plan.getPosY() - first_plan.getRetractedRadius() * 1.2 * density), getNamePaint(first_plan));
}
diff --git a/src/org/sflphone/model/SipCall.java b/src/org/sflphone/model/SipCall.java
index 1a9c297..10548ce 100644
--- a/src/org/sflphone/model/SipCall.java
+++ b/src/org/sflphone/model/SipCall.java
@@ -31,20 +31,24 @@
*/
package org.sflphone.model;
-import java.io.InvalidObjectException;
-import java.util.Random;
-
+import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
public class SipCall implements Parcelable {
+ public static String ID = "id";
+ public static String ACCOUNT = "account";
+ public static String CONTACT = "contcat";
+ public static String TYPE = "type";
+ public static String STATE = "state";
+
private static final String TAG = SipCall.class.getSimpleName();
private String mCallID = "";
private Account mAccount = null;
- private CallContact contact = null;
+ private CallContact mContact = null;
private boolean isRecording = false;
private long timestampStart_ = 0;
private long timestampEnd_ = 0;
@@ -52,42 +56,34 @@
private int mCallType;
private int mCallState = state.CALL_STATE_NONE;
- private boolean isSecured;
- private String SAS;
- private boolean confirmedSAS;
-
public boolean isSecured() {
- return isSecured;
+ return false;
}
-
/**
* *********************
* Construtors
* *********************
*/
- private SipCall(Parcel in) {
+ protected SipCall(Parcel in) {
mCallID = in.readString();
mAccount = in.readParcelable(Account.class.getClassLoader());
- contact = in.readParcelable(CallContact.class.getClassLoader());
+ mContact = in.readParcelable(CallContact.class.getClassLoader());
isRecording = in.readByte() == 1;
mCallType = in.readInt();
mCallState = in.readInt();
timestampStart_ = in.readLong();
timestampEnd_ = in.readLong();
- SAS = in.readString();
- confirmedSAS = in.readByte() == 1;
- isSecured = in.readByte() == 1;
}
- private SipCall(String id, Account account, int call_type, int call_state, CallContact c) {
- mCallID = id;
- mAccount = account;
- mCallType = call_type;
- mCallState = call_state;
- contact = c;
+ public SipCall(Bundle args) {
+ mCallID = args.getString(ID);
+ mAccount = args.getParcelable(ACCOUNT);
+ mCallType = args.getInt(TYPE);
+ mCallState = args.getInt(STATE);
+ mContact = args.getParcelable(CONTACT);
}
public long getTimestampEnd_() {
@@ -102,10 +98,17 @@
return mCallType;
}
- public void setSecured(boolean secured) {
- isSecured = secured;
+ public Bundle getBundle() {
+ Bundle args = new Bundle();
+ args.putString(SipCall.ID, mCallID);
+ args.putParcelable(SipCall.ACCOUNT, mAccount);
+ args.putInt(SipCall.STATE, mCallState);
+ args.putInt(SipCall.TYPE, mCallType);
+ args.putParcelable(SipCall.CONTACT, mContact);
+ return args;
}
+
public interface direction {
public static final int CALL_TYPE_INCOMING = 1;
public static final int CALL_TYPE_OUTGOING = 2;
@@ -133,15 +136,12 @@
out.writeString(mCallID);
out.writeParcelable(mAccount, 0);
- out.writeParcelable(contact, 0);
+ out.writeParcelable(mContact, 0);
out.writeByte((byte) (isRecording ? 1 : 0));
out.writeInt(mCallType);
out.writeInt(mCallState);
out.writeLong(timestampStart_);
out.writeLong(timestampEnd_);
- out.writeString(SAS);
- out.writeByte((byte) (confirmedSAS ? 1 : 0));
- out.writeByte((byte) (isSecured ? 1 : 0));
}
public static final Parcelable.Creator<SipCall> CREATOR = new Parcelable.Creator<SipCall>() {
@@ -197,12 +197,12 @@
mCallState = callState;
}
- public CallContact getContact() {
- return contact;
+ public CallContact getmContact() {
+ return mContact;
}
- public void setContact(CallContact contacts) {
- contact = contacts;
+ public void setmContact(CallContact contacts) {
+ mContact = contacts;
}
public String getCallStateString() {
@@ -246,59 +246,6 @@
this.isRecording = isRecording;
}
- public static class SipCallBuilder {
-
- private String bCallID = "";
- private Account bAccount = null;
- private CallContact bContact = null;
-
- private int bCallType;
- private int bCallState = state.CALL_STATE_NONE;
-
- public SipCallBuilder setCallType(int bCallType) {
- this.bCallType = bCallType;
- return this;
- }
-
- public SipCallBuilder setCallState(int state) {
- this.bCallState = state;
- return this;
- }
-
- public SipCallBuilder startCallCreation(String id) {
- bCallID = id;
- bCallType = direction.CALL_TYPE_INCOMING;
- return this;
- }
-
- public SipCallBuilder startCallCreation() {
- Random random = new Random();
- bCallID = Integer.toString(Math.abs(random.nextInt()));
- return this;
- }
-
- public SipCallBuilder setAccount(Account a) {
- bAccount = a;
- return this;
- }
-
- public SipCallBuilder setContact(CallContact c) {
- bContact = c;
- return this;
- }
-
- public SipCall build() throws InvalidObjectException {
- if (bCallID.contentEquals("") || bAccount == null || bContact == null) {
- throw new InvalidObjectException("SipCallBuilder's parameters missing");
- }
- return new SipCall(bCallID, bAccount, bCallType, bCallState, bContact);
- }
-
- public static SipCallBuilder getInstance() {
- return new SipCallBuilder();
- }
- }
-
public void printCallInfo() {
Log.i(TAG, "CallInfo: CallID: " + mCallID);
Log.i(TAG, " AccountID: " + mAccount.getAccountID());
@@ -375,19 +322,5 @@
return mCallState == state.CALL_STATE_CURRENT;
}
- public boolean isConfirmedSAS() {
- return confirmedSAS;
- }
- public void setConfirmedSAS(boolean confirmedSAS) {
- this.confirmedSAS = confirmedSAS;
- }
-
- public String getSAS() {
- return SAS;
- }
-
- public void setSAS(String SAS) {
- this.SAS = SAS;
- }
}
diff --git a/src/org/sflphone/service/CallManagerCallBack.java b/src/org/sflphone/service/CallManagerCallBack.java
index 97e1fab..45d709f 100644
--- a/src/org/sflphone/service/CallManagerCallBack.java
+++ b/src/org/sflphone/service/CallManagerCallBack.java
@@ -3,11 +3,13 @@
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
+import org.sflphone.account.AccountDetailSrtp;
import org.sflphone.client.CallActivity;
import org.sflphone.model.*;
import org.sflphone.utils.SwigNativeConverter;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
@@ -39,128 +41,102 @@
public void on_call_state_changed(String callID, String newState) {
Log.d(TAG, "on_call_state_changed : (" + callID + ", " + newState + ")");
+ Conference toUpdate = findConference(callID);
+
+ if (toUpdate == null) {
+ return;
+ }
+
Intent intent = new Intent(CALL_STATE_CHANGED);
intent.putExtra("CallID", callID);
intent.putExtra("State", newState);
+
if (newState.equals("RINGING")) {
- try {
- mService.getConferences().get(callID).setCallState(callID, SipCall.state.CALL_STATE_RINGING);
- } catch (NullPointerException e) {
- if (mService.getConferences() == null) {
- return;
- }
- if (mService.getConferences().get(callID) == null) {
- Log.e(TAG, "call for " + callID + " is null");
- return;
- }
- }
-
+ toUpdate.setCallState(callID, SipCall.state.CALL_STATE_RINGING);
} else if (newState.equals("CURRENT")) {
- if (mService.getConferences().get(callID) != null) {
- mService.getConferences().get(callID).setCallState(callID, SipCall.state.CALL_STATE_CURRENT);
- } else {
- // Check if call is in a conference
- Iterator<Map.Entry<String, Conference>> it = mService.getConferences().entrySet().iterator();
- while (it.hasNext()) {
- Conference tmp = it.next().getValue();
- for (SipCall c : tmp.getParticipants()) {
- if (c.getCallId().contentEquals(callID))
- c.setCallState(SipCall.state.CALL_STATE_CURRENT);
- }
- }
+ if(toUpdate.isRinging()){
+ toUpdate.getCallById(callID).setTimestampStart_(System.currentTimeMillis());
}
-
+ toUpdate.setCallState(callID, SipCall.state.CALL_STATE_CURRENT);
} else if (newState.equals("HUNGUP")) {
Log.d(TAG, "Hanging up " + callID);
- if (mService.getConferences().get(callID) != null) {
- if (mService.getConferences().get(callID).isRinging()
- && mService.getConferences().get(callID).isIncoming())
+ SipCall call = toUpdate.getCallById(callID);
+ if (!toUpdate.hasMultipleParticipants()) {
+ if (toUpdate.isRinging() && toUpdate.isIncoming()) {
mService.mNotificationManager.publishMissedCallNotification(mService.getConferences().get(callID));
-
- mService.mHistoryManager.insertNewEntry(mService.getConferences().get(callID));
- mService.getConferences().remove(callID);
- } else {
-
- Iterator<Map.Entry<String, Conference>> it = mService.getConferences().entrySet().iterator();
- while (it.hasNext()) {
- Conference tmp = it.next().getValue();
- for (SipCall c : tmp.getParticipants()) {
- if (c.getCallId().contentEquals(callID)) {
- mService.mHistoryManager.insertNewEntry(c);
- mService.getConferences().get(tmp.getId()).removeParticipant(c);
- break;
- }
- }
}
+ toUpdate.setCallState(callID, SipCall.state.CALL_STATE_HUNGUP);
+ mService.mHistoryManager.insertNewEntry(toUpdate);
+ mService.getConferences().remove(toUpdate.getId());
+ Log.e(TAG, "Conferences :"+ mService.getConferences().size());
+ Log.e(TAG, "toUpdate.getParticipants() :"+ toUpdate.getParticipants().size());
+ } else {
+ toUpdate.setCallState(callID, SipCall.state.CALL_STATE_HUNGUP);
+ mService.mHistoryManager.insertNewEntry(call);
}
-
} else if (newState.equals("BUSY")) {
- mService.getConferences().remove(callID);
+ toUpdate.setCallState(callID, SipCall.state.CALL_STATE_BUSY);
+ mService.getConferences().remove(toUpdate.getId());
} else if (newState.equals("FAILURE")) {
- mService.getConferences().remove(callID);
+ toUpdate.setCallState(callID, SipCall.state.CALL_STATE_FAILURE);
+ mService.getConferences().remove(toUpdate.getId());
} else if (newState.equals("HOLD")) {
- if (mService.getConferences().get(callID) != null) {
- mService.getConferences().get(callID).setCallState(callID, SipCall.state.CALL_STATE_HOLD);
- } else {
- // Check if call is in a conference
- Iterator<Map.Entry<String, Conference>> it = mService.getConferences().entrySet().iterator();
- while (it.hasNext()) {
- Conference tmp = it.next().getValue();
- for (SipCall c : tmp.getParticipants()) {
- if (c.getCallId().contentEquals(callID))
- c.setCallState(SipCall.state.CALL_STATE_HOLD);
- }
- }
- }
+ toUpdate.setCallState(callID, SipCall.state.CALL_STATE_HOLD);
} else if (newState.equals("UNHOLD")) {
+ toUpdate.setCallState(callID, SipCall.state.CALL_STATE_CURRENT);
+ }
+ intent.putExtra("conference", toUpdate);
+ mService.sendBroadcast(intent);
+ }
- if (mService.getConferences().get(callID) != null) {
- mService.getConferences().get(callID).setCallState(callID, SipCall.state.CALL_STATE_CURRENT);
- } else {
- // Check if call is in a conference
- Iterator<Map.Entry<String, Conference>> it = mService.getConferences().entrySet().iterator();
- while (it.hasNext()) {
- Conference tmp = it.next().getValue();
- for (SipCall c : tmp.getParticipants()) {
- if (c.getCallId().contentEquals(callID))
- c.setCallState(SipCall.state.CALL_STATE_CURRENT);
+ private Conference findConference(String callID) {
+ Conference result = null;
+ if (mService.getConferences().get(callID) != null) {
+ result = mService.getConferences().get(callID);
+ } else {
+ Iterator<Map.Entry<String, Conference>> it = mService.getConferences().entrySet().iterator();
+ while (it.hasNext()) {
+ Conference tmp = it.next().getValue();
+ for (SipCall c : tmp.getParticipants()) {
+ if (c.getCallId().contentEquals(callID)) {
+ result = tmp;
}
}
}
- } else {
- mService.getConferences().get(callID).setCallState(callID, SipCall.state.CALL_STATE_NONE);
}
- mService.sendBroadcast(intent);
+ return result;
}
@Override
public void on_incoming_call(String accountID, String callID, String from) {
Log.d(TAG, "on_incoming_call(" + accountID + ", " + callID + ", " + from + ")");
- SipCall.SipCallBuilder callBuilder = SipCall.SipCallBuilder.getInstance();
try {
StringMap details = mService.getConfigurationManagerJNI().getAccountDetails(accountID);
VectMap credentials = mService.getConfigurationManagerJNI().getCredentials(accountID);
Account acc = new Account(accountID, SwigNativeConverter.convertAccountToNative(details), SwigNativeConverter.convertCredentialsToNative(credentials));
- callBuilder.startCallCreation(callID).setAccount(acc).setCallState(SipCall.state.CALL_STATE_RINGING)
- .setCallType(SipCall.direction.CALL_TYPE_INCOMING);
- callBuilder.setContact(CallContact.ContactBuilder.buildUnknownContact(from));
+
+ Bundle args = new Bundle();
+ args.putString(SipCall.ID, callID);
+ args.putParcelable(SipCall.ACCOUNT, acc);
+ args.putInt(SipCall.STATE, SipCall.state.CALL_STATE_RINGING);
+ args.putInt(SipCall.TYPE, SipCall.direction.CALL_TYPE_INCOMING);
+
+ CallContact unknow = CallContact.ContactBuilder.buildUnknownContact(from);
+ args.putParcelable(SipCall.CONTACT, unknow);
Intent toSend = new Intent(CallManagerCallBack.INCOMING_CALL);
toSend.setClass(mService, CallActivity.class);
toSend.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- SipCall newCall = callBuilder.build();
- StringMap callDetails = mService.getCallManagerJNI().getCallDetails(callID);
+ SipCall newCall = new SipCall(args);
- newCall.setTimestampStart_(Long.parseLong(callDetails.get(ServiceConstants.call.TIMESTAMP_START)));
+ newCall.setTimestampStart_(System.currentTimeMillis());
Conference toAdd = new Conference(newCall);
-
mService.getConferences().put(toAdd.getId(), toAdd);
Bundle bundle = new Bundle();
-
bundle.putParcelable("conference", toAdd);
toSend.putExtra("resuming", false);
toSend.putExtras(bundle);
@@ -202,6 +178,7 @@
}
}
}
+ intent.putExtra("conference", created);
intent.putExtra("confID", created.getId());
mService.getConferences().put(created.getId(), created);
mService.sendBroadcast(intent);
@@ -217,6 +194,7 @@
if (mService.getConferences().get(ID) != null) {
mService.getConferences().get(ID).addSipMessage(new SipMessage(true, msg));
+ intent.putExtra("conference", mService.getConferences().get(ID));
} else {
Iterator<Map.Entry<String, Conference>> it = mService.getConferences().entrySet().iterator();
while (it.hasNext()) {
@@ -224,12 +202,12 @@
for (SipCall c : tmp.getParticipants()) {
if (c.getCallId().contentEquals(ID)) {
mService.getConferences().get(tmp.getId()).addSipMessage(new SipMessage(true, msg));
+ intent.putExtra("conference", tmp);
}
}
}
}
-
mService.sendBroadcast(intent);
}
@@ -243,6 +221,7 @@
for (SipCall call : toReInsert.getParticipants()) {
mService.getConferences().put(call.getCallId(), new Conference(call));
}
+ intent.putExtra("conference", mService.getConferences().get(confID));
mService.getConferences().remove(confID);
mService.sendBroadcast(intent);
@@ -254,12 +233,13 @@
Intent intent = new Intent(CONF_CHANGED);
intent.putExtra("confID", confID);
intent.putExtra("State", state);
- mService.getConferences().get(confID).setCallState(confID, state);
+
Log.i(TAG, "Received:" + intent.getAction());
Log.i(TAG, "State:" + state);
Conference toModify = mService.getConferences().get(confID);
+ toModify.setCallState(confID, state);
ArrayList<String> newParticipants = SwigNativeConverter.convertSwigToNative(mService.getCallManagerJNI().getParticipantList(intent.getStringExtra("confID")));
@@ -275,6 +255,7 @@
for (SipCall participant : toModify.getParticipants()) {
if (!newParticipants.contains(participant.getCallId())) {
mService.detachCallFromConference(toModify.getId(), participant);
+ break;
}
}
}
@@ -304,9 +285,17 @@
public void on_secure_zrtp_on(String callID, String cipher) {
Log.i(TAG, "on_secure_zrtp_on");
SipCall call = mService.getCallById(callID);
- call.setSecured(true);
+ Bundle secureArgs = new Bundle();
+ HashMap<String, String> details = SwigNativeConverter.convertAccountToNative(mService.getConfigurationManagerJNI().getAccountDetails(call.getAccount().getAccountID()));
+ secureArgs.putBoolean(SecureSipCall.DISPLAY_SAS, details.get(AccountDetailSrtp.CONFIG_ZRTP_DISPLAY_SAS).contentEquals("true"));
+ secureArgs.putBoolean(SecureSipCall.DISPLAY_SAS_ONCE, details.get(AccountDetailSrtp.CONFIG_ZRTP_DISPLAY_SAS_ONCE).contentEquals("true"));
+ secureArgs.putBoolean(SecureSipCall.DISPLAY_WARNING_ZRTP_NOT_SUPPORTED, details.get(AccountDetailSrtp.CONFIG_ZRTP_NOT_SUPP_WARNING).contentEquals("true"));
+ SecureSipCall replace = new SecureSipCall(call, secureArgs);
+ mService.replaceCall(replace);
+
Intent intent = new Intent(ZRTP_ON);
- intent.putExtra("callID", callID);
+ intent.putExtra("callID", replace.getCallId());
+ intent.putExtra("conference", findConference(callID));
mService.sendBroadcast(intent);
}
@@ -315,10 +304,12 @@
Log.i(TAG, "on_secure_zrtp_off");
SipCall call = mService.getCallById(callID);
- if (call != null) {
- call.setSecured(false);
+ if (call != null && call instanceof SecureSipCall) {
+ SipCall replace = new SipCall(call.getBundle());
+ mService.replaceCall(replace);
Intent intent = new Intent(ZRTP_OFF);
intent.putExtra("callID", callID);
+ intent.putExtra("conference", findConference(callID));
mService.sendBroadcast(intent);
}
@@ -328,13 +319,16 @@
public void on_show_sas(String callID, String sas, boolean verified) {
Log.i(TAG, "on_show_sas:" + sas);
Log.i(TAG, "SAS Verified:" + verified);
- SipCall call = mService.getCallById(callID);
- call.setSAS(sas);
- call.setConfirmedSAS(verified);
+
Intent intent = new Intent(DISPLAY_SAS);
intent.putExtra("callID", callID);
intent.putExtra("SAS", sas);
intent.putExtra("verified", verified);
+ SecureSipCall call = (SecureSipCall) mService.getCallById(callID);
+ intent.putExtra("conference", findConference(callID));
+
+ call.setSAS(sas);
+ call.setConfirmedSAS(verified);
mService.sendBroadcast(intent);
}
@@ -343,8 +337,6 @@
public void on_zrtp_not_supported(String callID) {
Log.i(TAG, "on_zrtp_not_supported");
Intent intent = new Intent(ZRTP_NOT_SUPPORTED);
- SipCall call = mService.getCallById(callID);
- call.setSecured(false);
intent.putExtra("callID", callID);
mService.sendBroadcast(intent);
}
@@ -353,8 +345,6 @@
public void on_zrtp_negociation_failed(String callID, String reason, String severity) {
Log.i(TAG, "on_zrtp_negociation_failed");
Intent intent = new Intent(ZRTP_NEGOTIATION_FAILED);
- SipCall call = mService.getCallById(callID);
- call.setSecured(false);
intent.putExtra("callID", callID);
intent.putExtra("reason", reason);
intent.putExtra("severity", severity);
diff --git a/src/org/sflphone/service/SipService.java b/src/org/sflphone/service/SipService.java
index a2ccf2a..258564b 100644
--- a/src/org/sflphone/service/SipService.java
+++ b/src/org/sflphone/service/SipService.java
@@ -32,10 +32,7 @@
import java.util.Map.Entry;
import org.sflphone.history.HistoryManager;
-import org.sflphone.model.Codec;
-import org.sflphone.model.Conference;
-import org.sflphone.model.SipCall;
-import org.sflphone.model.SipMessage;
+import org.sflphone.model.*;
import org.sflphone.utils.MediaManager;
import org.sflphone.utils.SipNotifications;
import org.sflphone.utils.SwigNativeConverter;
@@ -201,6 +198,30 @@
return null;
}
+ /*
+ *
+ * Used when we need to transform a SipCall in a SecureSipCall or vice versa
+ *
+ * */
+ public void replaceCall(SipCall replace) {
+ if (getConferences().get(replace.getCallId()) != null) {
+ getConferences().get(replace.getCallId()).removeParticipant(replace);
+ getConferences().get(replace.getCallId()).addParticipant(replace);
+ } else {
+ // Check if call is in a conference
+ Iterator<Map.Entry<String, Conference>> it = getConferences().entrySet().iterator();
+ while (it.hasNext()) {
+ Conference tmp = it.next().getValue();
+ SipCall c = tmp.getCallById(replace.getCallId());
+ if(c != null){
+ tmp.removeParticipant(c);
+ tmp.addParticipant(replace);
+ return;
+ }
+ }
+ }
+ }
+
// Executes immediate tasks in a single executorThread.
public static class SipServiceExecutor extends Handler {
@@ -355,18 +376,15 @@
@Override
public void placeCall(final SipCall call) {
+
getExecutor().execute(new SipRunnable() {
@Override
protected void doRun() throws SameThreadException {
Log.i(TAG, "SipService.placeCall() thread running...");
- callManagerJNI.placeCall(call.getAccount().getAccountID(), call.getCallId(), call.getContact().getPhones().get(0).getNumber());
-
- HashMap<String, String> details = SwigNativeConverter.convertCallDetailsToNative(callManagerJNI.getCallDetails(call.getCallId()));
- // watchout timestamp stored by sflphone is in seconds
- call.setTimestampStart_(Long.parseLong(details.get(ServiceConstants.call.TIMESTAMP_START)));
Conference toAdd = new Conference(call);
mConferences.put(toAdd.getId(), toAdd);
mMediaManager.obtainAudioFocus(false);
+ callManagerJNI.placeCall(call.getAccount().getAccountID(), call.getCallId(), call.getmContact().getPhones().get(0).getNumber());
}
});
}
diff --git a/src/org/sflphone/utils/SipNotifications.java b/src/org/sflphone/utils/SipNotifications.java
index 47961cc..a77f9c5 100644
--- a/src/org/sflphone/utils/SipNotifications.java
+++ b/src/org/sflphone/utils/SipNotifications.java
@@ -158,7 +158,7 @@
nb.setTicker(tickerText);
nb.setWhen(when);
nb.setContentTitle(context.getString(R.string.notif_missed_call_title));
- nb.setContentText(context.getString(R.string.notif_missed_call_content, missedConf.getParticipants().get(0).getContact().getmDisplayName()));
+ nb.setContentText(context.getString(R.string.notif_missed_call_content, missedConf.getParticipants().get(0).getmContact().getmDisplayName()));
Intent notificationIntent = new Intent(context, HomeActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);