diff --git a/res/layout/history_cell.xml b/res/layout/history_cell.xml
index 8e2240b0d..f5149806d 100644
--- a/res/layout/history_cell.xml
+++ b/res/layout/history_cell.xml
@@ -1,44 +1,40 @@
-
+ android:layout_width="fill_parent" android:layout_height="?android:attr/listPreferredItemHeight"
+ android:padding="6dip">
+
+
+
+
-
+ android:layout_width="fill_parent" android:layout_height="26dip"
+
+ android:layout_toRightOf="@id/history_cell_icon"
+ android:layout_alignParentBottom="true"
+ android:layout_alignParentRight="true" android:singleLine="true"
+ android:ellipsize="marquee" />
+
+
-
\ No newline at end of file
diff --git a/src/org/linphone/HistoryActivity.java b/src/org/linphone/HistoryActivity.java
index f4858343c..ee60fc7e9 100644
--- a/src/org/linphone/HistoryActivity.java
+++ b/src/org/linphone/HistoryActivity.java
@@ -34,6 +34,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
+import android.widget.ListView;
import android.widget.TextView;
public class HistoryActivity extends ListActivity {
@@ -46,6 +47,22 @@ public class HistoryActivity extends ListActivity {
@Override
+ protected void onListItemClick(ListView l, View v, int position, long id) {
+ super.onListItemClick(l, v, position, id);
+ TextView lFirstLineView = (TextView) v.findViewById(R.id.history_cell_first_line);
+ TextView lSecondLineView = (TextView) v.findViewById(R.id.history_cell_second_line);
+ if (lSecondLineView.getVisibility() == View.GONE) {
+ // no display name
+ DialerActivity.getDialer().setContactAddress(lFirstLineView.getText().toString(), null);
+ } else {
+ DialerActivity.getDialer().setContactAddress(lSecondLineView.getText().toString()
+ ,lFirstLineView.getText().toString());
+ }
+ LinphoneActivity.instance().getTabHost().setCurrentTabByTag(LinphoneActivity.DIALER_TAB);
+ }
+
+
+ @Override
protected void onResume() {
super.onResume();
setListAdapter(new CallHistoryAdapter(this));
@@ -73,21 +90,29 @@ public class HistoryActivity extends ListActivity {
}
public View getView(int position, View convertView, ViewGroup parent) {
- LinphoneCallLog lLog = mLogs.get(position);
View lView=null;
+ if (convertView !=null) {
+ lView = convertView;
+ } else {
+ lView = mInflater.inflate(R.layout.history_cell, parent,false);
+
+ }
+ LinphoneCallLog lLog = mLogs.get(mLogs.size()-position-1);
LinphoneAddress lAddress;
- lView = mInflater.inflate(R.layout.history_cell, null);
TextView lFirstLineView = (TextView) lView.findViewById(R.id.history_cell_first_line);
TextView lSecondLineView = (TextView) lView.findViewById(R.id.history_cell_second_line);
- ImageView lDirectionImage = (ImageView) lView.findViewById(R.id.history_cell_icon);
+ ImageView lDirectionImageIn = (ImageView) lView.findViewById(R.id.history_cell_icon_in);
+ ImageView lDirectionImageOut = (ImageView) lView.findViewById(R.id.history_cell_icon_out);
if (lLog.getDirection() == CallDirection.Callincoming) {
lAddress = lLog.getFrom();
- lDirectionImage.setImageResource(R.drawable.in_call);
+ lDirectionImageIn.setVisibility(View.VISIBLE);
+ lDirectionImageOut.setVisibility(View.GONE);
} else {
lAddress = lLog.getTo();
- lDirectionImage.setImageResource(R.drawable.out_call);
+ lDirectionImageIn.setVisibility(View.GONE);
+ lDirectionImageOut.setVisibility(View.VISIBLE);
}
if (lAddress.getDisplayName() == null) {
@@ -96,6 +121,7 @@ public class HistoryActivity extends ListActivity {
} else {
lFirstLineView.setText(lAddress.getDisplayName());
lSecondLineView.setText(lAddress.getUserName());
+ lSecondLineView.setVisibility(View.VISIBLE);
}
return lView;
diff --git a/src/org/linphone/LinphonePreferencesActivity.java b/src/org/linphone/LinphonePreferencesActivity.java
index 0bccb4b21..8c04785cc 100644
--- a/src/org/linphone/LinphonePreferencesActivity.java
+++ b/src/org/linphone/LinphonePreferencesActivity.java
@@ -18,7 +18,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.linphone;
-import org.linphone.core.LinphoneCoreException;
+
import android.os.Bundle;
import android.preference.PreferenceActivity;
diff --git a/src/org/linphone/LinphoneService.java b/src/org/linphone/LinphoneService.java
index 759ad7f11..2af991af5 100644
--- a/src/org/linphone/LinphoneService.java
+++ b/src/org/linphone/LinphoneService.java
@@ -1,5 +1,5 @@
/*
-Linphone.java
+LinphoneService.java
Copyright (C) 2010 Belledonne Communications, Grenoble, France
This program is free software; you can redistribute it and/or
@@ -32,6 +32,7 @@ import org.linphone.core.LinphoneCoreException;
import org.linphone.core.LinphoneCoreFactory;
import org.linphone.core.LinphoneCoreListener;
import org.linphone.core.LinphoneProxyConfig;
+import org.linphone.core.LinphoneCore.GeneralState;
import android.app.AlertDialog;
@@ -67,7 +68,7 @@ public class LinphoneService extends Service implements LinphoneCoreListener {
private SharedPreferences mPref;
Timer mTimer = new Timer("Linphone scheduler");
- private Handler mIteratehandler;
+ private Handler mHandler = new Handler() ;
static LinphoneService instance() {
if (theLinphone == null) {
@@ -92,17 +93,11 @@ public class LinphoneService extends Service implements LinphoneCoreListener {
, null);
initFromConf();
- mIteratehandler = new Handler() {
- public void handleMessage(Message msg) {
- //iterate is called inside an Android handler to allow UI interaction within LinphoneCoreListener
- mLinphoneCore.iterate();
- }
- };
TimerTask lTask = new TimerTask() {
@Override
public void run() {
- mIteratehandler.sendEmptyMessage(0);
+ mLinphoneCore.iterate();
}
};
@@ -159,17 +154,35 @@ public class LinphoneService extends Service implements LinphoneCoreListener {
// TODO Auto-generated method stub
}
- public void displayStatus(LinphoneCore lc, String message) {
+ public void displayStatus(final LinphoneCore lc, final String message) {
Log.i(TAG, message);
- if (DialerActivity.getDialer()!=null) DialerActivity.getDialer().displayStatus(lc,message);
+ if (DialerActivity.getDialer()!=null) {
+ mHandler.post(new Runnable() {
+ public void run() {
+ DialerActivity.getDialer().displayStatus(lc,message);
+ }
+
+ });
+
+ }
}
public void displayWarning(LinphoneCore lc, String message) {
// TODO Auto-generated method stub
}
- public void generalState(LinphoneCore lc, LinphoneCore.GeneralState state) {
+ public void generalState(final LinphoneCore lc, final LinphoneCore.GeneralState state) {
Log.i(TAG, "new state ["+state+"]");
- if (DialerActivity.getDialer()!=null) DialerActivity.getDialer().generalState(lc,state);
+ if (state == GeneralState.GSTATE_POWER_OFF) {
+ //just exist
+ System.exit(0);
+ }
+ if (DialerActivity.getDialer()!=null) {
+ mHandler.post(new Runnable() {
+ public void run() {
+ DialerActivity.getDialer().generalState(lc,state);
+ }
+ });
+ }
}
public void inviteReceived(LinphoneCore lc, String from) {
// TODO Auto-generated method stub
@@ -256,7 +269,8 @@ public class LinphoneService extends Service implements LinphoneCoreListener {
@Override
public void onDestroy() {
super.onDestroy();
- System.exit(0); // FIXME to destroy liblinphone
+ mTimer.cancel();
+ mLinphoneCore.destroy();
}
}
\ No newline at end of file
diff --git a/src/org/linphone/core/LinphoneCore.java b/src/org/linphone/core/LinphoneCore.java
index c39ef36f2..c886c4038 100644
--- a/src/org/linphone/core/LinphoneCore.java
+++ b/src/org/linphone/core/LinphoneCore.java
@@ -123,4 +123,9 @@ public interface LinphoneCore {
*/
public List getCallLogs();
+ /**
+ * destroy linphone core and free all underlying resources
+ */
+ public void destroy();
+
}
diff --git a/src/org/linphone/core/LinphoneCoreImpl.java b/src/org/linphone/core/LinphoneCoreImpl.java
index 80d24bd67..ba6f5a384 100644
--- a/src/org/linphone/core/LinphoneCoreImpl.java
+++ b/src/org/linphone/core/LinphoneCoreImpl.java
@@ -23,11 +23,15 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
+import org.linphone.LinphoneService;
+
+import android.util.Log;
+
class LinphoneCoreImpl implements LinphoneCore {
private final LinphoneCoreListener mListener;
- private final long nativePtr;
+ private long nativePtr = 0;
private native long newLinphoneCore(LinphoneCoreListener listener,String userConfig,String factoryConfig,Object userdata);
private native void iterate(long nativePtr);
private native long getDefaultProxyConfig(long nativePtr);
@@ -46,22 +50,29 @@ class LinphoneCoreImpl implements LinphoneCore {
private native void acceptCall(long nativePtr);
private native long getCallLog(long nativePtr,int position);
private native int getNumberOfCallLogs(long nativePtr);
+ private native void delete(long nativePtr);
LinphoneCoreImpl(LinphoneCoreListener listener, File userConfig,File factoryConfig,Object userdata) throws IOException {
mListener=listener;
nativePtr = newLinphoneCore(listener,userConfig.getCanonicalPath(),factoryConfig.getCanonicalPath(),userdata);
}
+ protected void finalize() throws Throwable {
+
+ }
public synchronized void addAuthInfo(LinphoneAuthInfo info) {
+ isValid();
addAuthInfo(nativePtr,((LinphoneAuthInfoImpl)info).nativePtr);
}
public synchronized LinphoneProxyConfig createProxyConfig(String identity, String proxy,String route,boolean enableRegister) throws LinphoneCoreException {
+ isValid();
return new LinphoneProxyConfigImpl(identity, proxy, route,enableRegister);
}
public synchronized LinphoneProxyConfig getDefaultProxyConfig() {
+ isValid();
long lNativePtr = getDefaultProxyConfig(nativePtr);
if (lNativePtr!=0) {
return new LinphoneProxyConfigImpl(lNativePtr);
@@ -71,32 +82,40 @@ class LinphoneCoreImpl implements LinphoneCore {
}
public synchronized void invite(String uri) {
+ isValid();
invite(nativePtr,uri);
}
public synchronized void iterate() {
+ isValid();
iterate(nativePtr);
}
public synchronized void setDefaultProxyConfig(LinphoneProxyConfig proxyCfg) {
+ isValid();
setDefaultProxyConfig(nativePtr,((LinphoneProxyConfigImpl)proxyCfg).nativePtr);
}
public synchronized void addtProxyConfig(LinphoneProxyConfig proxyCfg) throws LinphoneCoreException{
+ isValid();
if (addProxyConfig(nativePtr,((LinphoneProxyConfigImpl)proxyCfg).nativePtr) !=0) {
throw new LinphoneCoreException("bad proxy config");
}
}
public synchronized void clearAuthInfos() {
+ isValid();
clearAuthInfos(nativePtr);
}
public synchronized void clearProxyConfigs() {
+ isValid();
clearProxyConfigs(nativePtr);
}
public synchronized void terminateCall() {
+ isValid();
terminateCall(nativePtr);
}
public synchronized LinphoneAddress getRemoteAddress() {
+ isValid();
long ptr = getRemoteAddress(nativePtr);
if (ptr==0) {
return null;
@@ -105,20 +124,35 @@ class LinphoneCoreImpl implements LinphoneCore {
}
}
public synchronized boolean isIncall() {
+ isValid();
return isInCall(nativePtr);
}
public synchronized boolean isInComingInvitePending() {
+ isValid();
return isInComingInvitePending(nativePtr);
}
public synchronized void acceptCall() {
+ isValid();
acceptCall(nativePtr);
}
- public List getCallLogs() {
+ public synchronized List getCallLogs() {
+ isValid();
List logs = new ArrayList();
for (int i=0;i < getNumberOfCallLogs(nativePtr);i++) {
logs.add(new LinphoneCallLogImpl(getCallLog(nativePtr, i)));
}
return logs;
}
+ public synchronized void destroy() {
+ isValid();
+ delete(nativePtr);
+ nativePtr = 0;
+ }
+
+ private void isValid() {
+ if (nativePtr == 0) {
+ throw new RuntimeException("object already destroyed");
+ }
+ }
}