From 6f51902be9104ee6536661e114fa3581bf5c2eaf Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 1 Aug 2016 15:19:54 +0200 Subject: [PATCH 01/36] Updated cmakebuilder to set vCards enabled as default + rework keepalive --- AndroidManifest.xml | 8 +++- src/org/linphone/KeepAliveHandler.java | 47 --------------------- src/org/linphone/KeepAliveReceiver.java | 40 +++++++++++++++--- src/org/linphone/LinphoneManager.java | 27 +----------- src/org/linphone/LinphoneService.java | 14 +++--- submodules/cmake-builder | 2 +- submodules/externals/sqlite3/CMakeLists.txt | 2 +- 7 files changed, 50 insertions(+), 90 deletions(-) delete mode 100644 src/org/linphone/KeepAliveHandler.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 909529b19..59f557074 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -207,7 +207,13 @@ - + + + + + + + diff --git a/src/org/linphone/KeepAliveHandler.java b/src/org/linphone/KeepAliveHandler.java deleted file mode 100644 index 9812248f6..000000000 --- a/src/org/linphone/KeepAliveHandler.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.linphone; -/* -KeepAliveHandler.java -Copyright (C) 2013 Belledonne Communications, Grenoble, France - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -import org.linphone.core.LinphoneCoreFactory; -import org.linphone.mediastream.Log; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; - -public class KeepAliveHandler extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - boolean isDebugEnabled = LinphonePreferences.instance().isDebugEnabled(); - LinphoneCoreFactory.instance().enableLogCollection(isDebugEnabled); - LinphoneCoreFactory.instance().setDebugMode(isDebugEnabled, context.getString(R.string.app_name)); - - Log.i("Keep alive handler invoked"); - if (LinphoneManager.getLcIfManagerNotDestroyedOrNull() != null) { - //first refresh registers - LinphoneManager.getLc().refreshRegisters(); - //make sure iterate will have enough time, device will not sleep until exit from this method - try { - Thread.sleep(2000); - } catch (InterruptedException e) { - //Log.e("Cannot sleep for 2s", e); //TODO FIXME Crash since the log rework - } - } - } -} diff --git a/src/org/linphone/KeepAliveReceiver.java b/src/org/linphone/KeepAliveReceiver.java index 7c104f578..bc78137e4 100644 --- a/src/org/linphone/KeepAliveReceiver.java +++ b/src/org/linphone/KeepAliveReceiver.java @@ -18,12 +18,16 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package org.linphone; +import org.linphone.core.LinphoneCore; +import org.linphone.core.LinphoneCoreFactory; import org.linphone.mediastream.Log; +import android.app.AlarmManager; +import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; - +import android.os.SystemClock; /* * Purpose of this receiver is to disable keep alives when screen is off @@ -32,13 +36,37 @@ public class KeepAliveReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (!LinphoneService.isReady()) { - Log.i("Keep alive broadcast received while Linphone service not ready"); return; } else { - if (intent.getAction().equalsIgnoreCase(Intent.ACTION_SCREEN_ON)) { - LinphoneManager.getLc().enableKeepAlive(true); - } else if (intent.getAction().equalsIgnoreCase(Intent.ACTION_SCREEN_OFF)) { - LinphoneManager.getLc().enableKeepAlive(false); + boolean isDebugEnabled = LinphonePreferences.instance().isDebugEnabled(); + LinphoneCoreFactory.instance().enableLogCollection(isDebugEnabled); + LinphoneCoreFactory.instance().setDebugMode(isDebugEnabled, context.getString(R.string.app_name)); + LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); + if (lc == null) return; + + String action = intent.getAction(); + if (action == null) { + Log.i("[KeepAlive] Refresh registers"); + lc.refreshRegisters(); + //make sure iterate will have enough time, device will not sleep until exit from this method + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + Log.e("Cannot sleep for 2s", e); + } finally { + //make sure the application will at least wakes up every 10 mn + Intent newIntent = new Intent(context, KeepAliveReceiver.class); + PendingIntent keepAlivePendingIntent = PendingIntent.getBroadcast(context, 0, newIntent, PendingIntent.FLAG_ONE_SHOT); + ((AlarmManager) context.getSystemService(Context.ALARM_SERVICE)).setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP + , SystemClock.elapsedRealtime() + 600000 + , keepAlivePendingIntent); + } + } else if (action.equalsIgnoreCase(Intent.ACTION_SCREEN_ON)) { + Log.i("[KeepAlive] Screen is on, enable"); + lc.enableKeepAlive(true); + } else if (action.equalsIgnoreCase(Intent.ACTION_SCREEN_OFF)) { + Log.i("[KeepAlive] Screen is off, disable"); + lc.enableKeepAlive(false); } } } diff --git a/src/org/linphone/LinphoneManager.java b/src/org/linphone/LinphoneManager.java index 6d6056045..739387310 100644 --- a/src/org/linphone/LinphoneManager.java +++ b/src/org/linphone/LinphoneManager.java @@ -38,8 +38,6 @@ import java.util.TimerTask; import org.linphone.compatibility.Compatibility; import org.linphone.core.CallDirection; -import org.linphone.core.OpenH264DownloadHelperAction; -import org.linphone.core.OpenH264DownloadHelperListener; import org.linphone.core.LinphoneAddress; import org.linphone.core.LinphoneBuffer; import org.linphone.core.LinphoneCall; @@ -57,13 +55,13 @@ import org.linphone.core.LinphoneCore.RegistrationState; import org.linphone.core.LinphoneCore.RemoteProvisioningState; import org.linphone.core.LinphoneCoreException; import org.linphone.core.LinphoneCoreFactory; -import org.linphone.core.LinphoneCoreFactoryImpl; import org.linphone.core.LinphoneCoreListener; import org.linphone.core.LinphoneEvent; import org.linphone.core.LinphoneFriend; import org.linphone.core.LinphoneFriendList; import org.linphone.core.LinphoneInfoMessage; import org.linphone.core.LinphoneProxyConfig; +import org.linphone.core.OpenH264DownloadHelperListener; import org.linphone.core.PayloadType; import org.linphone.core.PresenceActivityType; import org.linphone.core.PresenceModel; @@ -82,12 +80,8 @@ import android.annotation.TargetApi; import android.app.Activity; import android.app.AlertDialog; import android.app.ProgressDialog; -import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.IntentFilter; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Resources; import android.hardware.Sensor; @@ -105,8 +99,6 @@ import android.os.PowerManager; import android.os.PowerManager.WakeLock; import android.os.Vibrator; import android.preference.CheckBoxPreference; -import android.provider.MediaStore; -import android.provider.MediaStore.Images; import android.provider.Settings; import android.provider.Settings.SettingNotFoundException; import android.telephony.TelephonyManager; @@ -207,11 +199,8 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag private final String mErrorToneFile; private final String mUserCertificatePath; private ByteArrayInputStream mUploadingImageStream; - private Timer mTimer; - private BroadcastReceiver mKeepAliveReceiver = new KeepAliveReceiver(); - private void routeAudioToSpeakerHelper(boolean speakerOn) { Log.w("Routing audio to " + (speakerOn ? "speaker" : "earpiece") + ", disabling bluetooth audio route"); BluetoothManager.getInstance().disableBluetoothSCO(); @@ -644,11 +633,6 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag Log.e(e); } finally { - try { - mServiceContext.unregisterReceiver(mKeepAliveReceiver); - } catch (Exception e) { - Log.e(e); - } mLc = null; } } @@ -656,10 +640,6 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag public void restartLinphoneCore() { destroyLinphoneCore(); startLibLinphone(mServiceContext); - - IntentFilter lFilter = new IntentFilter(Intent.ACTION_SCREEN_ON); - lFilter.addAction(Intent.ACTION_SCREEN_OFF); - mServiceContext.registerReceiver(mKeepAliveReceiver, lFilter); sExited = false; } @@ -750,10 +730,6 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag Compatibility.initPushNotificationService(mServiceContext); } - IntentFilter lFilter = new IntentFilter(Intent.ACTION_SCREEN_ON); - lFilter.addAction(Intent.ACTION_SCREEN_OFF); - mServiceContext.registerReceiver(mKeepAliveReceiver, lFilter); - updateNetworkReachability(); if (Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30)) { @@ -869,7 +845,6 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag Log.e(e); } finally { - mServiceContext.unregisterReceiver(mKeepAliveReceiver); mLc = null; instance = null; } diff --git a/src/org/linphone/LinphoneService.java b/src/org/linphone/LinphoneService.java index 402e29fde..5e7743a27 100644 --- a/src/org/linphone/LinphoneService.java +++ b/src/org/linphone/LinphoneService.java @@ -20,6 +20,7 @@ package org.linphone; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.Calendar; import org.linphone.compatibility.Compatibility; import org.linphone.core.LinphoneAddress; @@ -114,7 +115,6 @@ public final class LinphoneService extends Service { private Notification mCustomNotif; private int mMsgNotifCount; private PendingIntent mNotifContentIntent; - private PendingIntent mkeepAlivePendingIntent; private String mNotificationTitle; private boolean mDisableRegistrationStatus; private LinphoneCoreListenerBase mListener; @@ -287,12 +287,11 @@ public final class LinphoneService extends Service { } //make sure the application will at least wakes up every 10 mn - Intent intent = new Intent(this, KeepAliveHandler.class); - mkeepAlivePendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_ONE_SHOT); - ((AlarmManager) this.getSystemService(Context.ALARM_SERVICE)).setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP - , SystemClock.elapsedRealtime()+600000 - , 600000 - , mkeepAlivePendingIntent); + Intent intent = new Intent(this, KeepAliveReceiver.class); + PendingIntent keepAlivePendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_ONE_SHOT); + ((AlarmManager) this.getSystemService(Context.ALARM_SERVICE)).setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP + , SystemClock.elapsedRealtime() + 600000 + , keepAlivePendingIntent); mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE); } @@ -630,7 +629,6 @@ public final class LinphoneService extends Service { mNM.cancel(INCALL_NOTIF_ID); mNM.cancel(MESSAGE_NOTIF_ID); - ((AlarmManager) this.getSystemService(Context.ALARM_SERVICE)).cancel(mkeepAlivePendingIntent); super.onDestroy(); } diff --git a/submodules/cmake-builder b/submodules/cmake-builder index 6d4281181..29911ee5b 160000 --- a/submodules/cmake-builder +++ b/submodules/cmake-builder @@ -1 +1 @@ -Subproject commit 6d4281181addb913e851622e6d9b04d093c869d4 +Subproject commit 29911ee5ba6053dd041ee02c6dc13b0134e890d2 diff --git a/submodules/externals/sqlite3/CMakeLists.txt b/submodules/externals/sqlite3/CMakeLists.txt index 8c722641d..28a7b381c 100644 --- a/submodules/externals/sqlite3/CMakeLists.txt +++ b/submodules/externals/sqlite3/CMakeLists.txt @@ -16,7 +16,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. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # ############################################################################ From ad0702277b11114321ab215d329866578cc1ee57 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 1 Aug 2016 16:51:55 +0200 Subject: [PATCH 02/36] Revert part of previous commit as ScreenOn/Off broadcastreceiver must be registered by application --- AndroidManifest.xml | 10 ++-------- src/org/linphone/LinphoneManager.java | 28 ++++++++++++++++++++++++++- src/org/linphone/LinphoneService.java | 1 - 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 59f557074..b1904f9ca 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -207,14 +207,8 @@ - - - - - - - - + + diff --git a/src/org/linphone/LinphoneManager.java b/src/org/linphone/LinphoneManager.java index 739387310..3454c21d8 100644 --- a/src/org/linphone/LinphoneManager.java +++ b/src/org/linphone/LinphoneManager.java @@ -80,8 +80,11 @@ import android.annotation.TargetApi; import android.app.Activity; import android.app.AlertDialog; import android.app.ProgressDialog; +import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Resources; import android.hardware.Sensor; @@ -140,6 +143,8 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag private boolean mAudioFocused; private int mLastNetworkType=-1; private ConnectivityManager mConnectivityManager; + private BroadcastReceiver mKeepAliveReceiver; + private IntentFilter mKeepAliveIntentFilter; private Handler mHandler = new Handler(); private WakeLock mIncallWakeLock; private static List mPendingChatFileMessage; @@ -633,6 +638,11 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag Log.e(e); } finally { + try { + mServiceContext.unregisterReceiver(mKeepAliveReceiver); + } catch (Exception e) { + Log.e(e); + } mLc = null; } } @@ -640,7 +650,12 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag public void restartLinphoneCore() { destroyLinphoneCore(); startLibLinphone(mServiceContext); - + /* + You cannot receive this through components declared in manifests, only + by explicitly registering for it with Context.registerReceiver(). This is a protected intent that can only + be sent by the system. + */ + mServiceContext.registerReceiver(mKeepAliveReceiver, mKeepAliveIntentFilter); sExited = false; } @@ -730,6 +745,16 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag Compatibility.initPushNotificationService(mServiceContext); } + /* + You cannot receive this through components declared in manifests, only + by explicitly registering for it with Context.registerReceiver(). This is a protected intent that can only + be sent by the system. + */ + mKeepAliveIntentFilter = new IntentFilter(Intent.ACTION_SCREEN_ON); + mKeepAliveIntentFilter.addAction(Intent.ACTION_SCREEN_OFF); + mKeepAliveReceiver = new KeepAliveReceiver(); + mServiceContext.registerReceiver(mKeepAliveReceiver, mKeepAliveIntentFilter); + updateNetworkReachability(); if (Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30)) { @@ -845,6 +870,7 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag Log.e(e); } finally { + mServiceContext.unregisterReceiver(mKeepAliveReceiver); mLc = null; instance = null; } diff --git a/src/org/linphone/LinphoneService.java b/src/org/linphone/LinphoneService.java index 5e7743a27..813df0236 100644 --- a/src/org/linphone/LinphoneService.java +++ b/src/org/linphone/LinphoneService.java @@ -20,7 +20,6 @@ package org.linphone; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.util.Calendar; import org.linphone.compatibility.Compatibility; import org.linphone.core.LinphoneAddress; From 02319e73fea91ff11f334c9138e7482673ee7d7c Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 1 Aug 2016 16:54:29 +0200 Subject: [PATCH 03/36] Remove some warnings --- src/org/linphone/SettingsFragment.java | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/org/linphone/SettingsFragment.java b/src/org/linphone/SettingsFragment.java index 1230155f8..d7a9914dc 100644 --- a/src/org/linphone/SettingsFragment.java +++ b/src/org/linphone/SettingsFragment.java @@ -35,15 +35,15 @@ import org.linphone.core.PayloadType; import org.linphone.mediastream.Log; import org.linphone.mediastream.Version; import org.linphone.mediastream.video.capture.hwconf.AndroidCameraConfiguration; -import org.linphone.tools.OpenH264DownloadHelper; import org.linphone.purchase.InAppPurchaseActivity; +import org.linphone.tools.OpenH264DownloadHelper; import org.linphone.ui.LedPreference; import org.linphone.ui.PreferencesListFragment; -import android.app.AlertDialog; -import android.content.DialogInterface; import android.Manifest; +import android.app.AlertDialog; import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; @@ -668,7 +668,7 @@ public class SettingsFragment extends PreferencesListFragment { public boolean onPreferenceChange(Preference preference, Object newValue) { boolean enable = (Boolean) newValue; try { - if (enable && Version.getCpuAbis().contains("armeabi-v7a") && !Version.getCpuAbis().contains("x86") + if (enable && Version.getCpuAbis().contains("armeabi-v7a") && !Version.getCpuAbis().contains("x86") && pt.getMime().equals("H264") && !mCodecDownloader.isCodecFound()) { LinphoneManager.getInstance().getOpenH264DownloadHelper().setOpenH264HelperListener(LinphoneManager.getInstance().getOpenH264HelperListener()); LinphoneManager.getInstance().getOpenH264DownloadHelper().setUserData(0,LinphoneManager.getInstance().getContext()); @@ -676,18 +676,17 @@ public class SettingsFragment extends PreferencesListFragment { AlertDialog.Builder builder = new AlertDialog.Builder(LinphoneManager.getInstance().getContext()); builder.setCancelable(false); - AlertDialog.Builder show = builder.setMessage("Do you agree to download " - + mCodecDownloader.getLicenseMessage()).setPositiveButton("Yes", new DialogInterface.OnClickListener(){ + builder.setMessage("Do you agree to download " + mCodecDownloader.getLicenseMessage()).setPositiveButton("Yes", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { if (which == DialogInterface.BUTTON_POSITIVE) mCodecDownloader.downloadCodec(); } }); - builder.setNegativeButton("No", new DialogInterface.OnClickListener(){ + builder.setNegativeButton("No", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - if (which == DialogInterface.BUTTON_NEGATIVE){ + if (which == DialogInterface.BUTTON_NEGATIVE) { // Disable H264 } } @@ -981,7 +980,6 @@ public class SettingsFragment extends PreferencesListFragment { // Disable UPnP if ICE si enabled, or disable ICE if UPnP is enabled CheckBoxPreference ice = (CheckBoxPreference) findPreference(getString(R.string.pref_ice_enable_key)); CheckBoxPreference turn = (CheckBoxPreference) findPreference(getString(R.string.pref_turn_enable_key)); - CheckBoxPreference upnp = (CheckBoxPreference) findPreference(getString(R.string.pref_upnp_enable_key)); ice.setChecked(mPrefs.isIceEnabled()); turn.setChecked(mPrefs.isTurnEnabled()); @@ -1023,8 +1021,6 @@ public class SettingsFragment extends PreferencesListFragment { findPreference(getString(R.string.pref_ice_enable_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { - CheckBoxPreference upnp = (CheckBoxPreference) findPreference(getString(R.string.pref_upnp_enable_key)); - boolean value = (Boolean) newValue; mPrefs.setIceEnabled((Boolean) newValue); return true; } @@ -1033,8 +1029,6 @@ public class SettingsFragment extends PreferencesListFragment { findPreference(getString(R.string.pref_turn_enable_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { - CheckBoxPreference upnp = (CheckBoxPreference) findPreference(getString(R.string.pref_upnp_enable_key)); - boolean value = (Boolean) newValue; mPrefs.setTurnEnabled((Boolean) newValue); return true; } @@ -1043,7 +1037,6 @@ public class SettingsFragment extends PreferencesListFragment { findPreference(getString(R.string.pref_upnp_enable_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { - CheckBoxPreference ice = (CheckBoxPreference) findPreference(getString(R.string.pref_ice_enable_key)); boolean value = (Boolean) newValue; mPrefs.setUpnpEnabled(value); return true; From c26ae51d3f2c51e1f42301f12175ee70a58c59a6 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 2 Aug 2016 11:10:16 +0200 Subject: [PATCH 04/36] Fix for contacts not being fetched when permission is denied and is not asked anymore --- src/org/linphone/LinphoneActivity.java | 7 +++++++ src/org/linphone/LinphoneContact.java | 24 +++++++++--------------- submodules/linphone | 2 +- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/org/linphone/LinphoneActivity.java b/src/org/linphone/LinphoneActivity.java index 076ecd51d..4671e7941 100644 --- a/src/org/linphone/LinphoneActivity.java +++ b/src/org/linphone/LinphoneActivity.java @@ -1165,6 +1165,10 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta checkAndRequestPermission(Manifest.permission.READ_CONTACTS, PERMISSIONS_REQUEST_CONTACTS); } + private boolean willContactsPermissionBeAsked() { + return LinphonePreferences.instance().firstTimeAskingForPermission(Manifest.permission.READ_CONTACTS) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_CONTACTS); + } + public void checkAndRequestWriteContactsPermission() { checkAndRequestPermission(Manifest.permission.WRITE_CONTACTS, 0); } @@ -1265,6 +1269,9 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta ContactsManager.getInstance().enableContactsAccess(); ContactsManager.getInstance().fetchContactsAsync(); fetchedContactsOnce = true; + } else if (contacts != PackageManager.PERMISSION_GRANTED && !willContactsPermissionBeAsked()) { + ContactsManager.getInstance().fetchContactsAsync(); + fetchedContactsOnce = true; } else { checkAndRequestReadContactsPermission(); } diff --git a/src/org/linphone/LinphoneContact.java b/src/org/linphone/LinphoneContact.java index a50ec6fb3..82f038bc0 100644 --- a/src/org/linphone/LinphoneContact.java +++ b/src/org/linphone/LinphoneContact.java @@ -419,6 +419,7 @@ public class LinphoneContact implements Serializable, Comparable Date: Tue, 2 Aug 2016 12:10:18 +0200 Subject: [PATCH 05/36] Updated linphone --- submodules/linphone | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/linphone b/submodules/linphone index d843d2789..61a3b8a98 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit d843d278905d44ae20e51eebc5b6327a121e510f +Subproject commit 61a3b8a98e6d35bff351b64e2c6717491792afb3 From 67389858a0b5fbe716d39e41a3ab27890f82cceb Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 2 Aug 2016 13:52:10 +0200 Subject: [PATCH 06/36] This should fix the broken junit reports on Jenkins --- liblinphone_tester/custom_rules.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/liblinphone_tester/custom_rules.xml b/liblinphone_tester/custom_rules.xml index da0216dc5..8a36b3884 100644 --- a/liblinphone_tester/custom_rules.xml +++ b/liblinphone_tester/custom_rules.xml @@ -48,7 +48,7 @@ - + From 9f1360d7966906e2f7e84b6abcb896bcff3610fe Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 2 Aug 2016 13:54:32 +0200 Subject: [PATCH 07/36] Also fix junit reports for UI tester --- tests/custom_rules.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/custom_rules.xml b/tests/custom_rules.xml index 87abcd905..5e7d620df 100644 --- a/tests/custom_rules.xml +++ b/tests/custom_rules.xml @@ -40,7 +40,7 @@ - + From 3b885639d06d8951def0495b215e374ebc0947ba Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 2 Aug 2016 14:27:28 +0200 Subject: [PATCH 08/36] Do not add LinphoneFriend in LinphoneFriendList if already done before --- src/org/linphone/LinphoneContact.java | 19 +++++++++++-------- submodules/linphone | 2 +- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/org/linphone/LinphoneContact.java b/src/org/linphone/LinphoneContact.java index 82f038bc0..6d7670f22 100644 --- a/src/org/linphone/LinphoneContact.java +++ b/src/org/linphone/LinphoneContact.java @@ -446,15 +446,18 @@ public class LinphoneContact implements Serializable, Comparable Date: Tue, 2 Aug 2016 14:47:14 +0200 Subject: [PATCH 09/36] Added a shortcut in advanced preferences to go directly in Android app settings --- res/values/non_localizable_strings.xml | 1 + res/values/strings.xml | 1 + res/xml/preferences.xml | 5 +++++ src/org/linphone/SettingsFragment.java | 20 ++++++++++++++++++++ 4 files changed, 27 insertions(+) diff --git a/res/values/non_localizable_strings.xml b/res/values/non_localizable_strings.xml index 7b0463d28..499d95906 100644 --- a/res/values/non_localizable_strings.xml +++ b/res/values/non_localizable_strings.xml @@ -204,4 +204,5 @@ pref_use_lime_encryption_key pref_device_ringtone_key pref_auto_answer_key + pref_android_app_settings_key diff --git a/res/values/strings.xml b/res/values/strings.xml index 7d6534af1..e216ece92 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -312,6 +312,7 @@ Start at boot time Incoming call hangup (in seconds) Remote provisioning + Android app settings Primary account Display name Username diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml index ceadfee7f..a37f9ce5a 100644 --- a/res/xml/preferences.xml +++ b/res/xml/preferences.xml @@ -345,6 +345,11 @@ android:key="@string/pref_remote_provisioning_key" android:inputType="textUri" android:persistent="false"/> + + diff --git a/src/org/linphone/SettingsFragment.java b/src/org/linphone/SettingsFragment.java index d7a9914dc..9cd1cf1b7 100644 --- a/src/org/linphone/SettingsFragment.java +++ b/src/org/linphone/SettingsFragment.java @@ -48,6 +48,7 @@ import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.media.AudioManager; +import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.preference.CheckBoxPreference; @@ -58,6 +59,7 @@ import android.preference.Preference.OnPreferenceChangeListener; import android.preference.Preference.OnPreferenceClickListener; import android.preference.PreferenceCategory; import android.preference.PreferenceScreen; +import android.provider.Settings; /** * @author Sylvain Berfini @@ -1146,6 +1148,24 @@ public class SettingsFragment extends PreferencesListFragment { return true; } }); + + findPreference(getString(R.string.pref_android_app_settings_key)).setOnPreferenceClickListener(new OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + synchronized (SettingsFragment.this) { + Context context = SettingsFragment.this.getActivity(); + Intent i = new Intent(); + i.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); + i.addCategory(Intent.CATEGORY_DEFAULT); + i.setData(Uri.parse("package:" + context.getPackageName())); + i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); + i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); + context.startActivity(i); + } + return true; + } + }); findPreference(getString(R.string.pref_display_name_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() { @Override From a34ac838549e42b7327550eab020c2377e154729 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 2 Aug 2016 14:56:56 +0200 Subject: [PATCH 10/36] Added a way to hide organization field in app --- res/layout/contact_edit.xml | 1 + res/values/non_localizable_custom.xml | 2 ++ src/org/linphone/ContactDetailsFragment.java | 3 ++- src/org/linphone/ContactEditorFragment.java | 11 +++++++++-- src/org/linphone/ContactsListFragment.java | 3 ++- 5 files changed, 16 insertions(+), 4 deletions(-) diff --git a/res/layout/contact_edit.xml b/res/layout/contact_edit.xml index da442c190..933c88ab2 100644 --- a/res/layout/contact_edit.xml +++ b/res/layout/contact_edit.xml @@ -136,6 +136,7 @@ android:inputType="textPersonName|textCapWords"/> false false + true + false true diff --git a/src/org/linphone/ContactDetailsFragment.java b/src/org/linphone/ContactDetailsFragment.java index e24a0ccdd..1b43f9254 100644 --- a/src/org/linphone/ContactDetailsFragment.java +++ b/src/org/linphone/ContactDetailsFragment.java @@ -78,8 +78,9 @@ public class ContactDetailsFragment extends Fragment implements OnClickListener deleteContact.setOnClickListener(this); organization = (TextView) view.findViewById(R.id.contactOrganization); + boolean isOrgVisible = getResources().getBoolean(R.bool.display_contact_organization); String org = contact.getOrganization(); - if (org != null && !org.isEmpty()) { + if (org != null && !org.isEmpty() && isOrgVisible) { organization.setText(org); } else { organization.setVisibility(View.GONE); diff --git a/src/org/linphone/ContactEditorFragment.java b/src/org/linphone/ContactEditorFragment.java index 1d555988a..56d77f816 100644 --- a/src/org/linphone/ContactEditorFragment.java +++ b/src/org/linphone/ContactEditorFragment.java @@ -204,9 +204,16 @@ public class ContactEditorFragment extends Fragment { } }); + organization = (EditText) view.findViewById(R.id.contactOrganization); - if (!isNewContact) { - organization.setText(contact.getOrganization()); + boolean isOrgVisible = getResources().getBoolean(R.bool.display_contact_organization); + if (!isOrgVisible) { + organization.setVisibility(View.GONE); + view.findViewById(R.id.contactOrganizationTitle).setVisibility(View.GONE); + } else { + if (!isNewContact) { + organization.setText(contact.getOrganization()); + } } if (!isNewContact) { diff --git a/src/org/linphone/ContactsListFragment.java b/src/org/linphone/ContactsListFragment.java index fbc3d8673..de822fabe 100644 --- a/src/org/linphone/ContactsListFragment.java +++ b/src/org/linphone/ContactsListFragment.java @@ -501,8 +501,9 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O } TextView organization = (TextView) view.findViewById(R.id.contactOrganization); + boolean isOrgVisible = getResources().getBoolean(R.bool.display_contact_organization); String org = contact.getOrganization(); - if (org != null && !org.isEmpty()) { + if (org != null && !org.isEmpty() && isOrgVisible) { organization.setText(org); organization.setVisibility(View.VISIBLE); } else { From f61efe56855113115ed4278067a47fca7e46f48d Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 2 Aug 2016 15:24:35 +0200 Subject: [PATCH 11/36] Removed unused imports --- .../assistant/CodecDownloaderFragment.java | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/org/linphone/assistant/CodecDownloaderFragment.java b/src/org/linphone/assistant/CodecDownloaderFragment.java index 496dc3892..deb58390a 100644 --- a/src/org/linphone/assistant/CodecDownloaderFragment.java +++ b/src/org/linphone/assistant/CodecDownloaderFragment.java @@ -19,6 +19,13 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +import org.linphone.LinphoneManager; +import org.linphone.R; +import org.linphone.core.LinphoneCoreException; +import org.linphone.core.OpenH264DownloadHelperListener; +import org.linphone.core.PayloadType; +import org.linphone.tools.OpenH264DownloadHelper; + import android.app.Fragment; import android.os.Bundle; import android.os.Handler; @@ -29,15 +36,6 @@ import android.widget.Button; import android.widget.ProgressBar; import android.widget.TextView; -import org.linphone.LinphoneActivity; -import org.linphone.LinphoneManager; -import org.linphone.R; -import org.linphone.core.LinphoneCoreFactory; -import org.linphone.core.OpenH264DownloadHelperListener; -import org.linphone.core.LinphoneCoreException; -import org.linphone.core.PayloadType; -import org.linphone.tools.OpenH264DownloadHelper; - /** * @author Erwan CROZE */ From 970505e64e00503e20ad119c124f7560d583559c Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 2 Aug 2016 16:47:58 +0200 Subject: [PATCH 12/36] Fixed some deprecated symbols with API 24 + a bit of cleanup in Compatibility.java + removed deprecated Contact and ChatMessage classes --- src/org/linphone/ChatFragment.java | 24 +-- src/org/linphone/ChatMessage.java | 117 ----------- src/org/linphone/Contact.java | 139 ------------- src/org/linphone/LinphoneManager.java | 28 ++- src/org/linphone/OpenGLESDisplay.java | 6 - .../assistant/LinphoneLoginFragment.java | 4 +- .../linphone/compatibility/ApiEightPlus.java | 33 --- .../compatibility/ApiSixteenPlus.java | 1 + .../compatibility/ApiTwentyOnePlus.java | 1 + .../linphone/compatibility/Compatibility.java | 193 ++---------------- src/org/linphone/ui/BubbleChat.java | 4 +- 11 files changed, 58 insertions(+), 492 deletions(-) delete mode 100644 src/org/linphone/ChatMessage.java delete mode 100644 src/org/linphone/Contact.java delete mode 100644 src/org/linphone/OpenGLESDisplay.java diff --git a/src/org/linphone/ChatFragment.java b/src/org/linphone/ChatFragment.java index 4f8c4323e..24604d69e 100644 --- a/src/org/linphone/ChatFragment.java +++ b/src/org/linphone/ChatFragment.java @@ -387,7 +387,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC if(isEditMode) { deleteChatBubble.setVisibility(View.VISIBLE); - if(message.isOutgoing()){ + 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); @@ -419,7 +419,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC } }); - if(messagesList.isItemChecked(position)) { + if (messagesList.isItemChecked(position)) { deleteChatBubble.setChecked(true); } else { deleteChatBubble.setChecked(false); @@ -427,7 +427,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC rlayout.addView(v); } else { - if(message.isOutgoing()){ + 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); @@ -448,7 +448,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); LinphoneAddress lAddress = null; - if(sipUri == null){ + if (sipUri == null) { initNewChatConversation(); } else { try { @@ -477,7 +477,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC } private void displayMessageList() { - if(chatRoom != null) { + if (chatRoom != null) { if (adapter != null) { adapter.refreshHistory(); } else { @@ -488,7 +488,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC } private void displayChatHeader(LinphoneAddress address) { - if(contact != null) { + if (contact != null) { contactName.setText(contact.getFullName()); } else if(address != null){ contactName.setText(LinphoneUtils.getAddressDisplayName(address)); @@ -618,7 +618,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC String draft = getArguments().getString("messageDraft"); message.setText(draft); - if(!newChatConversation) { + if (!newChatConversation) { initChatRoom(sipUri); searchContactField.setVisibility(View.GONE); resultContactsSearch.setVisibility(View.GONE); @@ -626,10 +626,10 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC } } - private void selectAllList(boolean isSelectAll){ + private void selectAllList(boolean isSelectAll) { int size = messagesList.getAdapter().getCount(); - for(int i=0; i GCMRegistrar = Class.forName("com.google.android.gcm.GCMRegistrar"); + GCMRegistrar.getMethod("checkDevice", Context.class).invoke(null, mServiceContext); + try { + GCMRegistrar.getMethod("checkManifest", Context.class).invoke(null, mServiceContext); + } catch (IllegalStateException e) { + Log.e("[Push Notification] No receiver found", e); + } + final String regId = (String)GCMRegistrar.getMethod("getRegistrationId", Context.class).invoke(null, mServiceContext); + String newPushSenderID = mServiceContext.getString(R.string.push_sender_id); + String currentPushSenderID = LinphonePreferences.instance().getPushNotificationRegistrationID(); + if (regId.equals("") || currentPushSenderID == null || !currentPushSenderID.equals(newPushSenderID)) { + GCMRegistrar.getMethod("register", Context.class, String[].class).invoke(null, mServiceContext, new String[]{newPushSenderID}); + Log.i("[Push Notification] Storing current sender id = " + newPushSenderID); + } else { + Log.i("[Push Notification] Already registered with id = " + regId); + LinphonePreferences.instance().setPushNotificationRegistrationID(regId); + } + } catch (java.lang.UnsupportedOperationException e) { + Log.i("[Push Notification] Not activated"); + } catch (Exception e1) { + Log.i("[Push Notification] Assuming GCM jar is not provided."); + } + } private synchronized void initLiblinphone(LinphoneCore lc) throws LinphoneCoreException { mLc = lc; @@ -742,7 +768,7 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag mLc.migrateCallLogs(); if (mServiceContext.getResources().getBoolean(R.bool.enable_push_id)) { - Compatibility.initPushNotificationService(mServiceContext); + initPushNotificationsService(); } /* diff --git a/src/org/linphone/OpenGLESDisplay.java b/src/org/linphone/OpenGLESDisplay.java deleted file mode 100644 index 358667874..000000000 --- a/src/org/linphone/OpenGLESDisplay.java +++ /dev/null @@ -1,6 +0,0 @@ -package org.linphone; - -public class OpenGLESDisplay { - public static native void init(int ptr, int width, int height); - public static native void render(int ptr); -} diff --git a/src/org/linphone/assistant/LinphoneLoginFragment.java b/src/org/linphone/assistant/LinphoneLoginFragment.java index e606e00c5..e889336b1 100644 --- a/src/org/linphone/assistant/LinphoneLoginFragment.java +++ b/src/org/linphone/assistant/LinphoneLoginFragment.java @@ -18,11 +18,11 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import org.linphone.R; +import org.linphone.compatibility.Compatibility; import android.app.Fragment; import android.os.Bundle; import android.text.Editable; -import android.text.Html; import android.text.TextWatcher; import android.text.method.LinkMovementMethod; import android.view.LayoutInflater; @@ -53,7 +53,7 @@ public class LinphoneLoginFragment extends Fragment implements OnClickListener, password = (EditText) view.findViewById(R.id.assistant_password); password.addTextChangedListener(this); forgotPassword = (TextView) view.findViewById(R.id.forgot_password); - forgotPassword.setText(Html.fromHtml(""+ getString(R.string.forgot_password) + "")); + forgotPassword.setText(Compatibility.fromHtml(""+ getString(R.string.forgot_password) + "")); forgotPassword.setMovementMethod(LinkMovementMethod.getInstance()); displayName = (EditText) view.findViewById(R.id.assistant_display_name); apply = (Button) view.findViewById(R.id.assistant_apply); diff --git a/src/org/linphone/compatibility/ApiEightPlus.java b/src/org/linphone/compatibility/ApiEightPlus.java index 30f5a78fb..295e3bf9c 100644 --- a/src/org/linphone/compatibility/ApiEightPlus.java +++ b/src/org/linphone/compatibility/ApiEightPlus.java @@ -1,11 +1,6 @@ package org.linphone.compatibility; -import org.linphone.LinphonePreferences; -import org.linphone.R; -import org.linphone.mediastream.Log; - import android.annotation.TargetApi; -import android.content.Context; import android.media.AudioManager; /* @@ -33,34 +28,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. @TargetApi(8) public class ApiEightPlus { - public static void initPushNotificationService(Context context) { - try { - Class GCMRegistrar = Class.forName("com.google.android.gcm.GCMRegistrar"); - // Starting the push notification service - GCMRegistrar.getMethod("checkDevice", Context.class).invoke(null, context); - try { - GCMRegistrar.getMethod("checkManifest", Context.class).invoke(null, context); - } catch (IllegalStateException e){ - Log.e("Push notification: No receiver found",e); - } - final String regId = (String)GCMRegistrar.getMethod("getRegistrationId", Context.class).invoke(null, context); - String newPushSenderID = context.getString(R.string.push_sender_id); - String currentPushSenderID = LinphonePreferences.instance().getPushNotificationRegistrationID(); - if (regId.equals("") || currentPushSenderID == null || !currentPushSenderID.equals(newPushSenderID)) { - GCMRegistrar.getMethod("register", Context.class, String[].class).invoke(null, context, new String[]{newPushSenderID}); - Log.d("Push Notification: storing current sender id = " + newPushSenderID); - } else { - Log.d("Push Notification: already registered with id = " + regId); - LinphonePreferences.instance().setPushNotificationRegistrationID(regId); - } - } catch (java.lang.UnsupportedOperationException e) { - Log.i("Push Notification: not activated"); - } catch (Exception e1) { - //assume the jar is not provided - Log.i("Push Notification: assuming GCM jar is not provided."); - } - } - @SuppressWarnings("deprecation") public static String getAudioManagerEventForBluetoothConnectionStateChangedEvent() { return AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED; diff --git a/src/org/linphone/compatibility/ApiSixteenPlus.java b/src/org/linphone/compatibility/ApiSixteenPlus.java index 148756063..f7fff7d2f 100644 --- a/src/org/linphone/compatibility/ApiSixteenPlus.java +++ b/src/org/linphone/compatibility/ApiSixteenPlus.java @@ -33,6 +33,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. @TargetApi(16) public class ApiSixteenPlus { + @SuppressWarnings("deprecation") public static Notification createMessageNotification(Context context, int msgCount, String msgSender, String msg, Bitmap contactIcon, PendingIntent intent) { diff --git a/src/org/linphone/compatibility/ApiTwentyOnePlus.java b/src/org/linphone/compatibility/ApiTwentyOnePlus.java index b75b72ef2..66d0a37b6 100644 --- a/src/org/linphone/compatibility/ApiTwentyOnePlus.java +++ b/src/org/linphone/compatibility/ApiTwentyOnePlus.java @@ -33,6 +33,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. @TargetApi(21) public class ApiTwentyOnePlus { + @SuppressWarnings("deprecation") public static Notification createMessageNotification(Context context, int msgCount, String msgSender, String msg, Bitmap contactIcon, PendingIntent intent) { diff --git a/src/org/linphone/compatibility/Compatibility.java b/src/org/linphone/compatibility/Compatibility.java index 10846675d..556498c6d 100644 --- a/src/org/linphone/compatibility/Compatibility.java +++ b/src/org/linphone/compatibility/Compatibility.java @@ -17,79 +17,28 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import java.io.InputStream; -import java.util.ArrayList; import java.util.List; -import org.linphone.LinphoneContact; -import org.linphone.core.LinphoneAddress; import org.linphone.mediastream.Version; import android.app.Activity; import android.app.Notification; import android.app.PendingIntent; -import android.content.ContentProviderOperation; import android.content.ContentResolver; import android.content.Context; -import android.content.Intent; import android.database.Cursor; import android.graphics.Bitmap; import android.media.AudioManager; -import android.net.Uri; import android.os.PowerManager; -import android.preference.Preference; import android.provider.Settings; +import android.text.Html; +import android.text.Spanned; import android.view.ViewTreeObserver; import android.view.ViewTreeObserver.OnGlobalLayoutListener; /** * @author Sylvain Berfini */ public class Compatibility { - public static void overridePendingTransition(Activity activity, int idAnimIn, int idAnimOut) { - if (Version.sdkAboveOrEqual(Version.API05_ECLAIR_20)) { - ApiFivePlus.overridePendingTransition(activity, idAnimIn, idAnimOut); - } - } - - public static Intent prepareAddContactIntent(String displayName, String sipUri) { - if (Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30)) { - return ApiElevenPlus.prepareAddContactIntent(displayName, sipUri); - } else { - return ApiFivePlus.prepareAddContactIntent(displayName, sipUri); - } - } - - public static Intent prepareEditContactIntent(int id) { - if (Version.sdkAboveOrEqual(Version.API05_ECLAIR_20)) { - return ApiFivePlus.prepareEditContactIntent(id); - } - return null; - } - - public static Intent prepareEditContactIntentWithSipAddress(int id, String sipAddress) { - if (Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30)) { - return ApiElevenPlus.prepareEditContactIntentWithSipAddress(id, sipAddress); - } else { - return ApiFivePlus.prepareEditContactIntent(id); - } - } - - public static List extractContactNumbersAndAddresses(String id, ContentResolver cr) { - if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) { - return ApiNinePlus.extractContactNumbersAndAddresses(id, cr); - } else { - return ApiFivePlus.extractContactNumbersAndAddresses(id, cr); - } - } - - public static List extractContactImAddresses(String id, ContentResolver cr) { - if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) { - return ApiFivePlus.extractContactNumbersAndAddresses(id, cr); - } else { - return null; - } - } - public static Cursor getContactsCursor(ContentResolver cr, List contactsId) { if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) { return ApiNinePlus.getContactsCursor(cr, null, contactsId); @@ -98,63 +47,6 @@ public class Compatibility { } } - public static Cursor getContactsCursor(ContentResolver cr, String search, List contactsId) { - if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) { - return ApiNinePlus.getContactsCursor(cr, search, contactsId); - } else { - return ApiFivePlus.getContactsCursor(cr, contactsId); - } - } - - public static Cursor getSIPContactsCursor(ContentResolver cr, List contactsId) { - if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) { - return ApiNinePlus.getSIPContactsCursor(cr, null, contactsId); - } else { - return ApiFivePlus.getSIPContactsCursor(cr, contactsId); - } - } - - public static Cursor getSIPContactsCursor(ContentResolver cr, String search, List contactsId) { - if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) { - return ApiNinePlus.getSIPContactsCursor(cr, search, contactsId); - } else { - return ApiFivePlus.getSIPContactsCursor(cr, contactsId); - } - } - - public static Cursor getImContactsCursor(ContentResolver cr) { - return ApiFivePlus.getSIPContactsCursor(cr,null); - } - - public static int getCursorDisplayNameColumnIndex(Cursor cursor) { - if (Version.sdkAboveOrEqual(Version.API05_ECLAIR_20)) { - return ApiFivePlus.getCursorDisplayNameColumnIndex(cursor); - } - return -1; - } - - public static LinphoneContact getContact(ContentResolver cr, Cursor cursor, int position) { - if (Version.sdkAboveOrEqual(Version.API05_ECLAIR_20)) { - return ApiFivePlus.getContact(cr, cursor, position); - } - return null; - } - - public static InputStream getContactPictureInputStream(ContentResolver cr, String id) { - if (Version.sdkAboveOrEqual(Version.API05_ECLAIR_20)) { - return ApiFivePlus.getContactPictureInputStream(cr, id); - } - return null; - } - - public static Uri findUriPictureOfContactAndSetDisplayName(LinphoneAddress address, ContentResolver cr) { - if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) { - return ApiNinePlus.findUriPictureOfContactAndSetDisplayName(address, cr); - } else { - return ApiFivePlus.findUriPictureOfContactAndSetDisplayName(address, cr); - } - } - public static Notification createSimpleNotification(Context context, String title, String text, PendingIntent intent) { Notification notif = null; @@ -218,13 +110,6 @@ public class Compatibility { } } - public static String refreshContactName(ContentResolver cr, String id) { - if (Version.sdkAboveOrEqual(Version.API05_ECLAIR_20)) { - return ApiFivePlus.refreshContactName(cr, id); - } - return null; - } - public static CompatibilityScaleGestureDetector getScaleGestureDetector(Context context, CompatibilityScaleGestureListener listener) { if (Version.sdkAboveOrEqual(Version.API08_FROYO_22)) { CompatibilityScaleGestureDetector csgd = new CompatibilityScaleGestureDetector(context); @@ -233,29 +118,6 @@ public class Compatibility { } return null; } - - - public static void setPreferenceChecked(Preference preference, boolean checked) { - if (Version.sdkAboveOrEqual(Version.API14_ICE_CREAM_SANDWICH_40)) { - ApiFourteenPlus.setPreferenceChecked(preference, checked); - } else { - ApiFivePlus.setPreferenceChecked(preference, checked); - } - } - - public static boolean isPreferenceChecked(Preference preference) { - if (Version.sdkAboveOrEqual(Version.API14_ICE_CREAM_SANDWICH_40)) { - return ApiFourteenPlus.isPreferenceChecked(preference); - } else { - return ApiFivePlus.isPreferenceChecked(preference); - } - } - - public static void initPushNotificationService(Context context) { - if (Version.sdkAboveOrEqual(Version.API08_FROYO_22)) { - ApiEightPlus.initPushNotificationService(context); - } - } public static void copyTextToClipboard(Context context, String msg) { if(Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30)) { @@ -264,42 +126,6 @@ public class Compatibility { ApiFivePlus.copyTextToClipboard(context, msg); } } - - public static void addSipAddressToContact(Context context, ArrayList ops, String sipAddress) { - if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) { - ApiNinePlus.addSipAddressToContact(context, ops, sipAddress); - } else { - ApiFivePlus.addSipAddressToContact(context, ops, sipAddress); - } - } - - public static void addSipAddressToContact(Context context, ArrayList ops, String sipAddress, String rawContactID) { - if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) { - ApiNinePlus.addSipAddressToContact(context, ops, sipAddress, rawContactID); - } else { - ApiFivePlus.addSipAddressToContact(context, ops, sipAddress, rawContactID); - } - } - - public static void updateSipAddressForContact(ArrayList ops, String oldSipAddress, String newSipAddress, String contactID) { - if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) { - ApiNinePlus.updateSipAddressForContact(ops, oldSipAddress, newSipAddress, contactID); - } else { - ApiFivePlus.updateSipAddressForContact(ops, oldSipAddress, newSipAddress, contactID); - } - } - - public static void deleteSipAddressFromContact(ArrayList ops, String oldSipAddress, String contactID) { - if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) { - ApiNinePlus.deleteSipAddressFromContact(ops, oldSipAddress, contactID); - } else { - ApiFivePlus.deleteSipAddressFromContact(ops, oldSipAddress, contactID); - } - } - - public static void deleteImAddressFromContact(ArrayList ops, String oldSipAddress, String contactID) { - ApiFivePlus.deleteSipAddressFromContact(ops, oldSipAddress, contactID); - } public static void removeGlobalLayoutListener(ViewTreeObserver viewTreeObserver, OnGlobalLayoutListener keyboardListener) { if (Version.sdkAboveOrEqual(Version.API16_JELLY_BEAN_41)) { @@ -309,15 +135,13 @@ public class Compatibility { } } - public static void hideNavigationBar(Activity activity) - { + public static void hideNavigationBar(Activity activity) { if (Version.sdkAboveOrEqual(Version.API14_ICE_CREAM_SANDWICH_40)) { ApiFourteenPlus.hideNavigationBar(activity); } } - public static void showNavigationBar(Activity activity) - { + public static void showNavigationBar(Activity activity) { if (Version.sdkAboveOrEqual(Version.API14_ICE_CREAM_SANDWICH_40)) { ApiFourteenPlus.showNavigationBar(activity); } @@ -354,4 +178,13 @@ public class Compatibility { return pm.isScreenOn(); } } + + @SuppressWarnings("deprecation") + public static Spanned fromHtml(String text) { + if (Version.sdkAboveOrEqual(Version.API24_NOUGAT_70)) { + return Html.fromHtml(text, Html.FROM_HTML_MODE_LEGACY); + } else { + return Html.fromHtml(text); + } + } } diff --git a/src/org/linphone/ui/BubbleChat.java b/src/org/linphone/ui/BubbleChat.java index d65709eec..47a97e27f 100644 --- a/src/org/linphone/ui/BubbleChat.java +++ b/src/org/linphone/ui/BubbleChat.java @@ -31,6 +31,7 @@ import org.linphone.LinphoneContact; import org.linphone.LinphoneManager; import org.linphone.LinphoneUtils; import org.linphone.R; +import org.linphone.compatibility.Compatibility; import org.linphone.core.LinphoneBuffer; import org.linphone.core.LinphoneChatMessage; import org.linphone.core.LinphoneChatMessage.State; @@ -52,7 +53,6 @@ import android.net.Uri; import android.os.AsyncTask; import android.os.Environment; import android.provider.MediaStore; -import android.text.Html; import android.text.Spannable; import android.text.SpannableStringBuilder; import android.text.Spanned; @@ -312,7 +312,7 @@ public class BubbleChat implements LinphoneChatMessage.LinphoneChatMessageListen text = text.replaceFirst(link, "" + linkWithoutScheme + ""); } - return Html.fromHtml(text); + return Compatibility.fromHtml(text); } public String getTextMessage() { From e11780075a684273b74b817c201b684e0302fee3 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 2 Aug 2016 17:13:18 +0200 Subject: [PATCH 13/36] More cleanup in compatibility package --- src/org/linphone/BluetoothManager.java | 5 +- src/org/linphone/ChatFragment.java | 6 +- src/org/linphone/ContactsManager.java | 42 +- src/org/linphone/LinphoneManager.java | 22 +- .../linphone/compatibility/ApiEightPlus.java | 35 -- .../linphone/compatibility/ApiElevenPlus.java | 19 - .../linphone/compatibility/ApiFivePlus.java | 406 ------------------ .../compatibility/ApiFourteenPlus.java | 53 --- .../linphone/compatibility/ApiNinePlus.java | 195 --------- .../linphone/compatibility/Compatibility.java | 80 +--- src/org/linphone/gcm/GCMService.java | 8 +- 11 files changed, 72 insertions(+), 799 deletions(-) delete mode 100644 src/org/linphone/compatibility/ApiEightPlus.java delete mode 100644 src/org/linphone/compatibility/ApiFivePlus.java delete mode 100644 src/org/linphone/compatibility/ApiFourteenPlus.java delete mode 100644 src/org/linphone/compatibility/ApiNinePlus.java diff --git a/src/org/linphone/BluetoothManager.java b/src/org/linphone/BluetoothManager.java index 34982c4e0..b908a4359 100644 --- a/src/org/linphone/BluetoothManager.java +++ b/src/org/linphone/BluetoothManager.java @@ -19,7 +19,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import java.util.List; -import org.linphone.compatibility.Compatibility; import org.linphone.mediastream.Log; import android.annotation.TargetApi; @@ -81,7 +80,7 @@ public class BluetoothManager extends BroadcastReceiver { IntentFilter filter = new IntentFilter(); filter.addCategory(BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID_CATEGORY + "." + BluetoothAssignedNumbers.PLANTRONICS); - filter.addAction(Compatibility.getAudioManagerEventForBluetoothConnectionStateChangedEvent()); + filter.addAction(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED); filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED); filter.addAction(BluetoothHeadset.ACTION_VENDOR_SPECIFIC_HEADSET_EVENT); mContext.registerReceiver(this, filter); @@ -278,7 +277,7 @@ public class BluetoothManager extends BroadcastReceiver { return; String action = intent.getAction(); - if (Compatibility.getAudioManagerEventForBluetoothConnectionStateChangedEvent().equals(action)) { + if (AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED.equals(action)) { int state = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, 0); if (state == AudioManager.SCO_AUDIO_STATE_CONNECTED) { Log.d("Bluetooth sco state => connected"); diff --git a/src/org/linphone/ChatFragment.java b/src/org/linphone/ChatFragment.java index 24604d69e..42e404914 100644 --- a/src/org/linphone/ChatFragment.java +++ b/src/org/linphone/ChatFragment.java @@ -44,6 +44,8 @@ import android.app.Activity; import android.app.Dialog; import android.app.Fragment; import android.app.ProgressDialog; +import android.content.ClipData; +import android.content.ClipboardManager; import android.content.Context; import android.content.Intent; import android.content.res.Configuration; @@ -827,7 +829,9 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC txt = message.getText(); } if (txt != null) { - Compatibility.copyTextToClipboard(getActivity(), txt); + ClipboardManager clipboard = (ClipboardManager) getActivity().getSystemService(Context.CLIPBOARD_SERVICE); + ClipData clip = android.content.ClipData.newPlainText("Message", txt); + clipboard.setPrimaryClip(clip); LinphoneActivity.instance().displayCustomToast(getString(R.string.text_copied_to_clipboard), Toast.LENGTH_SHORT); } } diff --git a/src/org/linphone/ContactsManager.java b/src/org/linphone/ContactsManager.java index 4cbcdd7eb..b67f1453d 100644 --- a/src/org/linphone/ContactsManager.java +++ b/src/org/linphone/ContactsManager.java @@ -21,10 +21,11 @@ package org.linphone; import java.util.ArrayList; import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Locale; +import java.util.Set; -import org.linphone.compatibility.Compatibility; import org.linphone.core.LinphoneAddress; import org.linphone.core.LinphoneCore; import org.linphone.core.LinphoneFriend; @@ -38,11 +39,13 @@ import android.content.ContentResolver; import android.content.Context; import android.database.ContentObserver; import android.database.Cursor; +import android.database.MatrixCursor; import android.net.Uri; import android.os.AsyncTask; import android.os.Handler; import android.os.Message; import android.provider.ContactsContract; +import android.provider.ContactsContract.CommonDataKinds; import android.provider.ContactsContract.Data; interface ContactsUpdatedListener { @@ -228,14 +231,13 @@ public class ContactsManager extends ContentObserver { contactsFetchTask.execute(); } - private class ContactsFetchTask extends AsyncTask, List> { @SuppressWarnings("unchecked") protected List doInBackground(Void... params) { List contacts = new ArrayList(); if (hasContactsAccess()) { - Cursor c = Compatibility.getContactsCursor(contentResolver, null); + Cursor c = getContactsCursor(contentResolver); if (c != null) { while (c.moveToNext()) { String id = c.getString(c.getColumnIndex(Data.CONTACT_ID)); @@ -367,4 +369,38 @@ public class ContactsManager extends ContentObserver { public String getString(int resourceID) { return context.getString(resourceID); } + + private Cursor getContactsCursor(ContentResolver cr) { + String req = "(" + Data.MIMETYPE + " = '" + CommonDataKinds.Phone.CONTENT_ITEM_TYPE + + "' AND " + CommonDataKinds.Phone.NUMBER + " IS NOT NULL " + + " OR (" + Data.MIMETYPE + " = '" + CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE + + "' AND " + ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS + " IS NOT NULL))"; + String[] projection = new String[] { Data.CONTACT_ID, Data.DISPLAY_NAME }; + String query = Data.DISPLAY_NAME + " IS NOT NULL AND (" + req + ")"; + + Cursor cursor = cr.query(Data.CONTENT_URI, projection, query, null, " lower(" + Data.DISPLAY_NAME + ") COLLATE UNICODE ASC"); + if (cursor == null) { + return cursor; + } + + MatrixCursor result = new MatrixCursor(cursor.getColumnNames()); + Set groupBy = new HashSet(); + while (cursor.moveToNext()) { + String name = cursor.getString(cursor.getColumnIndex(Data.DISPLAY_NAME)); + if (!groupBy.contains(name)) { + groupBy.add(name); + Object[] newRow = new Object[cursor.getColumnCount()]; + + int contactID = cursor.getColumnIndex(Data.CONTACT_ID); + int displayName = cursor.getColumnIndex(Data.DISPLAY_NAME); + + newRow[contactID] = cursor.getString(contactID); + newRow[displayName] = cursor.getString(displayName); + + result.addRow(newRow); + } + } + cursor.close(); + return result; + } } diff --git a/src/org/linphone/LinphoneManager.java b/src/org/linphone/LinphoneManager.java index 232e1b4d9..d09a88545 100644 --- a/src/org/linphone/LinphoneManager.java +++ b/src/org/linphone/LinphoneManager.java @@ -36,7 +36,6 @@ import java.util.Set; import java.util.Timer; import java.util.TimerTask; -import org.linphone.compatibility.Compatibility; import org.linphone.core.CallDirection; import org.linphone.core.LinphoneAddress; import org.linphone.core.LinphoneBuffer; @@ -1046,7 +1045,16 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag } return null; } - + + public void setAudioManagerInCallMode() { + if (mAudioManager.getMode() == AudioManager.MODE_IN_COMMUNICATION) { + Log.w("---AudioManager: already in MODE_IN_COMMUNICATION, skipping..."); + return; + } + Log.d("---AudioManager: set mode to MODE_IN_COMMUNICATION"); + mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION); + } + @SuppressLint("Wakelock") public void callState(final LinphoneCore lc,final LinphoneCall call, final State state, final String message) { Log.i("New call state [",state,"]"); @@ -1082,7 +1090,7 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag if (state == State.Connected) { if (mLc.getCallsNb() == 1) { requestAudioFocus(); - Compatibility.setAudioManagerInCallMode(mAudioManager); + setAudioManagerInCallMode(); } if (Hacks.needSoftvolume()) { @@ -1092,7 +1100,7 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag } if (state == State.OutgoingEarlyMedia) { - Compatibility.setAudioManagerInCallMode(mAudioManager); + setAudioManagerInCallMode(); } if (state == State.CallReleased || state == State.Error) { @@ -1172,7 +1180,7 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag public void startEcCalibration(LinphoneCoreListener l) throws LinphoneCoreException { routeAudioToSpeaker(); - Compatibility.setAudioManagerInCallMode((AudioManager)getContext().getSystemService(Context.AUDIO_SERVICE)); + setAudioManagerInCallMode(); Log.i("Set audio mode on 'Voice Communication'"); int oldVolume = mAudioManager.getStreamVolume(STREAM_VOICE_CALL); int maxVolume = mAudioManager.getStreamMaxVolume(STREAM_VOICE_CALL); @@ -1390,11 +1398,11 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag if (nearby) { params.screenBrightness = 0.1f; view.setVisibility(View.INVISIBLE); - Compatibility.hideNavigationBar(activity); + activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION); } else { params.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE; view.setVisibility(View.VISIBLE); - Compatibility.showNavigationBar(activity); + activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); } window.setAttributes(params); } diff --git a/src/org/linphone/compatibility/ApiEightPlus.java b/src/org/linphone/compatibility/ApiEightPlus.java deleted file mode 100644 index 295e3bf9c..000000000 --- a/src/org/linphone/compatibility/ApiEightPlus.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.linphone.compatibility; - -import android.annotation.TargetApi; -import android.media.AudioManager; - -/* -ApiEightPlus.java -Copyright (C) 2012 Belledonne Communications, Grenoble, France - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -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. -*/ -/** - * @author Sylvain Berfini - */ - -@TargetApi(8) -public class ApiEightPlus { - - @SuppressWarnings("deprecation") - public static String getAudioManagerEventForBluetoothConnectionStateChangedEvent() { - return AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED; - } -} \ No newline at end of file diff --git a/src/org/linphone/compatibility/ApiElevenPlus.java b/src/org/linphone/compatibility/ApiElevenPlus.java index d763c5221..7b30e5581 100644 --- a/src/org/linphone/compatibility/ApiElevenPlus.java +++ b/src/org/linphone/compatibility/ApiElevenPlus.java @@ -3,19 +3,15 @@ package org.linphone.compatibility; import java.util.ArrayList; import org.linphone.R; -import org.linphone.mediastream.Log; import android.annotation.TargetApi; import android.app.Notification; import android.app.PendingIntent; -import android.content.ClipData; -import android.content.ClipboardManager; import android.content.ContentUris; import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; -import android.media.AudioManager; import android.net.Uri; import android.provider.ContactsContract; import android.provider.ContactsContract.CommonDataKinds.SipAddress; @@ -119,21 +115,6 @@ public class ApiElevenPlus { return notif; } - - public static void copyTextToClipboard(Context context, String msg) { - ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); - ClipData clip = android.content.ClipData.newPlainText("Message", msg); - clipboard.setPrimaryClip(clip); - } - - public static void setAudioManagerInCallMode(AudioManager manager) { - if (manager.getMode() == AudioManager.MODE_IN_COMMUNICATION) { - Log.w("---AudioManager: already in MODE_IN_COMMUNICATION, skipping..."); - return; - } - Log.d("---AudioManager: set mode to MODE_IN_COMMUNICATION"); - manager.setMode(AudioManager.MODE_IN_COMMUNICATION); - } public static Intent prepareAddContactIntent(String displayName, String sipUri) { Intent intent = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI); diff --git a/src/org/linphone/compatibility/ApiFivePlus.java b/src/org/linphone/compatibility/ApiFivePlus.java deleted file mode 100644 index 7adc28c1e..000000000 --- a/src/org/linphone/compatibility/ApiFivePlus.java +++ /dev/null @@ -1,406 +0,0 @@ -package org.linphone.compatibility; - -import java.io.InputStream; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.linphone.LinphoneContact; -import org.linphone.R; -import org.linphone.core.LinphoneAddress; - -import android.annotation.TargetApi; -import android.app.Activity; -import android.app.Notification; -import android.app.PendingIntent; -import android.content.ContentProviderOperation; -import android.content.ContentResolver; -import android.content.ContentUris; -import android.content.Context; -import android.content.Intent; -import android.database.Cursor; -import android.database.MatrixCursor; -import android.media.AudioManager; -import android.net.Uri; -import android.preference.CheckBoxPreference; -import android.preference.Preference; -import android.provider.ContactsContract; -import android.provider.ContactsContract.CommonDataKinds; -import android.provider.ContactsContract.CommonDataKinds.Phone; -import android.provider.ContactsContract.Contacts; -import android.provider.ContactsContract.Data; -import android.support.v4.app.NotificationCompat; -import android.text.ClipboardManager; -import android.text.TextUtils; -import android.view.ViewTreeObserver; -import android.view.ViewTreeObserver.OnGlobalLayoutListener; - -/* -ApiFivePlus.java -Copyright (C) 2012 Belledonne Communications, Grenoble, France - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ -/** - * @author Sylvain Berfini - */ -@SuppressWarnings("deprecation") -@TargetApi(5) -public class ApiFivePlus { - public static void overridePendingTransition(Activity activity, int idAnimIn, int idAnimOut) { - activity.overridePendingTransition(idAnimIn, idAnimOut); - } - - public static Intent prepareAddContactIntent(String displayName, String sipUri) { - Intent intent = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI); - intent.putExtra(ContactsContract.Intents.Insert.NAME, displayName); - - // VoIP field not available, we store the address in the IM field - intent.putExtra(ContactsContract.Intents.Insert.IM_HANDLE, sipUri); - intent.putExtra(ContactsContract.Intents.Insert.IM_PROTOCOL, "sip"); - - return intent; - } - - public static Intent prepareEditContactIntent(int id) { - Intent intent = new Intent(Intent.ACTION_EDIT, Contacts.CONTENT_URI); - Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, id); - intent.setData(contactUri); - - return intent; - } - - public static Intent prepareEditContactIntentWithSipAddress(int id, String sipUri) { - Intent intent = new Intent(Intent.ACTION_EDIT, Contacts.CONTENT_URI); - Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, id); - intent.setData(contactUri); - - // VoIP field not available, we store the address in the IM field - intent.putExtra(ContactsContract.Intents.Insert.IM_HANDLE, sipUri); - intent.putExtra(ContactsContract.Intents.Insert.IM_PROTOCOL, "sip"); - - return intent; - } - - public static List extractContactNumbersAndAddresses(String id, ContentResolver cr) { - List list = new ArrayList(); - - Uri uri = Data.CONTENT_URI; - String[] projection = {ContactsContract.CommonDataKinds.Im.DATA}; - - // IM addresses - String selection = new StringBuilder() - .append(Data.CONTACT_ID).append(" = ? AND ") - .append(Data.MIMETYPE).append(" = '") - .append(ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE) - .append("' AND lower(") - .append(ContactsContract.CommonDataKinds.Im.CUSTOM_PROTOCOL) - .append(") = 'sip'") - .toString(); - Cursor c = cr.query(uri, projection, selection, new String[]{id}, null); - if (c != null) { - int nbId = c.getColumnIndex(ContactsContract.CommonDataKinds.Im.DATA); - while (c.moveToNext()) { - list.add("sip:" + c.getString(nbId)); - } - c.close(); - } - - // Phone Numbers - c = cr.query(Phone.CONTENT_URI, new String[]{Phone.NUMBER}, Phone.CONTACT_ID + " = " + id, null, null); - if (c != null) { - while (c.moveToNext()) { - String number = c.getString(c.getColumnIndex(Phone.NUMBER)); - list.add(number); - } - c.close(); - } - - return list; - } - - public static Cursor getContactsCursor(ContentResolver cr, List ids) { - String req = Data.MIMETYPE + " = '" + CommonDataKinds.Phone.CONTENT_ITEM_TYPE - + "' AND " + CommonDataKinds.Phone.NUMBER + " IS NOT NULL"; - - req += " OR (" + Contacts.Data.MIMETYPE + " = '" + CommonDataKinds.Im.CONTENT_ITEM_TYPE - + "' AND lower(" + CommonDataKinds.Im.CUSTOM_PROTOCOL + ") = 'sip')"; - - if(ids != null){ - String s = TextUtils.join(",", ids); - req += " OR (" + Data.CONTACT_ID + " IN (" + s + "))"; - } - - return getGeneralContactCursor(cr, req, true); - } - - public static Cursor getSIPContactsCursor(ContentResolver cr, List ids) { - String req = null; - req = Contacts.Data.MIMETYPE + " = '" + CommonDataKinds.Im.CONTENT_ITEM_TYPE - + "' AND lower(" + CommonDataKinds.Im.CUSTOM_PROTOCOL + ") = 'sip'"; - - if(ids != null){ - String s = TextUtils.join(",", ids); - req += " OR (" + Data.CONTACT_ID + " IN (" + s + "))"; - } - - return getGeneralContactCursor(cr, req, true); - } - - private static Cursor getSIPContactCursor(ContentResolver cr, String id) { - String req = null; - req = Contacts.Data.MIMETYPE + " = '" + CommonDataKinds.Im.CONTENT_ITEM_TYPE - + " AND lower(" + CommonDataKinds.Im.CUSTOM_PROTOCOL + ") = 'sip' AND " - + android.provider.ContactsContract.CommonDataKinds.Im.DATA + " LIKE '" + id + "'"; - - return getGeneralContactCursor(cr, req, false); - } - - public static Cursor getGeneralContactCursor(ContentResolver cr, String select, boolean shouldGroupBy) { - String[] projection = new String[] { Data.CONTACT_ID, Data.DISPLAY_NAME }; - String query; - - query = Data.DISPLAY_NAME + " IS NOT NULL AND (" + select + ")"; - - Cursor cursor = cr.query(Data.CONTENT_URI, projection, query, null, " lower(" + Data.DISPLAY_NAME + ") COLLATE UNICODE ASC"); - - if (!shouldGroupBy || cursor == null) { - return cursor; - } - - MatrixCursor result = new MatrixCursor(cursor.getColumnNames()); - Set groupBy = new HashSet(); - while (cursor.moveToNext()) { - String name = cursor.getString(getCursorDisplayNameColumnIndex(cursor)); - if (!groupBy.contains(name)) { - groupBy.add(name); - Object[] newRow = new Object[cursor.getColumnCount()]; - - int contactID = cursor.getColumnIndex(Data.CONTACT_ID); - int displayName = cursor.getColumnIndex(Data.DISPLAY_NAME); - - newRow[contactID] = cursor.getString(contactID); - newRow[displayName] = cursor.getString(displayName); - - result.addRow(newRow); - } - } - cursor.close(); - return result; - } - - public static int getCursorDisplayNameColumnIndex(Cursor cursor) { - return cursor.getColumnIndex(Data.DISPLAY_NAME); - } - - public static LinphoneContact getContact(ContentResolver cr, Cursor cursor, int position) { - try { - if(cursor != null) { - cursor.moveToFirst(); - boolean success = cursor.move(position); - if (!success) - return null; - - String id = cursor.getString(cursor.getColumnIndex(Data.CONTACT_ID)); - String name = getContactDisplayName(cursor); - Uri thumbnail = getContactPictureUri(id); - Uri photo = getContactPhotoUri(id); - InputStream input = getContactPictureInputStream(cr, id); - - LinphoneContact contact = new LinphoneContact(); - contact.setAndroidId(id); - contact.setFullName(name); - if (input != null) { - contact.setPhotoUri(photo); - contact.setThumbnailUri(thumbnail); - } - - return contact; - } else { - return null; - } - } catch (Exception e) { - - } - return null; - } - - public static InputStream getContactPictureInputStream(ContentResolver cr, String id) { - Uri person = ContentUris.withAppendedId(Contacts.CONTENT_URI, Long.parseLong(id)); - return Contacts.openContactPhotoInputStream(cr, person); - } - - private static String getContactDisplayName(Cursor cursor) { - return cursor.getString(cursor.getColumnIndex(Data.DISPLAY_NAME)); - } - - 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)); - return Uri.withAppendedPath(person, Contacts.Photo.DISPLAY_PHOTO); - } - - public static Uri findUriPictureOfContactAndSetDisplayName(LinphoneAddress address, ContentResolver cr) { - String username = address.getUserName(); - String domain = address.getDomain(); - String sipUri = username + "@" + domain; - - Cursor cursor = getSIPContactCursor(cr, sipUri); - if(cursor != null) { - LinphoneContact contact = getContact(cr, cursor, 0); - if (contact != null && contact.getNumbersOrAddresses().contains(sipUri)) { - address.setDisplayName(contact.getFullName()); - cursor.close(); - return contact.getPhotoUri(); - } - cursor.close(); - } - return null; - } - - public static String refreshContactName(ContentResolver cr, String id) { - Cursor cursor = getGeneralContactCursor(cr, Data.CONTACT_ID + " = '" + id + "'", false); - if (cursor != null && cursor.moveToFirst()) { - String contactDisplayName = getContactDisplayName(cursor); - cursor.close(); - return contactDisplayName; - } - return null; - } - - public static Notification createMessageNotification(Context context, String title, String msg, PendingIntent intent) { - Notification notif = new Notification(); - notif.icon = R.drawable.topbar_chat_notification; - notif.iconLevel = 0; - notif.when = System.currentTimeMillis(); - notif.flags &= Notification.FLAG_ONGOING_EVENT; - - notif.defaults |= Notification.DEFAULT_VIBRATE; - notif.defaults |= Notification.DEFAULT_SOUND; - notif.defaults |= Notification.DEFAULT_LIGHTS; - - return notif; - } - - public static Notification createInCallNotification(Context context, String title, String msg, int iconID, PendingIntent intent) { - NotificationCompat.Builder notifBuilder = new NotificationCompat.Builder(context) - .setSmallIcon(iconID) - .setContentTitle(title) - .setContentText(msg) - .setContentIntent(intent); - - return notifBuilder.build(); - } - - public static void setPreferenceChecked(Preference preference, boolean checked) { - ((CheckBoxPreference) preference).setChecked(checked); - } - - public static boolean isPreferenceChecked(Preference preference) { - return ((CheckBoxPreference) preference).isChecked(); - } - - public static void copyTextToClipboard(Context context, String msg) { - ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); - clipboard.setText(msg); - } - - public static void addSipAddressToContact(Context context, ArrayList ops, String sipAddress) { - ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) - .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) - .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE) - .withValue(ContactsContract.CommonDataKinds.Im.DATA, sipAddress) - .withValue(ContactsContract.CommonDataKinds.Im.TYPE, ContactsContract.CommonDataKinds.Im.TYPE_CUSTOM) - .withValue(ContactsContract.CommonDataKinds.Im.LABEL, context.getString(R.string.addressbook_label)) - .build() - ); - } - - public static void addSipAddressToContact(Context context, ArrayList ops, String sipAddress, String rawContactID) { - ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) - .withValue(ContactsContract.Data.RAW_CONTACT_ID, rawContactID) - .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE) - .withValue(ContactsContract.CommonDataKinds.Im.DATA, sipAddress) - .withValue(ContactsContract.CommonDataKinds.Im.TYPE, ContactsContract.CommonDataKinds.Im.TYPE_CUSTOM) - .withValue(ContactsContract.CommonDataKinds.Im.LABEL, context.getString(R.string.addressbook_label)) - .build() - ); - } - - public static void updateSipAddressForContact(ArrayList ops, String oldSipAddress, String newSipAddress, String contactID) { - String select = ContactsContract.Data.CONTACT_ID + "=? AND " - + ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE + "' AND " - + ContactsContract.CommonDataKinds.Im.DATA + "=?"; - String[] args = new String[] { String.valueOf(contactID), oldSipAddress }; - - ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI) - .withSelection(select, args) - .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE) - .withValue(ContactsContract.CommonDataKinds.Im.DATA, newSipAddress) - .build() - ); - } - - public static void deleteSipAddressFromContact(ArrayList ops, String oldSipAddress, String contactID) { - String select = ContactsContract.Data.CONTACT_ID + "=? AND " - + ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE + "' AND " - + ContactsContract.CommonDataKinds.Im.DATA + "=?"; - String[] args = new String[] { String.valueOf(contactID), oldSipAddress }; - - ops.add(ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI) - .withSelection(select, args) - .build() - ); - } - - public static void removeGlobalLayoutListener(ViewTreeObserver viewTreeObserver, OnGlobalLayoutListener keyboardListener) { - viewTreeObserver.removeGlobalOnLayoutListener(keyboardListener); - } - - public static void setAudioManagerInCallMode(AudioManager manager) { - /* Do not use MODE_IN_CALL, because it is reserved to GSM. This is causing conflicts on audio system resulting in silenced audio.*/ - //manager.setMode(AudioManager.MODE_IN_CALL); - } - - public static Notification createNotification(Context context, String title, String message, int icon, int level, PendingIntent intent, boolean isOngoingEvent) { - NotificationCompat.Builder notifBuilder = new NotificationCompat.Builder(context) - .setSmallIcon(icon, level) - .setContentTitle(title) - .setContentText(message) - .setContentIntent(intent); - - return notifBuilder.build(); - } - - public static Notification createSimpleNotification(Context context, String title, String text, PendingIntent intent) { - NotificationCompat.Builder notifBuilder = new NotificationCompat.Builder(context) - .setSmallIcon(R.drawable.linphone_logo) - .setContentTitle(title) - .setContentText(text) - .setContentIntent(intent); - - Notification notif = notifBuilder.build(); - notif.defaults |= Notification.DEFAULT_VIBRATE; - notif.defaults |= Notification.DEFAULT_SOUND; - notif.defaults |= Notification.DEFAULT_LIGHTS; - - return notif; - } -} diff --git a/src/org/linphone/compatibility/ApiFourteenPlus.java b/src/org/linphone/compatibility/ApiFourteenPlus.java deleted file mode 100644 index df480ad78..000000000 --- a/src/org/linphone/compatibility/ApiFourteenPlus.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.linphone.compatibility; - -import android.annotation.TargetApi; -import android.app.Activity; -import android.media.AudioManager; -import android.preference.Preference; -import android.preference.TwoStatePreference; -import android.view.View; - -/* -ApiFourteenPlus.java -Copyright (C) 2012 Belledonne Communications, Grenoble, France - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ -/** - * @author Sylvain Berfini - */ -@TargetApi(14) -public class ApiFourteenPlus { - - public static void setPreferenceChecked(Preference preference, boolean checked) { - ((TwoStatePreference) preference).setChecked(checked); - } - - public static boolean isPreferenceChecked(Preference preference) { - return ((TwoStatePreference) preference).isChecked(); - } - - public static void hideNavigationBar(Activity activity) { - activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION); - } - - public static void showNavigationBar(Activity activity) { - activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); - } - - public static String getAudioManagerEventForBluetoothConnectionStateChangedEvent() { - return AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED; - } -} diff --git a/src/org/linphone/compatibility/ApiNinePlus.java b/src/org/linphone/compatibility/ApiNinePlus.java deleted file mode 100644 index 313ee4d1a..000000000 --- a/src/org/linphone/compatibility/ApiNinePlus.java +++ /dev/null @@ -1,195 +0,0 @@ -package org.linphone.compatibility; - -import java.util.ArrayList; -import java.util.List; - -import org.linphone.LinphoneContact; -import org.linphone.R; -import org.linphone.core.LinphoneAddress; - -import android.annotation.TargetApi; -import android.content.ContentProviderOperation; -import android.content.ContentResolver; -import android.content.Context; -import android.database.Cursor; -import android.net.Uri; -import android.provider.ContactsContract; -import android.provider.ContactsContract.CommonDataKinds; -import android.provider.ContactsContract.CommonDataKinds.Phone; -import android.provider.ContactsContract.Contacts; -import android.provider.ContactsContract.Data; -import android.text.TextUtils; - -/* -ApiNinePlus.java -Copyright (C) 2012 Belledonne Communications, Grenoble, France - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ -/** - * @author Sylvain Berfini - */ -@TargetApi(9) -public class ApiNinePlus { - - public static void addSipAddressToContact(Context context, ArrayList ops, String sipAddress) { - ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) - .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) - .withValue(ContactsContract.Data.MIMETYPE, CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE) - .withValue(ContactsContract.CommonDataKinds.SipAddress.DATA, sipAddress) - .withValue(CommonDataKinds.SipAddress.TYPE, CommonDataKinds.SipAddress.TYPE_CUSTOM) - .withValue(CommonDataKinds.SipAddress.LABEL, context.getString(R.string.addressbook_label)) - .build() - ); - } - - public static void addSipAddressToContact(Context context, ArrayList ops, String sipAddress, String rawContactID) { - ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) - .withValue(ContactsContract.Data.RAW_CONTACT_ID, rawContactID) - .withValue(ContactsContract.Data.MIMETYPE, CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE) - .withValue(ContactsContract.CommonDataKinds.SipAddress.DATA, sipAddress) - .withValue(CommonDataKinds.SipAddress.TYPE, CommonDataKinds.SipAddress.TYPE_CUSTOM) - .withValue(CommonDataKinds.SipAddress.LABEL, context.getString(R.string.addressbook_label)) - .build() - ); - } - - public static void updateSipAddressForContact(ArrayList ops, String oldSipAddress, String newSipAddress, String contactID) { - String select = ContactsContract.Data.CONTACT_ID + "=? AND " - + ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE + "' AND " - + ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS + "=?"; - String[] args = new String[] { String.valueOf(contactID), oldSipAddress }; - - ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI) - .withSelection(select, args) - .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE) - .withValue(ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS, newSipAddress) - .build() - ); - } - - public static void deleteSipAddressFromContact(ArrayList ops, String oldSipAddress, String contactID) { - String select = ContactsContract.Data.CONTACT_ID + "=? AND " - + ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE + "' AND " - + ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS + "=? "; - String[] args = new String[] { String.valueOf(contactID), oldSipAddress }; - - ops.add(ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI) - .withSelection(select, args) - .build() - ); - } - - public static List extractContactNumbersAndAddresses(String id, ContentResolver cr) { - List list = new ArrayList(); - - Uri uri = Data.CONTENT_URI; - String[] projection; - - // SIP addresses - String selection2 = new StringBuilder() - .append(Data.CONTACT_ID) - .append(" = ? AND ") - .append(Data.MIMETYPE) - .append(" = '") - .append(ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE) - .append("'") - .toString(); - projection = new String[] {ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS}; - Cursor c = cr.query(uri, projection, selection2, new String[]{id}, null); - if (c != null) { - int nbid = c.getColumnIndex(ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS); - while (c.moveToNext()) { - list.add("sip:" + c.getString(nbid)); - } - c.close(); - } - - // Phone Numbers - c = cr.query(Phone.CONTENT_URI, new String[] { Phone.NUMBER }, Phone.CONTACT_ID + " = " + id, null, null); - if (c != null) { - while (c.moveToNext()) { - String number = c.getString(c.getColumnIndex(Phone.NUMBER)); - list.add(number); - } - c.close(); - } - - return list; - } - - public static Cursor getContactsCursor(ContentResolver cr, String search, List ids) { - String req; - if(ids != null && ids.size() > 0) { - req = "(" + Data.MIMETYPE + " = '" + CommonDataKinds.Phone.CONTENT_ITEM_TYPE - + "' AND " + CommonDataKinds.Phone.NUMBER + " IS NOT NULL " - + " OR (" + Data.MIMETYPE + " = '" + CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE - + "' AND " + ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS + " IS NOT NULL)" - + " OR (" + Data.CONTACT_ID + " IN (" + TextUtils.join(" , ", ids) + ")))"; - } else { - req = "(" + Data.MIMETYPE + " = '" + CommonDataKinds.Phone.CONTENT_ITEM_TYPE - + "' AND " + CommonDataKinds.Phone.NUMBER + " IS NOT NULL " - + " OR (" + Data.MIMETYPE + " = '" + CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE - + "' AND " + ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS + " IS NOT NULL))"; - } - - if (search != null) { - req += " AND " + Data.DISPLAY_NAME + " LIKE '%" + search + "%'"; - } - - return ApiFivePlus.getGeneralContactCursor(cr, req, true); - } - - public static Cursor getSIPContactsCursor(ContentResolver cr, String search, List ids) { - - String req = "(" + Data.MIMETYPE + " = '" + CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE - + "' AND " + ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS + " IS NOT NULL) "; - - if(ids != null && ids.size() > 0) { - req += " OR (" + Data.CONTACT_ID + " IN (" + TextUtils.join(" , ", ids) + "))"; - } - - if (search != null) { - req += " AND " + Data.DISPLAY_NAME + " LIKE '%" + search + "%'"; - } - - return ApiFivePlus.getGeneralContactCursor(cr, req, true); - } - - private static Cursor getSIPContactCursor(ContentResolver cr, String id) { - String req = null; - req = Contacts.Data.MIMETYPE + " = '" + CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE - + "' AND " + ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS + " LIKE '" + id + "'"; - - return ApiFivePlus.getGeneralContactCursor(cr, req, false); - } - - public static Uri findUriPictureOfContactAndSetDisplayName(LinphoneAddress address, ContentResolver cr) { - String username = address.getUserName(); - String domain = address.getDomain(); - String sipUri = username + "@" + domain; - - Cursor cursor = getSIPContactCursor(cr, sipUri); - LinphoneContact contact = ApiFivePlus.getContact(cr, cursor, 0); - if (contact != null && contact.getNumbersOrAddresses().contains(sipUri)) { - address.setDisplayName(contact.getFullName()); - cursor.close(); - return contact.getPhotoUri(); - } - - cursor.close(); - return null; - } -} diff --git a/src/org/linphone/compatibility/Compatibility.java b/src/org/linphone/compatibility/Compatibility.java index 556498c6d..b37e784b4 100644 --- a/src/org/linphone/compatibility/Compatibility.java +++ b/src/org/linphone/compatibility/Compatibility.java @@ -17,18 +17,12 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import java.util.List; - import org.linphone.mediastream.Version; -import android.app.Activity; import android.app.Notification; import android.app.PendingIntent; -import android.content.ContentResolver; import android.content.Context; -import android.database.Cursor; import android.graphics.Bitmap; -import android.media.AudioManager; import android.os.PowerManager; import android.provider.Settings; import android.text.Html; @@ -39,61 +33,38 @@ import android.view.ViewTreeObserver.OnGlobalLayoutListener; * @author Sylvain Berfini */ public class Compatibility { - public static Cursor getContactsCursor(ContentResolver cr, List contactsId) { - if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) { - return ApiNinePlus.getContactsCursor(cr, null, contactsId); - } else { - return ApiFivePlus.getContactsCursor(cr, contactsId); - } - } - public static Notification createSimpleNotification(Context context, String title, String text, PendingIntent intent) { Notification notif = null; - if (Version.sdkAboveOrEqual(Version.API21_LOLLIPOP_50)) { return ApiTwentyOnePlus.createSimpleNotification(context, title, text, intent); } else if (Version.sdkAboveOrEqual(Version.API16_JELLY_BEAN_41)) { notif = ApiSixteenPlus.createSimpleNotification(context, title, text, intent); - } else if (Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30)) { - notif = ApiElevenPlus.createSimpleNotification(context, title, text, intent); } else { - notif = ApiFivePlus.createSimpleNotification(context, title, text, intent); + notif = ApiElevenPlus.createSimpleNotification(context, title, text, intent); } return notif; } public static Notification createMessageNotification(Context context, int msgCount, String msgSender, String msg, Bitmap contactIcon, PendingIntent intent) { - Notification notif = null; - String title; - if (msgCount == 1) { - title = "Unread message from %s".replace("%s", msgSender); - } else { - title = "%i unread messages".replace("%i", String.valueOf(msgCount)); - } - + Notification notif = null; if (Version.sdkAboveOrEqual(Version.API21_LOLLIPOP_50)) { return ApiTwentyOnePlus.createMessageNotification(context, msgCount, msgSender, msg, contactIcon, intent); } else if (Version.sdkAboveOrEqual(Version.API16_JELLY_BEAN_41)) { notif = ApiSixteenPlus.createMessageNotification(context, msgCount, msgSender, msg, contactIcon, intent); - } else if (Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30)) { - notif = ApiElevenPlus.createMessageNotification(context, msgCount, msgSender, msg, contactIcon, intent); } else { - notif = ApiFivePlus.createMessageNotification(context, title, msg, intent); + notif = ApiElevenPlus.createMessageNotification(context, msgCount, msgSender, msg, contactIcon, intent); } return notif; } public static Notification createInCallNotification(Context context, String title, String msg, int iconID, Bitmap contactIcon, String contactName, PendingIntent intent) { Notification notif = null; - if (Version.sdkAboveOrEqual(Version.API21_LOLLIPOP_50)) { return ApiTwentyOnePlus.createInCallNotification(context, title, msg, iconID, contactIcon, contactName, intent); } else if (Version.sdkAboveOrEqual(Version.API16_JELLY_BEAN_41)) { notif = ApiSixteenPlus.createInCallNotification(context, title, msg, iconID, contactIcon, contactName, intent); - } else if (Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30)) { - notif = ApiElevenPlus.createInCallNotification(context, title, msg, iconID, contactIcon, contactName, intent); } else { - notif = ApiFivePlus.createInCallNotification(context, title, msg, iconID, intent); + notif = ApiElevenPlus.createInCallNotification(context, title, msg, iconID, contactIcon, contactName, intent); } return notif; } @@ -103,10 +74,8 @@ public class Compatibility { return ApiTwentyOnePlus.createNotification(context, title, message, icon, iconLevel, largeIcon, intent, isOngoingEvent,priority); } else if (Version.sdkAboveOrEqual(Version.API16_JELLY_BEAN_41)) { return ApiSixteenPlus.createNotification(context, title, message, icon, iconLevel, largeIcon, intent, isOngoingEvent,priority); - } else if (Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30)) { - return ApiElevenPlus.createNotification(context, title, message, icon, iconLevel, largeIcon, intent, isOngoingEvent); } else { - return ApiFivePlus.createNotification(context, title, message, icon, iconLevel, intent, isOngoingEvent); + return ApiElevenPlus.createNotification(context, title, message, icon, iconLevel, largeIcon, intent, isOngoingEvent); } } @@ -119,47 +88,12 @@ public class Compatibility { return null; } - public static void copyTextToClipboard(Context context, String msg) { - if(Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30)) { - ApiElevenPlus.copyTextToClipboard(context, msg); - } else { - ApiFivePlus.copyTextToClipboard(context, msg); - } - } - + @SuppressWarnings("deprecation") public static void removeGlobalLayoutListener(ViewTreeObserver viewTreeObserver, OnGlobalLayoutListener keyboardListener) { if (Version.sdkAboveOrEqual(Version.API16_JELLY_BEAN_41)) { ApiSixteenPlus.removeGlobalLayoutListener(viewTreeObserver, keyboardListener); } else { - ApiFivePlus.removeGlobalLayoutListener(viewTreeObserver, keyboardListener); - } - } - - public static void hideNavigationBar(Activity activity) { - if (Version.sdkAboveOrEqual(Version.API14_ICE_CREAM_SANDWICH_40)) { - ApiFourteenPlus.hideNavigationBar(activity); - } - } - - public static void showNavigationBar(Activity activity) { - if (Version.sdkAboveOrEqual(Version.API14_ICE_CREAM_SANDWICH_40)) { - ApiFourteenPlus.showNavigationBar(activity); - } - } - - public static void setAudioManagerInCallMode(AudioManager manager) { - if (Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30)) { - ApiElevenPlus.setAudioManagerInCallMode(manager); - } else { - ApiFivePlus.setAudioManagerInCallMode(manager); - } - } - - public static String getAudioManagerEventForBluetoothConnectionStateChangedEvent() { - if (Version.sdkAboveOrEqual(Version.API14_ICE_CREAM_SANDWICH_40)) { - return ApiFourteenPlus.getAudioManagerEventForBluetoothConnectionStateChangedEvent(); - } else { - return ApiEightPlus.getAudioManagerEventForBluetoothConnectionStateChangedEvent(); + viewTreeObserver.removeGlobalOnLayoutListener(keyboardListener); } } diff --git a/src/org/linphone/gcm/GCMService.java b/src/org/linphone/gcm/GCMService.java index ebeb8f7f6..ebfc1273f 100644 --- a/src/org/linphone/gcm/GCMService.java +++ b/src/org/linphone/gcm/GCMService.java @@ -53,13 +53,13 @@ public class GCMService extends GCMBaseIntentService { @Override protected void onError(Context context, String errorId) { initLogger(context); - Log.e("Error while registering push notification : " + errorId); + Log.e("[Push Notification] Error while registering: " + errorId); } @Override protected void onMessage(Context context, Intent intent) { initLogger(context); - Log.d("Push notification received"); + Log.d("[Push Notification] Received"); if (!LinphoneService.isReady()) { startService(new Intent(ACTION_MAIN).setClass(this, LinphoneService.class)); @@ -79,7 +79,7 @@ public class GCMService extends GCMBaseIntentService { @Override protected void onRegistered(Context context, String regId) { initLogger(context); - Log.d("Registered push notification : " + regId); + Log.d("[Push Notification] Registered: " + regId); LinphonePreferences.instance().setPushNotificationRegistrationID(regId); } @@ -87,7 +87,7 @@ public class GCMService extends GCMBaseIntentService { @Override protected void onUnregistered(Context context, String regId) { initLogger(context); - Log.w("Unregistered push notification : " + regId); + Log.w("[Push Notification] Unregistered: " + regId); LinphonePreferences.instance().setPushNotificationRegistrationID(null); } From c4e9fc742bcf5407312b8e92375e50e098b69f94 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 2 Aug 2016 17:19:17 +0200 Subject: [PATCH 14/36] Reworked a few logs --- src/org/linphone/BluetoothManager.java | 50 +++++++++++++------------- src/org/linphone/LinphoneManager.java | 4 +-- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/org/linphone/BluetoothManager.java b/src/org/linphone/BluetoothManager.java index b908a4359..c3d0523ec 100644 --- a/src/org/linphone/BluetoothManager.java +++ b/src/org/linphone/BluetoothManager.java @@ -67,14 +67,14 @@ public class BluetoothManager extends BroadcastReceiver { public BluetoothManager() { isBluetoothConnected = false; if (!ensureInit()) { - Log.w("BluetoothManager tried to init but LinphoneService not ready yet..."); + Log.w("[Bluetooth] Manager tried to init but LinphoneService not ready yet..."); } instance = this; } public void initBluetooth() { if (!ensureInit()) { - Log.w("BluetoothManager tried to init bluetooth but LinphoneService not ready yet..."); + Log.w("[Bluetooth] Manager tried to init bluetooth but LinphoneService not ready yet..."); return; } @@ -84,14 +84,14 @@ public class BluetoothManager extends BroadcastReceiver { filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED); filter.addAction(BluetoothHeadset.ACTION_VENDOR_SPECIFIC_HEADSET_EVENT); mContext.registerReceiver(this, filter); - Log.d("Bluetooth receiver started"); + Log.d("[Bluetooth] Receiver started"); startBluetooth(); } private void startBluetooth() { if (isBluetoothConnected) { - Log.e("Bluetooth already started"); + Log.e("[Bluetooth] Already started, skipping..."); return; } @@ -99,14 +99,14 @@ public class BluetoothManager extends BroadcastReceiver { if (mBluetoothAdapter != null && mBluetoothAdapter.isEnabled()) { if (mProfileListener != null) { - Log.w("Bluetooth headset profile was already opened, let's close it"); + Log.w("[Bluetooth] Headset profile was already opened, let's close it"); mBluetoothAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mBluetoothHeadset); } mProfileListener = new BluetoothProfile.ServiceListener() { public void onServiceConnected(int profile, BluetoothProfile proxy) { if (profile == BluetoothProfile.HEADSET) { - Log.d("Bluetooth headset connected"); + Log.d("[Bluetooth] Headset connected"); mBluetoothHeadset = (BluetoothHeadset) proxy; isBluetoothConnected = true; } @@ -115,17 +115,17 @@ public class BluetoothManager extends BroadcastReceiver { if (profile == BluetoothProfile.HEADSET) { mBluetoothHeadset = null; isBluetoothConnected = false; - Log.d("Bluetooth headset disconnected"); + Log.d("[Bluetooth] Headset disconnected"); LinphoneManager.getInstance().routeAudioToReceiver(); } } }; boolean success = mBluetoothAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.HEADSET); if (!success) { - Log.e("Bluetooth getProfileProxy failed !"); + Log.e("[Bluetooth] getProfileProxy failed !"); } } else { - Log.w("Bluetooth interface disabled on device"); + Log.w("[Bluetooth] Interface disabled on device"); } } @@ -152,7 +152,7 @@ public class BluetoothManager extends BroadcastReceiver { if (mBluetoothAdapter != null && mBluetoothAdapter.isEnabled() && mAudioManager != null && mAudioManager.isBluetoothScoAvailableOffCall()) { if (isBluetoothHeadsetAvailable()) { if (mAudioManager != null && !mAudioManager.isBluetoothScoOn()) { - Log.d("Bluetooth sco off, let's start it"); + Log.d("[Bluetooth] SCO off, let's start it"); mAudioManager.setBluetoothScoOn(true); mAudioManager.startBluetoothSco(); } @@ -179,12 +179,12 @@ public class BluetoothManager extends BroadcastReceiver { } if (ok) { if (retries > 0) { - Log.d("Bluetooth route ok after " + retries + " retries"); + Log.d("[Bluetooth] Audio route ok after " + retries + " retries"); } else { - Log.d("Bluetooth route ok"); + Log.d("[Bluetooth] Audio route ok"); } } else { - Log.d("Bluetooth still not ok..."); + Log.d("[Bluetooth] Audio route still not ok..."); } return ok; @@ -211,7 +211,7 @@ public class BluetoothManager extends BroadcastReceiver { break; } } - Log.d(isHeadsetConnected ? "Headset found, bluetooth audio route available" : "No headset found, bluetooth audio route unavailable"); + Log.d(isHeadsetConnected ? "[Bluetooth] Headset found, bluetooth audio route available" : "[Bluetooth] No headset found, bluetooth audio route unavailable"); } return isHeadsetConnected; } @@ -236,12 +236,12 @@ public class BluetoothManager extends BroadcastReceiver { mAudioManager.stopBluetoothSco(); mAudioManager.setBluetoothScoOn(false); } - Log.w("Bluetooth sco disconnected!"); + Log.w("[Bluetooth] SCO disconnected!"); } } public void stopBluetooth() { - Log.w("Stopping bluetooth..."); + Log.w("[Bluetooth] Stopping..."); isBluetoothConnected = false; disableBluetoothSCO(); @@ -252,7 +252,7 @@ public class BluetoothManager extends BroadcastReceiver { } mBluetoothDevice = null; - Log.w("Bluetooth stopped!"); + Log.w("[Bluetooth] Stopped!"); if (LinphoneManager.isInstanciated()) { LinphoneManager.getInstance().routeAudioToReceiver(); @@ -265,7 +265,7 @@ public class BluetoothManager extends BroadcastReceiver { try { mContext.unregisterReceiver(this); - Log.d("Bluetooth receiver stopped"); + Log.d("[Bluetooth] Receiver stopped"); } catch (Exception e) {} } catch (Exception e) { Log.e(e); @@ -280,27 +280,27 @@ public class BluetoothManager extends BroadcastReceiver { if (AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED.equals(action)) { int state = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, 0); if (state == AudioManager.SCO_AUDIO_STATE_CONNECTED) { - Log.d("Bluetooth sco state => connected"); + Log.d("[Bluetooth] SCO state: connected"); // LinphoneManager.getInstance().audioStateChanged(AudioState.BLUETOOTH); isScoConnected = true; } else if (state == AudioManager.SCO_AUDIO_STATE_DISCONNECTED) { - Log.d("Bluetooth sco state => disconnected"); + Log.d("[Bluetooth] SCO state: disconnected"); // LinphoneManager.getInstance().audioStateChanged(AudioState.SPEAKER); isScoConnected = false; } else { - Log.d("Bluetooth sco state => " + state); + Log.d("[Bluetooth] SCO state: " + state); } } else if (BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED.equals(action)) { int state = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE, BluetoothAdapter.STATE_DISCONNECTED); if (state == 0) { - Log.d("Bluetooth state => disconnected"); + Log.d("[Bluetooth] State: disconnected"); stopBluetooth(); } else if (state == 2) { - Log.d("Bluetooth state => connected"); + Log.d("[Bluetooth] State: connected"); startBluetooth(); } else { - Log.d("Bluetooth state => " + state); + Log.d("[Bluetooth] State: " + state); } } else if (intent.getAction().equals(BluetoothHeadset.ACTION_VENDOR_SPECIFIC_HEADSET_EVENT)) { @@ -313,7 +313,7 @@ public class BluetoothManager extends BroadcastReceiver { if (eventName.equals("BUTTON") && args.length >= 3) { Integer buttonID = (Integer) args[1]; Integer mode = (Integer) args[2]; - Log.d("Bluetooth event: " + command + " : " + eventName + ", id = " + buttonID + " (" + mode + ")"); + Log.d("[Bluetooth] Event: " + command + " : " + eventName + ", id = " + buttonID + " (" + mode + ")"); } } } diff --git a/src/org/linphone/LinphoneManager.java b/src/org/linphone/LinphoneManager.java index d09a88545..ce162c143 100644 --- a/src/org/linphone/LinphoneManager.java +++ b/src/org/linphone/LinphoneManager.java @@ -1048,10 +1048,10 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag public void setAudioManagerInCallMode() { if (mAudioManager.getMode() == AudioManager.MODE_IN_COMMUNICATION) { - Log.w("---AudioManager: already in MODE_IN_COMMUNICATION, skipping..."); + Log.w("[AudioManager] already in MODE_IN_COMMUNICATION, skipping..."); return; } - Log.d("---AudioManager: set mode to MODE_IN_COMMUNICATION"); + Log.d("[AudioManager] Mode: MODE_IN_COMMUNICATION"); mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION); } From a8b9e4d09509ad5b1ce37c7dae0cc3f2c290ef9a Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Tue, 2 Aug 2016 22:00:53 +0200 Subject: [PATCH 15/36] update linphone and bctoolbox --- submodules/bctoolbox | 2 +- submodules/linphone | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/submodules/bctoolbox b/submodules/bctoolbox index fbac73d67..a2c4bfc0f 160000 --- a/submodules/bctoolbox +++ b/submodules/bctoolbox @@ -1 +1 @@ -Subproject commit fbac73d6704f9f5697770188747639e519a28819 +Subproject commit a2c4bfc0f2211dd5a429c659e16d7dfe9ce90a3b diff --git a/submodules/linphone b/submodules/linphone index be38b3474..3a462ec03 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit be38b3474cd4fc3ce48ebc09e645c71b2da857b3 +Subproject commit 3a462ec03ee0ce51e7819c7f566ea2f1fd4da9b9 From 7e21deaf3ef7a116b99f795bb7b6f513c0507bae Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 3 Aug 2016 09:58:16 +0200 Subject: [PATCH 16/36] Updated README --- README | 15 ++++++++------- res/xml/contacts.xml | 2 +- src/org/linphone/AboutFragment.java | 12 +++++------- src/org/linphone/AccountPreferencesFragment.java | 5 ++--- src/org/linphone/LinphoneUtils.java | 2 +- .../linphone/tutorials/TutorialCardDavSync.java | 3 +-- 6 files changed, 18 insertions(+), 21 deletions(-) diff --git a/README b/README index 1693d40d6..21dbfcf28 100644 --- a/README +++ b/README @@ -7,8 +7,8 @@ COMPILATION INSTRUCTIONS To build liblinphone for Android, you must: ------------------------------------------- -0) download the Android sdk with platform-tools and tools updated to latest revision (at least API 16 is needed), then add both 'tools' and 'platform-tools' folders in your path. -1) download the Android ndk (version r11) from google and add it to your path (no symlink !!!). +0) download the Android sdk (API 24) with platform-tools and tools updated to latest revision, then add both 'tools' and 'platform-tools' folders in your path. +1) download the Android ndk (version r11c or 12b) from google and add it to your path (no symlink !!!). 2) install yasm, nasm, ant, python, cmake and vim-common On 64 bits linux systems you'll need the ia32-libs package With the latest Debian (multiarch), you need this: @@ -27,11 +27,12 @@ To build liblinphone for Android, you must: $ make mediastreamer2-sdk 8) (Optional) To generate a signed apk to publish on the Google Play, run $ make release -Make sure you filled the ant.properties values for version.name, key.store and key.alias in order to correctly sign the generated apk. -You also may want to create a file name ant_password.properties with the following: -key.store.password=[your_password] -key.alias.password=[your_password] -If you don't, the passwords will be asked at the signing phase. + Make sure you filled the ant.properties values for version.name, key.store and key.alias in order to correctly sign the generated apk. + You also may want to create a file name ant_password.properties with the following: + key.store.password=[your_password] + key.alias.password=[your_password] + If you don't, the passwords will be asked at the signing phase. +9) (Optional) Once you compiled the libraries succesfully with 'make', you can reduce the compilation time using 'make quick': it will only generate a new APK from java files. To run the tutorials: -------------------- diff --git a/res/xml/contacts.xml b/res/xml/contacts.xml index 6b5d8e180..db84bc8c9 100644 --- a/res/xml/contacts.xml +++ b/res/xml/contacts.xml @@ -3,7 +3,7 @@ - + Date: Wed, 3 Aug 2016 10:05:46 +0200 Subject: [PATCH 17/36] Fix compil error for those who don't have SDK 24 installed yet --- README | 2 +- src/org/linphone/compatibility/Compatibility.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README b/README index 21dbfcf28..e2269f90d 100644 --- a/README +++ b/README @@ -7,7 +7,7 @@ COMPILATION INSTRUCTIONS To build liblinphone for Android, you must: ------------------------------------------- -0) download the Android sdk (API 24) with platform-tools and tools updated to latest revision, then add both 'tools' and 'platform-tools' folders in your path. +0) download the Android sdk (API 23 at least) with platform-tools and tools updated to latest revision, then add both 'tools' and 'platform-tools' folders in your path. 1) download the Android ndk (version r11c or 12b) from google and add it to your path (no symlink !!!). 2) install yasm, nasm, ant, python, cmake and vim-common On 64 bits linux systems you'll need the ia32-libs package diff --git a/src/org/linphone/compatibility/Compatibility.java b/src/org/linphone/compatibility/Compatibility.java index b37e784b4..4673f18f8 100644 --- a/src/org/linphone/compatibility/Compatibility.java +++ b/src/org/linphone/compatibility/Compatibility.java @@ -116,7 +116,7 @@ public class Compatibility { @SuppressWarnings("deprecation") public static Spanned fromHtml(String text) { if (Version.sdkAboveOrEqual(Version.API24_NOUGAT_70)) { - return Html.fromHtml(text, Html.FROM_HTML_MODE_LEGACY); + return Html.fromHtml(text, 0); //Html.FROM_HTML_MODE_LEGACY } else { return Html.fromHtml(text); } From f1a45ce51c52160608707f6be97e4e7a9aebd239 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 3 Aug 2016 10:26:25 +0200 Subject: [PATCH 18/36] Commented out part of code only supported in Android Nougat (7) for now --- src/org/linphone/compatibility/Compatibility.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/org/linphone/compatibility/Compatibility.java b/src/org/linphone/compatibility/Compatibility.java index 4673f18f8..cad5a21a0 100644 --- a/src/org/linphone/compatibility/Compatibility.java +++ b/src/org/linphone/compatibility/Compatibility.java @@ -115,10 +115,9 @@ public class Compatibility { @SuppressWarnings("deprecation") public static Spanned fromHtml(String text) { - if (Version.sdkAboveOrEqual(Version.API24_NOUGAT_70)) { - return Html.fromHtml(text, 0); //Html.FROM_HTML_MODE_LEGACY - } else { - return Html.fromHtml(text); - } + /*if (Version.sdkAboveOrEqual(Version.API24_NOUGAT_70)) { + return Html.fromHtml(text, Html.FROM_HTML_MODE_LEGACY); + }*/ + return Html.fromHtml(text); } } From abd7d67690889d0da88a5db4bd4da582525ce737 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 3 Aug 2016 13:43:37 +0200 Subject: [PATCH 19/36] Updated liblinphone --- submodules/linphone | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/linphone b/submodules/linphone index 3a462ec03..b0f08ed96 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit 3a462ec03ee0ce51e7819c7f566ea2f1fd4da9b9 +Subproject commit b0f08ed9677971b49339834980ed9c2e507c49d1 From 4e69ea1f1f75c52dce234ca3c76a7935cd8d1752 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 3 Aug 2016 16:28:51 +0200 Subject: [PATCH 20/36] Updated ms2 --- submodules/linphone | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/linphone b/submodules/linphone index b0f08ed96..25e652df1 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit b0f08ed9677971b49339834980ed9c2e507c49d1 +Subproject commit 25e652df1f498bb3a72fb4b9d27646d4a2c9eb1e From a30cc2b8f05b7b74630bd5a23d06f5fb28c1f940 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 3 Aug 2016 16:48:25 +0200 Subject: [PATCH 21/36] Updated bctoolbox to fix compil --- submodules/bctoolbox | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/bctoolbox b/submodules/bctoolbox index a2c4bfc0f..ddd39bf0a 160000 --- a/submodules/bctoolbox +++ b/submodules/bctoolbox @@ -1 +1 @@ -Subproject commit a2c4bfc0f2211dd5a429c659e16d7dfe9ce90a3b +Subproject commit ddd39bf0a9a60f8bafa98190f75adc1f05d5e8a3 From 9c75797d86b4aebf7d5b98ad3687c74a9a344ae8 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Thu, 4 Aug 2016 14:47:34 +0200 Subject: [PATCH 22/36] Update bctoolbox, belle-sip, cmake-builder and linphone submodules. --- submodules/bctoolbox | 2 +- submodules/belle-sip | 2 +- submodules/cmake-builder | 2 +- submodules/linphone | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/submodules/bctoolbox b/submodules/bctoolbox index ddd39bf0a..921a21332 160000 --- a/submodules/bctoolbox +++ b/submodules/bctoolbox @@ -1 +1 @@ -Subproject commit ddd39bf0a9a60f8bafa98190f75adc1f05d5e8a3 +Subproject commit 921a21332c327ae99900267950be0bfd2d7c6126 diff --git a/submodules/belle-sip b/submodules/belle-sip index 086bb16bd..b1ed6cc73 160000 --- a/submodules/belle-sip +++ b/submodules/belle-sip @@ -1 +1 @@ -Subproject commit 086bb16bd79180265136ed9d4a89661049c95016 +Subproject commit b1ed6cc738fde8beaaaeaed6860dfacc9908584d diff --git a/submodules/cmake-builder b/submodules/cmake-builder index 29911ee5b..f4eac4803 160000 --- a/submodules/cmake-builder +++ b/submodules/cmake-builder @@ -1 +1 @@ -Subproject commit 29911ee5ba6053dd041ee02c6dc13b0134e890d2 +Subproject commit f4eac4803eee43de3efa96ecca9450ba4f2bc7dc diff --git a/submodules/linphone b/submodules/linphone index 25e652df1..19384ed6d 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit 25e652df1f498bb3a72fb4b9d27646d4a2c9eb1e +Subproject commit 19384ed6de8e69a1fdbf73ca48b713049ae8a117 From 6ef2db07297dea5b86a012c72098701e77cfd5c8 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 4 Aug 2016 15:39:25 +0200 Subject: [PATCH 23/36] Updated liblinphone --- submodules/linphone | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/linphone b/submodules/linphone index 19384ed6d..2864c88b4 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit 19384ed6de8e69a1fdbf73ca48b713049ae8a117 +Subproject commit 2864c88b408c8413b9f499bd5b90b88a2fd54b7c From 5cb2e85aa4dc447c664fce40a5eddbbf2124ae5e Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 4 Aug 2016 17:25:01 +0200 Subject: [PATCH 24/36] Updated liblinphone --- submodules/linphone | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/linphone b/submodules/linphone index 2864c88b4..3567c38e1 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit 2864c88b408c8413b9f499bd5b90b88a2fd54b7c +Subproject commit 3567c38e1f72b1892bbc35a2aedd3abccc034903 From c4f52b2f9660970301779d253c7b6039a8d83593 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Fri, 5 Aug 2016 14:43:52 +0200 Subject: [PATCH 25/36] Update belle-sip submodule. --- submodules/belle-sip | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/belle-sip b/submodules/belle-sip index b1ed6cc73..b553f58c3 160000 --- a/submodules/belle-sip +++ b/submodules/belle-sip @@ -1 +1 @@ -Subproject commit b1ed6cc738fde8beaaaeaed6860dfacc9908584d +Subproject commit b553f58c3f23633b9c183af5784b2170b6b4aa91 From 9d8481386bea3b7d52544287fb018f4a59c84e55 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Sat, 6 Aug 2016 10:12:51 +0200 Subject: [PATCH 26/36] fix bug around proximity sensing in call activity. It could remain activated forever in some circumstances. --- src/org/linphone/CallActivity.java | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/org/linphone/CallActivity.java b/src/org/linphone/CallActivity.java index b9274d53d..da94060e8 100644 --- a/src/org/linphone/CallActivity.java +++ b/src/org/linphone/CallActivity.java @@ -119,6 +119,7 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve private boolean isConferenceRunning = false; private LinphoneCoreListenerBase mListener; private DrawerLayout sideMenu; + private boolean mProximitySensingEnabled; public static CallActivity instance() { return instance; @@ -800,8 +801,22 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve } } + private void enableProximitySensing(boolean enable){ + if (enable){ + if (!mProximitySensingEnabled){ + mSensorManager.registerListener(this, mProximity, SensorManager.SENSOR_DELAY_NORMAL); + mProximitySensingEnabled = true; + } + }else{ + if (mProximitySensingEnabled){ + mSensorManager.unregisterListener(this); + mProximitySensingEnabled = false; + } + } + } + private void showAudioView() { - mSensorManager.registerListener(this, mProximity, SensorManager.SENSOR_DELAY_NORMAL); + enableProximitySensing(true); replaceFragmentVideoByAudio(); displayAudioCall(); showStatusBar(); @@ -816,7 +831,7 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve } refreshInCallActions(); - mSensorManager.unregisterListener(this); + enableProximitySensing(false); replaceFragmentAudioByVideo(); hideStatusBar(); } @@ -1173,7 +1188,7 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve handleViewIntent(); if (!isVideoEnabled(LinphoneManager.getLc().getCurrentCall())) { - mSensorManager.registerListener(this, mProximity, SensorManager.SENSOR_DELAY_NORMAL); + enableProximitySensing(true); removeCallbacks(); } } @@ -1223,10 +1238,7 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve mControlsHandler.removeCallbacks(mControls); } mControls = null; - - if (!isVideoEnabled(LinphoneManager.getLc().getCurrentCall())) { - mSensorManager.unregisterListener(this); - } + enableProximitySensing(false); } @Override @@ -1239,7 +1251,7 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve mControls = null; mControlsHandler = null; - mSensorManager.unregisterListener(this); + enableProximitySensing(false); unbindDrawables(findViewById(R.id.topLayout)); instance = null; @@ -1510,7 +1522,7 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve private void displayConference(boolean isInConf){ if(isInConf) { mControlsLayout.setVisibility(View.VISIBLE); - mSensorManager.registerListener(this, mProximity, SensorManager.SENSOR_DELAY_NORMAL); + enableProximitySensing(true); mActiveCallHeader.setVisibility(View.GONE); mNoCurrentCall.setVisibility(View.GONE); conferenceList.removeAllViews(); From fc2fb6ceb7d348dccff512f398a65769b490d9e8 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Sat, 6 Aug 2016 10:19:10 +0200 Subject: [PATCH 27/36] remove code around proximity sensing in LinphoneManager.java, that is no longer used in the app. --- src/org/linphone/LinphoneManager.java | 82 --------------------------- 1 file changed, 82 deletions(-) diff --git a/src/org/linphone/LinphoneManager.java b/src/org/linphone/LinphoneManager.java index ce162c143..cf7ab079e 100644 --- a/src/org/linphone/LinphoneManager.java +++ b/src/org/linphone/LinphoneManager.java @@ -1362,88 +1362,6 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag mAudioManager.adjustStreamVolume(LINPHONE_VOLUME_STREAM, i < 0 ? AudioManager.ADJUST_LOWER : AudioManager.ADJUST_RAISE, AudioManager.FLAG_SHOW_UI); } - public static Boolean isProximitySensorNearby(final SensorEvent event) { - float threshold = 4.001f; // <= 4 cm is near - - final float distanceInCm = event.values[0]; - final float maxDistance = event.sensor.getMaximumRange(); - Log.d("Proximity sensor report [",distanceInCm,"] , for max range [",maxDistance,"]"); - - if (maxDistance <= threshold) { - // Case binary 0/1 and short sensors - threshold = maxDistance; - } - - return distanceInCm < threshold; - } - - private static boolean sLastProximitySensorValueNearby; - private static Set sProximityDependentActivities = new HashSet(); - private static SensorEventListener sProximitySensorListener = new SensorEventListener() { - @Override - public void onSensorChanged(SensorEvent event) { - if (event.timestamp == 0) return; //just ignoring for nexus 1 - sLastProximitySensorValueNearby = isProximitySensorNearby(event); - proximityNearbyChanged(); - } - @Override - public void onAccuracyChanged(Sensor sensor, int accuracy) {} - }; - - - private static void simulateProximitySensorNearby(Activity activity, boolean nearby) { - final Window window = activity.getWindow(); - WindowManager.LayoutParams params = window.getAttributes(); - View view = ((ViewGroup) window.getDecorView().findViewById(android.R.id.content)).getChildAt(0); - if (nearby) { - params.screenBrightness = 0.1f; - view.setVisibility(View.INVISIBLE); - activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION); - } else { - params.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE; - view.setVisibility(View.VISIBLE); - activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); - } - window.setAttributes(params); - } - - private static void proximityNearbyChanged() { - boolean nearby = sLastProximitySensorValueNearby; - for (Activity activity : sProximityDependentActivities) { - simulateProximitySensorNearby(activity, nearby); - } - } - - public static synchronized void startProximitySensorForActivity(Activity activity) { - if (sProximityDependentActivities.contains(activity)) { - Log.i("proximity sensor already active for " + activity.getLocalClassName()); - return; - } - if (sProximityDependentActivities.isEmpty()) { - SensorManager sm = (SensorManager) activity.getSystemService(Context.SENSOR_SERVICE); - Sensor s = sm.getDefaultSensor(Sensor.TYPE_PROXIMITY); - if (s != null) { - sm.registerListener(sProximitySensorListener,s,SensorManager.SENSOR_DELAY_UI); - Log.i("Proximity sensor detected, registering"); - } - } else if (sLastProximitySensorValueNearby){ - simulateProximitySensorNearby(activity, true); - } - - sProximityDependentActivities.add(activity); - } - - public static synchronized void stopProximitySensorForActivity(Activity activity) { - sProximityDependentActivities.remove(activity); - simulateProximitySensorNearby(activity, false); - if (sProximityDependentActivities.isEmpty()) { - SensorManager sm = (SensorManager) activity.getSystemService(Context.SENSOR_SERVICE); - sm.unregisterListener(sProximitySensorListener); - sLastProximitySensorValueNearby = false; - } - } - - public static synchronized LinphoneCore getLcIfManagerNotDestroyedOrNull() { if (sExited || instance == null) { // Can occur if the UI thread play a posted event but in the meantime the LinphoneManager was destroyed From 8ce45e702cccc553a0db805b37aef61024c3227c Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 8 Aug 2016 10:05:58 +0200 Subject: [PATCH 28/36] Updated liblinphone --- submodules/linphone | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/linphone b/submodules/linphone index 3567c38e1..6f1e96c8f 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit 3567c38e1f72b1892bbc35a2aedd3abccc034903 +Subproject commit 6f1e96c8f60576fb1cfe9750612f9fdb7c134c54 From fc269d9b0158d03d5cbbc33d848976a92143ddce Mon Sep 17 00:00:00 2001 From: Erwan Croze Date: Mon, 8 Aug 2016 12:08:53 +0200 Subject: [PATCH 29/36] Add echo tester in the audio settings --- res/values/non_localizable_strings.xml | 1 + res/values/strings.xml | 1 + res/xml/preferences.xml | 5 +++ src/org/linphone/LinphoneActivity.java | 9 ++++ src/org/linphone/LinphoneManager.java | 47 +++++++++++++++++++-- src/org/linphone/SettingsFragment.java | 58 +++++++++++++++++++++++--- src/org/linphone/StatusFragment.java | 5 ++- 7 files changed, 116 insertions(+), 10 deletions(-) diff --git a/res/values/non_localizable_strings.xml b/res/values/non_localizable_strings.xml index 7b0463d28..f4e25d109 100644 --- a/res/values/non_localizable_strings.xml +++ b/res/values/non_localizable_strings.xml @@ -107,6 +107,7 @@ pref_background_mode_key pref_codec_bitrate_limit_key pref_adaptive_rate_control_key + pref_echo_tester_key push_reg_id_key push_sender_id_key diff --git a/res/values/strings.xml b/res/values/strings.xml index 7d6534af1..a7edab164 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -245,6 +245,7 @@ Echo cancellation Removes the echo heard by other end Echo canceler calibration + Test echo Calibrating… Calibrated in %s ms No echo diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml index ceadfee7f..fe2e82710 100644 --- a/res/xml/preferences.xml +++ b/res/xml/preferences.xml @@ -69,6 +69,11 @@ android:title="@string/pref_echo_canceller_calibration" android:key="@string/pref_echo_canceller_calibration_key" android:persistent="false"/> + + box && ohcodec.getUserData(box) != null) - ((CheckBoxPreference)ohcodec.getUserData(box)).setSummary(mCodecDownloader.getLicenseMessage()); + if (ohcodec.getUserDataSize() > box && ohcodec.getUserData(box) != null) { + ((CheckBoxPreference) ohcodec.getUserData(box)).setSummary(mCodecDownloader.getLicenseMessage()); + ((CheckBoxPreference) ohcodec.getUserData(box)).setTitle("OpenH264"); + } } } }); @@ -1154,6 +1159,42 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag mAudioManager.setStreamVolume(STREAM_VOICE_CALL, oldVolume, 0); } + public int startEchoTester() throws LinphoneCoreException { + routeAudioToSpeaker(); + Compatibility.setAudioManagerInCallMode((AudioManager)getContext().getSystemService(Context.AUDIO_SERVICE)); + Log.i("Set audio mode on 'Voice Communication'"); + int oldVolume = mAudioManager.getStreamVolume(STREAM_VOICE_CALL); + int maxVolume = mAudioManager.getStreamMaxVolume(STREAM_VOICE_CALL); + int sampleRate = 0; + mAudioManager.setStreamVolume(STREAM_VOICE_CALL, maxVolume, 0); + String sampleRateProperty = mAudioManager.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE); + sampleRate = Integer.parseInt(sampleRateProperty); + int status = mLc.startEchoTester(sampleRate); + if (status > 0) + echoTesterIsRunning = true; + else { + echoTesterIsRunning = false; + routeAudioToReceiver(); + mAudioManager.setStreamVolume(STREAM_VOICE_CALL, oldVolume, 0); + ((AudioManager)getContext().getSystemService(Context.AUDIO_SERVICE)).setMode(AudioManager.MODE_NORMAL); + Log.i("Set audio mode on 'Normal'"); + } + return status; + } + + public int stopEchoTester() throws LinphoneCoreException { + echoTesterIsRunning = false; + int status = mLc.stopEchoTester(); + routeAudioToReceiver(); + ((AudioManager)getContext().getSystemService(Context.AUDIO_SERVICE)).setMode(AudioManager.MODE_NORMAL); + Log.i("Set audio mode on 'Normal'"); + return status; + } + + public boolean getEchoTesterStatus() { + return echoTesterIsRunning; + } + private boolean isRinging; private void requestAudioFocus(){ diff --git a/src/org/linphone/SettingsFragment.java b/src/org/linphone/SettingsFragment.java index 1230155f8..b9683e1d4 100644 --- a/src/org/linphone/SettingsFragment.java +++ b/src/org/linphone/SettingsFragment.java @@ -41,6 +41,7 @@ import org.linphone.ui.LedPreference; import org.linphone.ui.PreferencesListFragment; import android.app.AlertDialog; +import android.app.FragmentManager; import android.content.DialogInterface; import android.Manifest; import android.content.Context; @@ -611,6 +612,46 @@ public class SettingsFragment extends PreferencesListFragment { return true; } }); + + findPreference(getString(R.string.pref_echo_tester_key)).setOnPreferenceClickListener(new OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + synchronized (SettingsFragment.this) { + int recordAudio = getActivity().getPackageManager().checkPermission(Manifest.permission.RECORD_AUDIO, getActivity().getPackageName()); + if (recordAudio == PackageManager.PERMISSION_GRANTED) { + if (LinphoneManager.getInstance().getEchoTesterStatus()) + stopEchoTester(); + else + startEchoTester(); + } else { + LinphoneActivity.instance().checkAndRequestRecordAudioPermissionsForEchoTester(); + } + } + return true; + } + }); + } + + public void startEchoTester() { + Preference preference = findPreference(getString(R.string.pref_echo_tester_key)); + try { + if (LinphoneManager.getInstance().startEchoTester() > 0) { + preference.setSummary("Is running"); + } + } catch (LinphoneCoreException e) { + e.printStackTrace(); + } + } + + public void stopEchoTester() { + Preference preference = findPreference(getString(R.string.pref_echo_tester_key)); + try { + if (LinphoneManager.getInstance().stopEchoTester() > 0) { + preference.setSummary("Is stopped"); + } + } catch (LinphoneCoreException e) { + e.printStackTrace(); + } } public void startEchoCancellerCalibration() { @@ -642,7 +683,9 @@ public class SettingsFragment extends PreferencesListFragment { codecs.removeAll(); LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); + final OpenH264DownloadHelper mCodecDownloader = LinphoneManager.getInstance().getOpenH264DownloadHelper(); + for (final PayloadType pt : lc.getVideoCodecs()) { final CheckBoxPreference codec = new CheckBoxPreference(getActivity()); codec.setTitle(pt.getMime()); @@ -659,8 +702,10 @@ public class SettingsFragment extends PreferencesListFragment { } } } - if (pt.getMime().equals("H264") && mCodecDownloader.isCodecFound()) + if (pt.getMime().equals("H264") && mCodecDownloader.isCodecFound()) { codec.setSummary(mCodecDownloader.getLicenseMessage()); + codec.setTitle("OpenH264"); + } codec.setChecked(lc.isPayloadTypeEnabled(pt)); codec.setOnPreferenceChangeListener(new OnPreferenceChangeListener() { @@ -670,9 +715,9 @@ public class SettingsFragment extends PreferencesListFragment { try { if (enable && Version.getCpuAbis().contains("armeabi-v7a") && !Version.getCpuAbis().contains("x86") && pt.getMime().equals("H264") && !mCodecDownloader.isCodecFound()) { - LinphoneManager.getInstance().getOpenH264DownloadHelper().setOpenH264HelperListener(LinphoneManager.getInstance().getOpenH264HelperListener()); - LinphoneManager.getInstance().getOpenH264DownloadHelper().setUserData(0,LinphoneManager.getInstance().getContext()); - LinphoneManager.getInstance().getOpenH264DownloadHelper().setUserData(1,codec); + mCodecDownloader.setOpenH264HelperListener(LinphoneManager.getInstance().getOpenH264HelperListener()); + mCodecDownloader.setUserData(0,LinphoneManager.getInstance().getContext()); + mCodecDownloader.setUserData(1,codec); AlertDialog.Builder builder = new AlertDialog.Builder(LinphoneManager.getInstance().getContext()); builder.setCancelable(false); @@ -703,7 +748,6 @@ public class SettingsFragment extends PreferencesListFragment { codecs.addPreference(codec); } - ((CheckBoxPreference) findPreference(getString(R.string.pref_video_enable_key))).setChecked(mPrefs.isVideoEnabled()); ((CheckBoxPreference) findPreference(getString(R.string.pref_video_use_front_camera_key))).setChecked(mPrefs.useFrontCam()); ((CheckBoxPreference) findPreference(getString(R.string.pref_video_initiate_call_with_video_key))).setChecked(mPrefs.shouldInitiateVideoCall()); @@ -1189,9 +1233,11 @@ public class SettingsFragment extends PreferencesListFragment { } } - + @Override public void onPause() { + if (LinphoneManager.getInstance().getEchoTesterStatus()) + stopEchoTester(); LinphoneActivity.instance().hideTopBar(); super.onPause(); } diff --git a/src/org/linphone/StatusFragment.java b/src/org/linphone/StatusFragment.java index 64a842dc5..cfc8ffa0a 100644 --- a/src/org/linphone/StatusFragment.java +++ b/src/org/linphone/StatusFragment.java @@ -478,7 +478,10 @@ public class StatusFragment extends Fragment { PayloadType payloadAudio = params.getUsedAudioCodec(); PayloadType payloadVideo = params.getUsedVideoCodec(); if (payloadVideo != null && payloadAudio != null) { - codec.setText(payloadVideo.getMime() + " / " + payloadAudio.getMime() + (payloadAudio.getRate() / 1000)); + String videoMime = payloadVideo.getMime(); + if (payloadVideo.getMime().equals("H264") && LinphoneManager.getInstance().getOpenH264DownloadHelper().isCodecFound()) + videoMime = "OpenH264"; + codec.setText(videoMime + " / " + payloadAudio.getMime() + (payloadAudio.getRate() / 1000)); } dl.setText(String.valueOf((int) videoStats.getDownloadBandwidth()) + " / " + (int) audioStats.getDownloadBandwidth() + " kbits/s"); ul.setText(String.valueOf((int) videoStats.getUploadBandwidth()) + " / " + (int) audioStats.getUploadBandwidth() + " kbits/s"); From 98d2958a44bbd0d5e61bc2df192674a195ab21d7 Mon Sep 17 00:00:00 2001 From: Erwan Croze Date: Mon, 8 Aug 2016 12:50:03 +0200 Subject: [PATCH 30/36] Update submodule linphone --- submodules/linphone | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/linphone b/submodules/linphone index 6f1e96c8f..958366ce1 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit 6f1e96c8f60576fb1cfe9750612f9fdb7c134c54 +Subproject commit 958366ce1928bd0aabaf983082faa8c49e501c4a From 7c5fa67f43ecc36f36347f6c9e6a160d38cd3d28 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 8 Aug 2016 14:12:16 +0200 Subject: [PATCH 31/36] Improve scrolling speed in lists --- src/org/linphone/ChatFragment.java | 24 +++-- src/org/linphone/ChatListFragment.java | 109 ++++++++++++--------- src/org/linphone/ContactsListFragment.java | 89 ++++++++++------- src/org/linphone/HistoryListFragment.java | 53 ++++++---- src/org/linphone/LinphoneContact.java | 59 +++++++++++ src/org/linphone/LinphoneManager.java | 12 --- 6 files changed, 229 insertions(+), 117 deletions(-) diff --git a/src/org/linphone/ChatFragment.java b/src/org/linphone/ChatFragment.java index 42e404914..2f6ccb60e 100644 --- a/src/org/linphone/ChatFragment.java +++ b/src/org/linphone/ChatFragment.java @@ -387,7 +387,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC CheckBox deleteChatBubble = (CheckBox) v.findViewById(R.id.delete_message); - if(isEditMode) { + if (isEditMode) { deleteChatBubble.setVisibility(View.VISIBLE); if (message.isOutgoing()) { RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); @@ -1043,6 +1043,16 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC } class SearchContactsListAdapter extends BaseAdapter { + private class ViewHolder { + public TextView name; + public TextView address; + + public ViewHolder(View view) { + name = (TextView) view.findViewById(R.id.contact_name); + address = (TextView) view.findViewById(R.id.contact_address); + } + } + private List contacts; private LayoutInflater mInflater; @@ -1093,24 +1103,26 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC public View getView(int position, View convertView, ViewGroup parent) { View view = null; ContactAddress contact; + ViewHolder holder = null; + do { contact = getItem(position); } while (contact == null); if (convertView != null) { view = convertView; + holder = (ViewHolder) view.getTag(); } else { view = mInflater.inflate(R.layout.search_contact_cell, parent, false); + holder = new ViewHolder(view); + view.setTag(holder); } final String a = contact.address; LinphoneContact c = contact.contact; - TextView name = (TextView) view.findViewById(R.id.contact_name); - name.setText(c.getFullName()); - - TextView address = (TextView) view.findViewById(R.id.contact_address); - address.setText(a); + holder.name.setText(c.getFullName()); + holder.address.setText(a); view.setOnClickListener(new OnClickListener() { @Override diff --git a/src/org/linphone/ChatListFragment.java b/src/org/linphone/ChatListFragment.java index d978f2ad8..d18c84fdb 100644 --- a/src/org/linphone/ChatListFragment.java +++ b/src/org/linphone/ChatListFragment.java @@ -30,6 +30,7 @@ import org.linphone.mediastream.Log; import android.app.Dialog; import android.app.Fragment; +import android.graphics.Bitmap; import android.graphics.Typeface; import android.os.Bundle; import android.view.ContextMenu; @@ -117,15 +118,16 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte } } - private void removeChatsConversation(){ + private void removeChatsConversation() { int size = chatList.getAdapter().getCount(); - for(int i=0; i adapter, View view, int position, long id) { - String sipUri = (String) view.getTag(); + String sipUri = chatList.getAdapter().getItem(position).toString(); if (LinphoneActivity.isInstanciated() && !isEditMode) { LinphoneActivity.instance().displayChat(sipUri); @@ -339,7 +341,24 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte } class ChatListAdapter extends BaseAdapter { - + private class ViewHolder { + public TextView lastMessageView; + public TextView date; + public TextView displayName; + public TextView unreadMessages; + public CheckBox select; + public ImageView contactPicture; + + public ViewHolder(View view) { + lastMessageView = (TextView) view.findViewById(R.id.lastMessage); + date = (TextView) view.findViewById(R.id.date); + displayName = (TextView) view.findViewById(R.id.sipUri); + unreadMessages = (TextView) view.findViewById(R.id.unreadMessages); + select = (CheckBox) view.findViewById(R.id.delete_chatroom); + contactPicture = (ImageView) view.findViewById(R.id.contact_picture); + } + } + ChatListAdapter() {} public int getCount() { @@ -347,7 +366,7 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte } public Object getItem(int position) { - return position; + return mConversations.get(position); } public long getItemId(int position) { @@ -356,21 +375,23 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte public View getView(final int position, View convertView, ViewGroup parent) { View view = null; + ViewHolder holder = null; + String sipUri = mConversations.get(position); if (convertView != null) { view = convertView; + holder = (ViewHolder) view.getTag(); } else { view = mInflater.inflate(R.layout.chatlist_cell, parent, false); + holder = new ViewHolder(view); + view.setTag(holder); } - - String sipUri = mConversations.get(position); - view.setTag(sipUri); LinphoneAddress address; try { address = LinphoneCoreFactory.instance().createLinphoneAddress(sipUri); } catch (LinphoneCoreException e) { - Log.e("Chat view cannot parse address",e); + Log.e("Chat view cannot parse address", e); return view; } @@ -378,57 +399,55 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte String message = ""; Long time; - TextView lastMessageView = (TextView) view.findViewById(R.id.lastMessage); - TextView date = (TextView) view.findViewById(R.id.date); - TextView displayName = (TextView) view.findViewById(R.id.sipUri); - TextView unreadMessages = (TextView) view.findViewById(R.id.unreadMessages); - CheckBox select = (CheckBox) view.findViewById(R.id.delete_chatroom); - ImageView contactPicture = (ImageView) view.findViewById(R.id.contact_picture); - LinphoneChatRoom chatRoom = LinphoneManager.getLc().getChatRoom(address); int unreadMessagesCount = chatRoom.getUnreadMessagesCount(); LinphoneChatMessage[] history = chatRoom.getHistory(1); LinphoneChatMessage msg = history[0]; if(msg.getFileTransferInformation() != null || msg.getExternalBodyUrl() != null || msg.getAppData() != null ){ - lastMessageView.setBackgroundResource(R.drawable.chat_file_message); + holder.lastMessageView.setBackgroundResource(R.drawable.chat_file_message); time = msg.getTime(); - date.setText(LinphoneUtils.timestampToHumanDate(getActivity(),time,getString(R.string.messages_list_date_format))); - lastMessageView.setText(""); + holder.date.setText(LinphoneUtils.timestampToHumanDate(getActivity(),time,getString(R.string.messages_list_date_format))); + holder.lastMessageView.setText(""); } else if (msg.getText() != null && msg.getText().length() > 0 ){ message = msg.getText(); - lastMessageView.setBackgroundResource(0); + holder.lastMessageView.setBackgroundResource(0); time = msg.getTime(); - date.setText(LinphoneUtils.timestampToHumanDate(getActivity(),time,getString(R.string.messages_list_date_format))); - lastMessageView.setText(message); + holder.date.setText(LinphoneUtils.timestampToHumanDate(getActivity(),time,getString(R.string.messages_list_date_format))); + holder.lastMessageView.setText(message); } - displayName.setSelected(true); // For animation - displayName.setText(contact == null ? LinphoneUtils.getAddressDisplayName(address) : contact.getFullName()); + holder.displayName.setSelected(true); // For animation + holder.displayName.setText(contact == null ? LinphoneUtils.getAddressDisplayName(address) : contact.getFullName()); if (contact != null) { - LinphoneUtils.setImagePictureFromUri(view.getContext(), contactPicture, contact.getPhotoUri(), contact.getThumbnailUri()); + Bitmap photo = contact.getPhoto(); + if (photo != null) { + holder.contactPicture.setImageBitmap(photo); + } else { + LinphoneUtils.setImagePictureFromUri(getActivity(), holder.contactPicture, contact.getPhotoUri(), contact.getThumbnailUri()); + } } else { - contactPicture.setImageResource(R.drawable.avatar); + holder.contactPicture.setImageResource(R.drawable.avatar); } if (unreadMessagesCount > 0) { - unreadMessages.setVisibility(View.VISIBLE); - unreadMessages.setText(String.valueOf(unreadMessagesCount)); - if(unreadMessagesCount > 99){ - unreadMessages.setTextSize(12); + holder.unreadMessages.setVisibility(View.VISIBLE); + holder.unreadMessages.setText(String.valueOf(unreadMessagesCount)); + if (unreadMessagesCount > 99) { + holder.unreadMessages.setTextSize(12); } - displayName.setTypeface(null, Typeface.BOLD); + holder.displayName.setTypeface(null, Typeface.BOLD); } else { - unreadMessages.setVisibility(View.GONE); - displayName.setTypeface(null, Typeface.NORMAL); + holder.unreadMessages.setVisibility(View.GONE); + holder.displayName.setTypeface(null, Typeface.NORMAL); } if (isEditMode) { - unreadMessages.setVisibility(View.GONE); - select.setVisibility(View.VISIBLE); - select.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + holder.unreadMessages.setVisibility(View.GONE); + holder.select.setVisibility(View.VISIBLE); + holder.select.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton compoundButton, boolean b) { chatList.setItemChecked(position, b); @@ -450,13 +469,13 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte } }); if(chatList.isItemChecked(position)) { - select.setChecked(true); + holder.select.setChecked(true); } else { - select.setChecked(false); + holder.select.setChecked(false); } } else { if (unreadMessagesCount > 0) { - unreadMessages.setVisibility(View.VISIBLE); + holder.unreadMessages.setVisibility(View.VISIBLE); } } return view; diff --git a/src/org/linphone/ContactsListFragment.java b/src/org/linphone/ContactsListFragment.java index de822fabe..4e75ce1d6 100644 --- a/src/org/linphone/ContactsListFragment.java +++ b/src/org/linphone/ContactsListFragment.java @@ -30,6 +30,7 @@ import org.linphone.core.PresenceActivityType; import android.app.Dialog; import android.app.Fragment; +import android.graphics.Bitmap; import android.os.Bundle; import android.text.Editable; import android.text.TextWatcher; @@ -416,6 +417,28 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O } class ContactsListAdapter extends BaseAdapter implements SectionIndexer { + private class ViewHolder { + public CheckBox delete; + public ImageView linphoneFriend; + public TextView name; + public LinearLayout separator; + public TextView separatorText; + public ImageView contactPicture; + public TextView organization; + public ImageView friendStatus; + + public ViewHolder(View view) { + delete = (CheckBox) view.findViewById(R.id.delete); + linphoneFriend = (ImageView) view.findViewById(R.id.friendLinphone); + name = (TextView) view.findViewById(R.id.name); + separator = (LinearLayout) view.findViewById(R.id.separator); + separatorText = (TextView) view.findViewById(R.id.separator_text); + contactPicture = (ImageView) view.findViewById(R.id.contact_picture); + organization = (TextView) view.findViewById(R.id.contactOrganization); + friendStatus = (ImageView) view.findViewById(R.id.friendStatus); + } + } + private List contacts; String[] sections; ArrayList sectionsList; @@ -461,58 +484,57 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O LinphoneContact contact = (LinphoneContact) getItem(position); if (contact == null) return null; + ViewHolder holder = null; if (convertView != null) { view = convertView; + holder = (ViewHolder) view.getTag(); } else { view = mInflater.inflate(R.layout.contact_cell, parent, false); + holder = new ViewHolder(view); + view.setTag(holder); } - - CheckBox delete = (CheckBox) view.findViewById(R.id.delete); - ImageView linphoneFriend = (ImageView) view.findViewById(R.id.friendLinphone); - TextView name = (TextView) view.findViewById(R.id.name); - name.setText(contact.getFullName()); - - LinearLayout separator = (LinearLayout) view.findViewById(R.id.separator); - TextView separatorText = (TextView) view.findViewById(R.id.separator_text); + holder.name.setText(contact.getFullName()); + if (getPositionForSection(getSectionForPosition(position)) != position) { - separator.setVisibility(View.GONE); + holder.separator.setVisibility(View.GONE); } else { - separator.setVisibility(View.VISIBLE); + holder.separator.setVisibility(View.VISIBLE); String fullName = contact.getFullName(); if (fullName != null && !fullName.isEmpty()) { - separatorText.setText(String.valueOf(fullName.charAt(0))); + holder.separatorText.setText(String.valueOf(fullName.charAt(0))); } } if (contact.isInLinphoneFriendList()) { - linphoneFriend.setVisibility(View.VISIBLE); + holder.linphoneFriend.setVisibility(View.VISIBLE); } else { - linphoneFriend.setVisibility(View.GONE); + holder.linphoneFriend.setVisibility(View.GONE); } - ImageView icon = (ImageView) view.findViewById(R.id.contact_picture); if (contact.hasPhoto()) { - LinphoneUtils.setImagePictureFromUri(getActivity(), icon, contact.getPhotoUri(), contact.getThumbnailUri()); - } else if (contact.getPhotoUri() != null) { - icon.setImageURI(contact.getPhotoUri()); + Bitmap photo = contact.getPhoto(); + if (photo != null) { + holder.contactPicture.setImageBitmap(photo); + } else { + LinphoneUtils.setImagePictureFromUri(getActivity(), holder.contactPicture, contact.getPhotoUri(), contact.getThumbnailUri()); + } } else { - icon.setImageResource(R.drawable.avatar); + holder.contactPicture.setImageResource(R.drawable.avatar); } - TextView organization = (TextView) view.findViewById(R.id.contactOrganization); boolean isOrgVisible = getResources().getBoolean(R.bool.display_contact_organization); String org = contact.getOrganization(); if (org != null && !org.isEmpty() && isOrgVisible) { - organization.setText(org); - organization.setVisibility(View.VISIBLE); + holder.organization.setText(org); + holder.organization.setVisibility(View.VISIBLE); } else { - organization.setVisibility(View.GONE); + holder.organization.setVisibility(View.GONE); } if (isEditMode) { - delete.setVisibility(View.VISIBLE); - delete.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + holder.delete.setVisibility(View.VISIBLE); + holder.delete.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton compoundButton, boolean b) { contactsList.setItemChecked(position, b); @@ -534,29 +556,28 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O } }); if (contactsList.isItemChecked(position)) { - delete.setChecked(true); + holder.delete.setChecked(true); } else { - delete.setChecked(false); + holder.delete.setChecked(false); } } else { - delete.setVisibility(View.GONE); + holder.delete.setVisibility(View.GONE); } - ImageView friendStatus = (ImageView) view.findViewById(R.id.friendStatus); LinphoneFriend[] friends = LinphoneManager.getLc().getFriendList(); if (!ContactsManager.getInstance().isContactPresenceDisabled() && friends != null) { - friendStatus.setVisibility(View.VISIBLE); + holder.friendStatus.setVisibility(View.VISIBLE); PresenceActivityType presenceActivity = friends[0].getPresenceModel().getActivity().getType(); if (presenceActivity == PresenceActivityType.Online) { - friendStatus.setImageResource(R.drawable.led_connected); + holder.friendStatus.setImageResource(R.drawable.led_connected); } else if (presenceActivity == PresenceActivityType.Busy) { - friendStatus.setImageResource(R.drawable.led_error); + holder.friendStatus.setImageResource(R.drawable.led_error); } else if (presenceActivity == PresenceActivityType.Away) { - friendStatus.setImageResource(R.drawable.led_inprogress); + holder.friendStatus.setImageResource(R.drawable.led_inprogress); } else if (presenceActivity == PresenceActivityType.Offline) { - friendStatus.setImageResource(R.drawable.led_disconnected); + holder.friendStatus.setImageResource(R.drawable.led_disconnected); } else { - friendStatus.setImageResource(R.drawable.call_quality_indicator_0); + holder.friendStatus.setImageResource(R.drawable.call_quality_indicator_0); } } diff --git a/src/org/linphone/HistoryListFragment.java b/src/org/linphone/HistoryListFragment.java index bb148278c..83840f0da 100644 --- a/src/org/linphone/HistoryListFragment.java +++ b/src/org/linphone/HistoryListFragment.java @@ -31,6 +31,7 @@ import org.linphone.core.LinphoneCallLog.CallStatus; import android.annotation.SuppressLint; import android.app.Dialog; import android.content.Context; +import android.graphics.Bitmap; import android.os.Bundle; import android.app.Fragment; import android.view.LayoutInflater; @@ -349,6 +350,22 @@ public class HistoryListFragment extends Fragment implements OnClickListener, On } class CallHistoryAdapter extends BaseAdapter { + private class ViewHolder { + public TextView contact; + public ImageView detail; + public CheckBox select; + public ImageView callDirection; + public ImageView contactPicture; + + public ViewHolder(View view) { + contact = (TextView) view.findViewById(R.id.sip_uri); + detail = (ImageView) view.findViewById(R.id.detail); + select = (CheckBox) view.findViewById(R.id.delete); + callDirection = (ImageView) view.findViewById(R.id.icon); + contactPicture = (ImageView) view.findViewById(R.id.contact_picture); + } + } + CallHistoryAdapter(Context aContext) { } @@ -401,23 +418,20 @@ public class HistoryListFragment extends Fragment implements OnClickListener, On public View getView(final int position, View convertView, ViewGroup parent) { View view = null; - ViewHolder holder; + ViewHolder holder = null; + if (convertView != null) { view = convertView; holder = (ViewHolder) view.getTag(); } else { view = mInflater.inflate(R.layout.history_cell, parent,false); - holder = new ViewHolder(); - holder.contact = (TextView) view.findViewById(R.id.sip_uri); - holder.detail = (ImageView) view.findViewById(R.id.detail); - holder.select = (CheckBox) view.findViewById(R.id.delete); - holder.callDirection = (ImageView) view.findViewById(R.id.icon); - holder.contactPicture = (ImageView) view.findViewById(R.id.contact_picture); + holder = new ViewHolder(view); + view.setTag(holder); } final LinphoneCallLog log = mLogs.get(position); long timestamp = log.getTimestamp(); - final LinphoneAddress address; + LinphoneAddress address; holder.contact.setSelected(true); // For automated horizontal scrolling of long texts @@ -457,9 +471,18 @@ public class HistoryListFragment extends Fragment implements OnClickListener, On LinphoneContact c = ContactsManager.getInstance().findContactFromAddress(address); String displayName = null; final String sipUri = address.asString(); - if(c != null){ + if (c != null) { displayName = c.getFullName(); - LinphoneUtils.setImagePictureFromUri(view.getContext(),holder.contactPicture,c.getPhotoUri(),c.getThumbnailUri()); + if (c.hasPhoto()) { + Bitmap photo = c.getPhoto(); + if (photo != null) { + holder.contactPicture.setImageBitmap(photo); + } else { + LinphoneUtils.setImagePictureFromUri(getActivity(), holder.contactPicture, c.getPhotoUri(), c.getThumbnailUri()); + } + } else { + LinphoneUtils.setImagePictureFromUri(getActivity(), holder.contactPicture, c.getPhotoUri(), c.getThumbnailUri()); + } } else { holder.contactPicture.setImageResource(R.drawable.avatar); } @@ -469,7 +492,6 @@ public class HistoryListFragment extends Fragment implements OnClickListener, On } else { holder.contact.setText(displayName); } - //view.setTag(sipUri); if (isEditMode) { holder.select.setVisibility(View.VISIBLE); @@ -512,16 +534,7 @@ public class HistoryListFragment extends Fragment implements OnClickListener, On } }); } - view.setTag(holder); return view; } } - - static class ViewHolder { - TextView contact; - ImageView detail; - CheckBox select; - ImageView callDirection; - ImageView contactPicture; - } } \ No newline at end of file diff --git a/src/org/linphone/LinphoneContact.java b/src/org/linphone/LinphoneContact.java index 6d7670f22..c0b6419fa 100644 --- a/src/org/linphone/LinphoneContact.java +++ b/src/org/linphone/LinphoneContact.java @@ -18,6 +18,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package org.linphone; +import java.io.FileNotFoundException; +import java.io.IOException; import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; @@ -38,8 +40,10 @@ import android.content.ContentResolver; import android.content.ContentUris; import android.content.ContentValues; import android.database.Cursor; +import android.graphics.Bitmap; import android.net.Uri; import android.provider.ContactsContract; +import android.provider.MediaStore; import android.provider.ContactsContract.CommonDataKinds; public class LinphoneContact implements Serializable, Comparable { @@ -55,6 +59,7 @@ public class LinphoneContact implements Serializable, Comparable changesToCommit; private transient ArrayList changesToCommit2; private boolean hasSipAddress; + private Bitmap photoBitmap, thumbnailBitmap; public LinphoneContact() { addresses = new ArrayList(); @@ -66,6 +71,19 @@ public class LinphoneContact implements Serializable, Comparable Date: Mon, 8 Aug 2016 16:33:42 +0200 Subject: [PATCH 32/36] Update echo tester --- src/org/linphone/SettingsFragment.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/org/linphone/SettingsFragment.java b/src/org/linphone/SettingsFragment.java index 9defc8318..0e3844689 100644 --- a/src/org/linphone/SettingsFragment.java +++ b/src/org/linphone/SettingsFragment.java @@ -660,6 +660,8 @@ public class SettingsFragment extends PreferencesListFragment { public void startEchoCancellerCalibration() { try { + if (LinphoneManager.getInstance().getEchoTesterStatus()) + stopEchoTester(); LinphoneManager.getInstance().startEcCalibration(mListener); } catch (LinphoneCoreException e) { Log.e(e); From 73fa4868d0e43642728ec98ecc2fe7a2c3cf83cf Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 8 Aug 2016 16:59:43 +0200 Subject: [PATCH 33/36] Improved scroll speed in ChatFragment --- res/layout/chat_bubble.xml | 114 +++++ res/layout/chat_bubble_incoming.xml | 114 ----- res/layout/chat_bubble_outgoing.xml | 112 ----- src/org/linphone/ChatFragment.java | 612 ++++++++++++++++++++----- src/org/linphone/SettingsFragment.java | 3 - src/org/linphone/ui/BubbleChat.java | 463 ------------------- 6 files changed, 601 insertions(+), 817 deletions(-) create mode 100644 res/layout/chat_bubble.xml delete mode 100644 res/layout/chat_bubble_incoming.xml delete mode 100644 res/layout/chat_bubble_outgoing.xml delete mode 100644 src/org/linphone/ui/BubbleChat.java diff --git a/res/layout/chat_bubble.xml b/res/layout/chat_bubble.xml new file mode 100644 index 000000000..1b0bc6601 --- /dev/null +++ b/res/layout/chat_bubble.xml @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + + + + + +