* #25117 Better call management
diff --git a/src/com/savoirfairelinux/sflphone/adapters/CallListAdapter.java b/src/com/savoirfairelinux/sflphone/adapters/CallListAdapter.java
index 5422acf..15667da 100644
--- a/src/com/savoirfairelinux/sflphone/adapters/CallListAdapter.java
+++ b/src/com/savoirfairelinux/sflphone/adapters/CallListAdapter.java
@@ -60,7 +60,7 @@
SipCall tmp = calls.get(position);
((TextView)rowView.findViewById(R.id.call_title)).setText(tmp.getContacts().get(0).getmDisplayName());
- ((TextView)rowView.findViewById(R.id.call_status)).setText(""+tmp.getmCallState());
+ ((TextView)rowView.findViewById(R.id.call_status)).setText(""+tmp.getCallStateString());
diff --git a/src/com/savoirfairelinux/sflphone/client/CallActivity.java b/src/com/savoirfairelinux/sflphone/client/CallActivity.java
index 785a436..e8d87de 100644
--- a/src/com/savoirfairelinux/sflphone/client/CallActivity.java
+++ b/src/com/savoirfairelinux/sflphone/client/CallActivity.java
@@ -33,6 +33,7 @@
package com.savoirfairelinux.sflphone.client;
+import java.util.HashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -71,6 +72,8 @@
private ExecutorService infos_fetcher = Executors.newCachedThreadPool();
CallReceiver receiver;
+
+ SlidingPaneLayout slidingPaneLayout;
CallListFragment mCallsFragment;
CallFragment mCurrentCallFragment;
@@ -99,7 +102,7 @@
getFragmentManager().beginTransaction().replace(R.id.calllist_pane, mCallsFragment).commit();
- final SlidingPaneLayout slidingPaneLayout = (SlidingPaneLayout) findViewById(R.id.slidingpanelayout);
+ slidingPaneLayout = (SlidingPaneLayout) findViewById(R.id.slidingpanelayout);
slidingPaneLayout.setPanelSlideListener(new SlidingPaneLayout.PanelSlideListener() {
@Override
@@ -215,6 +218,20 @@
// CallFragment fr = mCurrentCallFragment;
mCallsFragment.update();
+
+ mCurrentCallFragment.changeCallState(callID, newState);
+
+ HashMap<String, SipCall> map;
+ try {
+ map = (HashMap<String, SipCall>) service.getCallList();
+ if(map.size() == 0){
+ finish();
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString());
+ }
+
+
// if (newState.equals("INCOMING")) {
// fr.changeCallState(SipCall.state.CALL_STATE_INCOMING);
@@ -278,6 +295,8 @@
b.putParcelable("CallInfo", call);
mCurrentCallFragment.setArguments(b);
getFragmentManager().beginTransaction().replace(R.id.ongoingcall_pane, mCurrentCallFragment).commit();
+
+ slidingPaneLayout.openPane();
}
diff --git a/src/com/savoirfairelinux/sflphone/fragments/CallFragment.java b/src/com/savoirfairelinux/sflphone/fragments/CallFragment.java
index 984d9a1..b9ee971 100644
--- a/src/com/savoirfairelinux/sflphone/fragments/CallFragment.java
+++ b/src/com/savoirfairelinux/sflphone/fragments/CallFragment.java
@@ -73,12 +73,18 @@
private TextView contact_name_txt;
+ CallContact myself = CallContact.ContactBuilder.buildUserContact("Me");
+
@Override
public void onCreate(Bundle savedBundle) {
super.onCreate(savedBundle);
model = new BubbleModel(getResources().getDisplayMetrics().density);
metrics = getResources().getDisplayMetrics();
screenCenter = new PointF(metrics.widthPixels / 2, metrics.heightPixels / 3);
+
+ Bundle b = getArguments();
+
+ mCall = b.getParcelable("CallInfo");
}
/**
@@ -86,8 +92,6 @@
*/
private static Callbacks sDummyCallbacks = new Callbacks() {
-
-
@Override
public void onSendMessage(SipCall call, String msg) {
@@ -100,43 +104,49 @@
@Override
public void onCallAccepted(SipCall call) {
// TODO Auto-generated method stub
-
+
}
@Override
public void onCallRejected(SipCall call) {
// TODO Auto-generated method stub
-
+
}
@Override
public void onCallEnded(SipCall call) {
// TODO Auto-generated method stub
-
+
}
@Override
public void onCallSuspended(SipCall call) {
// TODO Auto-generated method stub
-
+
}
@Override
public void onCallResumed(SipCall call) {
// TODO Auto-generated method stub
-
+
}
@Override
public void onCalltransfered(SipCall call, String to) {
// TODO Auto-generated method stub
-
+
}
@Override
public void onRecordCall(SipCall call) {
// TODO Auto-generated method stub
-
+
+ }
+
+ @Override
+ public ISipService getService() {
+ // TODO Auto-generated method stub
+ return null;
}
};
@@ -146,6 +156,8 @@
*/
public interface Callbacks {
+ public ISipService getService();
+
public void callContact(SipCall call);
public void onCallAccepted(SipCall call);
@@ -189,27 +201,87 @@
view = (BubblesView) rootView.findViewById(R.id.main_view);
view.setModel(model);
- Bundle b = getArguments();
-
- mCall = b.getParcelable("CallInfo");
Log.i(TAG, "Starting fragment for call " + mCall.getCallId());
mCall.printCallInfo();
- String pendingAction = b.getString("action");
- if (pendingAction != null && pendingAction.contentEquals("call")) {
- callContact(mCall);
- } else if (pendingAction.contentEquals(CallManagerCallBack.INCOMING_CALL)) {
- callIncoming();
+ if (mCall.isRinging()) {
+ initOutGoingCallDisplay();
+ }
+ if (mCall.isIncoming() && mCall.isRinging()) {
+ initIncomingCallDisplay();
+ }
+ try {
+ if (mCall.isOutGoing() && mCallbacks.getService().getCall(mCall.getCallId()) == null) {
+ mCallbacks.getService().placeCall(mCall);
+ initOutGoingCallDisplay();
+ } else if(mCall.isOutGoing() && mCall.isRinging()){
+ initOutGoingCallDisplay();
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString());
+ }
+
+ if(mCall.isOngoing()){
+ initNormalStateDisplay();
}
return rootView;
}
- private void callContact(SipCall infos) {
+ private void initNormalStateDisplay() {
+ Log.i(TAG, "Start normal display");
+ // TODO off-thread image loading
+ Bubble contact_bubble, me;
+ if (mCall.getContacts().get(0).getPhoto_id() > 0) {
+ Bitmap photo = ContactPictureLoader.loadContactPhoto(getActivity().getContentResolver(), mCall.getContacts().get(0).getId());
+ contact_bubble = new Bubble(getActivity(), screenCenter.x, screenCenter.y, 150, photo);
+ } else {
+ contact_bubble = new Bubble(getActivity(), screenCenter.x, screenCenter.y / 2 , 150, R.drawable.ic_contact_picture);
+ }
+
+ me = new Bubble(getActivity(), screenCenter.x, screenCenter.y * 3 / 2, 150, R.drawable.ic_contact_picture);
+
+ model.attractors.clear();
+ model.attractors.add(new Attractor(new PointF(metrics.widthPixels / 2, metrics.heightPixels * .8f), new Attractor.Callback() {
+ @Override
+ public void onBubbleSucked(Bubble b) {
+ Log.w(TAG, "Bubble sucked ! ");
+ mCallbacks.onCallEnded(mCall);
+ }
+ }));
+
+ contact_bubble.contact = mCall.getContacts().get(0);
+ me.contact = myself;
+ model.listBubbles.add(contact_bubble);
+ model.listBubbles.add(me);
+ contacts.put(mCall.getContacts().get(0), contact_bubble);
+ contacts.put(myself, me);
+
+ }
+
+ private void initIncomingCallDisplay() {
+ Log.i(TAG, "Start incoming display");
+ model.attractors.clear();
+ model.attractors.add(new Attractor(new PointF(3 * metrics.widthPixels / 4, metrics.heightPixels / 4), new Attractor.Callback() {
+ @Override
+ public void onBubbleSucked(Bubble b) {
+ mCallbacks.onCallAccepted(mCall);
+ }
+ }));
+ model.attractors.add(new Attractor(new PointF(metrics.widthPixels / 4, metrics.heightPixels / 4), new Attractor.Callback() {
+ @Override
+ public void onBubbleSucked(Bubble b) {
+ mCallbacks.onCallRejected(mCall);
+ }
+ }));
+ }
+
+ private void initOutGoingCallDisplay() {
+ Log.i(TAG, "Start outgoing display");
// TODO off-thread image loading
Bubble contact_bubble;
- if (infos.getContacts().get(0).getPhoto_id() > 0) {
- Bitmap photo = ContactPictureLoader.loadContactPhoto(getActivity().getContentResolver(), infos.getContacts().get(0).getId());
+ if (mCall.getContacts().get(0).getPhoto_id() > 0) {
+ Bitmap photo = ContactPictureLoader.loadContactPhoto(getActivity().getContentResolver(), mCall.getContacts().get(0).getId());
contact_bubble = new Bubble(getActivity(), screenCenter.x, screenCenter.y, 150, photo);
} else {
contact_bubble = new Bubble(getActivity(), screenCenter.x, screenCenter.y, 150, R.drawable.ic_contact_picture);
@@ -224,34 +296,22 @@
}
}));
- contact_bubble.contact = infos.getContacts().get(0);
+ contact_bubble.contact = mCall.getContacts().get(0);
model.listBubbles.add(contact_bubble);
- contacts.put(infos.getContacts().get(0), contact_bubble);
-
- mCallbacks.callContact(infos);
-
+ contacts.put(mCall.getContacts().get(0), contact_bubble);
}
- private void callIncoming() {
- model.attractors.clear();
- model.attractors.add(new Attractor(new PointF(3 * metrics.widthPixels / 4, metrics.heightPixels / 4), new Attractor.Callback() {
- @Override
- public void onBubbleSucked(Bubble b) {
- mCallbacks.onCallAccepted(mCall);
- }
- }));
- model.attractors.add(new Attractor(new PointF(metrics.widthPixels / 4, metrics.heightPixels / 4), new Attractor.Callback() {
- @Override
- public void onBubbleSucked(Bubble b) {
- mCallbacks.onCallRejected(mCall);
- }
- }));
-
- }
-
- public void changeCallState(int callState) {
-
- mCall.setCallState(callState);
+ public void changeCallState(String callID, String newState) {
+
+ Log.w(TAG, "Changing call state of "+callID);
+ mCall.printCallInfo();
+ if(callID != mCall.getCallId())
+ return;
+
+ mCall.setCallState(newState);
+ if(mCall.isOngoing()){
+ initNormalStateDisplay();
+ }
}
}
diff --git a/src/com/savoirfairelinux/sflphone/fragments/CallListFragment.java b/src/com/savoirfairelinux/sflphone/fragments/CallListFragment.java
index c6a07d9..b1d175c 100644
--- a/src/com/savoirfairelinux/sflphone/fragments/CallListFragment.java
+++ b/src/com/savoirfairelinux/sflphone/fragments/CallListFragment.java
@@ -45,6 +45,7 @@
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
+import android.widget.Toast;
import com.savoirfairelinux.sflphone.R;
import com.savoirfairelinux.sflphone.adapters.CallListAdapter;
@@ -138,6 +139,7 @@
@Override
public void onItemClick(AdapterView<?> arg0, View view, int pos, long arg3) {
+ Toast.makeText(getActivity(), "ItemClicked", Toast.LENGTH_SHORT).show();
mCallbacks.onCallSelected(mAdapter.getItem(pos));
}
diff --git a/src/com/savoirfairelinux/sflphone/fragments/DialingFragment.java b/src/com/savoirfairelinux/sflphone/fragments/DialingFragment.java
index 97afcd0..10d6300 100644
--- a/src/com/savoirfairelinux/sflphone/fragments/DialingFragment.java
+++ b/src/com/savoirfairelinux/sflphone/fragments/DialingFragment.java
@@ -109,6 +109,7 @@
}
mCallbacks = (Callbacks) activity;
+
}
@Override
@@ -183,11 +184,17 @@
});
isReady = true;
+
+ return inflatedView;
+ }
+
+ @Override
+ public void onResume(){
+ super.onResume();
if (mCallbacks.getService() != null) {
onServiceSipBinded(mCallbacks.getService());
}
- return inflatedView;
}
@Override
diff --git a/src/com/savoirfairelinux/sflphone/model/CallContact.java b/src/com/savoirfairelinux/sflphone/model/CallContact.java
index b69c794..69f209f 100644
--- a/src/com/savoirfairelinux/sflphone/model/CallContact.java
+++ b/src/com/savoirfairelinux/sflphone/model/CallContact.java
@@ -158,6 +158,12 @@
return new CallContact(-1, to, 0, phones, new ArrayList<CallContact.Phone>(), "");
}
+
+ public static CallContact buildUserContact(String displayName) {
+ ArrayList<Phone> phones = new ArrayList<Phone>();
+
+ return new CallContact(-1, displayName, 0, phones, new ArrayList<CallContact.Phone>(), "");
+ }
}
diff --git a/src/com/savoirfairelinux/sflphone/model/SipCall.java b/src/com/savoirfairelinux/sflphone/model/SipCall.java
index b5c873a..62c719a 100644
--- a/src/com/savoirfairelinux/sflphone/model/SipCall.java
+++ b/src/com/savoirfairelinux/sflphone/model/SipCall.java
@@ -93,7 +93,6 @@
this.contacts = new ArrayList<CallContact>(c);
}
-
// public SipCall() {
// }
@@ -173,6 +172,17 @@
return mCallType;
}
+ public String getCallTypeString() {
+ switch (mCallType) {
+ case state.CALL_TYPE_INCOMING:
+ return "CALL_TYPE_INCOMING";
+ case state.CALL_TYPE_OUTGOING:
+ return "CALL_TYPE_OUTGOING";
+ default:
+ return "CALL_TYPE_UNDETERMINED";
+ }
+ }
+
public void setCallState(int callState) {
mCallState = callState;
}
@@ -213,14 +223,6 @@
this.mCallType = mCallType;
}
- public int getmCallState() {
- return mCallState;
- }
-
- public void setmCallState(int mCallState) {
- this.mCallState = mCallState;
- }
-
public int getmMediaState() {
return mMediaState;
}
@@ -273,7 +275,6 @@
return mMediaState;
}
-
public static class SipCallBuilder {
private String bCallID = "";
@@ -284,8 +285,6 @@
private int bCallState = state.CALL_STATE_NONE;
private int bMediaState = state.MEDIA_STATE_NONE;
-
-
public SipCallBuilder setCallType(int bCallType) {
this.bCallType = bCallType;
return this;
@@ -300,9 +299,9 @@
this.bCallState = state;
return this;
}
-
+
private static final String TAG = SipCallBuilder.class.getSimpleName();
-
+
public SipCallBuilder startCallCreation(String id) {
bCallID = id;
bContacts = new ArrayList<CallContact>();
@@ -339,15 +338,14 @@
return new SipCallBuilder();
}
-
}
- public void printCallInfo() {
- Log.i(TAG, "CallInfo: CallID: " + mCallID);
- Log.i(TAG, " AccountID: " + mAccountID);
- Log.i(TAG, " CallState: " + mCallState);
- Log.i(TAG, " CallType: " + mCallType);
- }
+ public void printCallInfo() {
+ Log.i(TAG, "CallInfo: CallID: " + mCallID);
+ Log.i(TAG, " AccountID: " + mAccountID);
+ Log.i(TAG, " CallState: " + mCallState);
+ Log.i(TAG, " CallType: " + mCallType);
+ }
/**
* Compare sip calls based on call ID
@@ -361,5 +359,55 @@
}
+ public boolean isOutGoing() {
+ if (mCallType == state.CALL_TYPE_OUTGOING)
+ return true;
+
+ return false;
+ }
+
+ public boolean isRinging() {
+ if (mCallState == state.CALL_STATE_RINGING || mCallState == state.CALL_STATE_NONE)
+ return true;
+
+ return false;
+ }
+
+ public boolean isIncoming() {
+ if (mCallType == state.CALL_TYPE_INCOMING)
+ return true;
+
+ return false;
+ }
+
+ public void setCallState(String newState) {
+ if (newState.equals("INCOMING")) {
+ setCallState(SipCall.state.CALL_STATE_INCOMING);
+ } else if (newState.equals("RINGING")) {
+ setCallState(SipCall.state.CALL_STATE_RINGING);
+ } else if (newState.equals("CURRENT")) {
+ setCallState(SipCall.state.CALL_STATE_CURRENT);
+ } else if (newState.equals("HUNGUP")) {
+ setCallState(SipCall.state.CALL_STATE_HUNGUP);
+ } else if (newState.equals("BUSY")) {
+ setCallState(SipCall.state.CALL_STATE_BUSY);
+ } else if (newState.equals("FAILURE")) {
+ setCallState(SipCall.state.CALL_STATE_FAILURE);
+ } else if (newState.equals("HOLD")) {
+ setCallState(SipCall.state.CALL_STATE_HOLD);
+ } else if (newState.equals("UNHOLD")) {
+ setCallState(SipCall.state.CALL_STATE_CURRENT);
+ } else {
+ setCallState(SipCall.state.CALL_STATE_NONE);
+ }
+
+ }
+
+ public boolean isOngoing() {
+ if (mCallState == state.CALL_STATE_RINGING || mCallState == state.CALL_STATE_NONE || mCallState == state.CALL_STATE_FAILURE || mCallState == state.CALL_STATE_BUSY || mCallState == state.CALL_STATE_HUNGUP)
+ return false;
+
+ return true;
+ }
}
diff --git a/src/com/savoirfairelinux/sflphone/service/ISipService.aidl b/src/com/savoirfairelinux/sflphone/service/ISipService.aidl
index 71692ea..95460bb 100644
--- a/src/com/savoirfairelinux/sflphone/service/ISipService.aidl
+++ b/src/com/savoirfairelinux/sflphone/service/ISipService.aidl
@@ -50,4 +50,9 @@
List getParticipantList(in String confID);
String getConferenceId(in String callID);
Map getConferenceDetails(in String callID);
+
+
+ /* */
+
+ SipCall getCall(String callID);
}
diff --git a/src/com/savoirfairelinux/sflphone/service/SipService.java b/src/com/savoirfairelinux/sflphone/service/SipService.java
index 35a3b62..1abfdaa 100644
--- a/src/com/savoirfairelinux/sflphone/service/SipService.java
+++ b/src/com/savoirfairelinux/sflphone/service/SipService.java
@@ -70,9 +70,8 @@
private ConfigurationManagerCallback configurationManagerCallback;
private ManagerImpl managerImpl;
private boolean isPjSipStackStarted = false;
-
- HashMap<String, SipCall> current_calls = new HashMap<String, SipCall>();
+ HashMap<String, SipCall> current_calls = new HashMap<String, SipCall>();
private BroadcastReceiver IncomingReceiver = new BroadcastReceiver() {
@@ -91,32 +90,32 @@
sendBroadcast(intent);
} else if (intent.getAction().contentEquals(CallManagerCallBack.INCOMING_CALL)) {
Bundle b = intent.getBundleExtra("com.savoirfairelinux.sflphone.service.newcall");
-
+
SipCall.SipCallBuilder callBuilder = SipCall.SipCallBuilder.getInstance();
- callBuilder.startCallCreation(b.getString("CallID")).setAccountID(b.getString("AccountID")).setCallType(SipCall.state.CALL_TYPE_OUTGOING);
+ callBuilder.startCallCreation(b.getString("CallID")).setAccountID(b.getString("AccountID"))
+ .setCallState(SipCall.state.CALL_STATE_RINGING).setCallType(SipCall.state.CALL_TYPE_INCOMING);
callBuilder.addContact(CallContact.ContactBuilder.buildUnknownContact(b.getString("From")));
-
+
Intent toSend = new Intent(CallManagerCallBack.INCOMING_CALL);
try {
SipCall newCall = callBuilder.build();
- toSend.putExtra("newcall",newCall);
+ toSend.putExtra("newcall", newCall);
current_calls.put(newCall.getCallId(), newCall);
sendBroadcast(toSend);
} catch (Exception e) {
Log.e(TAG, e.toString());
}
-
-
+
} else if (intent.getAction().contentEquals(CallManagerCallBack.CALL_STATE_CHANGED)) {
-
+
Bundle b = intent.getBundleExtra("com.savoirfairelinux.sflphone.service.newstate");
String newState = b.getString("State");
if (newState.equals("INCOMING")) {
- current_calls.get(b.getString("CallID")).setmCallState(SipCall.state.CALL_STATE_INCOMING);
+ current_calls.get(b.getString("CallID")).setCallState(SipCall.state.CALL_STATE_INCOMING);
} else if (newState.equals("RINGING")) {
- current_calls.get(b.getString("CallID")).setmCallState(SipCall.state.CALL_STATE_RINGING);
+ current_calls.get(b.getString("CallID")).setCallState(SipCall.state.CALL_STATE_RINGING);
} else if (newState.equals("CURRENT")) {
- current_calls.get(b.getString("CallID")).setmCallState(SipCall.state.CALL_STATE_CURRENT);
+ current_calls.get(b.getString("CallID")).setCallState(SipCall.state.CALL_STATE_CURRENT);
} else if (newState.equals("HUNGUP")) {
current_calls.remove(b.getString("CallID"));
} else if (newState.equals("BUSY")) {
@@ -124,13 +123,13 @@
} else if (newState.equals("FAILURE")) {
current_calls.remove(b.getString("CallID"));
} else if (newState.equals("HOLD")) {
- current_calls.get(b.getString("CallID")).setmCallState(SipCall.state.CALL_STATE_HOLD);
+ current_calls.get(b.getString("CallID")).setCallState(SipCall.state.CALL_STATE_HOLD);
} else if (newState.equals("UNHOLD")) {
- current_calls.get(b.getString("CallID")).setmCallState(SipCall.state.CALL_STATE_CURRENT);
+ current_calls.get(b.getString("CallID")).setCallState(SipCall.state.CALL_STATE_CURRENT);
} else {
- current_calls.get(b.getString("CallID")).setmCallState(SipCall.state.CALL_STATE_NONE);
+ current_calls.get(b.getString("CallID")).setCallState(SipCall.state.CALL_STATE_NONE);
}
-
+
sendBroadcast(intent);
} else if (intent.getAction().contentEquals(CallManagerCallBack.NEW_CALL_CREATED)) {
Log.i(TAG, "Received" + intent.getAction());
@@ -590,7 +589,6 @@
});
}
-
@Override
public ArrayList<HashMap<String, String>> getHistory() throws RemoteException {
class History extends SipRunnableWithReturn {
@@ -903,31 +901,36 @@
@Override
public HashMap<String, SipCall> getCallList() throws RemoteException {
-// class CallList extends SipRunnableWithReturn {
-//
-// @Override
-// protected StringVect doRun() throws SameThreadException {
-// Log.i(TAG, "SipService.getCallList() thread running...");
-// return callManagerJNI.getCallList();
-// }
-// }
-//
-// CallList runInstance = new CallList();
-// getExecutor().execute(runInstance);
-// while (!runInstance.isDone()) {
-// Log.w(TAG, "Waiting for getAudioCodecList");
-// }
-// StringVect swigmap = (StringVect) runInstance.getVal();
-//
-// ArrayList<String> nativemap = new ArrayList<String>();
-// for (int i = 0; i < swigmap.size(); ++i) {
-//
-// String t = swigmap.get(i);
-// nativemap.add(t);
-// }
+ // class CallList extends SipRunnableWithReturn {
+ //
+ // @Override
+ // protected StringVect doRun() throws SameThreadException {
+ // Log.i(TAG, "SipService.getCallList() thread running...");
+ // return callManagerJNI.getCallList();
+ // }
+ // }
+ //
+ // CallList runInstance = new CallList();
+ // getExecutor().execute(runInstance);
+ // while (!runInstance.isDone()) {
+ // Log.w(TAG, "Waiting for getAudioCodecList");
+ // }
+ // StringVect swigmap = (StringVect) runInstance.getVal();
+ //
+ // ArrayList<String> nativemap = new ArrayList<String>();
+ // for (int i = 0; i < swigmap.size(); ++i) {
+ //
+ // String t = swigmap.get(i);
+ // nativemap.add(t);
+ // }
return current_calls;
}
+ @Override
+ public SipCall getCall(String callID) throws RemoteException {
+ return current_calls.get(callID);
+ }
+
};
}