Merge remote-tracking branch 'linphone/master'

Conflicts:
	src/org/linphone/ChatFragment.java
	src/org/linphone/LinphoneActivity.java
This commit is contained in:
Margaux Clerc 2015-08-14 11:07:23 +02:00
commit 5755ccc374
16 changed files with 339 additions and 189 deletions

View file

@ -134,7 +134,7 @@
<property name="out.library.jar.file" location="${out.absolute.dir}/linphone.jar" />
<jar destfile="${out.library.jar.file}">
<fileset dir="${out.classes.absolute.dir}"
includes="org/linphone/mediastream/**/*.class org/linphone/core/**/*.class org/linphone/**/*.class"/>
includes="org/linphone/mediastream/**/*.class org/linphone/core/**/*.class org/linphone/**/*.class de/timroes/axmlrpc/**/*.class de/timroes/base64/Base64.class"/>
<fileset dir="submodules/linphone/java" >
<include name="common/org/linphone/core/*.java"/>
<include name="j2se/org/linphone/core/*.java"/>

View file

@ -32,10 +32,11 @@
<ProgressBar
android:id="@+id/spinner"
android:visibility="gone"
android:indeterminate="true"
android:visibility="gone"
android:layout_marginTop="20dp"
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
android:layout_height="5dp" />
<TextView
android:id="@+id/time"

View file

@ -374,6 +374,9 @@
<string name="error_incompatible_media">Incompatible media parameters</string>
<string name="error_low_bandwidth">Your correspondent has low bandwidth, video can\'t be started</string>
<string name="error_network_unreachable">Network is unreachable</string>
<string name="error_bad_credentials">Bad credentials</string>
<string name="error_unauthorized">Unauthorized</string>
<string name="error_io_error">Network error</string>
<string name="today">Today</string>
<string name="yesterday">Yesterday</string>
<string name="call_state_missed">Missed</string>

View file

@ -35,6 +35,7 @@ import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceCategory;
import android.preference.PreferenceScreen;
import android.text.InputType;
import android.view.WindowManager;
/**
* @author Sylvain Berfini
@ -65,7 +66,9 @@ public class AccountPreferencesFragment extends PreferencesListFragment {
} else {
manageAccountPreferencesFields(screen);
}
// Force hide keyboard
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
}
public static boolean isEditTextEmpty(String s){
@ -496,7 +499,7 @@ public class AccountPreferencesFragment extends PreferencesListFragment {
} catch (LinphoneCoreException e) {
e.printStackTrace();
}
LinphoneActivity.instance().isNewProxyConfig();
LinphoneManager.getLc().refreshRegisters();
}
}

View file

@ -21,9 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import android.content.CursorLoader;
import android.graphics.Matrix;
import java.util.ArrayList;
import java.util.List;
@ -33,7 +31,6 @@ import org.linphone.compatibility.Compatibility;
import org.linphone.core.LinphoneAddress;
import org.linphone.core.LinphoneBuffer;
import org.linphone.core.LinphoneChatMessage;
import org.linphone.core.LinphoneChatMessage.LinphoneChatMessageListener;
import org.linphone.core.LinphoneChatRoom;
import org.linphone.core.LinphoneContent;
import org.linphone.core.LinphoneCore;
@ -46,6 +43,7 @@ import org.linphone.ui.AvatarWithShadow;
import org.linphone.ui.BubbleChat;
import android.media.ExifInterface;
import android.support.v4.content.CursorLoader;
import android.annotation.SuppressLint;
import android.app.Activity;
@ -63,7 +61,7 @@ import android.os.Bundle;
import android.os.Environment;
import android.os.Parcelable;
import android.provider.MediaStore;
import android.app.Fragment;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.text.InputType;
import android.text.TextWatcher;
@ -86,7 +84,7 @@ import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
public class ChatFragment extends Fragment implements OnClickListener, LinphoneChatMessageListener {
public class ChatFragment extends Fragment implements OnClickListener, LinphoneChatMessage.LinphoneChatMessageListener {
private static ChatFragment instance;
private static final int ADD_PHOTO = 1337;
@ -114,9 +112,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
private ChatMessageAdapter adapter;
private LinphoneCoreListenerBase mListener;
private ByteArrayOutputStream mDownloadedImageStream;
private ByteArrayInputStream mUploadingImageStream;
private int mDownloadedImageStreamSize;
private LinphoneChatMessage currentMessageInFileTransferUploadState;
public static boolean isInstanciated() {
@ -128,7 +124,8 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
super.onCreate(savedInstanceState);
instance = this;
View view = inflater.inflate(R.layout.chat, container, false);
LinphoneManager.addListener(this);
// Retain the fragment across configuration changes
setRetainInstance(true);
@ -195,6 +192,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
progressBar.setProgress(0);
currentMessageInFileTransferUploadState.cancelFileTransfer();
currentMessageInFileTransferUploadState = null;
LinphoneManager.getInstance().setUploadPendingFileMessage(null);
}
}
});
@ -212,6 +210,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
LinphoneAddress from = cr.getPeerAddress();
if (from.asStringUriOnly().equals(sipUri)) {
invalidate();
messagesList.setSelection(adapter.getCount()-1);
}
}
@ -241,7 +240,6 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
// Force hide keyboard
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
return view;
}
@ -284,7 +282,6 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
topBar.setVisibility(View.GONE);
}
contactPicture.setVisibility(View.GONE);
//scrollToEnd();
}
public void hideKeyboardVisibleMode() {
@ -293,7 +290,6 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
if (isOrientationLandscape && topBar != null) {
topBar.setVisibility(View.VISIBLE);
}
//scrollToEnd();
}
class ChatMessageAdapter extends BaseAdapter {
@ -328,11 +324,23 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
public View getView(int position, View convertView, ViewGroup parent) {
LinphoneChatMessage message = history[position];
BubbleChat bubble = new BubbleChat(context, message, ChatFragment.this);
BubbleChat bubble = new BubbleChat(context, message);
View v = bubble.getView();
registerForContextMenu(v);
RelativeLayout rlayout = new RelativeLayout(context);
if(message.isOutgoing()){
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
layoutParams.setMargins(100, 10, 10, 10);
v.setLayoutParams(layoutParams);
} else {
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
layoutParams.setMargins(10, 10, 100, 10);
v.setLayoutParams(layoutParams);
}
rlayout.addView(v);
return rlayout;
@ -454,8 +462,14 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
lc.removeListener(mListener);
}
LinphoneManager.removeListener(this);
onSaveInstanceState(getArguments());
uploadLayout.setVisibility(View.GONE);
textLayout.setVisibility(View.VISIBLE);
progressBar.setProgress(0);
//Hide keybord
InputMethodManager imm = (InputMethodManager)getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(message.getWindowToken(), 0);
@ -480,12 +494,34 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
LinphoneActivity.instance().updateChatFragment(this);
}
LinphoneManager.addListener(this);
final LinphoneChatMessage msg = LinphoneManager.getInstance().getMessageUploadPending();
if(msg != null && msg.getTo().asString().equals(sipUri)){
uploadLayout.setVisibility(View.VISIBLE);
textLayout.setVisibility(View.GONE);
if(msg.getFileTransferInformation() != null){
progressBar.setProgress(msg.getFileTransferInformation().getRealSize());
}
cancelUpload.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
uploadLayout.setVisibility(View.GONE);
textLayout.setVisibility(View.VISIBLE);
progressBar.setProgress(0);
msg.cancelFileTransfer();
LinphoneManager.getInstance().setUploadPendingFileMessage(null);
}
});
}
String draft = getArguments().getString("messageDraft");
message.setText(draft);
remoteComposing.setVisibility(chatRoom.isRemoteComposing() ? View.VISIBLE : View.GONE);
dispayMessageList();
super.onResume();
}
@ -505,13 +541,14 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
if (chatRoom != null && messageToSend != null && messageToSend.length() > 0 && isNetworkReachable) {
LinphoneChatMessage message = chatRoom.createLinphoneChatMessage(messageToSend);
message.setListener(this);
chatRoom.sendChatMessage(message);
if (LinphoneActivity.isInstanciated()) {
LinphoneActivity.instance().onMessageSent(sipUri, messageToSend);
}
message.setListener(LinphoneManager.getInstance());
invalidate();
Log.i("Sent message current status: " + message.getStatus());
} else if (!isNetworkReachable && LinphoneActivity.isInstanciated()) {
@ -563,7 +600,6 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
}
// Rotate the bitmap if possible/needed, using EXIF data
Log.w(path);
try {
if (path != null) {
ExifInterface exif = new ExifInterface(path);
@ -601,9 +637,12 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
content.setName(fileName);
LinphoneChatMessage message = chatRoom.createFileTransferMessage(content);
message.setListener(ChatFragment.this);
message.setListener(LinphoneManager.getInstance());
message.setAppData(path);
LinphoneManager.getInstance().setUploadPendingFileMessage(message);
LinphoneManager.getInstance().setUploadingImageStream(mUploadingImageStream);
chatRoom.sendChatMessage(message);
currentMessageInFileTransferUploadState = message;
}
@ -704,32 +743,6 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
@Override
public void onLinphoneChatMessageStateChanged(LinphoneChatMessage msg, State state) {
if (LinphoneActivity.isInstanciated() && state != LinphoneChatMessage.State.InProgress) {
if (msg != null) {
LinphoneActivity.instance().onMessageStateChanged(sipUri, msg.getText(), state.toInt());
}
invalidate();
}
if (state == State.FileTransferDone) {
if (mDownloadedImageStream != null) {
byte[] bytes = mDownloadedImageStream.toByteArray();
Bitmap bm = BitmapFactory.decodeByteArray(bytes, 0, mDownloadedImageStreamSize);
String path = msg.getExternalBodyUrl();
String fileName = path.substring(path.lastIndexOf("/") + 1);
String url = MediaStore.Images.Media.insertImage(getActivity().getContentResolver(), bm, fileName, null);
if (url != null) {
msg.setAppData(url);
}
mDownloadedImageStream = null;
mDownloadedImageStreamSize = 0;
} else if (mUploadingImageStream != null) {
mUploadingImageStream = null;
}
}
if (state == State.FileTransferDone || state == State.FileTransferError) {
uploadLayout.setVisibility(View.GONE);
textLayout.setVisibility(View.VISIBLE);
@ -741,33 +754,10 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
@Override
public void onLinphoneChatMessageFileTransferReceived(LinphoneChatMessage msg, LinphoneContent content, LinphoneBuffer buffer) {
if (mDownloadedImageStream == null) {
mDownloadedImageStream = new ByteArrayOutputStream();
mDownloadedImageStreamSize = 0;
}
if (buffer != null && buffer.getSize() > 0) {
try {
mDownloadedImageStream.write(buffer.getContent());
mDownloadedImageStreamSize += buffer.getSize();
} catch (IOException e) {
Log.e(e);
}
}
}
@Override
public void onLinphoneChatMessageFileTransferSent(LinphoneChatMessage msg, LinphoneContent content, int offset, int size, LinphoneBuffer bufferToFill) {
if (mUploadingImageStream != null && size > 0) {
byte[] data = new byte[size];
int read = mUploadingImageStream.read(data, 0, size);
if (read > 0) {
bufferToFill.setContent(data);
bufferToFill.setSize(read);
} else {
Log.e("Error, upload task asking for more bytes(" + size + ") than available (" + mUploadingImageStream.available() + ")");
}
}
}
@Override

View file

@ -92,8 +92,11 @@ public class ContactsManager {
initializeContactManager(context,contentResolver);
Account newAccount = new Account(context.getString(R.string.sync_account_name), context.getString(R.string.sync_account_type));
AccountManager accountManager = (AccountManager) context.getSystemService(context.ACCOUNT_SERVICE);
accountManager.addAccountExplicitly(newAccount, null, null);
mAccount = newAccount;
if(accountManager.addAccountExplicitly(newAccount, null, null)){
mAccount = newAccount;
} else {
mAccount = null;
}
}
public String getDisplayName(String firstName, String lastName) {

View file

@ -43,6 +43,7 @@ import org.linphone.core.LinphoneCoreException;
import org.linphone.core.LinphoneCoreFactory;
import org.linphone.core.LinphoneCoreListenerBase;
import org.linphone.core.LinphoneProxyConfig;
import org.linphone.core.Reason;
import org.linphone.mediastream.Log;
import org.linphone.setup.RemoteProvisioningLoginActivity;
import org.linphone.setup.SetupActivity;
@ -50,16 +51,20 @@ import org.linphone.ui.AddressText;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.database.ContentObserver;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.support.v4.app.Fragment;
import android.support.v4.app.Fragment.SavedState;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@ -80,7 +85,7 @@ import android.widget.Toast;
/**
* @author Sylvain Berfini
*/
public class LinphoneActivity extends Activity implements OnClickListener, ContactPicked {
public class LinphoneActivity extends FragmentActivity implements OnClickListener, ContactPicked {
public static final String PREF_FIRST_LAUNCH = "pref_first_launch";
private static final int SETTINGS_ACTIVITY = 123;
private static final int FIRST_LOGIN_ACTIVITY = 101;
@ -99,7 +104,8 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
private List<FragmentsAvailable> fragmentsHistory;
private Fragment dialerFragment, messageListFragment, friendStatusListenerFragment;
private ChatFragment chatFragment;
private Fragment.SavedState dialerSavedState;
private SavedState dialerSavedState;
private boolean newProxyConfig;
private boolean isAnimationDisabled = false, preferLinphoneContacts = false;
private OrientationEventListener mOrientationHelper;
private LinphoneCoreListenerBase mListener;
@ -168,7 +174,7 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
if (findViewById(R.id.fragmentContainer) != null) {
dialerFragment = new DialerFragment();
dialerFragment.setArguments(getIntent().getExtras());
getFragmentManager().beginTransaction().add(R.id.fragmentContainer, dialerFragment, currentFragment.toString()).commit();
getSupportFragmentManager().beginTransaction().add(R.id.fragmentContainer, dialerFragment, currentFragment.toString()).commit();
selectMenu(FragmentsAvailable.DIALER);
}
}
@ -194,6 +200,19 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
lc.removeAuthInfo(authInfo);
}
}
if(state.equals(RegistrationState.RegistrationFailed) && newProxyConfig) {
newProxyConfig = false;
if (proxy.getError() == Reason.BadCredentials) {
displayCustomToast(getString(R.string.error_bad_credentials), Toast.LENGTH_LONG);
}
if (proxy.getError() == Reason.Unauthorized) {
displayCustomToast(getString(R.string.error_unauthorized), Toast.LENGTH_LONG);
}
if (proxy.getError() == Reason.IOError) {
displayCustomToast(getString(R.string.error_io_error), Toast.LENGTH_LONG);
}
}
}
@Override
@ -208,11 +227,11 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
}
} else if (state == State.CallEnd || state == State.Error || state == State.CallReleased) {
// Convert LinphoneCore message for internalization
if (message != null && message.equals("Call declined.")) {
if (message != null && call.getReason() == Reason.Declined) {
displayCustomToast(getString(R.string.error_call_declined), Toast.LENGTH_LONG);
} else if (message != null && message.equals("Not Found")) {
} else if (message != null && call.getReason() == Reason.NotFound) {
displayCustomToast(getString(R.string.error_user_not_found), Toast.LENGTH_LONG);
} else if (message != null && message.equals("Unsupported media type")) {
} else if (message != null && call.getReason() == Reason.Media) {
displayCustomToast(getString(R.string.error_incompatible_media), Toast.LENGTH_LONG);
} else if (message != null && state == State.Error) {
displayCustomToast(getString(R.string.error_unknown) + " - " + message, Toast.LENGTH_LONG);
@ -255,7 +274,6 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
updateAnimationsState();
}
private void initButtons() {
menu = (LinearLayout) findViewById(R.id.menu);
mark = (LinearLayout) findViewById(R.id.mark);
@ -318,6 +336,10 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
findViewById(R.id.fragmentContainer).setPadding(0, LinphoneUtils.pixelsToDpi(getResources(), 40), 0, 0);
}
public void isNewProxyConfig(){
newProxyConfig = true;
}
private void changeCurrentFragment(FragmentsAvailable newFragmentType, Bundle extras) {
changeCurrentFragment(newFragmentType, extras, false);
}
@ -330,7 +352,7 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
if (currentFragment == FragmentsAvailable.DIALER) {
try {
dialerSavedState = getFragmentManager().saveFragmentInstanceState(dialerFragment);
dialerSavedState = getSupportFragmentManager().saveFragmentInstanceState(dialerFragment);
} catch (Exception e) {
}
}
@ -419,7 +441,7 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
statusFragment.closeStatusBar();
}
FragmentTransaction transaction = getFragmentManager().beginTransaction();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
if (!withoutAnimation && !isAnimationDisabled && currentFragment.shouldAnimate()) {
if (newFragmentType.isRightOf(currentFragment)) {
@ -445,7 +467,7 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
}
transaction.replace(R.id.fragmentContainer, newFragment, newFragmentType.toString());
transaction.commitAllowingStateLoss();
getFragmentManager().executePendingTransactions();
getSupportFragmentManager().executePendingTransactions();
currentFragment = newFragmentType;
}
@ -464,7 +486,7 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
LinearLayout ll = (LinearLayout) findViewById(R.id.fragmentContainer2);
FragmentTransaction transaction = getFragmentManager().beginTransaction();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
if (newFragmentType.shouldAddItselfToTheRightOf(currentFragment)) {
ll.setVisibility(View.VISIBLE);
@ -493,7 +515,7 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
transaction.replace(R.id.fragmentContainer, newFragment);
}
transaction.commitAllowingStateLoss();
getFragmentManager().executePendingTransactions();
getSupportFragmentManager().executePendingTransactions();
currentFragment = newFragmentType;
if (newFragmentType == FragmentsAvailable.DIALER
@ -504,7 +526,7 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
|| newFragmentType == FragmentsAvailable.CHATLIST
|| newFragmentType == FragmentsAvailable.HISTORY) {
try {
getFragmentManager().popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
getSupportFragmentManager().popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
} catch (java.lang.IllegalStateException e) {
}
@ -539,7 +561,7 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
String callTime = secondsToDisplayableString(log.getCallDuration());
String callDate = String.valueOf(log.getTimestamp());
Fragment fragment2 = getFragmentManager().findFragmentById(R.id.fragmentContainer2);
Fragment fragment2 = getSupportFragmentManager().findFragmentById(R.id.fragmentContainer2);
if (fragment2 != null && fragment2.isVisible() && currentFragment == FragmentsAvailable.HISTORY_DETAIL) {
HistoryDetailFragment historyDetailFragment = (HistoryDetailFragment) fragment2;
historyDetailFragment.changeDisplayedHistory(sipUri, displayName, pictureUri, status, callTime, callDate);
@ -567,7 +589,7 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
}
public void displayContact(Contact contact, boolean chatOnly) {
Fragment fragment2 = getFragmentManager().findFragmentById(R.id.fragmentContainer2);
Fragment fragment2 = getSupportFragmentManager().findFragmentById(R.id.fragmentContainer2);
if (fragment2 != null && fragment2.isVisible() && currentFragment == FragmentsAvailable.CONTACT) {
ContactFragment contactFragment = (ContactFragment) fragment2;
contactFragment.changeDisplayedContact(contact);
@ -635,7 +657,7 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
if (isTablet()){
if (currentFragment == FragmentsAvailable.CHATLIST || currentFragment == FragmentsAvailable.CHAT){
Fragment fragment2 = getFragmentManager().findFragmentById(R.id.fragmentContainer2);
Fragment fragment2 = getSupportFragmentManager().findFragmentById(R.id.fragmentContainer2);
if (fragment2 != null && fragment2.isVisible() && currentFragment == FragmentsAvailable.CHAT) {
ChatFragment chatFragment = (ChatFragment) fragment2;
chatFragment.changeDisplayedChat(sipUri, displayName, pictureUri);

View file

@ -22,13 +22,17 @@ import static android.media.AudioManager.MODE_RINGTONE;
import static android.media.AudioManager.STREAM_RING;
import static android.media.AudioManager.STREAM_VOICE_CALL;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
@ -36,6 +40,7 @@ import java.util.TimerTask;
import org.linphone.compatibility.Compatibility;
import org.linphone.core.CallDirection;
import org.linphone.core.LinphoneAddress;
import org.linphone.core.LinphoneBuffer;
import org.linphone.core.LinphoneCall;
import org.linphone.core.LinphoneCall.State;
import org.linphone.core.LinphoneCallParams;
@ -88,10 +93,12 @@ import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.os.Vibrator;
import android.provider.MediaStore;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.telephony.TelephonyManager;
@ -116,7 +123,7 @@ import android.widget.Toast;
* @author Guillaume Beraudo
*
*/
public class LinphoneManager implements LinphoneCoreListener {
public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessage.LinphoneChatMessageListener {
private static LinphoneManager instance;
private Context mServiceContext;
@ -133,9 +140,21 @@ public class LinphoneManager implements LinphoneCoreListener {
private ConnectivityManager mConnectivityManager;
private Handler mHandler = new Handler();
private WakeLock mIncallWakeLock;
private static List<LinphoneChatMessage> mPendingChatFileMessage;
private static LinphoneChatMessage mUploadPendingFileMessage;
public String wizardLoginViewDomain = null;
private static List<LinphoneChatMessage.LinphoneChatMessageListener> simpleListeners = new ArrayList<LinphoneChatMessage.LinphoneChatMessageListener>();
public static void addListener(LinphoneChatMessage.LinphoneChatMessageListener listener) {
if (!simpleListeners.contains(listener)) {
simpleListeners.add(listener);
}
}
public static void removeListener(LinphoneChatMessage.LinphoneChatMessageListener listener) {
simpleListeners.remove(listener);
}
protected LinphoneManager(final Context c) {
sExited = false;
mServiceContext = c;
@ -156,6 +175,7 @@ public class LinphoneManager implements LinphoneCoreListener {
mPowerManager = (PowerManager) c.getSystemService(Context.POWER_SERVICE);
mConnectivityManager = (ConnectivityManager) c.getSystemService(Context.CONNECTIVITY_SERVICE);
mR = c.getResources();
mPendingChatFileMessage = new ArrayList<LinphoneChatMessage>();
}
private static final int LINPHONE_VOLUME_STREAM = STREAM_VOICE_CALL;
@ -170,6 +190,7 @@ public class LinphoneManager implements LinphoneCoreListener {
private final String mPauseSoundFile;
private final String mChatDatabaseFile;
private final String mErrorToneFile;
private ByteArrayInputStream mUploadingImageStream;
private Timer mTimer;
@ -213,6 +234,98 @@ public class LinphoneManager implements LinphoneCoreListener {
return instance;
}
public void addDownloadMessagePending(LinphoneChatMessage message){
synchronized (mPendingChatFileMessage) {
mPendingChatFileMessage.add(message);
}
}
public boolean isMessagePending(LinphoneChatMessage message){
boolean messagePending = false;
synchronized (mPendingChatFileMessage) {
for (LinphoneChatMessage chat : mPendingChatFileMessage) {
if (chat.getStorageId() == message.getStorageId()) {
messagePending = true;
break;
}
}
}
return messagePending;
}
public void removePendingMessage(LinphoneChatMessage message){
synchronized (mPendingChatFileMessage) {
for (LinphoneChatMessage chat : mPendingChatFileMessage) {
if (chat.getStorageId() == message.getStorageId()) {
mPendingChatFileMessage.remove(chat);
}
break;
}
}
}
public void setUploadPendingFileMessage(LinphoneChatMessage message){
mUploadPendingFileMessage = message;
}
public LinphoneChatMessage getMessageUploadPending(){
return mUploadPendingFileMessage;
}
public void setUploadingImageStream(ByteArrayInputStream array){
this.mUploadingImageStream = array;
}
@Override
public void onLinphoneChatMessageStateChanged(LinphoneChatMessage msg, LinphoneChatMessage.State state) {
if (state == LinphoneChatMessage.State.FileTransferDone || state == LinphoneChatMessage.State.FileTransferError) {
if(msg.isOutgoing() && mUploadingImageStream != null){
mUploadPendingFileMessage = null;
mUploadingImageStream = null;
} else {
File file = new File(Environment.getExternalStorageDirectory(), msg.getFileTransferInformation().getName());
try {
String url = MediaStore.Images.Media.insertImage(getContext().getContentResolver(), file.getPath(), msg.getFileTransferInformation().getName(), null);
msg.setAppData(url);
file.delete();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
removePendingMessage(msg);
}
}
for (LinphoneChatMessage.LinphoneChatMessageListener l: simpleListeners) {
l.onLinphoneChatMessageStateChanged(msg, state);
}
}
@Override
public void onLinphoneChatMessageFileTransferReceived(LinphoneChatMessage msg, LinphoneContent content, LinphoneBuffer buffer) {
}
@Override
public void onLinphoneChatMessageFileTransferSent(LinphoneChatMessage msg, LinphoneContent content, int offset, int size, LinphoneBuffer bufferToFill) {
if (mUploadingImageStream != null && size > 0) {
byte[] data = new byte[size];
int read = mUploadingImageStream.read(data, 0, size);
if (read > 0) {
bufferToFill.setContent(data);
bufferToFill.setSize(read);
} else {
Log.e("Error, upload task asking for more bytes(" + size + ") than available (" + mUploadingImageStream.available() + ")");
}
}
}
@Override
public void onLinphoneChatMessageFileTransferProgressChanged(LinphoneChatMessage msg, LinphoneContent content, int offset, int total) {
for (LinphoneChatMessage.LinphoneChatMessageListener l: simpleListeners) {
l.onLinphoneChatMessageFileTransferProgressChanged(msg, content, offset, total);
}
}
private boolean isPresenceModelActivitySet() {
LinphoneCore lc = getLcIfManagerNotDestroyedOrNull();
if (isInstanciated() && lc != null) {
@ -331,7 +444,6 @@ public class LinphoneManager implements LinphoneCoreListener {
LinphoneManager.getLc().setVideoDevice(camId);
}
public static interface AddressType {
void setText(CharSequence s);
CharSequence getText();
@ -688,11 +800,6 @@ public class LinphoneManager implements LinphoneCoreListener {
public void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf) {
}
public void textReceived(LinphoneCore lc, LinphoneChatRoom cr,
LinphoneAddress from, String message) {
//deprecated
}
@Override
public void dtmfReceived(LinphoneCore lc, LinphoneCall call, int dtmf) {
Log.d("DTMF received: " + dtmf);
@ -1097,7 +1204,6 @@ public class LinphoneManager implements LinphoneCoreListener {
return distanceInCm < threshold;
}
private static boolean sLastProximitySensorValueNearby;
private static Set<Activity> sProximityDependentActivities = new HashSet<Activity>();
private static SensorEventListener sProximitySensorListener = new SensorEventListener() {

View file

@ -430,8 +430,10 @@ public class LinphonePreferences {
prxCfg.setIdentity(identity);
prxCfg.done();
info.setUsername(username);
saveAuthInfo(info);
if(info != null) {
info.setUsername(username);
saveAuthInfo(info);
}
} catch (LinphoneCoreException e) {
e.printStackTrace();
}
@ -468,8 +470,10 @@ public class LinphonePreferences {
public void setAccountUserId(int n, String userId) {
LinphoneAuthInfo info = getClonedAuthInfo(n);
info.setUserId(userId);
saveAuthInfo(info);
if(info != null) {
info.setUserId(userId);
saveAuthInfo(info);
}
}
public String getAccountUserId(int n) {
@ -479,8 +483,10 @@ public class LinphonePreferences {
public void setAccountPassword(int n, String password) {
LinphoneAuthInfo info = getClonedAuthInfo(n);
info.setPassword(password);
saveAuthInfo(info);
if(info != null) {
info.setPassword(password);
saveAuthInfo(info);
}
}
public String getAccountPassword(int n) {
@ -492,8 +498,10 @@ public class LinphonePreferences {
try {
LinphoneAuthInfo authInfo = getClonedAuthInfo(n);
authInfo.setDomain(domain);
saveAuthInfo(authInfo);
if(authInfo != null) {
authInfo.setDomain(domain);
saveAuthInfo(authInfo);
}
LinphoneProxyConfig prxCfg = getProxyConfig(n);
prxCfg.edit();
@ -1026,7 +1034,7 @@ public class LinphonePreferences {
}
public boolean isAutoStartEnabled() {
return getConfig().getBool("app", "auto_start", false);
return getConfig().getBool("app", "auto_start", true);
}
public void setAutoStart(boolean autoStartEnabled) {

View file

@ -119,10 +119,14 @@ public class StatusFragment extends Fragment {
if (!isAttached || !LinphoneService.isReady()) {
return;
}
if (lc.getDefaultProxyConfig().equals(proxy)) {
statusLed.setImageResource(getStatusIconResource(state, true));
statusText.setText(getStatusIconText(state));
}
if (lc.getDefaultProxyConfig() != null && lc.getDefaultProxyConfig().equals(proxy)) {
statusLed.setImageResource(getStatusIconResource(state, true));
statusText.setText(getStatusIconText(state));
} else if(lc.getDefaultProxyConfig() == null) {
statusLed.setImageResource(getStatusIconResource(state, true));
statusText.setText(getStatusIconText(state));
}
try {
if (getResources().getBoolean(R.bool.lock_statusbar)) {
@ -554,6 +558,9 @@ public class StatusFragment extends Fragment {
CheckBox checkBox = (CheckBox) v;
if (checkBox.isChecked()) {
String tag = (String) checkBox.getTag();
if(tag.startsWith("sip:")) {
tag = tag.substring(4);
}
String sipAddress = tag.split(":")[0];
int accountPosition = Integer.parseInt(tag.split(":")[1]);

View file

@ -81,8 +81,6 @@ public class EchoCancellerCalibrationFragment extends Fragment {
return view;
}
public void enableEcCalibrationResultSending(boolean enabled) {
mSendEcCalibrationResult = enabled;
}
@ -111,9 +109,10 @@ public class EchoCancellerCalibrationFragment extends Fragment {
}
};
Log.i("Add echo canceller calibration result: manufacturer=" + Build.MANUFACTURER + " model=" + Build.MODEL + " status=" + status + " delay=" + delayMs + "ms");
client.callAsync(listener, "add_ec_calibration_result", Build.MANUFACTURER, Build.MODEL, status.toString(), delayMs);
}
Boolean hasBuiltInEchoCanceler = LinphoneManager.getLc().hasBuiltInEchoCanceler();
Log.i("Add echo canceller calibration result: manufacturer=" + Build.MANUFACTURER + " model=" + Build.MODEL + " status=" + status + " delay=" + delayMs + "ms" + " hasBuiltInEchoCanceler " + hasBuiltInEchoCanceler);
client.callAsync(listener, "add_ec_calibration_result", Build.MANUFACTURER, Build.MODEL, status.toString(), delayMs, hasBuiltInEchoCanceler);
}
catch(Exception ex) {}
}
}

View file

@ -17,6 +17,7 @@ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
import org.linphone.LinphoneActivity;
import org.linphone.LinphoneManager;
import org.linphone.LinphonePreferences;
import org.linphone.LinphonePreferences.AccountBuilder;
@ -222,7 +223,7 @@ public class SetupActivity extends Activity implements OnClickListener {
cancel.setEnabled(false);
} else {
if (mPrefs.isFirstLaunch()) {
mPrefs.setEchoCancellation(LinphoneManager.getLc().needsEchoCanceler());
mPrefs.setEchoCancellation(LinphoneManager.getLc().hasBuiltInEchoCanceler());
}
success();
}
@ -308,6 +309,9 @@ public class SetupActivity extends Activity implements OnClickListener {
username = username.substring(4);
}
if (username.contains("@"))
username = username.split("@")[0];
if(domain.startsWith("sip:")) {
domain = domain.substring(4);
}
@ -401,6 +405,7 @@ public class SetupActivity extends Activity implements OnClickListener {
public void success() {
mPrefs.firstLaunchSuccessful();
LinphoneActivity.instance().isNewProxyConfig();
setResult(Activity.RESULT_OK);
finish();
}

View file

@ -17,6 +17,7 @@ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.ref.WeakReference;
@ -25,7 +26,9 @@ import java.util.Calendar;
import java.util.HashMap;
import java.util.Map.Entry;
import org.linphone.LinphoneManager;
import org.linphone.R;
import org.linphone.core.LinphoneBuffer;
import org.linphone.core.LinphoneChatMessage;
import org.linphone.core.LinphoneChatMessage.State;
import org.linphone.core.LinphoneContent;
@ -42,6 +45,7 @@ import android.graphics.drawable.Drawable;
import android.media.ThumbnailUtils;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.Html;
import android.text.Spannable;
@ -56,15 +60,13 @@ import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.TextView;
/**
* @author Sylvain Berfini
*/
@SuppressLint("SimpleDateFormat")
public class BubbleChat {
public class BubbleChat implements LinphoneChatMessage.LinphoneChatMessageListener {
private static final HashMap<String, Integer> emoticons = new HashMap<String, Integer>();
static {
emoticons.put(":)", R.drawable.emo_im_happy);
@ -96,82 +98,72 @@ public class BubbleChat {
emoticons.put(":'(", R.drawable.emo_im_crying);
emoticons.put("$.$", R.drawable.emo_im_money_mouth);
}
private RelativeLayout view;
private LinearLayout view;
private ImageView statusView;
private LinphoneChatMessage nativeMessage;
private LinphoneChatMessage.LinphoneChatMessageListener fileTransferListener;
private Context mContext;
private static final int SIZE_MAX = 512;
private ProgressBar spinner;
@SuppressLint("InflateParams")
public BubbleChat(final Context context, LinphoneChatMessage message, LinphoneChatMessage.LinphoneChatMessageListener listener) {
public BubbleChat(final Context context, LinphoneChatMessage message) {
if (message == null) {
return;
}
nativeMessage = message;
fileTransferListener = listener;
mContext = context;
view = new RelativeLayout(context);
LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
if (message.isOutgoing()) {
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
view.setBackgroundResource(R.drawable.chat_bubble_outgoing);
}
else {
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
view.setBackgroundResource(R.drawable.chat_bubble_incoming);
}
layoutParams.setMargins(10, 0, 10, 0);
view.setId(message.getStorageId());
view.setLayoutParams(layoutParams);
LinearLayout layout;
if (context.getResources().getBoolean(R.bool.display_time_aside)) {
if (message.isOutgoing()) {
layout = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.chat_bubble_alt_outgoing, null);
} else {
layout = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.chat_bubble_alt_incoming, null);
}
} else {
if (message.isOutgoing()) {
layout = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.chat_bubble_outgoing, null);
} else {
layout = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.chat_bubble_incoming, null);
}
}
if (message.isOutgoing()) {
view = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.chat_bubble_outgoing, null);
view.setBackgroundResource(R.drawable.chat_bubble_outgoing);
} else {
view = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.chat_bubble_incoming, null);
view.setBackgroundResource(R.drawable.chat_bubble_incoming);
}
view.setId(message.getStorageId());
spinner = (ProgressBar) view.findViewById(R.id.spinner);
String externalBodyUrl = message.getExternalBodyUrl();
LinphoneContent fileTransferContent = message.getFileTransferInformation();
if (externalBodyUrl != null || fileTransferContent != null) {
Button download = (Button) layout.findViewById(R.id.download);
ImageView imageView = (ImageView) layout.findViewById(R.id.image);
Button download = (Button) view.findViewById(R.id.download);
ImageView imageView = (ImageView) view.findViewById(R.id.image);
String appData = message.getAppData();
if (appData == null) {
download.setVisibility(View.VISIBLE);
download.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
v.setEnabled(false);
ProgressBar spinner = (ProgressBar) view.findViewById(R.id.spinner);
spinner.setVisibility(View.VISIBLE);
v.setVisibility(View.GONE);
LinphoneManager.addListener(this);
if(LinphoneManager.getInstance().isMessagePending(nativeMessage)){
download.setEnabled(false);
ProgressBar spinner = (ProgressBar) view.findViewById(R.id.spinner);
spinner.setVisibility(View.VISIBLE);
download.setVisibility(View.GONE);
} else {
download.setVisibility(View.VISIBLE);
download.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
v.setEnabled(false);
spinner.setVisibility(View.VISIBLE);
v.setVisibility(View.GONE);
nativeMessage.setListener(fileTransferListener);
nativeMessage.downloadFile();
}
});
File file = new File(Environment.getExternalStorageDirectory(), nativeMessage.getFileTransferInformation().getName());
nativeMessage.setListener(LinphoneManager.getInstance());
nativeMessage.setFileTransferFilepath(file.getPath());
nativeMessage.downloadFile();
LinphoneManager.getInstance().addDownloadMessagePending(nativeMessage);
}
});
}
} else {
imageView.setVisibility(View.VISIBLE);
loadBitmap(appData, imageView);
LinphoneManager.removeListener(this);
imageView.setVisibility(View.VISIBLE);
loadBitmap(appData, imageView);
}
} else {
TextView msgView = (TextView) layout.findViewById(R.id.message);
TextView msgView = (TextView) view.findViewById(R.id.message);
if (msgView != null) {
Spanned text = null;
String msg = message.getText();
@ -188,11 +180,11 @@ public class BubbleChat {
}
}
TextView timeView = (TextView) layout.findViewById(R.id.time);
TextView timeView = (TextView) view.findViewById(R.id.time);
timeView.setText(timestampToHumanDate(context, message.getTime()));
LinphoneChatMessage.State status = message.getStatus();
statusView = (ImageView) layout.findViewById(R.id.status);
statusView = (ImageView) view.findViewById(R.id.status);
if (statusView != null) {
if (status == LinphoneChatMessage.State.Delivered) {
statusView.setImageResource(R.drawable.chat_message_delivered);
@ -203,7 +195,7 @@ public class BubbleChat {
}
}
view.addView(layout);
//view.addView(layout);
}
public void updateStatusView() {
@ -325,7 +317,7 @@ public class BubbleChat {
task.execute(path);
}
}
private class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> {
private final WeakReference<ImageView> imageViewReference;
public String path;
@ -432,4 +424,22 @@ public class BubbleChat {
}
return null;
}
@Override
public void onLinphoneChatMessageStateChanged(LinphoneChatMessage msg, State state) {
}
@Override
public void onLinphoneChatMessageFileTransferReceived(LinphoneChatMessage msg, LinphoneContent content, LinphoneBuffer buffer) {
}
@Override
public void onLinphoneChatMessageFileTransferSent(LinphoneChatMessage msg, LinphoneContent content, int offset, int size, LinphoneBuffer bufferToFill) {
}
@Override
public void onLinphoneChatMessageFileTransferProgressChanged(LinphoneChatMessage msg, LinphoneContent content, int offset, int total) {
if(nativeMessage.getStorageId() == msg.getStorageId())
spinner.setProgress(offset * 100 / total);
}
}

@ -1 +1 @@
Subproject commit 580012c556ba0e4d0f09bf3f182cdf55e030f215
Subproject commit 91ae7c164d9d20fd36657943a0aba807b4dfeb4f

@ -1 +1 @@
Subproject commit 157c61d2f5e6b476e8150cfff64e2142795e6d8a
Subproject commit 075f13f233c21caec79ca0e3ed3796f0e0082e4f

View file

@ -338,13 +338,6 @@ public class LinphoneTestManager implements LinphoneCoreListener{
}
@Override
public void textReceived(LinphoneCore lc, LinphoneChatRoom cr,
LinphoneAddress from, String message) {
// TODO Auto-generated method stub
}
@Override
public void messageReceived(LinphoneCore lc, LinphoneChatRoom cr,
LinphoneChatMessage message) {