Merge branch 'master' into dev_in_app_purchase

This commit is contained in:
Sylvain Berfini 2015-04-28 16:37:46 +02:00
commit 6eab3e71b9
26 changed files with 302 additions and 90 deletions

View file

@ -13,7 +13,7 @@ dependencies {
} }
android { android {
compileSdkVersion 19 compileSdkVersion 22
buildToolsVersion "20.0.0" buildToolsVersion "20.0.0"
sourceSets { sourceSets {

View file

@ -55,7 +55,7 @@
<antcall target="check-for-crash"/> <antcall target="check-for-crash"/>
<fail message="Tests failed"> <fail message="Tests failed" status="42">
<condition> <condition>
<resourcecontains resource="${output.file}" substring="FAILURES" /> <resourcecontains resource="${output.file}" substring="FAILURES" />
</condition> </condition>
@ -73,6 +73,6 @@
<arg value="-c" /> <arg value="-c" />
<arg value="cat ${archive.name} |ndk-stack -sym obj/local/`adb shell getprop ro.product.cpu.abi | tr -d '\r'`" /> <arg value="cat ${archive.name} |ndk-stack -sym obj/local/`adb shell getprop ro.product.cpu.abi | tr -d '\r'`" />
</exec> </exec>
<fail message="Tests crashed"/> <fail message="Tests crashed" status="125"/>
</target> </target>
</project> </project>

View file

@ -393,7 +393,7 @@
<string name="setup_remote_provisioning_hint">Cet assistant va télécharger une configuration existante.</string> <string name="setup_remote_provisioning_hint">Cet assistant va télécharger une configuration existante.</string>
<string name="setup_remote_provisioning_url_hint">addresse où télécharger la configuration</string> <string name="setup_remote_provisioning_url_hint">addresse où télécharger la configuration</string>
<string name="setup_remote_provisioning_login_hint">La configuration téléchargée ne contient pas votre compte. Veuillez le remplir.</string> <string name="setup_remote_provisioning_login_hint">La configuration téléchargée ne contient pas votre compte. Veuillez le remplir.</string>
<string name="setup_confirm_username">Votre nom d\'utilisateur sera %s (les majuscules sont interdites). Acceptez-vous ?</string> <string name="setup_confirm_username">Votre nom d\'utilisateur sera %s.\r\n\r\nIl peut différer de celui que vous avez choisi afin de remplir certains critères nécessaires.\r\nAcceptez-vous ?</string>
<string name="setup_title_assistant">Assistant de création de compte</string> <string name="setup_title_assistant">Assistant de création de compte</string>
<string name="zrtp_accept">Accepter</string> <string name="zrtp_accept">Accepter</string>
<string name="zrtp_deny">Refuser</string> <string name="zrtp_deny">Refuser</string>

View file

@ -33,6 +33,7 @@
<bool name="hide_accounts">false</bool> <bool name="hide_accounts">false</bool>
<bool name="display_account_wizard_at_first_start">true</bool> <bool name="display_account_wizard_at_first_start">true</bool>
<bool name="use_linphone_server_ports">true</bool> <bool name="use_linphone_server_ports">true</bool>
<bool name="allow_only_phone_numbers_in_wizard">true</bool>
<bool name="use_android_native_contact_edit_interface">false</bool> <bool name="use_android_native_contact_edit_interface">false</bool>
<!-- The following settings are only usefull if use_android_native_contact_edit_interface = false --> <!-- The following settings are only usefull if use_android_native_contact_edit_interface = false -->

View file

@ -396,7 +396,7 @@
<string name="setup_remote_provisioning_hint">This assistant will download an existing configuration.</string> <string name="setup_remote_provisioning_hint">This assistant will download an existing configuration.</string>
<string name="setup_remote_provisioning_url_hint">provisioning url</string> <string name="setup_remote_provisioning_url_hint">provisioning url</string>
<string name="setup_remote_provisioning_login_hint">The configuration you downloaded doesn\'t include your account. Please fill it in.</string> <string name="setup_remote_provisioning_login_hint">The configuration you downloaded doesn\'t include your account. Please fill it in.</string>
<string name="setup_confirm_username">Your username will be %s (uppercase characters are not allowed). Do you accept ?</string> <string name="setup_confirm_username">Your username will be %s.\r\n\r\nIt may differ from what you entered to match some requierements.\r\nDo you accept ?</string>
<string name="setup_title_assistant">Account setup assistant</string> <string name="setup_title_assistant">Account setup assistant</string>
<string name="zrtp_accept">Accept</string> <string name="zrtp_accept">Accept</string>
<string name="zrtp_deny">Deny</string> <string name="zrtp_deny">Deny</string>

View file

@ -34,6 +34,7 @@ public class ChatActivity extends FragmentActivity {
extras.putString("SipUri", getIntent().getExtras().getString("SipUri")); extras.putString("SipUri", getIntent().getExtras().getString("SipUri"));
extras.putString("DisplayName", getIntent().getExtras().getString("DisplayName")); extras.putString("DisplayName", getIntent().getExtras().getString("DisplayName"));
extras.putString("PictureUri", getIntent().getExtras().getString("PictureUri")); extras.putString("PictureUri", getIntent().getExtras().getString("PictureUri"));
extras.putString("ThumbnailUri", getIntent().getExtras().getString("ThumbnailUri"));
ChatFragment fragment = new ChatFragment(); ChatFragment fragment = new ChatFragment();
fragment.setArguments(extras); fragment.setArguments(extras);

View file

@ -20,24 +20,29 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar;
import java.util.List; import java.util.List;
import org.linphone.compatibility.Compatibility; import org.linphone.compatibility.Compatibility;
import org.linphone.core.LinphoneAddress; import org.linphone.core.LinphoneAddress;
import org.linphone.core.LinphoneBuffer; import org.linphone.core.LinphoneBuffer;
import org.linphone.core.LinphoneChatMessage; import org.linphone.core.LinphoneChatMessage;
import org.linphone.core.LinphoneChatMessage.LinphoneChatMessageListener; import org.linphone.core.LinphoneChatMessage.LinphoneChatMessageListener;
import org.linphone.core.LinphoneChatMessage.State;
import org.linphone.core.LinphoneChatRoom; import org.linphone.core.LinphoneChatRoom;
import org.linphone.core.LinphoneContent; import org.linphone.core.LinphoneContent;
import org.linphone.core.LinphoneCore; import org.linphone.core.LinphoneCore;
import org.linphone.core.LinphoneChatMessage.State;
import org.linphone.core.LinphoneCoreException;
import org.linphone.core.LinphoneCoreFactory; import org.linphone.core.LinphoneCoreFactory;
import org.linphone.core.LinphoneCoreListenerBase; import org.linphone.core.LinphoneCoreListenerBase;
import org.linphone.mediastream.Log; import org.linphone.mediastream.Log;
import org.linphone.ui.AvatarWithShadow; import org.linphone.ui.AvatarWithShadow;
import org.linphone.ui.BubbleChat; import org.linphone.ui.BubbleChat;
import android.support.v4.content.CursorLoader;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.Activity; import android.app.Activity;
@ -52,10 +57,10 @@ import android.graphics.Rect;
import android.net.Uri; import android.net.Uri;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.os.Environment;
import android.os.Parcelable; import android.os.Parcelable;
import android.provider.MediaStore; import android.provider.MediaStore;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v4.content.CursorLoader;
import android.text.Editable; import android.text.Editable;
import android.text.InputType; import android.text.InputType;
import android.text.TextWatcher; import android.text.TextWatcher;
@ -84,6 +89,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
private static final int MENU_DELETE_MESSAGE = 0; private static final int MENU_DELETE_MESSAGE = 0;
private static final int MENU_COPY_TEXT = 6; private static final int MENU_COPY_TEXT = 6;
private static final int MENU_RESEND_MESSAGE = 7; private static final int MENU_RESEND_MESSAGE = 7;
private static final int SIZE_MAX = 2048;
private LinphoneChatRoom chatRoom; private LinphoneChatRoom chatRoom;
private String sipUri; private String sipUri;
@ -334,6 +340,20 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
} }
private void displayChatHeader(String displayName, String pictureUri) { private void displayChatHeader(String displayName, String pictureUri) {
LinphoneAddress lAddress;
try {
lAddress = LinphoneCoreFactory.instance().createLinphoneAddress(sipUri);
Contact contact = ContactsManager.getInstance().findContactWithAddress(getActivity().getContentResolver(), lAddress);
if (contact != null) {
LinphoneUtils.setImagePictureFromUri(getActivity(), contactPicture.getView(), contact.getPhotoUri(), contact.getThumbnailUri(), R.drawable.unknown_small);
} else {
contactPicture.setImageResource(R.drawable.unknown_small);
}
} catch (LinphoneCoreException e) {
e.printStackTrace();
}
if (displayName == null && getResources().getBoolean(R.bool.only_display_username_if_unknown) && LinphoneUtils.isSipAddress(sipUri)) { if (displayName == null && getResources().getBoolean(R.bool.only_display_username_if_unknown) && LinphoneUtils.isSipAddress(sipUri)) {
contactName.setText(LinphoneUtils.getUsernameFromAddress(sipUri)); contactName.setText(LinphoneUtils.getUsernameFromAddress(sipUri));
} else if (displayName == null) { } else if (displayName == null) {
@ -342,11 +362,6 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
contactName.setText(displayName); contactName.setText(displayName);
} }
if (pictureUri != null) {
LinphoneUtils.setImagePictureFromUri(getActivity(), contactPicture.getView(), Uri.parse(pictureUri), R.drawable.unknown_small);
} else {
contactPicture.setImageResource(R.drawable.unknown_small);
}
} }
public void changeDisplayedChat(String newSipUri, String displayName, String pictureUri) { public void changeDisplayedChat(String newSipUri, String displayName, String pictureUri) {
@ -526,6 +541,14 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
@Override @Override
protected byte[] doInBackground(Bitmap... params) { protected byte[] doInBackground(Bitmap... params) {
Bitmap bm = params[0]; Bitmap bm = params[0];
if (bm.getWidth() > bm.getHeight() && bm.getWidth() > SIZE_MAX) {
bm = Bitmap.createScaledBitmap(bm, SIZE_MAX, (SIZE_MAX * bm.getHeight()) / bm.getWidth(), false);
} else if (bm.getHeight() > bm.getWidth() && bm.getHeight() > SIZE_MAX) {
bm = Bitmap.createScaledBitmap(bm, (SIZE_MAX * bm.getWidth()) / bm.getHeight(), SIZE_MAX, false);
}
ByteArrayOutputStream stream = new ByteArrayOutputStream(); ByteArrayOutputStream stream = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.PNG, 100, stream); bm.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray(); byte[] byteArray = stream.toByteArray();
@ -601,6 +624,9 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
private void pickImage() { private void pickImage() {
List<Intent> cameraIntents = new ArrayList<Intent>(); List<Intent> cameraIntents = new ArrayList<Intent>();
Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File file = new File(Environment.getExternalStorageDirectory(), getString(R.string.temp_photo_name) + Calendar.getInstance().getTime());
imageToUploadUri = Uri.fromFile(file);
captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageToUploadUri);
cameraIntents.add(captureIntent); cameraIntents.add(captureIntent);
Intent galleryIntent = new Intent(); Intent galleryIntent = new Intent();

View file

@ -356,7 +356,7 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte
Log.e("Chat view cannot parse address",e); Log.e("Chat view cannot parse address",e);
return view; return view;
} }
Contact lContact = ContactsManager.getInstance().findContactWithAddress(address); Contact lContact = ContactsManager.getInstance().findContactWithAddress(getActivity().getContentResolver(), address);
String message = ""; String message = "";
if (useNativeAPI) { if (useNativeAPI) {
@ -365,7 +365,7 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte
if (history != null && history.length > 0) { if (history != null && history.length > 0) {
for (int i = history.length - 1; i >= 0; i--) { for (int i = history.length - 1; i >= 0; i--) {
LinphoneChatMessage msg = history[i]; LinphoneChatMessage msg = history[i];
if (msg.getText() != null && msg.getText().length() > 0) { if (msg.getText() != null && msg.getText().length() > 0 && msg.getFileTransferInformation() == null) {
message = msg.getText(); message = msg.getText();
break; break;
} }

View file

@ -37,6 +37,7 @@ public class Contact implements Serializable {
private String id; private String id;
private String name; private String name;
private transient Uri photoUri; private transient Uri photoUri;
private transient Uri thumbnailUri;
private transient Bitmap photo; private transient Bitmap photo;
private List<String> numbersOrAddresses; private List<String> numbersOrAddresses;
private boolean hasFriends; private boolean hasFriends;
@ -46,23 +47,26 @@ public class Contact implements Serializable {
this.id = id; this.id = id;
this.name = name; this.name = name;
this.photoUri = null; this.photoUri = null;
this.thumbnailUri = null;
this.hasFriends = false; this.hasFriends = false;
} }
public Contact(String id, String name, Uri photo) { public Contact(String id, String name, Uri photo, Uri thumbnail) {
super(); super();
this.id = id; this.id = id;
this.name = name; this.name = name;
this.photoUri = photo; this.photoUri = photo;
this.thumbnailUri = thumbnail;
this.photo = null; this.photo = null;
this.hasFriends = false; this.hasFriends = false;
} }
public Contact(String id, String name, Uri photo, Bitmap picture) { public Contact(String id, String name, Uri photo, Uri thumbnail, Bitmap picture) {
super(); super();
this.id = id; this.id = id;
this.name = name; this.name = name;
this.photoUri = photo; this.photoUri = photo;
this.thumbnailUri = thumbnail;
this.photo = picture; this.photo = picture;
this.hasFriends = false; this.hasFriends = false;
} }
@ -83,6 +87,10 @@ public class Contact implements Serializable {
public Uri getPhotoUri() { public Uri getPhotoUri() {
return photoUri; return photoUri;
} }
public Uri getThumbnailUri() {
return thumbnailUri;
}
public Bitmap getPhoto() { public Bitmap getPhoto() {
return photo; return photo;
@ -96,7 +104,7 @@ public class Contact implements Serializable {
public void refresh(ContentResolver cr) { public void refresh(ContentResolver cr) {
this.numbersOrAddresses = Compatibility.extractContactNumbersAndAddresses(id, cr); this.numbersOrAddresses = Compatibility.extractContactNumbersAndAddresses(id, cr);
for(LinphoneFriend friend : LinphoneManager.getLc().getFriendList()) { for(LinphoneFriend friend : LinphoneManager.getLcIfManagerNotDestroyedOrNull().getFriendList()) {
if (friend.getRefKey().equals(id)) { if (friend.getRefKey().equals(id)) {
hasFriends = true; hasFriends = true;
this.numbersOrAddresses.add(friend.getAddress().asStringUriOnly()); this.numbersOrAddresses.add(friend.getAddress().asStringUriOnly());

View file

@ -26,11 +26,14 @@ import android.content.Context;
import android.database.Cursor; import android.database.Cursor;
import android.net.Uri; import android.net.Uri;
import android.provider.ContactsContract; import android.provider.ContactsContract;
import org.linphone.compatibility.Compatibility; import org.linphone.compatibility.Compatibility;
import org.linphone.core.LinphoneAddress; import org.linphone.core.LinphoneAddress;
import org.linphone.core.LinphoneCore;
import org.linphone.core.LinphoneCoreException; import org.linphone.core.LinphoneCoreException;
import org.linphone.core.LinphoneCoreFactory; import org.linphone.core.LinphoneCoreFactory;
import org.linphone.core.LinphoneFriend; import org.linphone.core.LinphoneFriend;
import org.linphone.core.LinphoneProxyConfig;
import org.linphone.mediastream.Log; import org.linphone.mediastream.Log;
import java.util.ArrayList; import java.util.ArrayList;
@ -101,7 +104,7 @@ public class ContactsManager {
} }
//Contacts //Contacts
public void createNewContact(ArrayList<ContentProviderOperation> ops, String firstName, String lastName){ public void createNewContact(ArrayList<ContentProviderOperation> ops, String firstName, String lastName) {
int contactID = 0; int contactID = 0;
ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI) ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
@ -117,7 +120,7 @@ public class ContactsManager {
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE) .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, firstName) .withValue(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, firstName)
.withValue(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME, lastName) .withValue(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME, lastName)
.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, getDisplayName(firstName,lastName)) .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, getDisplayName(firstName, lastName))
.build() .build()
); );
} }
@ -125,8 +128,8 @@ public class ContactsManager {
public void updateExistingContact(ArrayList<ContentProviderOperation> ops, Contact contact, String firstName, String lastName) { public void updateExistingContact(ArrayList<ContentProviderOperation> ops, Contact contact, String firstName, String lastName) {
if (getDisplayName(firstName, lastName) != null) { if (getDisplayName(firstName, lastName) != null) {
String select = ContactsContract.Data.CONTACT_ID + "=? AND " + ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE + "'" ; String select = ContactsContract.Data.CONTACT_ID + "=? AND " + ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE + "'";
String[] args = new String[] { String.valueOf(contact.getID()) }; String[] args = new String[]{String.valueOf(contact.getID())};
ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI) ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
.withSelection(select, args) .withSelection(select, args)
@ -145,12 +148,13 @@ public class ContactsManager {
} }
LinphoneFriend friend = LinphoneCoreFactory.instance().createLinphoneFriend(sipUri); LinphoneFriend friend = LinphoneCoreFactory.instance().createLinphoneFriend(sipUri);
if(friend != null) { if (friend != null) {
friend.edit(); friend.edit();
friend.enableSubscribes(false);
friend.setRefKey(contact.getID()); friend.setRefKey(contact.getID());
friend.done(); friend.done();
try { try {
LinphoneManager.getLc().addFriend(friend); LinphoneManager.getLcIfManagerNotDestroyedOrNull().addFriend(friend);
return true; return true;
} catch (LinphoneCoreException e) { } catch (LinphoneCoreException e) {
e.printStackTrace(); e.printStackTrace();
@ -170,8 +174,8 @@ public class ContactsManager {
oldSipUri = "sip:" + oldSipUri; oldSipUri = "sip:" + oldSipUri;
} }
LinphoneFriend friend = LinphoneManager.getLc().findFriendByAddress(oldSipUri); LinphoneFriend friend = LinphoneManager.getLcIfManagerNotDestroyedOrNull().findFriendByAddress(oldSipUri);
if(friend != null) { if (friend != null) {
friend.edit(); friend.edit();
try { try {
friend.setAddress(LinphoneCoreFactory.instance().createLinphoneAddress(newSipUri)); friend.setAddress(LinphoneCoreFactory.instance().createLinphoneAddress(newSipUri));
@ -187,36 +191,59 @@ public class ContactsManager {
sipUri = "sip:" + sipUri; sipUri = "sip:" + sipUri;
} }
LinphoneFriend friend = LinphoneManager.getLc().findFriendByAddress(sipUri); LinphoneFriend friend = LinphoneManager.getLcIfManagerNotDestroyedOrNull().findFriendByAddress(sipUri);
if (friend != null) { if (friend != null) {
LinphoneManager.getLc().removeFriend(friend); LinphoneManager.getLcIfManagerNotDestroyedOrNull().removeFriend(friend);
return true; return true;
} }
return false; return false;
} }
public void removeAllFriends(Contact contact) { public void removeAllFriends(Contact contact) {
for(LinphoneFriend friend : LinphoneManager.getLc().getFriendList()){ for (LinphoneFriend friend : LinphoneManager.getLcIfManagerNotDestroyedOrNull().getFriendList()) {
if(friend.getRefKey().equals(contact.getID())) { if (friend.getRefKey().equals(contact.getID())) {
LinphoneManager.getLc().removeFriend(friend); LinphoneManager.getLcIfManagerNotDestroyedOrNull().removeFriend(friend);
} }
} }
} }
public Contact findContactWithDisplayName(String displayName) { public Contact findContactWithDisplayName(String displayName) {
String[] projection = { ContactsContract.Data.CONTACT_ID, ContactsContract.Data.DISPLAY_NAME }; String[] projection = {ContactsContract.Data.CONTACT_ID, ContactsContract.Data.DISPLAY_NAME};
String selection = new StringBuilder() String selection = new StringBuilder()
.append(ContactsContract.Data.DISPLAY_NAME) .append(ContactsContract.Data.DISPLAY_NAME)
.append(" = ?").toString(); .append(" = ?").toString();
Cursor c = contentResolver.query(ContactsContract.Data.CONTENT_URI,projection,selection, Cursor c = contentResolver.query(ContactsContract.Data.CONTENT_URI, projection, selection,
new String[]{displayName}, null); new String[]{displayName}, null);
if (c != null) { if (c != null) {
if (c.moveToFirst()) { if (c.moveToFirst()) {
Contact contact = Compatibility.getContact(contentResolver,c,c.getPosition()); Contact contact = Compatibility.getContact(contentResolver, c, c.getPosition());
c.close(); c.close();
if(contact != null) { if (contact != null) {
return contact;
} else {
return null;
}
}
c.close();
}
return null;
}
public Contact getContact(String id, ContentResolver contentResolver){
String[] projection = {ContactsContract.Data.CONTACT_ID, ContactsContract.Data.DISPLAY_NAME};
String selection = new StringBuilder()
.append(ContactsContract.Data.CONTACT_ID)
.append(" = ?").toString();
Cursor c = contentResolver.query(ContactsContract.Data.CONTENT_URI, projection, selection, new String[]{id}, null);
if(c!=null){
if (c.moveToFirst()) {
Contact contact = Compatibility.getContact(contentResolver, c, c.getPosition());
c.close();
if (contact != null) {
return contact; return contact;
} else { } else {
return null; return null;
@ -229,8 +256,11 @@ public class ContactsManager {
public List<String> getContactsId(){ public List<String> getContactsId(){
List<String> ids = new ArrayList<String>(); List<String> ids = new ArrayList<String>();
if(LinphoneManager.getLc().getFriendList() == null) return null; if(LinphoneManager.getLcIfManagerNotDestroyedOrNull().getFriendList() == null) return null;
for(LinphoneFriend friend : LinphoneManager.getLc().getFriendList()) { for(LinphoneFriend friend : LinphoneManager.getLcIfManagerNotDestroyedOrNull().getFriendList()) {
friend.edit();
friend.enableSubscribes(false);
friend.done();
if(!ids.contains(friend.getRefKey())){ if(!ids.contains(friend.getRefKey())){
ids.add(friend.getRefKey()); ids.add(friend.getRefKey());
} }
@ -241,15 +271,18 @@ public class ContactsManager {
//End linphone Friend //End linphone Friend
public boolean removeContactTagIsNeeded(Contact contact){ public boolean removeContactTagIsNeeded(Contact contact){
contact.refresh(contentResolver); LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
boolean onlyNumbers = true; if (lc != null) {
for(String address: contact.getNumbersOrAddresses()){ LinphoneProxyConfig lpc = lc.createProxyConfig();
if(LinphoneUtils.isSipAddress(address)){ contact.refresh(contentResolver);
onlyNumbers = false; for (String address : contact.getNumbersOrAddresses()) {
if (!lpc.isPhoneNumber(address)) {
return false;
}
} }
return true;
} }
return false;
return onlyNumbers;
} }
public void removeLinphoneContactTag(Contact contact){ public void removeLinphoneContactTag(Contact contact){
@ -270,12 +303,84 @@ public class ContactsManager {
} }
} }
public Contact findContactWithAddress(LinphoneAddress address){ private Contact checkPhoneQueryResult(ContentResolver contentResolver, Cursor c, String columnPhone, String columnId, String username) {
for(Contact contact : contactList){ boolean contactFound = false;
if(contact.getNumbersOrAddresses().contains(address.asStringUriOnly()) || contact.getNumbersOrAddresses().contains(address.getUserName())){
return contact; if (c != null) {
while (!contactFound && c.moveToNext()) {
String phone = c.getString(c.getColumnIndex(columnPhone));
if (phone.equals(username)) {
contactFound = true;
} else {
String normalizedUsername = null;
LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
if (lc != null) {
LinphoneProxyConfig lpc = lc.getDefaultProxyConfig();
if (lpc != null) {
normalizedUsername = lpc.normalizePhoneNumber(phone);
}
}
if (normalizedUsername != null && normalizedUsername.equals(username)) {
contactFound = true;
}
}
if(contactFound){
Contact contact = getContact(c.getString(c.getColumnIndex(columnId)), contentResolver);
c.close();
return contact;
}
}
c.close();
}
return null;
}
public Contact findContactWithAddress(ContentResolver contentResolver, LinphoneAddress address){
String sipUri = address.asStringUriOnly();
if (sipUri.startsWith("sip:"))
sipUri = sipUri.substring(4);
if(LinphoneManager.getLcIfManagerNotDestroyedOrNull().getFriendList() != null && LinphoneManager.getLcIfManagerNotDestroyedOrNull().getFriendList().length > 0) {
for (LinphoneFriend friend : LinphoneManager.getLcIfManagerNotDestroyedOrNull().getFriendList()) {
if (friend.getAddress().equals(address)) {
return getContact(friend.getRefKey(), contentResolver);
}
} }
} }
//Find Sip address
Contact contact;
String [] projection = new String[] {ContactsContract.Data.CONTACT_ID, ContactsContract.Data.DISPLAY_NAME};
String selection = new StringBuilder()
.append(ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS)
.append(" = ?").toString();
Cursor cur = contentResolver.query(ContactsContract.Data.CONTENT_URI, projection, selection,
new String[]{sipUri}, null);
if (cur != null) {
if (cur.moveToFirst()) {
contact = Compatibility.getContact(contentResolver, cur, cur.getPosition());
cur.close();
if (contact != null) {
return contact;
}
}
cur.close();
}
//Find number
Uri lookupUri = Uri.withAppendedPath(android.provider.ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(address.getUserName()));
projection = new String[] {ContactsContract.PhoneLookup._ID,ContactsContract.PhoneLookup.NUMBER,ContactsContract.PhoneLookup.DISPLAY_NAME };
Cursor c = contentResolver.query(lookupUri, projection, null, null, null);
contact = checkPhoneQueryResult(contentResolver, c, ContactsContract.PhoneLookup.NUMBER, ContactsContract.PhoneLookup._ID, address.getUserName());
if (contact != null) {
return contact;
}
return null; return null;
} }
@ -425,7 +530,7 @@ public class ContactsManager {
contact.refresh(contentResolver); contact.refresh(contentResolver);
//Add tag to Linphone contact if it not existed //Add tag to Linphone contact if it not existed
if (LinphoneActivity.instance().getResources().getBoolean(R.bool.use_linphone_tag)) { if (LinphoneActivity.isInstanciated() && LinphoneActivity.instance().getResources().getBoolean(R.bool.use_linphone_tag)) {
if (!isContactHasLinphoneTag(contact, contentResolver)) { if (!isContactHasLinphoneTag(contact, contentResolver)) {
Compatibility.createLinphoneContactTag(context, contentResolver, contact, Compatibility.createLinphoneContactTag(context, contentResolver, contact,
findRawContactID(contentResolver, String.valueOf(contact.getID()))); findRawContactID(contentResolver, String.valueOf(contact.getID())));
@ -438,13 +543,12 @@ public class ContactsManager {
if (contactCursor != null) { if (contactCursor != null) {
for (int i = 0; i < contactCursor.getCount(); i++) { for (int i = 0; i < contactCursor.getCount(); i++) {
Contact contact = Compatibility.getContact(contentResolver, contactCursor, i); Contact contact = Compatibility.getContact(contentResolver, contactCursor, i);
if (contact == null) if (contact == null)
continue; continue;
//Remove linphone contact tag if the contact has no sip address //Remove linphone contact tag if the contact has no sip address
if (LinphoneActivity.instance().getResources().getBoolean(R.bool.use_linphone_tag)) { if (LinphoneActivity.isInstanciated() && LinphoneActivity.instance().getResources().getBoolean(R.bool.use_linphone_tag)) {
if (removeContactTagIsNeeded(contact) && isContactHasLinphoneTag(contact, contentResolver)) { if (removeContactTagIsNeeded(contact) && findRawLinphoneContactID(contact.getID()) != null) {
removeLinphoneContactTag(contact); removeLinphoneContactTag(contact);
} }
} }

View file

@ -102,6 +102,7 @@ public class EditContactFragment extends Fragment {
try { try {
getActivity().getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops); getActivity().getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
addLinphoneFriendIfNeeded(); addLinphoneFriendIfNeeded();
removeLinphoneTagIfNeeded();
contactsManager.prepareContactsInBackground(); contactsManager.prepareContactsInBackground();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
@ -415,6 +416,21 @@ public class EditContactFragment extends Fragment {
} }
} }
} }
private void removeLinphoneTagIfNeeded(){
if(!isNewContact) {
boolean areAllSipFielsEmpty = true;
for (NewOrUpdatedNumberOrAddress nounoa : numbersAndAddresses) {
if (!nounoa.isSipAddress && (nounoa.oldNumberOrAddress != null && !nounoa.oldNumberOrAddress.equals("") || nounoa.newNumberOrAddress != null && !nounoa.newNumberOrAddress.equals(""))) {
areAllSipFielsEmpty = false;
break;
}
}
if (areAllSipFielsEmpty && contactsManager.findRawLinphoneContactID(contact.getID()) != null) {
contactsManager.removeLinphoneContactTag(contact);
}
}
}
class NewOrUpdatedNumberOrAddress { class NewOrUpdatedNumberOrAddress {
private String oldNumberOrAddress; private String oldNumberOrAddress;

View file

@ -23,6 +23,7 @@ import java.util.Calendar;
import org.linphone.core.LinphoneAddress; import org.linphone.core.LinphoneAddress;
import org.linphone.core.LinphoneCoreException; import org.linphone.core.LinphoneCoreException;
import org.linphone.core.LinphoneCoreFactory; import org.linphone.core.LinphoneCoreFactory;
import org.linphone.mediastream.Log;
import org.linphone.ui.AvatarWithShadow; import org.linphone.ui.AvatarWithShadow;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
@ -112,12 +113,12 @@ public class HistoryDetailFragment extends Fragment implements OnClickListener {
LinphoneAddress lAddress; LinphoneAddress lAddress;
try { try {
lAddress = LinphoneCoreFactory.instance().createLinphoneAddress(sipUri); lAddress = LinphoneCoreFactory.instance().createLinphoneAddress(sipUri);
Contact contact = ContactsManager.getInstance().findContactWithAddress(lAddress); Contact contact = ContactsManager.getInstance().findContactWithAddress(getActivity().getContentResolver(), lAddress);
if (contact != null) { if (contact != null) {
LinphoneUtils.setImagePictureFromUri(view.getContext(), contactPicture.getView(),contact.getPhotoUri(), R.drawable.unknown_small); LinphoneUtils.setImagePictureFromUri(view.getContext(), contactPicture.getView(),contact.getPhotoUri(), contact.getThumbnailUri(), R.drawable.unknown_small);
view.findViewById(R.id.addContactRow).setVisibility(View.GONE); view.findViewById(R.id.addContactRow).setVisibility(View.GONE);
} else { } else {
LinphoneUtils.setImagePictureFromUri(view.getContext(), contactPicture.getView(),null ,R.drawable.unknown_small); LinphoneUtils.setImagePictureFromUri(view.getContext(), contactPicture.getView(),null, null ,R.drawable.unknown_small);
} }
} catch (LinphoneCoreException e) { } catch (LinphoneCoreException e) {
e.printStackTrace(); e.printStackTrace();

View file

@ -178,7 +178,7 @@ public class HistoryFragment extends Fragment implements OnClickListener, OnChil
address = log.getTo(); address = log.getTo();
} }
Contact contact = ContactsManager.getInstance().findContactWithAddress(address); Contact contact = ContactsManager.getInstance().findContactWithAddress(getActivity().getContentResolver(), address);
String sipUri = address.asStringUriOnly(); String sipUri = address.asStringUriOnly();
if (contact == null) { if (contact == null) {
if (getResources().getBoolean(R.bool.only_display_username_if_unknown) && LinphoneUtils.isSipAddress(sipUri)) { if (getResources().getBoolean(R.bool.only_display_username_if_unknown) && LinphoneUtils.isSipAddress(sipUri)) {

View file

@ -392,7 +392,7 @@ public class HistorySimpleFragment extends Fragment implements OnClickListener,
callDirection.setImageBitmap(outgoingCall); callDirection.setImageBitmap(outgoingCall);
} }
Contact c = ContactsManager.getInstance().findContactWithAddress(address); Contact c = ContactsManager.getInstance().findContactWithAddress(getActivity().getContentResolver(), address);
String displayName = null; String displayName = null;
final String sipUri = address.asStringUriOnly(); final String sipUri = address.asStringUriOnly();
if(c != null){ if(c != null){

View file

@ -1299,11 +1299,11 @@ public class InCallActivity extends FragmentActivity implements OnClickListener
// Image Row // Image Row
LinearLayout imageView = (LinearLayout) inflater.inflate(R.layout.active_call_image_row, container, false); LinearLayout imageView = (LinearLayout) inflater.inflate(R.layout.active_call_image_row, container, false);
Contact contact = ContactsManager.getInstance().findContactWithAddress(lAddress); Contact contact = ContactsManager.getInstance().findContactWithAddress(imageView.getContext().getContentResolver(), lAddress);
if(contact != null) { if(contact != null) {
displayOrHideContactPicture(imageView, contact.getPhotoUri(), false); displayOrHideContactPicture(imageView, contact.getPhotoUri(), contact.getThumbnailUri(), false);
} else { } else {
displayOrHideContactPicture(imageView, null, false); displayOrHideContactPicture(imageView, null, null, false);
} }
callsList.addView(imageView); callsList.addView(imageView);
@ -1326,7 +1326,7 @@ public class InCallActivity extends FragmentActivity implements OnClickListener
private void setContactName(LinearLayout callView, LinphoneAddress lAddress, String sipUri, Resources resources) { private void setContactName(LinearLayout callView, LinphoneAddress lAddress, String sipUri, Resources resources) {
TextView contact = (TextView) callView.findViewById(R.id.contactNameOrNumber); TextView contact = (TextView) callView.findViewById(R.id.contactNameOrNumber);
Contact lContact = ContactsManager.getInstance().findContactWithAddress(lAddress); Contact lContact = ContactsManager.getInstance().findContactWithAddress(callView.getContext().getContentResolver(), lAddress);
if (lContact == null) { if (lContact == null) {
if (resources.getBoolean(R.bool.only_display_username_if_unknown) && LinphoneUtils.isSipAddress(sipUri)) { if (resources.getBoolean(R.bool.only_display_username_if_unknown) && LinphoneUtils.isSipAddress(sipUri)) {
contact.setText(lAddress.getUserName()); contact.setText(lAddress.getUserName());
@ -1366,10 +1366,10 @@ public class InCallActivity extends FragmentActivity implements OnClickListener
return isCallPaused || isInConference; return isCallPaused || isInConference;
} }
private void displayOrHideContactPicture(LinearLayout callView, Uri pictureUri, boolean hide) { private void displayOrHideContactPicture(LinearLayout callView, Uri pictureUri, Uri thumbnailUri, boolean hide) {
AvatarWithShadow contactPicture = (AvatarWithShadow) callView.findViewById(R.id.contactPicture); AvatarWithShadow contactPicture = (AvatarWithShadow) callView.findViewById(R.id.contactPicture);
if (pictureUri != null) { if (pictureUri != null) {
LinphoneUtils.setImagePictureFromUri(callView.getContext(), contactPicture.getView(), Uri.parse(pictureUri.toString()), R.drawable.unknown_small); LinphoneUtils.setImagePictureFromUri(callView.getContext(), contactPicture.getView(), Uri.parse(pictureUri.toString()), thumbnailUri, R.drawable.unknown_small);
} }
callView.setVisibility(hide ? View.GONE : View.VISIBLE); callView.setVisibility(hide ? View.GONE : View.VISIBLE);
} }

View file

@ -124,8 +124,9 @@ public class IncomingCallActivity extends Activity implements LinphoneSliderTrig
} }
LinphoneAddress address = mCall.getRemoteAddress(); LinphoneAddress address = mCall.getRemoteAddress();
// May be greatly sped up using a drawable cache // May be greatly sped up using a drawable cache
Contact contact = ContactsManager.getInstance().findContactWithAddress(address); Contact contact = ContactsManager.getInstance().findContactWithAddress(getContentResolver(), address);
LinphoneUtils.setImagePictureFromUri(this, mPictureView.getView(), contact != null ? contact.getPhotoUri() : null, R.drawable.unknown_small); LinphoneUtils.setImagePictureFromUri(this, mPictureView.getView(), contact != null ? contact.getPhotoUri() : null,
contact != null ? contact.getThumbnailUri() : null, R.drawable.unknown_small);
// To be done after findUriPictureOfContactAndSetDisplayName called // To be done after findUriPictureOfContactAndSetDisplayName called
mNameView.setText(contact != null ? contact.getName() : ""); mNameView.setText(contact != null ? contact.getName() : "");

View file

@ -518,7 +518,7 @@ public class LinphoneActivity extends FragmentActivity implements OnClickListene
Log.e("Cannot display history details",e); Log.e("Cannot display history details",e);
return; return;
} }
Contact c = ContactsManager.getInstance().findContactWithAddress(lAddress); Contact c = ContactsManager.getInstance().findContactWithAddress(getContentResolver(), lAddress);
String displayName = c != null ? c.getName() : null; String displayName = c != null ? c.getName() : null;
String pictureUri = c != null && c.getPhotoUri() != null ? c.getPhotoUri().toString() : null; String pictureUri = c != null && c.getPhotoUri() != null ? c.getPhotoUri().toString() : null;
@ -611,9 +611,15 @@ public class LinphoneActivity extends FragmentActivity implements OnClickListene
Log.e("Cannot display chat",e); Log.e("Cannot display chat",e);
return; return;
} }
Contact contact = ContactsManager.getInstance().findContactWithAddress(lAddress); Contact contact = ContactsManager.getInstance().findContactWithAddress(getContentResolver(), lAddress);
String displayName = contact != null ? contact.getName() : null; String displayName = contact != null ? contact.getName() : null;
String pictureUri = contact != null && contact.getPhotoUri() != null ? contact.getPhotoUri().toString() : null;
String pictureUri = null;
String thumbnailUri = null;
if(contact != null && contact.getPhotoUri() != null){
pictureUri = contact.getPhotoUri().toString();
thumbnailUri = contact.getThumbnailUri().toString();
}
if (isTablet()){ if (isTablet()){
if (currentFragment == FragmentsAvailable.CHATLIST || currentFragment == FragmentsAvailable.CHAT){ if (currentFragment == FragmentsAvailable.CHATLIST || currentFragment == FragmentsAvailable.CHAT){
@ -624,9 +630,10 @@ public class LinphoneActivity extends FragmentActivity implements OnClickListene
} else { } else {
Bundle extras = new Bundle(); Bundle extras = new Bundle();
extras.putString("SipUri", sipUri); extras.putString("SipUri", sipUri);
if (lAddress.getDisplayName() != null) { if (contact != null) {
extras.putString("DisplayName", displayName); extras.putString("DisplayName", displayName);
extras.putString("PictureUri", pictureUri); extras.putString("PictureUri", pictureUri);
extras.putString("ThumbnailUri", thumbnailUri);
} }
changeCurrentFragment(FragmentsAvailable.CHAT, extras); changeCurrentFragment(FragmentsAvailable.CHAT, extras);
} }
@ -639,7 +646,8 @@ public class LinphoneActivity extends FragmentActivity implements OnClickListene
intent.putExtra("SipUri", sipUri); intent.putExtra("SipUri", sipUri);
if (contact != null) { if (contact != null) {
intent.putExtra("DisplayName", contact.getName()); intent.putExtra("DisplayName", contact.getName());
intent.putExtra("PictureUri", contact.getPhotoUri()); intent.putExtra("PictureUri", pictureUri);
intent.putExtra("ThumbnailUri", thumbnailUri);
} }
startOrientationSensor(); startOrientationSensor();
startActivityForResult(intent, CHAT_ACTIVITY); startActivityForResult(intent, CHAT_ACTIVITY);

View file

@ -715,7 +715,7 @@ public class LinphoneManager implements LinphoneCoreListener {
} }
try { try {
Contact contact = ContactsManager.getInstance().findContactWithAddress(from); Contact contact = ContactsManager.getInstance().findContactWithAddress(mServiceContext.getContentResolver(),from);
if (!mServiceContext.getResources().getBoolean(R.bool.disable_chat__message_notification)) { if (!mServiceContext.getResources().getBoolean(R.bool.disable_chat__message_notification)) {
if(contact != null) { if(contact != null) {
LinphoneService.instance().displayMessageNotification(from.asStringUriOnly(), contact.getName(), textMessage); LinphoneService.instance().displayMessageNotification(from.asStringUriOnly(), contact.getName(), textMessage);

View file

@ -312,7 +312,7 @@ public final class LinphoneService extends Service {
LinphoneAddress address = LinphoneCoreFactory.instance().createLinphoneAddress(userName,domain,null); LinphoneAddress address = LinphoneCoreFactory.instance().createLinphoneAddress(userName,domain,null);
address.setDisplayName(displayName); address.setDisplayName(displayName);
Contact contact = ContactsManager.getInstance().findContactWithAddress(address); Contact contact = ContactsManager.getInstance().findContactWithAddress(getContentResolver(), address);
Uri pictureUri = contact != null ? contact.getPhotoUri() : null; Uri pictureUri = contact != null ? contact.getPhotoUri() : null;
Bitmap bm = null; Bitmap bm = null;
try { try {
@ -390,7 +390,7 @@ public final class LinphoneService extends Service {
Uri pictureUri = null; Uri pictureUri = null;
try { try {
Contact contact = ContactsManager.getInstance().findContactWithAddress(LinphoneCoreFactory.instance().createLinphoneAddress(fromSipUri)); Contact contact = ContactsManager.getInstance().findContactWithAddress(getContentResolver(), LinphoneCoreFactory.instance().createLinphoneAddress(fromSipUri));
if (contact != null) if (contact != null)
pictureUri = contact.getPhotoUri(); pictureUri = contact.getPhotoUri();
} catch (LinphoneCoreException e1) { } catch (LinphoneCoreException e1) {

View file

@ -56,6 +56,7 @@ import android.net.ConnectivityManager;
import android.net.NetworkInfo; import android.net.NetworkInfo;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.provider.MediaStore;
import android.telephony.TelephonyManager; import android.telephony.TelephonyManager;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.KeyEvent; import android.view.KeyEvent;
@ -156,7 +157,7 @@ public final class LinphoneUtils {
} }
public static void setImagePictureFromUri(Context c, ImageView view, Uri uri, int notFoundResource) { public static void setImagePictureFromUri(Context c, ImageView view, Uri uri, Uri tUri, int notFoundResource) {
if (uri == null) { if (uri == null) {
view.setImageResource(notFoundResource); view.setImageResource(notFoundResource);
return; return;
@ -167,7 +168,17 @@ public final class LinphoneUtils {
view.setImageBitmap(bm); view.setImageBitmap(bm);
} else { } else {
if (Version.sdkAboveOrEqual(Version.API06_ECLAIR_201)) { if (Version.sdkAboveOrEqual(Version.API06_ECLAIR_201)) {
view.setImageURI(uri); Bitmap bm = null;
try {
bm = MediaStore.Images.Media.getBitmap(c.getContentResolver(),uri);
} catch (IOException e) {
if(tUri != null){
view.setImageURI(tUri);
}
}
if(bm != null) {
view.setImageBitmap(bm);
}
} else { } else {
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
Bitmap bitmap = android.provider.Contacts.People.loadContactPhoto(c, uri, notFoundResource, null); Bitmap bitmap = android.provider.Contacts.People.loadContactPhoto(c, uri, notFoundResource, null);

View file

@ -216,7 +216,8 @@ public class ApiFivePlus {
String id = cursor.getString(cursor.getColumnIndex(Data.CONTACT_ID)); String id = cursor.getString(cursor.getColumnIndex(Data.CONTACT_ID));
String name = getContactDisplayName(cursor); String name = getContactDisplayName(cursor);
Uri photo = getContactPictureUri(id); Uri thumbnail = getContactPictureUri(id);
Uri photo = getContactPhotoUri(id);
InputStream input = getContactPictureInputStream(cr, id); InputStream input = getContactPictureInputStream(cr, id);
Contact contact; Contact contact;
@ -228,7 +229,7 @@ public class ApiFivePlus {
try { try {
bm = BitmapFactory.decodeStream(input); bm = BitmapFactory.decodeStream(input);
} catch (OutOfMemoryError oome) {} } catch (OutOfMemoryError oome) {}
contact = new Contact(id, name, photo, bm); contact = new Contact(id, name, photo, thumbnail, bm);
} }
return contact; return contact;
@ -248,6 +249,11 @@ public class ApiFivePlus {
} }
private static Uri getContactPictureUri(String id) { private static Uri getContactPictureUri(String id) {
Uri person = ContentUris.withAppendedId(Contacts.CONTENT_URI, Long.parseLong(id));
return Uri.withAppendedPath(person, Contacts.Photo.CONTENT_DIRECTORY);
}
private static Uri getContactPhotoUri(String id) {
Uri person = ContentUris.withAppendedId(Contacts.CONTENT_URI, Long.parseLong(id)); Uri person = ContentUris.withAppendedId(Contacts.CONTENT_URI, Long.parseLong(id));
return Uri.withAppendedPath(person, Contacts.Photo.DISPLAY_PHOTO); return Uri.withAppendedPath(person, Contacts.Photo.DISPLAY_PHOTO);
} }

View file

@ -24,6 +24,7 @@ import java.util.regex.Pattern;
import org.linphone.LinphoneManager; import org.linphone.LinphoneManager;
import org.linphone.LinphoneService; import org.linphone.LinphoneService;
import org.linphone.R; import org.linphone.R;
import org.linphone.core.LinphoneProxyConfig;
import android.accounts.Account; import android.accounts.Account;
import android.accounts.AccountManager; import android.accounts.AccountManager;
@ -65,6 +66,17 @@ public class WizardFragment extends Fragment {
private char[] acceptedChars = new char[]{ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', private char[] acceptedChars = new char[]{ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', '_', '-' }; '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', '_', '-' };
private char[] acceptedCharsForPhoneNumbers = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '+' };
private String inputFilterCharacters;
private String getUsername() {
String username = this.username.getText().toString();
if (getResources().getBoolean(R.bool.allow_only_phone_numbers_in_wizard)) {
LinphoneProxyConfig lpc = LinphoneManager.getLc().createProxyConfig();
username = lpc.normalizePhoneNumber(username);
}
return username.toLowerCase(Locale.getDefault());
}
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@ -73,12 +85,17 @@ public class WizardFragment extends Fragment {
username = (EditText) view.findViewById(R.id.setup_username); username = (EditText) view.findViewById(R.id.setup_username);
ImageView usernameOkIV = (ImageView) view.findViewById(R.id.setup_username_ok); ImageView usernameOkIV = (ImageView) view.findViewById(R.id.setup_username_ok);
addXMLRPCUsernameHandler(username, usernameOkIV); addXMLRPCUsernameHandler(username, usernameOkIV);
inputFilterCharacters = new String(acceptedChars);
if (getResources().getBoolean(R.bool.allow_only_phone_numbers_in_wizard)) {
inputFilterCharacters = new String(acceptedCharsForPhoneNumbers);
}
InputFilter filter = new InputFilter(){ InputFilter filter = new InputFilter(){
@Override @Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
if (end > start) { if (end > start) {
for (int index = start; index < end; index++) { for (int index = start; index < end; index++) {
if (!new String(acceptedChars).contains(String.valueOf(source.charAt(index)))) { if (!inputFilterCharacters.contains(String.valueOf(source.charAt(index)))) {
return ""; return "";
} }
} }
@ -110,20 +127,16 @@ public class WizardFragment extends Fragment {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setPositiveButton(R.string.button_ok, new DialogInterface.OnClickListener() { builder.setPositiveButton(R.string.button_ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) { public void onClick(DialogInterface dialog, int id) {
createAccount(username.getText().toString().toLowerCase(Locale.getDefault()), password.getText().toString(), email.getText().toString(), false); createAccount(getUsername(), password.getText().toString(), email.getText().toString(), false);
} }
}); });
builder.setNegativeButton(R.string.button_cancel, new DialogInterface.OnClickListener() { builder.setNegativeButton(R.string.button_cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) { public void onClick(DialogInterface dialog, int id) {
} }
}); });
if(!username.getText().toString().equals(username.getText().toString().toLowerCase(Locale.getDefault()))){ builder.setMessage(getString(R.string.setup_confirm_username).replace("%s", getUsername()));
builder.setMessage(getString(R.string.setup_confirm_username).replace("%s", username.getText().toString().toLowerCase(Locale.getDefault()))); AlertDialog dialog = builder.create();
AlertDialog dialog = builder.create(); dialog.show();
dialog.show();
} else {
createAccount(username.getText().toString().toLowerCase(Locale.getDefault()), password.getText().toString(), email.getText().toString(), false);
}
} }
}); });
@ -143,7 +156,11 @@ public class WizardFragment extends Fragment {
} }
private boolean isUsernameCorrect(String username) { private boolean isUsernameCorrect(String username) {
return username.matches("^[a-zA-Z]+[a-zA-Z0-9.\\-_]{2,}$"); if (getResources().getBoolean(R.bool.allow_only_phone_numbers_in_wizard)) {
return username.matches("^(\\+)?(\\d-)?(\\d{3}-)?(\\d{3}-)?\\d{4,}$");
} else {
return username.matches("^[a-zA-Z]+[a-zA-Z0-9.\\-_]{2,}$");
}
} }
private void isUsernameRegistred(String username, final ImageView icon) { private void isUsernameRegistred(String username, final ImageView icon) {
@ -278,6 +295,10 @@ public class WizardFragment extends Fragment {
usernameOk = false; usernameOk = false;
String username = field.getText().toString().toLowerCase(Locale.getDefault()); String username = field.getText().toString().toLowerCase(Locale.getDefault());
if (isUsernameCorrect(username)) { if (isUsernameCorrect(username)) {
if (getResources().getBoolean(R.bool.allow_only_phone_numbers_in_wizard)) {
LinphoneProxyConfig lpc = LinphoneManager.getLc().createProxyConfig();
username = lpc.normalizePhoneNumber(username);
}
isUsernameRegistred(username, icon); isUsernameRegistred(username, icon);
} else { } else {
errorMessage.setText(R.string.wizard_username_incorrect); errorMessage.setText(R.string.wizard_username_incorrect);

View file

@ -95,6 +95,7 @@ public class BubbleChat {
private ImageView statusView; private ImageView statusView;
private LinphoneChatMessage nativeMessage; private LinphoneChatMessage nativeMessage;
private LinphoneChatMessage.LinphoneChatMessageListener fileTransferListener; private LinphoneChatMessage.LinphoneChatMessageListener fileTransferListener;
private static final int SIZE_MAX = 2048;
@SuppressLint("InflateParams") @SuppressLint("InflateParams")
public BubbleChat(final Context context, LinphoneChatMessage message, LinphoneChatMessage.LinphoneChatMessageListener listener) { public BubbleChat(final Context context, LinphoneChatMessage message, LinphoneChatMessage.LinphoneChatMessageListener listener) {
@ -173,6 +174,13 @@ public class BubbleChat {
bm = BitmapFactory.decodeFile(appData); bm = BitmapFactory.decodeFile(appData);
appData = "file://" + appData; appData = "file://" + appData;
} }
if (bm.getWidth() > bm.getHeight() && bm.getWidth() > SIZE_MAX) {
bm = Bitmap.createScaledBitmap(bm, SIZE_MAX, (SIZE_MAX * bm.getHeight()) / bm.getWidth(), false);
} else if (bm.getHeight() > bm.getWidth() && bm.getHeight() > SIZE_MAX) {
bm = Bitmap.createScaledBitmap(bm, (SIZE_MAX * bm.getWidth()) / bm.getHeight(), SIZE_MAX, false);
}
if (bm != null) { if (bm != null) {
imageView.setImageBitmap(bm); imageView.setImageBitmap(bm);

@ -1 +1 @@
Subproject commit b3fcd2a8503069a9e9b0d15cc872e55c0eb48cf3 Subproject commit 7d27eb87c5dbd530e1c0a95cd0da2e233fb4d6b5

@ -1 +1 @@
Subproject commit 5913eff7a5ff4516c745669b6bedb87f367a84fa Subproject commit 5a0c92bac32d086e176e2b10d13c7fd5bb4c1032

View file

@ -48,7 +48,7 @@
<antcall target="check-for-crash"/> <antcall target="check-for-crash"/>
<fail message="Tests failed"> <fail message="Tests failed" status="42">
<condition> <condition>
<resourcecontains resource="${output.file}" substring="FAILURES" /> <resourcecontains resource="${output.file}" substring="FAILURES" />
</condition> </condition>
@ -65,6 +65,6 @@
<arg value="-c" /> <arg value="-c" />
<arg value="cat ${archive.name} |ndk-stack -sym obj/local/`adb shell getprop ro.product.cpu.abi | tr -d '\r'`" /> <arg value="cat ${archive.name} |ndk-stack -sym obj/local/`adb shell getprop ro.product.cpu.abi | tr -d '\r'`" />
</exec> </exec>
<fail message="Tests crashed"/> <fail message="Tests crashed" status="125"/>
</target> </target>
</project> </project>