diff --git a/README.md b/README.md
index df4f16c35..afd28c46f 100644
--- a/README.md
+++ b/README.md
@@ -8,9 +8,9 @@ Linphone is a free VoIP and video softphone based on the SIP protocol.
1. Download the Android sdk (API 28.0.0 at max) with platform-tools and tools updated to latest revision, then add both 'tools' and 'platform-tools' folders in your path and the android-sdk folder to ANDROID_HOME environment variable.
-2. Download the Android ndk (version 16) from google and add it to your path (no symlink !!!) and ANDROID_NDK environment variable.
+2. Download the Android NDK 17 from google and add it to your path (no symlink !!!) and ANDROID_NDK environment variable.
-3. Install _yasm_, _nasm_ (For OpenH224 support only), _python_, _pkg_config_ and _cmake(>=3.10)_.
+3. Install _yasm_, _nasm_ (For OpenH224 support only), _python_, _pkg_config_ and _cmake(>=3.12)_.
* On 64 bits linux systems you'll need the _ia32-libs_ package.
* With the latest Debian (multiarch), you need this:
* `dpkg --add-architecture i386`
diff --git a/gradle.properties b/gradle.properties
index 7cd8189f4..878417ffc 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -3,5 +3,5 @@ RELEASE_STORE_FILE=""
RELEASE_STORE_PASSWORD=
RELEASE_KEY_ALIAS=
RELEASE_KEY_PASSWORD=
-source:https://docs.gradle.org/current/userguide/build_environment.html#sec:configuring_jvm_memory
-org.gradle.jvmargs=-Xmx2g -XX:MaxPermSize=1024m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+#source:https://docs.gradle.org/current/userguide/build_environment.html#sec:configuring_jvm_memory
+org.gradle.jvmargs=-Xmx2g -XX:MaxPermSize=2048m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
diff --git a/res/values/non_localizable_custom.xml b/res/values/non_localizable_custom.xml
index d2a5c766a..dd0645646 100644
--- a/res/values/non_localizable_custom.xml
+++ b/res/values/non_localizable_custom.xml
@@ -80,6 +80,7 @@
false
linphone-android-photo-temp
linphone-android-photo-%s
+ false
false
diff --git a/src/android/org/linphone/LinphoneManager.java b/src/android/org/linphone/LinphoneManager.java
index 4046e3ecb..acc843bbd 100644
--- a/src/android/org/linphone/LinphoneManager.java
+++ b/src/android/org/linphone/LinphoneManager.java
@@ -1012,9 +1012,7 @@ public class LinphoneManager implements CoreListener, SensorEventListener, Accou
private Vibrator mVibrator;
public void onNewSubscriptionRequested(Core lc, Friend lf, String url) {}
- public void onNotifyPresenceReceived(Core lc, Friend lf) {
- ContactsManager.getInstance().refreshSipContact(lf);
- }
+ public void onNotifyPresenceReceived(Core lc, Friend lf) {}
@Override
public void onEcCalibrationAudioInit(Core lc) {
@@ -1659,12 +1657,12 @@ public class LinphoneManager implements CoreListener, SensorEventListener, Accou
@Override
public void onFriendListCreated(Core lc, FriendList list) {
- // TODO Auto-generated method stub
+ list.setListener(ContactsManager.getInstance());
}
@Override
public void onFriendListRemoved(Core lc, FriendList list) {
- // TODO Auto-generated method stub
+ list.setListener(null);
}
@Override
diff --git a/src/android/org/linphone/LinphoneUtils.java b/src/android/org/linphone/LinphoneUtils.java
index ab6057a1e..fa576a7e4 100644
--- a/src/android/org/linphone/LinphoneUtils.java
+++ b/src/android/org/linphone/LinphoneUtils.java
@@ -22,9 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ContentResolver;
-import android.content.ContentUris;
import android.content.Context;
-import android.content.CursorLoader;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
@@ -37,8 +35,8 @@ import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.os.ParcelFileDescriptor;
-import android.provider.DocumentsContract;
import android.provider.MediaStore;
+import android.provider.OpenableColumns;
import android.telephony.TelephonyManager;
import android.text.Spanned;
import android.text.TextUtils;
@@ -599,88 +597,42 @@ public final class LinphoneUtils {
}
- /************************************************************************************************
- * Picasa/Photos management workaround *
- ************************************************************************************************/
-
public static String getFilePath(final Context context, final Uri uri) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && DocumentsContract.isDocumentUri(context, uri)) {
- // ExternalStorageProvider
- if ("com.android.externalstorage.documents".equals(uri.getAuthority())) {
- final String docId = DocumentsContract.getDocumentId(uri);
- final String[] split = docId.split(":");
- if (split.length >= 1) return Environment.getExternalStorageDirectory() + "/" + split[1];
+ if (uri == null) return null;
- // TODO handle non-primary volumes
- }// Docs storage
- else if ("com.google.android.apps.docs.storage".equals(uri.getAuthority())) {
- //Google doc not supported right now
+ String result = null;
+ String name = getNameFromUri(uri, context);
+
+ try {
+ File localFile = createFile(context, name);
+ InputStream remoteFile = context.getContentResolver().openInputStream(uri);
+
+ if(copyToFile(remoteFile, localFile)) {
+ result = localFile.getAbsolutePath();
}
- // DownloadsProvider
- else if ("com.android.providers.downloads.documents".equals(uri.getAuthority())) {
- final String id = DocumentsContract.getDocumentId(uri);
- try {
- final Uri contentUri = ContentUris.withAppendedId(
- Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
-
- return getDataColumn(context, contentUri, null, null);
- } catch (NumberFormatException nfe) {
- if (id.startsWith("raw:")) {
- return id.substring(4);
- }
- }
- }
- // MediaProvider
- else if ("com.android.providers.media.documents".equals(uri.getAuthority())) {
- final String docId = DocumentsContract.getDocumentId(uri);
- final String[] split = docId.split(":");
- final String type = split[0];
-
- Uri contentUri = null;
- if ("image".equals(type)) {
- contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
- } else if ("video".equals(type)) {
- contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
- } else if ("audio".equals(type)) {
- contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
- }
-
- final String selection = "_id=?";
- final String[] selectionArgs = new String[] {
- split[1]
- };
-
- return getDataColumn(context, contentUri, selection, selectionArgs);
- }
- } else if ("content".equalsIgnoreCase(uri.getScheme())) {
- String type = getTypeFromUri(uri, context);
- String result = getDataColumn(context, uri, null, null); //
- if (TextUtils.isEmpty(result))
- if (uri.getAuthority().contains("com.google.android") || uri.getAuthority().contains("com.android")) {
- try {
- File localFile = createFile(context, null, type);
- FileInputStream remoteFile = getSourceStream(context, uri);
- if(copyToFile(remoteFile, localFile))
- result = localFile.getAbsolutePath();
- remoteFile.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- return result;
- } else if ("file".equalsIgnoreCase(uri.getScheme())) { // File
- return uri.getPath();
+ remoteFile.close();
+ } catch (IOException e) {
+ Log.e("Enable to get sharing file", e);
}
- return null;
+
+ return result;
}
-
- private static String getTypeFromUri(Uri uri, Context context){
- ContentResolver cR = context.getContentResolver();
- MimeTypeMap mime = MimeTypeMap.getSingleton();
- String type = mime.getExtensionFromMimeType(cR.getType(uri));
- return type;
+ private static String getNameFromUri(Uri uri, Context context) {
+ String name = null;
+ if (uri.getScheme().equals("content")) {
+ Cursor returnCursor = context.getContentResolver().query(uri, null, null, null, null);
+ if (returnCursor != null) {
+ returnCursor.moveToFirst();
+ int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
+ name = returnCursor.getString(nameIndex);
+ returnCursor.close();
+ }
+ } else if (uri.getScheme().equals("file")) {
+ name = uri.getLastPathSegment();
+ }
+ return name;
}
/**
@@ -714,74 +666,25 @@ public final class LinphoneUtils {
}
}
- public static File createFile(Context context, String imageFileName, String type) throws IOException {
- if (TextUtils.isEmpty(imageFileName))
- imageFileName = getStartDate()+"."+type; // make random filename if you want.
+ public static File createFile(Context context, String fileName) throws IOException {
+ if (TextUtils.isEmpty(fileName))
+ fileName = getStartDate();
+
+ if (!fileName.contains(".")) {
+ fileName = fileName + ".unknown";
+ }
final File root;
- imageFileName = imageFileName;
root = context.getExternalCacheDir();
if (root != null && !root.exists())
root.mkdirs();
- return new File(root, imageFileName);
- }
-
-
- public static FileInputStream getSourceStream(Context context, Uri u) throws FileNotFoundException {
- FileInputStream out = null;
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
- ParcelFileDescriptor parcelFileDescriptor =
- context.getContentResolver().openFileDescriptor(u, "r");
- FileDescriptor fileDescriptor = null;
- if (parcelFileDescriptor != null) {
- fileDescriptor = parcelFileDescriptor.getFileDescriptor();
- out = new FileInputStream(fileDescriptor);
- }
- } else {
- out = (FileInputStream) context.getContentResolver().openInputStream(u);
- }
- return out;
- }
-
- /**
- * Get the value of the data column for this Uri. This is useful for
- * MediaStore Uris, and other file-based ContentProviders.
- *
- * @param context The context.
- * @param uri The Uri to query.
- * @param selection (Optional) Filter used in the query.
- * @param selectionArgs (Optional) Selection arguments used in the query.
- * @return The value of the _data column, which is typically a file path.
- */
- static String getDataColumn(Context context, Uri uri, String selection,
- String[] selectionArgs) {
-
- Cursor cursor = null;
- final String column = "_data";
- final String[] projection = {
- column
- };
-
- try {
- cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
- null);
- if (cursor != null && cursor.moveToFirst()) {
- final int column_index = cursor.getColumnIndexOrThrow(column);
- return cursor.getString(column_index);
- }
- } finally {
- if (cursor != null)
- cursor.close();
- }
-
- return null;
+ return new File(root, fileName);
}
public static String getRealPathFromURI(Context context, Uri contentUri) {
String[] proj = {MediaStore.Images.Media.DATA};
- CursorLoader loader = new CursorLoader(context, contentUri, proj, null, null, null);
- Cursor cursor = loader.loadInBackground();
+ Cursor cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
String result = cursor.getString(column_index);
@@ -791,32 +694,6 @@ public final class LinphoneUtils {
return null;
}
- public static String processContactUri(Context context, Uri contactUri){
- ContentResolver cr = context.getContentResolver();
- InputStream stream = null;
- if(cr !=null) {
- try {
- stream = cr.openInputStream(contactUri);
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- }
- if(stream != null) {
- StringBuffer fileContent = new StringBuffer("");
- int ch;
- try {
- while ((ch = stream.read()) != -1)
- fileContent.append((char) ch);
- } catch (IOException e) {
- e.printStackTrace();
- }
- String data = new String(fileContent);
- return data;
- }
- return null;
- }
- return null;
- }
-
public static String getContactNameFromVcard(String vcard){
if(vcard != null) {
String contactName = vcard.substring(vcard.indexOf("FN:") + 3);
@@ -844,7 +721,7 @@ public final class LinphoneUtils {
public static Spanned getTextWithHttpLinks(String text) {
if (text == null) return null;
-
+
if (text.contains("<")) {
text = text.replace("<", "<");
}
diff --git a/src/android/org/linphone/activities/LinphoneLauncherActivity.java b/src/android/org/linphone/activities/LinphoneLauncherActivity.java
index 1dfc4b657..0eb500607 100644
--- a/src/android/org/linphone/activities/LinphoneLauncherActivity.java
+++ b/src/android/org/linphone/activities/LinphoneLauncherActivity.java
@@ -132,26 +132,12 @@ public class LinphoneLauncherActivity extends Activity {
String type = intent.getType();
newIntent.setData(intent.getData());
if (Intent.ACTION_SEND.equals(action) && type != null) {
- if (type.contains("text/")){
- if(("text/plain").equals(type) && (String)intent.getStringExtra(Intent.EXTRA_TEXT)!= null) {
- stringFileShared = intent.getStringExtra(Intent.EXTRA_TEXT);
- newIntent.putExtra("msgShared", stringFileShared);
- } else if(((Uri) intent.getExtras().get(Intent.EXTRA_STREAM)) != null){
- stringFileShared = (LinphoneUtils.createCvsFromString(LinphoneUtils.processContactUri(getApplicationContext(), (Uri)intent.getExtras().get(Intent.EXTRA_STREAM)))).toString();
- newIntent.putExtra("fileShared", stringFileShared);
- }
- }else {
- if(((String) intent.getStringExtra(Intent.EXTRA_STREAM)) != null){
- stringUriFileShared = intent.getStringExtra(Intent.EXTRA_STREAM);
- }else {
- fileUri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);
- stringUriFileShared = LinphoneUtils.getRealPathFromURI(getBaseContext(), fileUri);
- if(stringUriFileShared == null)
- if(fileUri.getPath().contains("/0/1/mediakey:/local") || fileUri.getPath().contains("/ORIGINAL/NONE/")) {
- stringUriFileShared = LinphoneUtils.getFilePath(getBaseContext(), fileUri);
- }else
- stringUriFileShared = fileUri.getPath();
- }
+ if(("text/plain").equals(type) && (String)intent.getStringExtra(Intent.EXTRA_TEXT)!= null) {
+ stringFileShared = intent.getStringExtra(Intent.EXTRA_TEXT);
+ newIntent.putExtra("msgShared", stringFileShared);
+ } else {
+ fileUri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);
+ stringUriFileShared = LinphoneUtils.getFilePath(getBaseContext(), fileUri);
newIntent.putExtra("fileShared", stringUriFileShared);
}
}else if (Intent.ACTION_SEND_MULTIPLE.equals(action) && type != null) {
diff --git a/src/android/org/linphone/chat/ChatEventsAdapter.java b/src/android/org/linphone/chat/ChatEventsAdapter.java
index 3ed0db2ce..9fb0958ad 100644
--- a/src/android/org/linphone/chat/ChatEventsAdapter.java
+++ b/src/android/org/linphone/chat/ChatEventsAdapter.java
@@ -163,10 +163,23 @@ public class ChatEventsAdapter extends SelectableAdapter {
holder.delete.setTag(position);
}
- if (event.getType() == EventLog.Type.ConferenceChatMessage) {
- holder.bubbleLayout.setVisibility(View.VISIBLE);
+ if (event.getType() == EventLog.Type.ConferenceChatMessage) {
+ holder.bubbleLayout.setVisibility(View.VISIBLE);
+ final ChatMessage message = event.getChatMessage();
+
+ if (position > 0 && mContext.getResources().getBoolean(R.bool.lower_space_between_chat_bubbles_if_same_person)) {
+ EventLog previousEvent = (EventLog)getItem(position-1);
+ if (previousEvent.getType() == EventLog.Type.ConferenceChatMessage) {
+ ChatMessage previousMessage = previousEvent.getChatMessage();
+ if (previousMessage.getFromAddress().weakEqual(message.getFromAddress())) {
+ holder.separatorLayout.setVisibility(View.GONE);
+ }
+ } else {
+ // No separator if previous event is not a message
+ holder.separatorLayout.setVisibility(View.GONE);
+ }
+ }
- final ChatMessage message = event.getChatMessage();
holder.messageId = message.getMessageId();
message.setUserData(holder);
@@ -238,7 +251,6 @@ public class ChatEventsAdapter extends SelectableAdapter {
}
}
-
if (isEditionEnabled()) {
layoutParams.addRule(RelativeLayout.LEFT_OF, holder.delete.getId());
layoutParams.setMargins(SIDE_MARGIN, MARGIN_BETWEEN_MESSAGES/2, 0, MARGIN_BETWEEN_MESSAGES/2);
diff --git a/src/android/org/linphone/compatibility/ApiTwentyOnePlus.java b/src/android/org/linphone/compatibility/ApiTwentyOnePlus.java
index 8215d4e0d..d633daa18 100644
--- a/src/android/org/linphone/compatibility/ApiTwentyOnePlus.java
+++ b/src/android/org/linphone/compatibility/ApiTwentyOnePlus.java
@@ -59,6 +59,8 @@ public class ApiTwentyOnePlus {
.setVisibility(Notification.VISIBILITY_PRIVATE)
.setPriority(Notification.PRIORITY_HIGH)
.setNumber(msgCount)
+ .setWhen(System.currentTimeMillis())
+ .setShowWhen(true)
.build();
return notif;
@@ -80,6 +82,7 @@ public class ApiTwentyOnePlus {
.setLights(ContextCompat.getColor(context, R.color.notification_color_led),
context.getResources().getInteger(R.integer.notification_ms_on),
context.getResources().getInteger(R.integer.notification_ms_off))
+ .setShowWhen(true)
.build();
return notif;
@@ -100,7 +103,9 @@ public class ApiTwentyOnePlus {
.setLights(ContextCompat.getColor(context, R.color.notification_color_led),
context.getResources().getInteger(R.integer.notification_ms_on),
context.getResources().getInteger(R.integer.notification_ms_off))
+ .setWhen(System.currentTimeMillis())
.setPriority(priority)
+ .setShowWhen(true)
.build();
} else {
notif = new Notification.Builder(context)
@@ -114,6 +119,8 @@ public class ApiTwentyOnePlus {
context.getResources().getInteger(R.integer.notification_ms_on),
context.getResources().getInteger(R.integer.notification_ms_off))
.setPriority(priority)
+ .setWhen(System.currentTimeMillis())
+ .setShowWhen(true)
.build();
}
@@ -139,6 +146,8 @@ public class ApiTwentyOnePlus {
context.getResources().getInteger(R.integer.notification_ms_on),
context.getResources().getInteger(R.integer.notification_ms_off))
.setPriority(Notification.PRIORITY_HIGH)
+ .setWhen(System.currentTimeMillis())
+ .setShowWhen(true)
.build();
return notif;
@@ -158,7 +167,9 @@ public class ApiTwentyOnePlus {
.setLights(ContextCompat.getColor(context, R.color.notification_color_led),
context.getResources().getInteger(R.integer.notification_ms_on),
context.getResources().getInteger(R.integer.notification_ms_off))
+ .setWhen(System.currentTimeMillis())
.setPriority(Notification.PRIORITY_HIGH)
+ .setShowWhen(true)
.build();
return notif;
diff --git a/src/android/org/linphone/compatibility/ApiTwentySixPlus.java b/src/android/org/linphone/compatibility/ApiTwentySixPlus.java
index 0ed80b882..f40c1b892 100644
--- a/src/android/org/linphone/compatibility/ApiTwentySixPlus.java
+++ b/src/android/org/linphone/compatibility/ApiTwentySixPlus.java
@@ -87,6 +87,10 @@ public class ApiTwentySixPlus {
.setVisibility(Notification.VISIBILITY_PRIVATE)
.setPriority(Notification.PRIORITY_HIGH)
.setNumber(msgCount)
+ .setWhen(System.currentTimeMillis())
+ .setShowWhen(true)
+ .setColorized(true)
+ .setColor(context.getColor(R.color.notification_color_led))
.build();
return notif;
@@ -106,6 +110,10 @@ public class ApiTwentySixPlus {
.setCategory(Notification.CATEGORY_CALL)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setPriority(Notification.PRIORITY_HIGH)
+ .setWhen(System.currentTimeMillis())
+ .setShowWhen(true)
+ .setColorized(true)
+ .setColor(context.getColor(R.color.notification_color_led))
.build();
return notif;
@@ -124,6 +132,10 @@ public class ApiTwentySixPlus {
.setCategory(Notification.CATEGORY_SERVICE)
.setVisibility(Notification.VISIBILITY_SECRET)
.setPriority(priority)
+ .setWhen(System.currentTimeMillis())
+ .setShowWhen(true)
+ .setColorized(true)
+ .setColor(context.getColor(R.color.notification_color_led))
.build();
} else {
notif = new Notification.Builder(context, context.getString(R.string.notification_service_channel_id))
@@ -134,6 +146,10 @@ public class ApiTwentySixPlus {
.setCategory(Notification.CATEGORY_SERVICE)
.setVisibility(Notification.VISIBILITY_SECRET)
.setPriority(priority)
+ .setWhen(System.currentTimeMillis())
+ .setShowWhen(true)
+ .setColorized(true)
+ .setColor(context.getColor(R.color.notification_color_led))
.build();
}
@@ -156,6 +172,10 @@ public class ApiTwentySixPlus {
.setCategory(Notification.CATEGORY_MESSAGE)
.setVisibility(Notification.VISIBILITY_PRIVATE)
.setPriority(Notification.PRIORITY_HIGH)
+ .setWhen(System.currentTimeMillis())
+ .setShowWhen(true)
+ .setColorized(true)
+ .setColor(context.getColor(R.color.notification_color_led))
.build();
return notif;
@@ -173,6 +193,10 @@ public class ApiTwentySixPlus {
.setCategory(Notification.CATEGORY_MESSAGE)
.setVisibility(Notification.VISIBILITY_PRIVATE)
.setPriority(Notification.PRIORITY_HIGH)
+ .setWhen(System.currentTimeMillis())
+ .setShowWhen(true)
+ .setColorized(true)
+ .setColor(context.getColor(R.color.notification_color_led))
.build();
return notif;
diff --git a/src/android/org/linphone/contacts/ContactsListFragment.java b/src/android/org/linphone/contacts/ContactsListFragment.java
index 49566c9ad..d0ad0d9e4 100644
--- a/src/android/org/linphone/contacts/ContactsListFragment.java
+++ b/src/android/org/linphone/contacts/ContactsListFragment.java
@@ -167,7 +167,8 @@ public class ContactsListFragment extends Fragment implements OnItemClickListene
dividerItemDecoration.setDrawable(getActivity().getResources().getDrawable(R.drawable.divider));
contactsList.addItemDecoration(dividerItemDecoration);
- ContactsManager.getInstance().fetchContactsAsync();
+ contactsFetchInProgress = (ProgressBar) view.findViewById(R.id.contactsFetchInProgress);
+ contactsFetchInProgress.setVisibility(View.VISIBLE);
return view;
}
@@ -312,8 +313,8 @@ public class ContactsListFragment extends Fragment implements OnItemClickListene
@Override
public void onResume() {
- ContactsManager.addContactsListener(this);
super.onResume();
+ ContactsManager.addContactsListener(this);
if (editConsumed) {
editOnClick = false;
diff --git a/src/android/org/linphone/contacts/ContactsManager.java b/src/android/org/linphone/contacts/ContactsManager.java
index dd493f25b..c86ad3e05 100644
--- a/src/android/org/linphone/contacts/ContactsManager.java
+++ b/src/android/org/linphone/contacts/ContactsManager.java
@@ -45,6 +45,7 @@ import org.linphone.core.Core;
import org.linphone.core.Factory;
import org.linphone.core.Friend;
import org.linphone.core.FriendList;
+import org.linphone.core.FriendListListener;
import org.linphone.core.MagicSearch;
import org.linphone.core.ProxyConfig;
import org.linphone.mediastream.Log;
@@ -59,7 +60,7 @@ import java.util.Locale;
import java.util.Set;
import java.util.concurrent.TimeUnit;
-public class ContactsManager extends ContentObserver {
+public class ContactsManager extends ContentObserver implements FriendListListener {
private static ContactsManager instance;
private List contacts, sipContacts;
@@ -93,6 +94,12 @@ public class ContactsManager extends ContentObserver {
}
public void destroy() {
+ Core lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
+ if (lc != null) {
+ for (FriendList list : lc.getFriendsLists()) {
+ list.setListener(null);
+ }
+ }
defaultAvatar.recycle();
instance = null;
}
@@ -293,10 +300,6 @@ public class ContactsManager extends ContentObserver {
LinphoneContact contact = (LinphoneContact)lf.getUserData();
if (contact != null && !sipContacts.contains(contact)) {
sipContacts.add(contact);
- Collections.sort(sipContacts);
- for (ContactsUpdatedListener listener : contactsUpdatedListeners) {
- listener.onContactsUpdated();
- }
}
}
@@ -590,4 +593,36 @@ public class ContactsManager extends ContentObserver {
Cursor c = getContentResolver().query(ContactsContract.Data.CONTENT_URI, projection, select, new String[]{ ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE }, null);
return c;
}
+
+ @Override
+ public void onContactCreated(FriendList list, Friend lf) {
+
+ }
+
+ @Override
+ public void onContactDeleted(FriendList list, Friend lf) {
+
+ }
+
+ @Override
+ public void onContactUpdated(FriendList list, Friend newFriend, Friend oldFriend) {
+
+ }
+
+ @Override
+ public void onSyncStatusChanged(FriendList list, FriendList.SyncStatus status, String msg) {
+
+ }
+
+ @Override
+ public void onPresenceReceived(FriendList list, Friend[] friends) {
+ for (Friend lf : friends) {
+ ContactsManager.getInstance().refreshSipContact(lf);
+ }
+
+ Collections.sort(sipContacts);
+ for (ContactsUpdatedListener listener : contactsUpdatedListeners) {
+ listener.onContactsUpdated();
+ }
+ }
}
diff --git a/submodules/bcmatroska2 b/submodules/bcmatroska2
index ca4a89930..e8a69bdc3 160000
--- a/submodules/bcmatroska2
+++ b/submodules/bcmatroska2
@@ -1 +1 @@
-Subproject commit ca4a89930dd8db94a60ae4a1dbf44a3710497429
+Subproject commit e8a69bdc3f8828cfd83b0938955132918364b175
diff --git a/submodules/bctoolbox b/submodules/bctoolbox
index ed53ae3c9..88ed003be 160000
--- a/submodules/bctoolbox
+++ b/submodules/bctoolbox
@@ -1 +1 @@
-Subproject commit ed53ae3c9da4fb15c13454153383014b3257939a
+Subproject commit 88ed003beb9a33d9d80bbac8c53287039e1e30b0
diff --git a/submodules/belle-sip b/submodules/belle-sip
index 11f4c9c61..41666379a 160000
--- a/submodules/belle-sip
+++ b/submodules/belle-sip
@@ -1 +1 @@
-Subproject commit 11f4c9c61feece2d46909ae62e91ac1bace64c2c
+Subproject commit 41666379abcdd4f14fcf08732e21b2d7b81cf729
diff --git a/submodules/cmake-builder b/submodules/cmake-builder
index f58510c8c..81f2fa301 160000
--- a/submodules/cmake-builder
+++ b/submodules/cmake-builder
@@ -1 +1 @@
-Subproject commit f58510c8ce6cd89dadff2b29574d03b05c6efcc9
+Subproject commit 81f2fa301e392a33e63fb6ac6ded9b9d48832605
diff --git a/submodules/linphone b/submodules/linphone
index d0232344c..494baf59e 160000
--- a/submodules/linphone
+++ b/submodules/linphone
@@ -1 +1 @@
-Subproject commit d0232344c705a482feb5ca272abcb044303ef284
+Subproject commit 494baf59e48e38f92e959ee1aac763d2caca39ce
diff --git a/submodules/mediastreamer2 b/submodules/mediastreamer2
index 52d316934..94892b662 160000
--- a/submodules/mediastreamer2
+++ b/submodules/mediastreamer2
@@ -1 +1 @@
-Subproject commit 52d3169349b55b27090ecb81f88d10ebb65fa469
+Subproject commit 94892b662ef2009f27eaa4c164a0595b32d7f5c8
diff --git a/submodules/oRTP b/submodules/oRTP
index a88be02b9..c9dde282b 160000
--- a/submodules/oRTP
+++ b/submodules/oRTP
@@ -1 +1 @@
-Subproject commit a88be02b93e2274ae3fcf80e1e0032adc43c0448
+Subproject commit c9dde282bf48af9a8844f0686a09a1d0347e6856