From 9dab31ee5407fd49bad6a80617e7739f543b0595 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 23 Oct 2019 09:06:37 +0200 Subject: [PATCH 01/84] Switched to releases maven repository + increased version code --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index d0494b6a4..00bb79459 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -74,7 +74,7 @@ excludePackage.add('**/LICENSE.txt') repositories { maven { // Replace snapshots by releases for releases ! - url "https://linphone.org/snapshots/maven_repository" + url "https://linphone.org/releases/maven_repository" } } @@ -89,7 +89,7 @@ android { defaultConfig { minSdkVersion 21 targetSdkVersion 29 - versionCode 4129 + versionCode 4200 versionName "${project.version}" applicationId getPackageName() multiDexEnabled true From 2fb953e80e8dd9c99855424a55049f745f695da6 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 25 Oct 2019 10:57:53 +0200 Subject: [PATCH 02/84] Fixed crash in contacts fetching --- .../linphone/contacts/LinphoneContact.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/app/src/main/java/org/linphone/contacts/LinphoneContact.java b/app/src/main/java/org/linphone/contacts/LinphoneContact.java index 756d71c58..7b46e6425 100644 --- a/app/src/main/java/org/linphone/contacts/LinphoneContact.java +++ b/app/src/main/java/org/linphone/contacts/LinphoneContact.java @@ -553,6 +553,11 @@ public class LinphoneContact extends AndroidContact } if (ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE.equals(mime)) { + if (data1 == null && data4 == null) { + Log.e("[Linphone Contact] Phone number data are both null !"); + return; + } + Log.d("[Linphone Contact] Found phone number " + data1 + " (" + data4 + ")"); addNumberOrAddress(new LinphoneNumberOrAddress(data1, data4)); } else if (ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE.equals(mime) @@ -560,12 +565,27 @@ public class LinphoneContact extends AndroidContact .getApplicationContext() .getString(R.string.linphone_address_mime_type) .equals(mime)) { + if (data1 == null) { + Log.e("[Linphone Contact] SIP address is null !"); + return; + } + Log.d("[Linphone Contact] Found SIP address " + data1); addNumberOrAddress(new LinphoneNumberOrAddress(data1, true)); } else if (ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE.equals(mime)) { + if (data1 == null) { + Log.e("[Linphone Contact] Organization is null !"); + return; + } + Log.d("[Linphone Contact] Found organization " + data1); setOrganization(data1, false); } else if (ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE.equals(mime)) { + if (data2 == null && data3 == null) { + Log.e("[Linphone Contact] Firstname and lastname are both null !"); + return; + } + Log.d("[Linphone Contact] Found first name " + data2 + " and last name " + data3); setFirstNameAndLastName(data2, data3, false); } else { From 426262c3d7c5e9c83c7bc20dfed5d0c682d90e83 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 25 Oct 2019 11:06:28 +0200 Subject: [PATCH 03/84] Improved camera switching algorithm --- .../java/org/linphone/call/CallManager.java | 40 ++++++++----------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/org/linphone/call/CallManager.java b/app/src/main/java/org/linphone/call/CallManager.java index aa4d778b3..3f5e68310 100644 --- a/app/src/main/java/org/linphone/call/CallManager.java +++ b/app/src/main/java/org/linphone/call/CallManager.java @@ -87,32 +87,26 @@ public class CallManager { public void switchCamera() { Core core = LinphoneManager.getCore(); - try { - String currentDevice = core.getVideoDevice(); - String[] devices = core.getVideoDevicesList(); - int index = 0; - for (String d : devices) { - if (d.equals(currentDevice)) { - break; - } - index++; - } + if (core == null) return; - String newDevice; - if (index == 1) newDevice = devices[0]; - else if (devices.length > 1) newDevice = devices[1]; - else newDevice = devices[index]; - core.setVideoDevice(newDevice); - - Call call = core.getCurrentCall(); - if (call == null) { - Log.w("[Call Manager] Trying to switch camera while not in call"); - return; + String currentDevice = core.getVideoDevice(); + Log.i("[Call Manager] Current camera device is " + currentDevice); + + String[] devices = core.getVideoDevicesList(); + for (String d : devices) { + if (!d.equals(currentDevice) && !d.equals("StaticImage: Static picture")) { + Log.i("[Call Manager] New camera device will be " + d); + core.setVideoDevice(d); + break; } - call.update(null); - } catch (ArithmeticException ae) { - Log.e("[Call Manager] [Video] Cannot switch camera: no camera"); } + + Call call = core.getCurrentCall(); + if (call == null) { + Log.i("[Call Manager] Switching camera while not in call"); + return; + } + call.update(null); } public boolean acceptCall(Call call) { From 26d61fef4e2d15aa6fbe15d70b7a4577c9e93055 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 28 Oct 2019 09:30:40 +0100 Subject: [PATCH 04/84] Restart service if foreground service setting is on when app is updated --- CHANGELOG.md | 1 + app/src/main/AndroidManifest.xml | 3 +-- .../java/org/linphone/call/CallManager.java | 2 +- .../org/linphone/receivers/BootReceiver.java | 27 +++++++++++++++---- 4 files changed, 25 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5dcac501a..d4c34ecd4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ Group changes to describe their impact on the project, as follows: - Using new AAudio & Camera2 frameworks for better performances (if available) - Android 10 compatibility - New plugin loader to be compatible with app bundle distribution mode +- Restart service if foreground service setting is on when app is updated ## Changed - Improved performances to reduce startup time diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ef5e73bb9..a1d880262 100755 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -252,9 +252,8 @@ - - + diff --git a/app/src/main/java/org/linphone/call/CallManager.java b/app/src/main/java/org/linphone/call/CallManager.java index 3f5e68310..2c82893aa 100644 --- a/app/src/main/java/org/linphone/call/CallManager.java +++ b/app/src/main/java/org/linphone/call/CallManager.java @@ -91,7 +91,7 @@ public class CallManager { String currentDevice = core.getVideoDevice(); Log.i("[Call Manager] Current camera device is " + currentDevice); - + String[] devices = core.getVideoDevicesList(); for (String d : devices) { if (!d.equals(currentDevice) && !d.equals("StaticImage: Static picture")) { diff --git a/app/src/main/java/org/linphone/receivers/BootReceiver.java b/app/src/main/java/org/linphone/receivers/BootReceiver.java index 37a0966e6..b7a3e53be 100644 --- a/app/src/main/java/org/linphone/receivers/BootReceiver.java +++ b/app/src/main/java/org/linphone/receivers/BootReceiver.java @@ -36,17 +36,34 @@ public class BootReceiver extends BroadcastReceiver { "[Boot Receiver] Device is shutting down, destroying Core to unregister"); context.stopService( new Intent(Intent.ACTION_MAIN).setClass(context, LinphoneService.class)); - } else { + } else if (intent.getAction().equalsIgnoreCase(Intent.ACTION_BOOT_COMPLETED)) { LinphonePreferences.instance().setContext(context); boolean autostart = LinphonePreferences.instance().isAutoStartEnabled(); android.util.Log.i( "Linphone", "[Boot Receiver] Device is starting, auto_start is " + autostart); + if (autostart && !LinphoneService.isReady()) { - Intent serviceIntent = new Intent(Intent.ACTION_MAIN); - serviceIntent.setClass(context, LinphoneService.class); - serviceIntent.putExtra("ForceStartForeground", true); - Compatibility.startService(context, serviceIntent); + startService(context); + } + } else if (intent.getAction().equalsIgnoreCase(Intent.ACTION_MY_PACKAGE_REPLACED)) { + LinphonePreferences.instance().setContext(context); + boolean foregroundService = + LinphonePreferences.instance().getServiceNotificationVisibility(); + android.util.Log.i( + "Linphone", + "[Boot Receiver] App has been updated, foreground service is " + + foregroundService); + + if (foregroundService && !LinphoneService.isReady()) { + startService(context); } } } + + private void startService(Context context) { + Intent serviceIntent = new Intent(Intent.ACTION_MAIN); + serviceIntent.setClass(context, LinphoneService.class); + serviceIntent.putExtra("ForceStartForeground", true); + Compatibility.startService(context, serviceIntent); + } } From aeb92f6b28d06a4d20a9bc00f718ecc593456aa2 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 28 Oct 2019 10:18:01 +0100 Subject: [PATCH 05/84] Fixed launcher issue on latest Samsung when using the Quit button --- app/src/main/java/org/linphone/activities/MainActivity.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/linphone/activities/MainActivity.java b/app/src/main/java/org/linphone/activities/MainActivity.java index e8e83b83c..15e9f5d35 100644 --- a/app/src/main/java/org/linphone/activities/MainActivity.java +++ b/app/src/main/java/org/linphone/activities/MainActivity.java @@ -20,7 +20,6 @@ package org.linphone.activities; import android.Manifest; -import android.app.ActivityManager; import android.app.Dialog; import android.app.Fragment; import android.app.FragmentManager; @@ -444,9 +443,9 @@ public abstract class MainActivity extends LinphoneGenericActivity private void quit() { goHomeAndClearStack(); stopService(new Intent(Intent.ACTION_MAIN).setClass(this, LinphoneService.class)); - ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); + /*ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); am.killBackgroundProcesses(getString(R.string.sync_account_type)); - android.os.Process.killProcess(android.os.Process.myPid()); + android.os.Process.killProcess(android.os.Process.myPid());*/ } // Tab, Top and Status bars From 2d3744fdbd0c0fae288aeb50bf8759f3575f5252 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 30 Oct 2019 15:08:42 +0100 Subject: [PATCH 06/84] Changes for assistant : fixed SHA-256, improved logs & use of xml default configs --- .../AccountConnectionAssistantActivity.java | 16 ++++++-- .../linphone/assistant/AssistantActivity.java | 31 ++++++++++++++++ ...EmailAccountCreationAssistantActivity.java | 24 +++++++++--- ...ailAccountValidationAssistantActivity.java | 6 ++- .../GenericConnectionAssistantActivity.java | 9 +++++ .../OpenH264DownloadAssistantActivity.java | 6 +-- ...PhoneAccountCreationAssistantActivity.java | 24 +++++++++--- .../PhoneAccountLinkingAssistantActivity.java | 37 +++++++++++++------ .../main/res/raw/default_assistant_create.rc | 1 + .../main/res/raw/linphone_assistant_create.rc | 1 + 10 files changed, 125 insertions(+), 30 deletions(-) diff --git a/app/src/main/java/org/linphone/assistant/AccountConnectionAssistantActivity.java b/app/src/main/java/org/linphone/assistant/AccountConnectionAssistantActivity.java index 635994b82..7e4ed53f0 100644 --- a/app/src/main/java/org/linphone/assistant/AccountConnectionAssistantActivity.java +++ b/app/src/main/java/org/linphone/assistant/AccountConnectionAssistantActivity.java @@ -31,9 +31,11 @@ import android.widget.RelativeLayout; import android.widget.Switch; import android.widget.TextView; import androidx.annotation.Nullable; +import org.linphone.LinphoneManager; import org.linphone.R; import org.linphone.core.AccountCreator; import org.linphone.core.AccountCreatorListenerStub; +import org.linphone.core.Core; import org.linphone.core.DialPlan; import org.linphone.core.tools.Log; @@ -70,7 +72,6 @@ public class AccountConnectionAssistantActivity extends AssistantActivity { new View.OnClickListener() { @Override public void onClick(View v) { - mAccountCreator.setDomain(getString(R.string.default_domain)); mConnect.setEnabled(false); if (mUsernameConnectionSwitch.isChecked()) { @@ -83,7 +84,9 @@ public class AccountConnectionAssistantActivity extends AssistantActivity { AccountCreator.Status status = mAccountCreator.recoverAccount(); if (status != AccountCreator.Status.RequestOk) { - Log.e("[Account Connection] recoverAccount returned " + status); + Log.e( + "[Account Connection Assistant] recoverAccount returned " + + status); mConnect.setEnabled(true); showGenericErrorDialog(status); } @@ -202,7 +205,9 @@ public class AccountConnectionAssistantActivity extends AssistantActivity { @Override public void onRecoverAccount( AccountCreator creator, AccountCreator.Status status, String resp) { - Log.i("[Account Connection] onRecoverAccount status is " + status); + Log.i( + "[Account Connection Assistant] onRecoverAccount status is " + + status); if (status.equals(AccountCreator.Status.RequestOk)) { Intent intent = new Intent( @@ -216,6 +221,11 @@ public class AccountConnectionAssistantActivity extends AssistantActivity { } } }; + + Core core = LinphoneManager.getCore(); + if (core != null) { + reloadLinphoneAccountCreatorConfig(); + } } @Override diff --git a/app/src/main/java/org/linphone/assistant/AssistantActivity.java b/app/src/main/java/org/linphone/assistant/AssistantActivity.java index 2edc702b5..58852270e 100644 --- a/app/src/main/java/org/linphone/assistant/AssistantActivity.java +++ b/app/src/main/java/org/linphone/assistant/AssistantActivity.java @@ -33,6 +33,7 @@ import org.linphone.R; import org.linphone.activities.DialerActivity; import org.linphone.activities.LinphoneGenericActivity; import org.linphone.core.AccountCreator; +import org.linphone.core.Config; import org.linphone.core.Core; import org.linphone.core.DialPlan; import org.linphone.core.Factory; @@ -104,22 +105,52 @@ public abstract class AssistantActivity extends LinphoneGenericActivity } } + private void reloadAccountCreatorConfig(String path) { + Core core = LinphoneManager.getCore(); + if (core != null) { + core.loadConfigFromXml(path); + if (mAccountCreator != null) { + // Below two settings are applied to account creator when it is built. + // Reloading Core config after won't change the account creator configuration, + // hence the manual reload + Config config = LinphonePreferences.instance().getConfig(); + mAccountCreator.setDomain(config.getString("assistant", "domain", null)); + mAccountCreator.setAlgorithm(config.getString("assistant", "algorithm", null)); + } + } + } + + void reloadDefaultAccountCreatorConfig() { + Log.i("[Assistant] Reloading configuration with default"); + reloadAccountCreatorConfig(LinphonePreferences.instance().getDefaultDynamicConfigFile()); + } + + void reloadLinphoneAccountCreatorConfig() { + Log.i("[Assistant] Reloading configuration with specifics"); + reloadAccountCreatorConfig(LinphonePreferences.instance().getLinphoneDynamicConfigFile()); + } + void createProxyConfigAndLeaveAssistant() { Core core = LinphoneManager.getCore(); boolean useLinphoneDefaultValues = getString(R.string.default_domain).equals(mAccountCreator.getDomain()); if (useLinphoneDefaultValues) { + Log.i("[Assistant] Default domain found, reloading configuration"); core.loadConfigFromXml(LinphonePreferences.instance().getLinphoneDynamicConfigFile()); + } else { + Log.i("[Assistant] Third party domain found, keeping default values"); } ProxyConfig proxyConfig = mAccountCreator.createProxyConfig(); if (useLinphoneDefaultValues) { // Restore default values + Log.i("[Assistant] Restoring default assistant configuration"); core.loadConfigFromXml(LinphonePreferences.instance().getDefaultDynamicConfigFile()); } else { // If this isn't a sip.linphone.org account, disable push notifications and enable // service notification, otherwise incoming calls won't work (most probably) + Log.w("[Assistant] Unknown domain used, push probably won't work, enable service mode"); LinphonePreferences.instance().setServiceNotificationVisibility(true); LinphoneContext.instance().getNotificationManager().startForeground(); } diff --git a/app/src/main/java/org/linphone/assistant/EmailAccountCreationAssistantActivity.java b/app/src/main/java/org/linphone/assistant/EmailAccountCreationAssistantActivity.java index 36812b18a..dc11d3fb0 100644 --- a/app/src/main/java/org/linphone/assistant/EmailAccountCreationAssistantActivity.java +++ b/app/src/main/java/org/linphone/assistant/EmailAccountCreationAssistantActivity.java @@ -30,9 +30,11 @@ import android.view.View; import android.widget.EditText; import android.widget.TextView; import androidx.annotation.Nullable; +import org.linphone.LinphoneManager; import org.linphone.R; import org.linphone.core.AccountCreator; import org.linphone.core.AccountCreatorListenerStub; +import org.linphone.core.Core; import org.linphone.core.tools.Log; public class EmailAccountCreationAssistantActivity extends AssistantActivity { @@ -161,12 +163,13 @@ public class EmailAccountCreationAssistantActivity extends AssistantActivity { @Override public void onClick(View v) { enableButtonsAndFields(false); - mAccountCreator.setDomain(getString(R.string.default_domain)); AccountCreator.Status status = mAccountCreator.isAccountExist(); if (status != AccountCreator.Status.RequestOk) { enableButtonsAndFields(true); - Log.e("[Email Account Creation] isAccountExists returned " + status); + Log.e( + "[Email Account Creation Assistant] isAccountExists returned " + + status); showGenericErrorDialog(status); } } @@ -177,7 +180,9 @@ public class EmailAccountCreationAssistantActivity extends AssistantActivity { new AccountCreatorListenerStub() { public void onIsAccountExist( AccountCreator creator, AccountCreator.Status status, String resp) { - Log.i("[Email Account Creation] onIsAccountExist status is " + status); + Log.i( + "[Email Account Creation Assistant] onIsAccountExist status is " + + status); if (status.equals(AccountCreator.Status.AccountExist) || status.equals(AccountCreator.Status.AccountExistWithAlias)) { showAccountAlreadyExistsDialog(); @@ -185,7 +190,9 @@ public class EmailAccountCreationAssistantActivity extends AssistantActivity { } else if (status.equals(AccountCreator.Status.AccountNotExist)) { status = mAccountCreator.createAccount(); if (status != AccountCreator.Status.RequestOk) { - Log.e("[Email Account Creation] createAccount returned " + status); + Log.e( + "[Email Account Creation Assistant] createAccount returned " + + status); enableButtonsAndFields(true); showGenericErrorDialog(status); } @@ -198,7 +205,9 @@ public class EmailAccountCreationAssistantActivity extends AssistantActivity { @Override public void onCreateAccount( AccountCreator creator, AccountCreator.Status status, String resp) { - Log.i("[Email Account Creation] onCreateAccount status is " + status); + Log.i( + "[Email Account Creation Assistant] onCreateAccount status is " + + status); if (status.equals(AccountCreator.Status.AccountCreated)) { startActivity( new Intent( @@ -210,6 +219,11 @@ public class EmailAccountCreationAssistantActivity extends AssistantActivity { } } }; + + Core core = LinphoneManager.getCore(); + if (core != null) { + reloadLinphoneAccountCreatorConfig(); + } } private void enableButtonsAndFields(boolean enable) { diff --git a/app/src/main/java/org/linphone/assistant/EmailAccountValidationAssistantActivity.java b/app/src/main/java/org/linphone/assistant/EmailAccountValidationAssistantActivity.java index 40c6c342f..81d08f836 100644 --- a/app/src/main/java/org/linphone/assistant/EmailAccountValidationAssistantActivity.java +++ b/app/src/main/java/org/linphone/assistant/EmailAccountValidationAssistantActivity.java @@ -52,7 +52,9 @@ public class EmailAccountValidationAssistantActivity extends AssistantActivity { AccountCreator.Status status = mAccountCreator.isAccountActivated(); if (status != AccountCreator.Status.RequestOk) { - Log.e("[Email Account Validation] activateAccount returned " + status); + Log.e( + "[Email Account Validation Assistant] activateAccount returned " + + status); mFinishCreation.setEnabled(true); showGenericErrorDialog(status); } @@ -65,7 +67,7 @@ public class EmailAccountValidationAssistantActivity extends AssistantActivity { public void onIsAccountActivated( AccountCreator creator, AccountCreator.Status status, String resp) { Log.i( - "[Email Account Validation] onIsAccountActivated status is " + "[Email Account Validation Assistant] onIsAccountActivated status is " + status); if (status.equals(AccountCreator.Status.AccountActivated)) { createProxyConfigAndLeaveAssistant(); diff --git a/app/src/main/java/org/linphone/assistant/GenericConnectionAssistantActivity.java b/app/src/main/java/org/linphone/assistant/GenericConnectionAssistantActivity.java index 3dd5b8247..3c029e3f1 100644 --- a/app/src/main/java/org/linphone/assistant/GenericConnectionAssistantActivity.java +++ b/app/src/main/java/org/linphone/assistant/GenericConnectionAssistantActivity.java @@ -27,8 +27,11 @@ import android.widget.EditText; import android.widget.RadioGroup; import android.widget.TextView; import androidx.annotation.Nullable; +import org.linphone.LinphoneManager; import org.linphone.R; +import org.linphone.core.Core; import org.linphone.core.TransportType; +import org.linphone.core.tools.Log; public class GenericConnectionAssistantActivity extends AssistantActivity implements TextWatcher { private TextView mLogin; @@ -60,6 +63,12 @@ public class GenericConnectionAssistantActivity extends AssistantActivity implem mDomain = findViewById(R.id.assistant_domain); mDomain.addTextChangedListener(this); mTransport = findViewById(R.id.assistant_transports); + + Core core = LinphoneManager.getCore(); + if (core != null) { + Log.i("[Generic Connection Assistant] Reloading configuration with default"); + reloadDefaultAccountCreatorConfig(); + } } private void configureAccount() { diff --git a/app/src/main/java/org/linphone/assistant/OpenH264DownloadAssistantActivity.java b/app/src/main/java/org/linphone/assistant/OpenH264DownloadAssistantActivity.java index cc564fb7a..b2b38ecc5 100644 --- a/app/src/main/java/org/linphone/assistant/OpenH264DownloadAssistantActivity.java +++ b/app/src/main/java/org/linphone/assistant/OpenH264DownloadAssistantActivity.java @@ -58,7 +58,7 @@ public class OpenH264DownloadAssistantActivity extends AssistantActivity { public void onClick(View v) { mYes.setEnabled(false); mNo.setEnabled(false); - Log.e("[OpenH264 Downloader] Start download"); + Log.e("[OpenH264 Downloader Assistant] Start download"); mProgress.setVisibility(View.VISIBLE); mHelper.downloadCodec(); } @@ -71,7 +71,7 @@ public class OpenH264DownloadAssistantActivity extends AssistantActivity { public void onClick(View v) { mYes.setEnabled(false); mNo.setEnabled(false); - Log.e("[OpenH264 Downloader] Download refused"); + Log.e("[OpenH264 Downloader Assistant] Download refused"); goToLinphoneActivity(); } }); @@ -96,7 +96,7 @@ public class OpenH264DownloadAssistantActivity extends AssistantActivity { @Override public void OnError(String s) { - Log.e("[OpenH264 Downloader] " + s); + Log.e("[OpenH264 Downloader Assistant] " + s); mYes.setEnabled(true); mNo.setEnabled(true); } diff --git a/app/src/main/java/org/linphone/assistant/PhoneAccountCreationAssistantActivity.java b/app/src/main/java/org/linphone/assistant/PhoneAccountCreationAssistantActivity.java index fb66e5c45..424b934a0 100644 --- a/app/src/main/java/org/linphone/assistant/PhoneAccountCreationAssistantActivity.java +++ b/app/src/main/java/org/linphone/assistant/PhoneAccountCreationAssistantActivity.java @@ -30,9 +30,11 @@ import android.widget.EditText; import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.Nullable; +import org.linphone.LinphoneManager; import org.linphone.R; import org.linphone.core.AccountCreator; import org.linphone.core.AccountCreatorListenerStub; +import org.linphone.core.Core; import org.linphone.core.DialPlan; import org.linphone.core.tools.Log; @@ -74,11 +76,12 @@ public class PhoneAccountCreationAssistantActivity extends AssistantActivity { } else { mAccountCreator.setUsername(mAccountCreator.getPhoneNumber()); } - mAccountCreator.setDomain(getString(R.string.default_domain)); AccountCreator.Status status = mAccountCreator.isAccountExist(); if (status != AccountCreator.Status.RequestOk) { - Log.e("[Phone Account Creation] isAccountExists returned " + status); + Log.e( + "[Phone Account Creation Assistant] isAccountExists returned " + + status); enableButtonsAndFields(true); showGenericErrorDialog(status); } @@ -167,7 +170,9 @@ public class PhoneAccountCreationAssistantActivity extends AssistantActivity { new AccountCreatorListenerStub() { public void onIsAccountExist( AccountCreator creator, AccountCreator.Status status, String resp) { - Log.i("[Phone Account Creation] onIsAccountExist status is " + status); + Log.i( + "[Phone Account Creation Assistant] onIsAccountExist status is " + + status); if (status.equals(AccountCreator.Status.AccountExist) || status.equals(AccountCreator.Status.AccountExistWithAlias)) { showAccountAlreadyExistsDialog(); @@ -175,7 +180,9 @@ public class PhoneAccountCreationAssistantActivity extends AssistantActivity { } else if (status.equals(AccountCreator.Status.AccountNotExist)) { status = mAccountCreator.createAccount(); if (status != AccountCreator.Status.RequestOk) { - Log.e("[Phone Account Creation] createAccount returned " + status); + Log.e( + "[Phone Account Creation Assistant] createAccount returned " + + status); enableButtonsAndFields(true); showGenericErrorDialog(status); } @@ -188,7 +195,9 @@ public class PhoneAccountCreationAssistantActivity extends AssistantActivity { @Override public void onCreateAccount( AccountCreator creator, AccountCreator.Status status, String resp) { - Log.i("[Phone Account Creation] onCreateAccount status is " + status); + Log.i( + "[Phone Account Creation Assistant] onCreateAccount status is " + + status); if (status.equals(AccountCreator.Status.AccountCreated)) { startActivity( new Intent( @@ -200,6 +209,11 @@ public class PhoneAccountCreationAssistantActivity extends AssistantActivity { } } }; + + Core core = LinphoneManager.getCore(); + if (core != null) { + reloadLinphoneAccountCreatorConfig(); + } } @Override diff --git a/app/src/main/java/org/linphone/assistant/PhoneAccountLinkingAssistantActivity.java b/app/src/main/java/org/linphone/assistant/PhoneAccountLinkingAssistantActivity.java index 95edb6a52..02f23f189 100644 --- a/app/src/main/java/org/linphone/assistant/PhoneAccountLinkingAssistantActivity.java +++ b/app/src/main/java/org/linphone/assistant/PhoneAccountLinkingAssistantActivity.java @@ -56,7 +56,7 @@ public class PhoneAccountLinkingAssistantActivity extends AssistantActivity { int proxyConfigIndex = getIntent().getExtras().getInt("AccountNumber"); Core core = LinphoneManager.getCore(); if (core == null) { - Log.e("[Account Linking] Core not available"); + Log.e("[Account Linking Assistant] Core not available"); unexpectedError(); } @@ -66,12 +66,12 @@ public class PhoneAccountLinkingAssistantActivity extends AssistantActivity { Address identity = mProxyConfig.getIdentityAddress(); if (identity == null) { - Log.e("[Account Linking] Proxy doesn't have an identity address"); + Log.e("[Account Linking Assistant] Proxy doesn't have an identity address"); unexpectedError(); } if (!mProxyConfig.getDomain().equals(getString(R.string.default_domain))) { Log.e( - "[Account Linking] Can't link account on domain " + "[Account Linking Assistant] Can't link account on domain " + mProxyConfig.getDomain()); unexpectedError(); } @@ -79,18 +79,18 @@ public class PhoneAccountLinkingAssistantActivity extends AssistantActivity { AuthInfo authInfo = mProxyConfig.findAuthInfo(); if (authInfo == null) { - Log.e("[Account Linking] Auth info not found"); + Log.e("[Account Linking Assistant] Auth info not found"); unexpectedError(); } mAccountCreator.setHa1(authInfo.getHa1()); - - mAccountCreator.setDomain(getString(R.string.default_domain)); } else { - Log.e("[Account Linking] Proxy config index out of bounds: " + proxyConfigIndex); + Log.e( + "[Account Linking Assistant] Proxy config index out of bounds: " + + proxyConfigIndex); unexpectedError(); } } else { - Log.e("[Account Linking] Proxy config index not found"); + Log.e("[Account Linking Assistant] Proxy config index not found"); unexpectedError(); } @@ -114,7 +114,9 @@ public class PhoneAccountLinkingAssistantActivity extends AssistantActivity { AccountCreator.Status status = mAccountCreator.isAliasUsed(); if (status != AccountCreator.Status.RequestOk) { - Log.e("[Phone Account Linking] isAliasUsed returned " + status); + Log.e( + "[Phone Account Linking Assistant] isAliasUsed returned " + + status); enableButtonsAndFields(true); showGenericErrorDialog(status); } @@ -178,11 +180,15 @@ public class PhoneAccountLinkingAssistantActivity extends AssistantActivity { @Override public void onIsAliasUsed( AccountCreator creator, AccountCreator.Status status, String resp) { - Log.i("[Phone Account Linking] onIsAliasUsed status is " + status); + Log.i( + "[Phone Account Linking Assistant] onIsAliasUsed status is " + + status); if (status.equals(AccountCreator.Status.AliasNotExist)) { status = mAccountCreator.linkAccount(); if (status != AccountCreator.Status.RequestOk) { - Log.e("[Phone Account Linking] linkAccount returned " + status); + Log.e( + "[Phone Account Linking Assistant] linkAccount returned " + + status); enableButtonsAndFields(true); showGenericErrorDialog(status); } @@ -200,7 +206,9 @@ public class PhoneAccountLinkingAssistantActivity extends AssistantActivity { @Override public void onLinkAccount( AccountCreator creator, AccountCreator.Status status, String resp) { - Log.i("[Phone Account Linking] onLinkAccount status is " + status); + Log.i( + "[Phone Account Linking Assistant] onLinkAccount status is " + + status); if (status.equals(AccountCreator.Status.RequestOk)) { Intent intent = new Intent( @@ -214,6 +222,11 @@ public class PhoneAccountLinkingAssistantActivity extends AssistantActivity { } } }; + + Core core = LinphoneManager.getCore(); + if (core != null) { + reloadLinphoneAccountCreatorConfig(); + } } @Override diff --git a/app/src/main/res/raw/default_assistant_create.rc b/app/src/main/res/raw/default_assistant_create.rc index b96506737..489dfaa24 100644 --- a/app/src/main/res/raw/default_assistant_create.rc +++ b/app/src/main/res/raw/default_assistant_create.rc @@ -27,6 +27,7 @@
+ MD5 -1 0 diff --git a/app/src/main/res/raw/linphone_assistant_create.rc b/app/src/main/res/raw/linphone_assistant_create.rc index 0025e2f00..0c793b49e 100644 --- a/app/src/main/res/raw/linphone_assistant_create.rc +++ b/app/src/main/res/raw/linphone_assistant_create.rc @@ -27,6 +27,7 @@ https://lime.linphone.org/lime-server/lime-server.php
+ sip.linphone.org SHA-256 -1 1 From dab574000dcbe9ac2e4c5e3be00ac1c43e04184f Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 1 Nov 2019 10:19:10 +0100 Subject: [PATCH 07/84] Prevent touch event to go through the side menu when opened --- app/src/main/res/layout/side_menu.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/layout/side_menu.xml b/app/src/main/res/layout/side_menu.xml index f27c5949f..0b964dc30 100644 --- a/app/src/main/res/layout/side_menu.xml +++ b/app/src/main/res/layout/side_menu.xml @@ -37,6 +37,7 @@ android:layout_height="match_parent" android:layout_above="@id/side_menu_quit" android:background="?attr/backgroundColor" + android:clickable="true" android:orientation="vertical"> From 745c5324613c406a0b4daeccff379cc3b198ab3e Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 4 Nov 2019 11:43:36 +0100 Subject: [PATCH 08/84] Change BT device volume during call if connected and used --- CHANGELOG.md | 1 + .../linphone/utils/AndroidAudioManager.java | 20 ++++++++++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d4c34ecd4..603346a55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ Group changes to describe their impact on the project, as follows: - Android 10 compatibility - New plugin loader to be compatible with app bundle distribution mode - Restart service if foreground service setting is on when app is updated +- Change bluetooth volume while in call if BT device connected and used ## Changed - Improved performances to reduce startup time diff --git a/app/src/main/java/org/linphone/utils/AndroidAudioManager.java b/app/src/main/java/org/linphone/utils/AndroidAudioManager.java index dc60a0367..643b5b561 100644 --- a/app/src/main/java/org/linphone/utils/AndroidAudioManager.java +++ b/app/src/main/java/org/linphone/utils/AndroidAudioManager.java @@ -54,8 +54,6 @@ import org.linphone.receivers.HeadsetReceiver; import org.linphone.settings.LinphonePreferences; public class AndroidAudioManager { - private static final int LINPHONE_VOLUME_STREAM = STREAM_VOICE_CALL; - private Context mContext; private AudioManager mAudioManager; private Call mRingingCall; @@ -415,10 +413,22 @@ public class AndroidAudioManager { } private void adjustVolume(int i) { - // starting from ICS, volume must be adjusted by the application, at least for - // STREAM_VOICE_CALL volume stream + if (mAudioManager.isVolumeFixed()) { + Log.e("[Audio Manager] Can't adjust volume, device has it fixed..."); + // Keep going just in case... + } + + int stream = STREAM_VOICE_CALL; + if (mIsBluetoothHeadsetScoConnected) { + Log.i( + "[Audio Manager] Bluetooth is connected, try to change the volume on STREAM_BLUETOOTH_SCO"); + stream = 6; // STREAM_BLUETOOTH_SCO, it's hidden... + } + + // starting from ICS, volume must be adjusted by the application, + // at least for STREAM_VOICE_CALL volume stream mAudioManager.adjustStreamVolume( - LINPHONE_VOLUME_STREAM, + stream, i < 0 ? AudioManager.ADJUST_LOWER : AudioManager.ADJUST_RAISE, AudioManager.FLAG_SHOW_UI); } From ef1c04eab5a1ffaaba4a33d36ea3224f6dc2ae02 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 4 Nov 2019 15:07:41 +0100 Subject: [PATCH 09/84] Fixed power saver dialog that keeps showing up even if user did whitelist app --- app/src/main/java/org/linphone/utils/DeviceUtils.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/linphone/utils/DeviceUtils.java b/app/src/main/java/org/linphone/utils/DeviceUtils.java index 4339e97bc..bbd2c0243 100644 --- a/app/src/main/java/org/linphone/utils/DeviceUtils.java +++ b/app/src/main/java/org/linphone/utils/DeviceUtils.java @@ -197,10 +197,9 @@ public class DeviceUtils { public void onClick(View v) { Log.w( "[Hacks] Power saver detected, user is going to settings :)"); - if (doNotAskAgain.isChecked()) { - LinphonePreferences.instance() - .powerSaverDialogPrompted(true); - } + // If user is going into the settings, + // assume it will make the change so don't prompt again + LinphonePreferences.instance().powerSaverDialogPrompted(true); context.startActivity(intent); dialog.dismiss(); From 0c75dbd9dd8c4c90ac8e0805c35890efba0117ee Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 4 Nov 2019 15:56:26 +0100 Subject: [PATCH 10/84] Fixed null pointer exception --- app/src/main/java/org/linphone/call/CallActivity.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/linphone/call/CallActivity.java b/app/src/main/java/org/linphone/call/CallActivity.java index 5bd4e77d0..5420af913 100644 --- a/app/src/main/java/org/linphone/call/CallActivity.java +++ b/app/src/main/java/org/linphone/call/CallActivity.java @@ -437,7 +437,7 @@ public class CallActivity extends LinphoneGenericActivity Call call = mCore.getCurrentCall(); boolean videoEnabled = LinphonePreferences.instance().isVideoEnabled() - && call.getCurrentParams().videoEnabled(); + && call != null && call.getCurrentParams().videoEnabled(); if (videoEnabled) { mAudioManager = LinphoneManager.getAudioManager(); @@ -825,7 +825,7 @@ public class CallActivity extends LinphoneGenericActivity boolean videoEnabled = LinphonePreferences.instance().isVideoEnabled() - && call.getCurrentParams().videoEnabled(); + && call != null && call.getCurrentParams().videoEnabled(); showVideoControls(videoEnabled); } From 372e408fbbb0da29f94472c5b719d0b831a7371a Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 4 Nov 2019 16:26:06 +0100 Subject: [PATCH 11/84] Fixed wrong missed call number on app badge --- app/src/main/java/org/linphone/call/CallActivity.java | 6 ++++-- .../java/org/linphone/compatibility/ApiTwentyOnePlus.java | 3 ++- .../java/org/linphone/compatibility/ApiTwentySixPlus.java | 3 ++- .../java/org/linphone/compatibility/Compatibility.java | 7 ++++--- .../org/linphone/notifications/NotificationsManager.java | 3 ++- 5 files changed, 14 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/org/linphone/call/CallActivity.java b/app/src/main/java/org/linphone/call/CallActivity.java index 5420af913..2375f07c0 100644 --- a/app/src/main/java/org/linphone/call/CallActivity.java +++ b/app/src/main/java/org/linphone/call/CallActivity.java @@ -437,7 +437,8 @@ public class CallActivity extends LinphoneGenericActivity Call call = mCore.getCurrentCall(); boolean videoEnabled = LinphonePreferences.instance().isVideoEnabled() - && call != null && call.getCurrentParams().videoEnabled(); + && call != null + && call.getCurrentParams().videoEnabled(); if (videoEnabled) { mAudioManager = LinphoneManager.getAudioManager(); @@ -825,7 +826,8 @@ public class CallActivity extends LinphoneGenericActivity boolean videoEnabled = LinphonePreferences.instance().isVideoEnabled() - && call != null && call.getCurrentParams().videoEnabled(); + && call != null + && call.getCurrentParams().videoEnabled(); showVideoControls(videoEnabled); } diff --git a/app/src/main/java/org/linphone/compatibility/ApiTwentyOnePlus.java b/app/src/main/java/org/linphone/compatibility/ApiTwentyOnePlus.java index 47faa1a2b..761830adb 100644 --- a/app/src/main/java/org/linphone/compatibility/ApiTwentyOnePlus.java +++ b/app/src/main/java/org/linphone/compatibility/ApiTwentyOnePlus.java @@ -183,7 +183,7 @@ class ApiTwentyOnePlus { } public static Notification createMissedCallNotification( - Context context, String title, String text, PendingIntent intent) { + Context context, String title, String text, PendingIntent intent, int count) { return new Notification.Builder(context) .setContentTitle(title) @@ -201,6 +201,7 @@ class ApiTwentyOnePlus { .setPriority(Notification.PRIORITY_HIGH) .setWhen(System.currentTimeMillis()) .setShowWhen(true) + .setNumber(count) .build(); } diff --git a/app/src/main/java/org/linphone/compatibility/ApiTwentySixPlus.java b/app/src/main/java/org/linphone/compatibility/ApiTwentySixPlus.java index 4474cd15e..76d466cac 100644 --- a/app/src/main/java/org/linphone/compatibility/ApiTwentySixPlus.java +++ b/app/src/main/java/org/linphone/compatibility/ApiTwentySixPlus.java @@ -255,7 +255,7 @@ class ApiTwentySixPlus { } public static Notification createMissedCallNotification( - Context context, String title, String text, PendingIntent intent) { + Context context, String title, String text, PendingIntent intent, int count) { return new Notification.Builder( context, context.getString(R.string.notification_channel_id)) .setContentTitle(title) @@ -269,6 +269,7 @@ class ApiTwentySixPlus { .setPriority(Notification.PRIORITY_HIGH) .setWhen(System.currentTimeMillis()) .setShowWhen(true) + .setNumber(count) .setColor(context.getColor(R.color.notification_led_color)) .build(); } diff --git a/app/src/main/java/org/linphone/compatibility/Compatibility.java b/app/src/main/java/org/linphone/compatibility/Compatibility.java index ad2b2af26..a4e05e732 100644 --- a/app/src/main/java/org/linphone/compatibility/Compatibility.java +++ b/app/src/main/java/org/linphone/compatibility/Compatibility.java @@ -103,11 +103,12 @@ public class Compatibility { } public static Notification createMissedCallNotification( - Context context, String title, String text, PendingIntent intent) { + Context context, String title, String text, PendingIntent intent, int count) { if (Version.sdkAboveOrEqual(Version.API26_O_80)) { - return ApiTwentySixPlus.createMissedCallNotification(context, title, text, intent); + return ApiTwentySixPlus.createMissedCallNotification( + context, title, text, intent, count); } - return ApiTwentyOnePlus.createMissedCallNotification(context, title, text, intent); + return ApiTwentyOnePlus.createMissedCallNotification(context, title, text, intent, count); } public static Notification createInCallNotification( diff --git a/app/src/main/java/org/linphone/notifications/NotificationsManager.java b/app/src/main/java/org/linphone/notifications/NotificationsManager.java index 8cc5e8638..12ff8c176 100644 --- a/app/src/main/java/org/linphone/notifications/NotificationsManager.java +++ b/app/src/main/java/org/linphone/notifications/NotificationsManager.java @@ -521,7 +521,8 @@ public class NotificationsManager { mContext, mContext.getString(R.string.missed_calls_notif_title), body, - pendingIntent); + pendingIntent, + missedCallCount); sendNotification(MISSED_CALLS_NOTIF_ID, notif); } From 5e04f0b86da027c1c1895cc0c168cb6a2deba43e Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 4 Nov 2019 16:56:16 +0100 Subject: [PATCH 12/84] Remove missed call notification when going into the History activity --- app/src/main/java/org/linphone/history/HistoryActivity.java | 2 ++ .../java/org/linphone/notifications/NotificationsManager.java | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/app/src/main/java/org/linphone/history/HistoryActivity.java b/app/src/main/java/org/linphone/history/HistoryActivity.java index 01399cca4..052550a38 100644 --- a/app/src/main/java/org/linphone/history/HistoryActivity.java +++ b/app/src/main/java/org/linphone/history/HistoryActivity.java @@ -23,6 +23,7 @@ import android.app.Fragment; import android.content.Intent; import android.os.Bundle; import android.view.View; +import org.linphone.LinphoneContext; import org.linphone.LinphoneManager; import org.linphone.R; import org.linphone.activities.MainActivity; @@ -71,6 +72,7 @@ public class HistoryActivity extends MainActivity { mHistorySelected.setVisibility(View.VISIBLE); LinphoneManager.getCore().resetMissedCallsCount(); displayMissedCalls(); + LinphoneContext.instance().getNotificationManager().dismissMissedCallNotification(); } @Override diff --git a/app/src/main/java/org/linphone/notifications/NotificationsManager.java b/app/src/main/java/org/linphone/notifications/NotificationsManager.java index 12ff8c176..438443c91 100644 --- a/app/src/main/java/org/linphone/notifications/NotificationsManager.java +++ b/app/src/main/java/org/linphone/notifications/NotificationsManager.java @@ -327,6 +327,10 @@ public class NotificationsManager { } } + public void dismissMissedCallNotification() { + dismissNotification(MISSED_CALLS_NOTIF_ID); + } + public void sendNotification(int id, Notification notif) { Log.i("[Notifications Manager] Notifying " + id); mNM.notify(id, notif); From 217db2f175b2344f5fdab0aae99cf3a1d2d1dd5f Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 5 Nov 2019 11:32:46 +0100 Subject: [PATCH 13/84] Fixed add contact button on dialer not disabled --- .../main/java/org/linphone/activities/DialerActivity.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/linphone/activities/DialerActivity.java b/app/src/main/java/org/linphone/activities/DialerActivity.java index ccec6c105..45ac4bb5f 100644 --- a/app/src/main/java/org/linphone/activities/DialerActivity.java +++ b/app/src/main/java/org/linphone/activities/DialerActivity.java @@ -259,9 +259,7 @@ public class DialerActivity extends MainActivity implements AddressText.AddressC @Override public void onAddressChanged() { - Core core = LinphoneManager.getCore(); - mAddContact.setEnabled( - core != null && core.getCallsNb() > 0 || !mAddress.getText().toString().equals("")); + mAddContact.setEnabled(!mAddress.getText().toString().isEmpty()); } private void updateLayout() { @@ -273,6 +271,8 @@ public class DialerActivity extends MainActivity implements AddressText.AddressC boolean atLeastOneCall = core.getCallsNb() > 0; mStartCall.setVisibility(atLeastOneCall ? View.GONE : View.VISIBLE); mAddContact.setVisibility(atLeastOneCall ? View.GONE : View.VISIBLE); + mAddContact.setEnabled(!mAddress.getText().toString().isEmpty()); + if (!atLeastOneCall) { if (core.getVideoActivationPolicy().getAutomaticallyInitiate()) { mStartCall.setImageResource(R.drawable.call_video_start); From 83c7a69d513823a74dd05549fb56f60d5dc3b4b2 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 5 Nov 2019 16:52:54 +0100 Subject: [PATCH 14/84] Updated README --- README.md | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index a682c7e86..cd8579f4f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,34 @@ + [![pipeline status](https://gitlab.linphone.org/BC/public/linphone-android/badges/master/pipeline.svg)](https://gitlab.linphone.org/BC/public/linphone-android/commits/master) -Linphone is a free VoIP and video softphone based on the SIP protocol. + +Linphone is an open source softphone for voice and video over IP calling and instant messaging. + +It is fully SIP-based, for all calling, presence and IM features. + +General description is available from [linphone web site](https://www.linphone.org/technical-corner/linphone) + +### License + +Copyright © Belledonne Communications + +Linphone is dual licensed, and is available either : + + - under a [GNU/GPLv3 license](https://www.gnu.org/licenses/gpl-3.0.en.html), for free (open source). Please make sure that you + +understand and agree with the terms of this license before using it (see LICENSE file for + +details). + + - under a proprietary license, for a fee, to be used in closed source applications. Contact + +[Belledonne Communications](https://www.linphone.org/contact) for any question about costs and services. + +### Documentation + +- Supported features and RFCs : https://www.linphone.org/technical-corner/linphone/features + +- Linphone public wiki : https://wiki.linphone.org/xwiki/wiki/public/view/Linphone/ # What's new @@ -69,7 +97,7 @@ Now, simply edit the app/build.gradle file and change the value returned by meth The next build will automatically use this value everywhere thanks to ```manifestPlaceholders``` feature of gradle and Android. You may have already noticed that the app installed by Android Studio has ```org.linphone.debug``` package name. -If you build the app as release, the package name will be ```org.linphone```. +If you build the app as release, the package name will be ```org.linphone```. ## Firebase push notifications @@ -98,7 +126,7 @@ to push new strings to transifex so they can be translated. In order to submit a patch for inclusion in linphone's source code: -1. First make sure your patch applies to latest git sources before submitting: patches made to old versions can't and won't be merged. -2. Fill out and send us an email with the link of pullrequest and the [Contributor Agreement](http://www.belledonne-communications.com/downloads/Belledonne_communications_CA.pdf) for your patch to be included in the git tree. +1. First make sure your patch applies to latest git sources before submitting: patches made to old versions can't and won't be merged. +2. Fill out and send us an email with the link of pullrequest and the [Contributor Agreement](http://www.belledonne-communications.com/downloads/Belledonne_communications_CA.pdf) for your patch to be included in the git tree. -The goal of this agreement to grant us peaceful exercise of our rights on the linphone source code, while not losing your rights on your contribution. +The goal of this agreement to grant us peaceful exercise of our rights on the linphone source code, while not losing your rights on your contribution. \ No newline at end of file From 1b344c30135ed3bdc9f7eeb8686c9f762a9facf6 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 6 Nov 2019 17:21:56 +0100 Subject: [PATCH 15/84] Finish incoming call activity when clicking on decline button --- app/src/main/java/org/linphone/call/CallIncomingActivity.java | 3 ++- app/src/main/java/org/linphone/call/CallOutgoingActivity.java | 2 +- build.gradle | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/linphone/call/CallIncomingActivity.java b/app/src/main/java/org/linphone/call/CallIncomingActivity.java index 205c22f47..ee4e34ac9 100644 --- a/app/src/main/java/org/linphone/call/CallIncomingActivity.java +++ b/app/src/main/java/org/linphone/call/CallIncomingActivity.java @@ -122,7 +122,7 @@ public class CallIncomingActivity extends LinphoneGenericActivity { Core core, Call call, State state, String message) { if (call == mCall) { if (state == State.Connected) { - // This is done by the Service listener now + // This is done by the LinphoneContext listener now // startActivity(new Intent(CallOutgoingActivity.this, // CallActivity.class)); } @@ -230,6 +230,7 @@ public class CallIncomingActivity extends LinphoneGenericActivity { mAlreadyAcceptedOrDeniedCall = true; mCall.terminate(); + finish(); } private void answer() { diff --git a/app/src/main/java/org/linphone/call/CallOutgoingActivity.java b/app/src/main/java/org/linphone/call/CallOutgoingActivity.java index 372019192..e797670b3 100644 --- a/app/src/main/java/org/linphone/call/CallOutgoingActivity.java +++ b/app/src/main/java/org/linphone/call/CallOutgoingActivity.java @@ -125,7 +125,7 @@ public class CallOutgoingActivity extends LinphoneGenericActivity implements OnC .show(); } } else if (state == State.Connected) { - // This is done by the Service listener now + // This is done by the LinphoneContext listener now // startActivity(new Intent(CallOutgoingActivity.this, // CallActivity.class)); } diff --git a/build.gradle b/build.gradle index b0c72ac51..e2b619b41 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ buildscript { } } dependencies { - classpath 'com.android.tools.build:gradle:3.5.1' + classpath 'com.android.tools.build:gradle:3.5.2' classpath 'com.google.gms:google-services:4.3.2' classpath "com.diffplug.spotless:spotless-plugin-gradle:3.24.2" From 4860538466a545b9b1332964f430f7a67e79db01 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 13 Nov 2019 09:55:53 +0100 Subject: [PATCH 16/84] Fixed a crash when VCard support has been disabled --- .../main/java/org/linphone/contacts/LinphoneContact.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/linphone/contacts/LinphoneContact.java b/app/src/main/java/org/linphone/contacts/LinphoneContact.java index 7b46e6425..f4ed675f5 100644 --- a/app/src/main/java/org/linphone/contacts/LinphoneContact.java +++ b/app/src/main/java/org/linphone/contacts/LinphoneContact.java @@ -352,9 +352,10 @@ public class LinphoneContact extends AndroidContact if (mFriend.getVcard() != null) { mFriend.getVcard().setFamilyName(mLastName); mFriend.getVcard().setGivenName(mFirstName); - } - if (mOrganization != null) { - mFriend.getVcard().setOrganization(mOrganization); + + if (mOrganization != null) { + mFriend.getVcard().setOrganization(mOrganization); + } } if (!created) { From a66d57dc4d382ed7470f1c54389fc088954f2a85 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 13 Nov 2019 10:31:13 +0100 Subject: [PATCH 17/84] Fixed registration status after removing account --- .../linphone/fragments/StatusBarFragment.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/org/linphone/fragments/StatusBarFragment.java b/app/src/main/java/org/linphone/fragments/StatusBarFragment.java index 27f31d648..9c7e53bb6 100644 --- a/app/src/main/java/org/linphone/fragments/StatusBarFragment.java +++ b/app/src/main/java/org/linphone/fragments/StatusBarFragment.java @@ -79,10 +79,8 @@ public class StatusBarFragment extends Fragment { final RegistrationState state, String smessage) { if (core.getProxyConfigList() == null) { - mStatusLed.setImageResource(R.drawable.led_disconnected); - mStatusText.setText(getString(R.string.no_account)); - } else { - mStatusLed.setVisibility(View.VISIBLE); + showNoAccountConfigured(); + return; } if ((core.getDefaultProxyConfig() != null @@ -152,6 +150,8 @@ public class StatusBarFragment extends Fragment { ProxyConfig lpc = core.getDefaultProxyConfig(); if (lpc != null) { mListener.onRegistrationStateChanged(core, lpc, lpc.getState(), null); + } else { + showNoAccountConfigured(); } } else { mStatusText.setVisibility(View.VISIBLE); @@ -178,12 +178,16 @@ public class StatusBarFragment extends Fragment { mVoicemailCount.setVisibility(View.VISIBLE); if (core.getProxyConfigList().length == 0) { - mStatusLed.setImageResource(R.drawable.led_disconnected); - mStatusText.setText(getString(R.string.no_account)); + showNoAccountConfigured(); } } } + private void showNoAccountConfigured() { + mStatusLed.setImageResource(R.drawable.led_disconnected); + mStatusText.setText(getString(R.string.no_account)); + } + private int getStatusIconResource(RegistrationState state) { try { if (state == RegistrationState.Ok) { From a9949c660cf96dc65524dd7f55bf65c4cc2d3c13 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 13 Nov 2019 12:52:56 +0100 Subject: [PATCH 18/84] Switched to new maven repository --- app/build.gradle | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 00bb79459..519c2103a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -73,8 +73,7 @@ excludePackage.add('**/LICENSE.txt') repositories { maven { - // Replace snapshots by releases for releases ! - url "https://linphone.org/releases/maven_repository" + url "https://linphone.org/maven_repository" } } From 9cab87e84795aa8d52c414ed326911cfe8171cab Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 12 Nov 2019 15:57:13 +0100 Subject: [PATCH 19/84] Changes & fixes required for new SHA256 accounts and previously created MD5 ones --- ...oneAccountValidationAssistantActivity.java | 48 +++++++++++++------ .../settings/AccountSettingsFragment.java | 3 ++ .../assistant_phone_account_validation.xml | 2 +- 3 files changed, 37 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/org/linphone/assistant/PhoneAccountValidationAssistantActivity.java b/app/src/main/java/org/linphone/assistant/PhoneAccountValidationAssistantActivity.java index dacf89144..aa54e7e93 100644 --- a/app/src/main/java/org/linphone/assistant/PhoneAccountValidationAssistantActivity.java +++ b/app/src/main/java/org/linphone/assistant/PhoneAccountValidationAssistantActivity.java @@ -40,7 +40,7 @@ public class PhoneAccountValidationAssistantActivity extends AssistantActivity { private ClipboardManager mClipboard; private int mActivationCodeLength; - private boolean mIsLinking; + private boolean mIsLinking = false, mIsLogin = false; private AccountCreatorListenerStub mListener; @Override @@ -50,13 +50,14 @@ public class PhoneAccountValidationAssistantActivity extends AssistantActivity { setContentView(R.layout.assistant_phone_account_validation); if (getIntent() != null && getIntent().getBooleanExtra("isLoginVerification", false)) { - findViewById(R.id.title_account_creation).setVisibility(View.VISIBLE); + findViewById(R.id.title_account_login).setVisibility(View.VISIBLE); + mIsLogin = true; } else if (getIntent() != null && getIntent().getBooleanExtra("isLinkingVerification", false)) { mIsLinking = true; findViewById(R.id.title_account_linking).setVisibility(View.VISIBLE); } else { - findViewById(R.id.title_account_activation).setVisibility(View.VISIBLE); + findViewById(R.id.title_account_creation).setVisibility(View.VISIBLE); } mActivationCodeLength = @@ -93,6 +94,8 @@ public class PhoneAccountValidationAssistantActivity extends AssistantActivity { AccountCreator.Status status; if (mIsLinking) { status = mAccountCreator.activateAlias(); + } else if (mIsLogin) { + status = mAccountCreator.loginLinphoneAccount(); } else { status = mAccountCreator.activateAccount(); } @@ -101,7 +104,10 @@ public class PhoneAccountValidationAssistantActivity extends AssistantActivity { "[Phone Account Validation] " + (mIsLinking ? "linkAccount" - : "activateAccount" + " returned ") + : (mIsLogin + ? "loginLinphoneAccount" + : "activateAccount") + + " returned ") + status); mFinishCreation.setEnabled(true); showGenericErrorDialog(status); @@ -118,12 +124,7 @@ public class PhoneAccountValidationAssistantActivity extends AssistantActivity { if (status.equals(AccountCreator.Status.AccountActivated)) { createProxyConfigAndLeaveAssistant(); } else { - mFinishCreation.setEnabled(true); - showGenericErrorDialog(status); - - if (status.equals(AccountCreator.Status.WrongActivationCode)) { - // TODO do something so the server re-send a SMS - } + onError(status); } } @@ -135,12 +136,20 @@ public class PhoneAccountValidationAssistantActivity extends AssistantActivity { LinphonePreferences.instance().setLinkPopupTime(""); goToLinphoneActivity(); } else { - mFinishCreation.setEnabled(true); - showGenericErrorDialog(status); + onError(status); + } + } - if (status.equals(AccountCreator.Status.WrongActivationCode)) { - // TODO do something so the server re-send a SMS - } + @Override + public void onLoginLinphoneAccount( + AccountCreator creator, AccountCreator.Status status, String resp) { + Log.i( + "[Phone Account Validation] onLoginLinphoneAccount status is " + + status); + if (status.equals(AccountCreator.Status.RequestOk)) { + createProxyConfigAndLeaveAssistant(); + } else { + onError(status); } } }; @@ -175,4 +184,13 @@ public class PhoneAccountValidationAssistantActivity extends AssistantActivity { super.onPause(); mAccountCreator.removeListener(mListener); } + + private void onError(AccountCreator.Status status) { + mFinishCreation.setEnabled(true); + showGenericErrorDialog(status); + + if (status.equals(AccountCreator.Status.WrongActivationCode)) { + // TODO do something so the server re-send a SMS + } + } } diff --git a/app/src/main/java/org/linphone/settings/AccountSettingsFragment.java b/app/src/main/java/org/linphone/settings/AccountSettingsFragment.java index 3499bf606..9be93c880 100644 --- a/app/src/main/java/org/linphone/settings/AccountSettingsFragment.java +++ b/app/src/main/java/org/linphone/settings/AccountSettingsFragment.java @@ -240,6 +240,9 @@ public class AccountSettingsFragment extends SettingsFragment { if (mAuthInfo != null) { mAuthInfo.setHa1(null); mAuthInfo.setPassword(newValue); + // Reset algorithm to generate correct hash depending on + // algorithm set in next to come 401 + mAuthInfo.setAlgorithm(null); Core core = LinphoneManager.getCore(); if (core != null) { core.addAuthInfo(mAuthInfo); diff --git a/app/src/main/res/layout/assistant_phone_account_validation.xml b/app/src/main/res/layout/assistant_phone_account_validation.xml index ef446c1e1..80780f375 100644 --- a/app/src/main/res/layout/assistant_phone_account_validation.xml +++ b/app/src/main/res/layout/assistant_phone_account_validation.xml @@ -37,7 +37,7 @@ android:paddingTop="10dp"/> Date: Thu, 14 Nov 2019 10:01:08 +0100 Subject: [PATCH 20/84] Disable media encryption mandatory setting if media encryption set to None + display security icon on incoming call view if media encryption is mandatory --- .../org/linphone/call/CallStatusBarFragment.java | 12 +++++++++++- .../linphone/settings/CallSettingsFragment.java | 14 +++++++++++--- .../org/linphone/settings/LinphonePreferences.java | 2 +- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/org/linphone/call/CallStatusBarFragment.java b/app/src/main/java/org/linphone/call/CallStatusBarFragment.java index 3ac6b6acf..16e6180b5 100644 --- a/app/src/main/java/org/linphone/call/CallStatusBarFragment.java +++ b/app/src/main/java/org/linphone/call/CallStatusBarFragment.java @@ -288,9 +288,19 @@ public class CallStatusBarFragment extends Fragment { public void refreshStatusItems(final Call call) { if (call != null) { - MediaEncryption mediaEncryption = call.getCurrentParams().getMediaEncryption(); + if (call.getDir() == Call.Dir.Incoming + && call.getState() == Call.State.IncomingReceived + && LinphonePreferences.instance().isMediaEncryptionMandatory()) { + // If the incoming call view is displayed while encryption is mandatory, + // we can safely show the security_ok icon + mEncryption.setImageResource(R.drawable.security_ok); + mEncryption.setVisibility(View.VISIBLE); + return; + } + MediaEncryption mediaEncryption = call.getCurrentParams().getMediaEncryption(); mEncryption.setVisibility(View.VISIBLE); + if (mediaEncryption == MediaEncryption.SRTP || (mediaEncryption == MediaEncryption.ZRTP && call.getAuthenticationTokenVerified()) diff --git a/app/src/main/java/org/linphone/settings/CallSettingsFragment.java b/app/src/main/java/org/linphone/settings/CallSettingsFragment.java index eadeda704..d0ee874af 100644 --- a/app/src/main/java/org/linphone/settings/CallSettingsFragment.java +++ b/app/src/main/java/org/linphone/settings/CallSettingsFragment.java @@ -167,8 +167,15 @@ public class CallSettingsFragment extends SettingsFragment { @Override public void onListValueChanged(int position, String newLabel, String newValue) { try { - mPrefs.setMediaEncryption( - MediaEncryption.fromInt(Integer.parseInt(newValue))); + MediaEncryption encryption = + MediaEncryption.fromInt(Integer.parseInt(newValue)); + mPrefs.setMediaEncryption(encryption); + + if (encryption == MediaEncryption.None) { + mMediaEncryptionMandatory.setChecked(false); + } + mMediaEncryptionMandatory.setEnabled( + encryption != MediaEncryption.None); } catch (NumberFormatException nfe) { Log.e(nfe); } @@ -248,7 +255,8 @@ public class CallSettingsFragment extends SettingsFragment { mDndPermissionSettings.setVisibility( Version.sdkAboveOrEqual(Version.API23_MARSHMALLOW_60) ? View.VISIBLE : View.GONE); - mMediaEncryptionMandatory.setChecked(mPrefs.acceptMediaEncryptionMandatory()); + mMediaEncryptionMandatory.setChecked(mPrefs.isMediaEncryptionMandatory()); + mMediaEncryptionMandatory.setEnabled(mPrefs.getMediaEncryption() != MediaEncryption.None); setListeners(); } diff --git a/app/src/main/java/org/linphone/settings/LinphonePreferences.java b/app/src/main/java/org/linphone/settings/LinphonePreferences.java index d1d6aa11a..5583990a2 100644 --- a/app/src/main/java/org/linphone/settings/LinphonePreferences.java +++ b/app/src/main/java/org/linphone/settings/LinphonePreferences.java @@ -459,7 +459,7 @@ public class LinphonePreferences { // End of contact settings // Call settings - public boolean acceptMediaEncryptionMandatory() { + public boolean isMediaEncryptionMandatory() { return getLc().isMediaEncryptionMandatory(); } From c8d5582ecc6e8ff8417b1de7a0238668e2cd3dbb Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 14 Nov 2019 10:52:52 +0100 Subject: [PATCH 21/84] Fixed custom video preset bandwidth value overriden to 0 after restart --- app/src/main/res/raw/linphonerc_default | 5 +++++ app/src/main/res/raw/linphonerc_factory | 3 --- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/raw/linphonerc_default b/app/src/main/res/raw/linphonerc_default index a220030d0..808feee28 100644 --- a/app/src/main/res/raw/linphonerc_default +++ b/app/src/main/res/raw/linphonerc_default @@ -8,6 +8,11 @@ sip_tcp_port=-1 sip_tls_port=-1 media_encryption=none +[net] +#Because dynamic bitrate adaption can increase bitrate, we must allow "no limit" +download_bw=0 +upload_bw=0 + [video] size=vga diff --git a/app/src/main/res/raw/linphonerc_factory b/app/src/main/res/raw/linphonerc_factory index 85a96a979..a9a51cb5a 100644 --- a/app/src/main/res/raw/linphonerc_factory +++ b/app/src/main/res/raw/linphonerc_factory @@ -4,9 +4,6 @@ #Paths to resources must be set from LinphoneManager, after creating LinphoneCore. [net] mtu=1300 -#Because dynamic bitrate adaption can increase bitrate, we must allow "no limit" -download_bw=0 -upload_bw=0 force_ice_disablement=0 [sip] From 76262573a6198b14e2e652cf69ce7a6987fc5ade Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 14 Nov 2019 15:21:03 +0100 Subject: [PATCH 22/84] Added custom option to keep missed call notif upon app restart --- .../compatibility/ApiTwentyThreePlus.java | 5 +++++ .../org/linphone/compatibility/Compatibility.java | 10 ++++++++++ .../notifications/NotificationsManager.java | 15 ++++++++++++++- .../main/res/values/non_localizable_custom.xml | 3 +++ 4 files changed, 32 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/linphone/compatibility/ApiTwentyThreePlus.java b/app/src/main/java/org/linphone/compatibility/ApiTwentyThreePlus.java index fd81bae66..cb0c0d24b 100644 --- a/app/src/main/java/org/linphone/compatibility/ApiTwentyThreePlus.java +++ b/app/src/main/java/org/linphone/compatibility/ApiTwentyThreePlus.java @@ -23,6 +23,7 @@ import android.annotation.TargetApi; import android.app.NotificationManager; import android.content.Context; import android.os.PowerManager; +import android.service.notification.StatusBarNotification; import org.linphone.contacts.ContactsManager; import org.linphone.contacts.LinphoneContact; import org.linphone.core.Address; @@ -111,4 +112,8 @@ class ApiTwentyThreePlus { return true; } + + public static StatusBarNotification[] getActiveNotifications(NotificationManager manager) { + return manager.getActiveNotifications(); + } } diff --git a/app/src/main/java/org/linphone/compatibility/Compatibility.java b/app/src/main/java/org/linphone/compatibility/Compatibility.java index a4e05e732..057c6e68a 100644 --- a/app/src/main/java/org/linphone/compatibility/Compatibility.java +++ b/app/src/main/java/org/linphone/compatibility/Compatibility.java @@ -22,6 +22,7 @@ package org.linphone.compatibility; import android.app.Activity; import android.app.FragmentTransaction; import android.app.Notification; +import android.app.NotificationManager; import android.app.PendingIntent; import android.bluetooth.BluetoothAdapter; import android.content.ContentProviderClient; @@ -30,6 +31,7 @@ import android.content.Intent; import android.graphics.Bitmap; import android.os.Build; import android.provider.Settings; +import android.service.notification.StatusBarNotification; import org.linphone.core.Address; import org.linphone.mediastream.Version; import org.linphone.notifications.Notifiable; @@ -309,4 +311,12 @@ public class Compatibility { } return null; } + + public static StatusBarNotification[] getActiveNotifications(NotificationManager manager) { + if (Version.sdkAboveOrEqual(Version.API23_MARSHMALLOW_60)) { + return ApiTwentyThreePlus.getActiveNotifications(manager); + } + + return new StatusBarNotification[0]; + } } diff --git a/app/src/main/java/org/linphone/notifications/NotificationsManager.java b/app/src/main/java/org/linphone/notifications/NotificationsManager.java index 438443c91..f960c6f54 100644 --- a/app/src/main/java/org/linphone/notifications/NotificationsManager.java +++ b/app/src/main/java/org/linphone/notifications/NotificationsManager.java @@ -29,6 +29,7 @@ import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; +import android.service.notification.StatusBarNotification; import java.io.File; import java.util.HashMap; import org.linphone.LinphoneManager; @@ -84,7 +85,19 @@ public class NotificationsManager { mCurrentChatRoomAddress = null; mNM = (NotificationManager) mContext.getSystemService(NOTIFICATION_SERVICE); - mNM.cancelAll(); + + if (mContext.getResources().getBoolean(R.bool.keep_missed_call_notification_upon_restart)) { + StatusBarNotification[] notifs = Compatibility.getActiveNotifications(mNM); + if (notifs != null && notifs.length > 1) { + for (StatusBarNotification notif : notifs) { + if (notif.getId() != MISSED_CALLS_NOTIF_ID) { + dismissNotification(notif.getId()); + } + } + } + } else { + mNM.cancelAll(); + } mLastNotificationId = 5; // Do not conflict with hardcoded notifications ids ! diff --git a/app/src/main/res/values/non_localizable_custom.xml b/app/src/main/res/values/non_localizable_custom.xml index b94817cc8..1b644be68 100644 --- a/app/src/main/res/values/non_localizable_custom.xml +++ b/app/src/main/res/values/non_localizable_custom.xml @@ -132,6 +132,9 @@ 1000 7000 + + false + false From 10d8eb4d8c880bba56f701498d81dbb316f4a83f Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 14 Nov 2019 17:27:44 +0100 Subject: [PATCH 23/84] Added a custom setting to hide dark mode feature in app --- .../java/org/linphone/settings/AdvancedSettingsFragment.java | 2 ++ .../main/java/org/linphone/settings/LinphonePreferences.java | 1 + app/src/main/res/values/non_localizable_custom.xml | 1 + 3 files changed, 4 insertions(+) diff --git a/app/src/main/java/org/linphone/settings/AdvancedSettingsFragment.java b/app/src/main/java/org/linphone/settings/AdvancedSettingsFragment.java index f769af665..cc27bcb31 100644 --- a/app/src/main/java/org/linphone/settings/AdvancedSettingsFragment.java +++ b/app/src/main/java/org/linphone/settings/AdvancedSettingsFragment.java @@ -83,6 +83,8 @@ public class AdvancedSettingsFragment extends SettingsFragment { mStartAtBoot = mRootView.findViewById(R.id.pref_autostart); mDarkMode = mRootView.findViewById(R.id.pref_dark_mode); + mDarkMode.setVisibility( + getResources().getBoolean(R.bool.allow_dark_mode) ? View.VISIBLE : View.GONE); mRemoteProvisioningUrl = mRootView.findViewById(R.id.pref_remote_provisioning); mRemoteProvisioningUrl.setInputType( diff --git a/app/src/main/java/org/linphone/settings/LinphonePreferences.java b/app/src/main/java/org/linphone/settings/LinphonePreferences.java index 5583990a2..1a9b8aa29 100644 --- a/app/src/main/java/org/linphone/settings/LinphonePreferences.java +++ b/app/src/main/java/org/linphone/settings/LinphonePreferences.java @@ -1136,6 +1136,7 @@ public class LinphonePreferences { public boolean isDarkModeEnabled() { if (getConfig() == null) return false; + if (!mContext.getResources().getBoolean(R.bool.allow_dark_mode)) return false; boolean useNightModeDefault = AppCompatDelegate.getDefaultNightMode() == AppCompatDelegate.MODE_NIGHT_YES; diff --git a/app/src/main/res/values/non_localizable_custom.xml b/app/src/main/res/values/non_localizable_custom.xml index 1b644be68..c68dd5ca1 100644 --- a/app/src/main/res/values/non_localizable_custom.xml +++ b/app/src/main/res/values/non_localizable_custom.xml @@ -34,6 +34,7 @@ true false true + true EEE d MMM From 8975920035117fd09d45b8e153e65657899fe9b5 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 15 Nov 2019 10:24:16 +0100 Subject: [PATCH 24/84] Added a shortcut to call/service notifications channel settings --- .../settings/CallSettingsFragment.java | 32 ++++++++++++++++++- app/src/main/res/layout/settings_call.xml | 6 ++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/linphone/settings/CallSettingsFragment.java b/app/src/main/java/org/linphone/settings/CallSettingsFragment.java index d0ee874af..597af0fc1 100644 --- a/app/src/main/java/org/linphone/settings/CallSettingsFragment.java +++ b/app/src/main/java/org/linphone/settings/CallSettingsFragment.java @@ -20,9 +20,12 @@ package org.linphone.settings; import android.Manifest; +import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; +import android.os.Build; import android.os.Bundle; +import android.provider.Settings; import android.text.InputType; import android.view.LayoutInflater; import android.view.View; @@ -54,7 +57,7 @@ public class CallSettingsFragment extends SettingsFragment { mAutoAnswer; private ListSetting mMediaEncryption; private TextSetting mAutoAnswerTime, mIncomingCallTimeout, mVoiceMailUri; - private BasicSetting mDndPermissionSettings; + private BasicSetting mDndPermissionSettings, mAndroidNotificationSettings; @Nullable @Override @@ -90,6 +93,8 @@ public class CallSettingsFragment extends SettingsFragment { mMediaEncryption = mRootView.findViewById(R.id.pref_media_encryption); initMediaEncryptionList(); + mAndroidNotificationSettings = mRootView.findViewById(R.id.pref_android_app_notif_settings); + mAutoAnswerTime = mRootView.findViewById(R.id.pref_auto_answer_time); mAutoAnswerTime.setInputType(InputType.TYPE_CLASS_NUMBER); @@ -230,6 +235,27 @@ public class CallSettingsFragment extends SettingsFragment { mPrefs.setMediaEncryptionMandatory(newValue); } }); + + mAndroidNotificationSettings.setListener( + new SettingListenerBase() { + @Override + public void onClicked() { + if (Build.VERSION.SDK_INT >= Version.API26_O_80) { + Context context = getActivity(); + Intent i = new Intent(); + i.setAction(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS); + i.putExtra(Settings.EXTRA_APP_PACKAGE, context.getPackageName()); + i.putExtra( + Settings.EXTRA_CHANNEL_ID, + context.getString(R.string.notification_service_channel_id)); + i.addCategory(Intent.CATEGORY_DEFAULT); + i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); + i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); + startActivity(i); + } + } + }); } private void updateValues() { @@ -258,6 +284,10 @@ public class CallSettingsFragment extends SettingsFragment { mMediaEncryptionMandatory.setChecked(mPrefs.isMediaEncryptionMandatory()); mMediaEncryptionMandatory.setEnabled(mPrefs.getMediaEncryption() != MediaEncryption.None); + if (Version.sdkStrictlyBelow(Version.API26_O_80)) { + mAndroidNotificationSettings.setVisibility(View.GONE); + } + setListeners(); } diff --git a/app/src/main/res/layout/settings_call.xml b/app/src/main/res/layout/settings_call.xml index 75143a543..6c716502c 100644 --- a/app/src/main/res/layout/settings_call.xml +++ b/app/src/main/res/layout/settings_call.xml @@ -54,6 +54,12 @@ android:layout_height="wrap_content" linphone:title="@string/pref_rfc2833_dtmf" /> + + Date: Fri, 15 Nov 2019 10:42:02 +0100 Subject: [PATCH 25/84] Fixed incall numpad button state when numpad is visible --- app/src/main/java/org/linphone/call/CallActivity.java | 10 +++++----- app/src/main/res/drawable/call_numpad.xml | 10 ++++++++++ app/src/main/res/layout/call_primary_buttons.xml | 2 +- 3 files changed, 16 insertions(+), 6 deletions(-) create mode 100644 app/src/main/res/drawable/call_numpad.xml diff --git a/app/src/main/java/org/linphone/call/CallActivity.java b/app/src/main/java/org/linphone/call/CallActivity.java index 2375f07c0..bc902d08d 100644 --- a/app/src/main/java/org/linphone/call/CallActivity.java +++ b/app/src/main/java/org/linphone/call/CallActivity.java @@ -306,13 +306,13 @@ public class CallActivity extends LinphoneGenericActivity new View.OnClickListener() { @Override public void onClick(View v) { - findViewById(R.id.numpad) - .setVisibility( - findViewById(R.id.numpad).getVisibility() == View.VISIBLE - ? View.GONE - : View.VISIBLE); + View numpad = findViewById(R.id.numpad); + boolean isNumpadVisible = numpad.getVisibility() == View.VISIBLE; + numpad.setVisibility(isNumpadVisible ? View.GONE : View.VISIBLE); + v.setSelected(!isNumpadVisible); } }); + numpadButton.setSelected(false); ImageView hangUp = findViewById(R.id.hang_up); hangUp.setOnClickListener( diff --git a/app/src/main/res/drawable/call_numpad.xml b/app/src/main/res/drawable/call_numpad.xml new file mode 100644 index 000000000..340e506d4 --- /dev/null +++ b/app/src/main/res/drawable/call_numpad.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/call_primary_buttons.xml b/app/src/main/res/layout/call_primary_buttons.xml index 6db6b8744..3f16c6f1b 100644 --- a/app/src/main/res/layout/call_primary_buttons.xml +++ b/app/src/main/res/layout/call_primary_buttons.xml @@ -38,7 +38,7 @@ android:background="@drawable/button_background_dark" android:contentDescription="@string/content_description_numpad" android:padding="15dp" - android:src="@drawable/footer_dialer" /> + android:src="@drawable/call_numpad" /> From 5b5a08e00aa2088e7e5a6cfcf8cfb6f711241106 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 15 Nov 2019 11:01:29 +0100 Subject: [PATCH 26/84] Improved incall numpad view space --- app/src/main/res/layout-land/call.xml | 24 +++++++++++++----------- app/src/main/res/layout/call.xml | 27 +++++++++++++++------------ 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/app/src/main/res/layout-land/call.xml b/app/src/main/res/layout-land/call.xml index b47c08bba..836374fce 100644 --- a/app/src/main/res/layout-land/call.xml +++ b/app/src/main/res/layout-land/call.xml @@ -109,6 +109,7 @@ android:id="@+id/buttons" android:layout_width="match_parent" android:layout_height="match_parent" + android:layout_marginTop="40dp" android:gravity="bottom"> @@ -119,28 +120,29 @@ android:layout_centerHorizontal="true" /> - + - + diff --git a/app/src/main/res/layout/call.xml b/app/src/main/res/layout/call.xml index d484a5ae3..32277a192 100644 --- a/app/src/main/res/layout/call.xml +++ b/app/src/main/res/layout/call.xml @@ -106,8 +106,10 @@ - + - + From 9eeb79a5a9a4fb2566babe5088e79acb5681bd44 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 15 Nov 2019 11:16:11 +0100 Subject: [PATCH 27/84] Updated translations from transifex --- .tx/config | 1 + app/src/main/res/values-it/strings.xml | 9 +++++++++ app/src/main/res/values-nl/strings.xml | 12 ++++++++++++ app/src/main/res/values-ru/strings.xml | 4 ++-- app/src/main/res/values-sv/strings.xml | 5 +++++ 5 files changed, 29 insertions(+), 2 deletions(-) diff --git a/.tx/config b/.tx/config index 35511f253..93225826f 100644 --- a/.tx/config +++ b/.tx/config @@ -8,3 +8,4 @@ type = ANDROID file_filter = app/src/main/res/values-/strings.xml source_file = app/src/main/res/values/strings.xml source_lang = en + diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 998ef0bf5..8a06bdc9f 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -243,6 +243,7 @@ Scarica Scegli una conversazione o creane una nuova Il trust è stato negato. Effettua una chiamata per avviare nuovamente la procedura di autenticazione. + Impossibile aprire il file, nessuna applicazione disponibile per questo formato. Connesso Non connesso @@ -286,7 +287,9 @@ Buffer jitter: Encoder: Decoder: + Filtro di riproduzione: Filtro di visualizzazione: + Filtro di acquisizione: Chiamata Vuoi cancellare il registro delle chiamate selezionate? @@ -366,6 +369,9 @@ Tunnel Nome host Porta + Abilita modalità doppia + Nome host (2° server per la modalità doppia) + Porta (2° server per la modalità doppia) Modalità @@ -394,6 +400,7 @@ Codec Video + Fotocamera Sovrapposizione video Mostra video di chiamata sul display quando ci si trova all\'esterno dell\'applicazione Usa la fotocamera frontale @@ -442,6 +449,8 @@ Mai Sempre Se minore della grandezza massima + Nascondi chat room vuote + Se mancano le chat room, prova a deselezionare questa impostazione Rete Usa solo Wi-Fi diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 47a1f996e..ee7cdd695 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -6,10 +6,20 @@ Linphone Linphone Bezig met opstarten + %s verbonden + %s verbinding kon niet tot stand gebracht worden Linphone Android %s Linphone Core %s + Linphone SDK %s + Lees onze privacy verklaring + linphone contacten + Antwoord + Verstuurd antwoord: %s + Verbinding verbreken + Beantwoorden + Aanduiden als gelezen Gebruikersnaam Telefoonnummer @@ -42,6 +52,7 @@ Nee prima Ja + Niet opnieuw tonen omschrijving @@ -54,6 +65,7 @@ geldig account_1 linphoen Transport + Uw SIP adres is Wachtwoord is te kort Wachtwoiord is te lang diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index fedf91a19..7bc8e371a 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -450,8 +450,8 @@ Всегда Если он легче максимального размера Скрыть пустые чаты - Скрыть чаты из удалённых настроек прокси - Если у вас есть отсутствующие чаты, то попробуйте снять этот флажок + Скрыть чаты из удаленных настроек прокси + Если у вас есть отсутствующие чаты, попробуйте снять флажок с этого параметра. Сеть Использовать только WiFi diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index cbde3df58..8150a74f2 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -243,6 +243,7 @@ Ladda ner Välj en konversation eller skapa en ny Förtroende har nekats. Ring ett samtal för att starta autentiseringsprocessen igen. + Kan inte öppna filen, inget program tillgängligt för detta format. Ansluten Inte ansluten @@ -286,6 +287,7 @@ Jitterbuffert: Kodare: Avkodare: + Spelarfilter: Visningsfilter: Ring Vill du ta bort de valda samtalsloggarna? @@ -394,6 +396,7 @@ Kodek Video + Kamera Videoöverlagring Visningsvideo i överlagring när det är utanför applikationen Använd front-kamera @@ -407,6 +410,8 @@ Bandbreddsgräns i kbit/s Kodek + Närvaroinformation i lokal kontakt + Infogar informationsgenvägar från Linphone-kontakten i lokala Android-kontakter Kontakt Visa kontaktorganisation From cdf8b55d060f9ad7fe515936ac757e087f6fae32 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 15 Nov 2019 11:34:15 +0100 Subject: [PATCH 28/84] Increased importance of service notification channel (also used for active call notifications) --- .../main/java/org/linphone/compatibility/ApiTwentySixPlus.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/linphone/compatibility/ApiTwentySixPlus.java b/app/src/main/java/org/linphone/compatibility/ApiTwentySixPlus.java index 76d466cac..270408d3f 100644 --- a/app/src/main/java/org/linphone/compatibility/ApiTwentySixPlus.java +++ b/app/src/main/java/org/linphone/compatibility/ApiTwentySixPlus.java @@ -76,7 +76,7 @@ class ApiTwentySixPlus { CharSequence name = context.getString(R.string.content_title_notification_service); String description = context.getString(R.string.content_title_notification_service); NotificationChannel channel = - new NotificationChannel(id, name, NotificationManager.IMPORTANCE_NONE); + new NotificationChannel(id, name, NotificationManager.IMPORTANCE_LOW); channel.setDescription(description); channel.enableVibration(false); channel.enableLights(false); From ba6a3c70bba5dc84331c5ffaec033fe57f802220 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 13 Nov 2019 11:18:15 +0100 Subject: [PATCH 29/84] Fixed empty history & missing contacts when fetched through remote provisionning --- .../java/org/linphone/LinphoneContext.java | 47 +++++++- .../java/org/linphone/LinphoneManager.java | 41 ++----- .../contacts/AsyncContactsLoader.java | 100 ++++++++++-------- .../linphone/contacts/ContactsManager.java | 23 ++-- .../org/linphone/history/HistoryFragment.java | 30 ++++-- 5 files changed, 144 insertions(+), 97 deletions(-) diff --git a/app/src/main/java/org/linphone/LinphoneContext.java b/app/src/main/java/org/linphone/LinphoneContext.java index 0db32d971..c02c81a4d 100644 --- a/app/src/main/java/org/linphone/LinphoneContext.java +++ b/app/src/main/java/org/linphone/LinphoneContext.java @@ -26,15 +26,18 @@ import android.content.Context; import android.content.Intent; import android.os.Build; import android.provider.ContactsContract; +import java.util.ArrayList; import org.linphone.call.CallActivity; import org.linphone.call.CallIncomingActivity; import org.linphone.call.CallOutgoingActivity; import org.linphone.compatibility.Compatibility; import org.linphone.contacts.ContactsManager; import org.linphone.core.Call; +import org.linphone.core.ConfiguringState; import org.linphone.core.Core; import org.linphone.core.CoreListenerStub; import org.linphone.core.Factory; +import org.linphone.core.GlobalState; import org.linphone.core.LogLevel; import org.linphone.core.LoggingService; import org.linphone.core.LoggingServiceListener; @@ -79,6 +82,7 @@ public class LinphoneContext { private LinphoneManager mLinphoneManager; private ContactsManager mContactsManager; private Class mIncomingReceivedActivity = CallIncomingActivity.class; + private final ArrayList mCoreStartedListeners; public static boolean isReady() { return sInstance != null; @@ -90,6 +94,7 @@ public class LinphoneContext { public LinphoneContext(Context context) { mContext = context; + mCoreStartedListeners = new ArrayList<>(); LinphonePreferences.instance().setContext(context); Factory.instance().setLogCollectionPath(context.getFilesDir().getAbsolutePath()); @@ -114,9 +119,35 @@ public class LinphoneContext { mListener = new CoreListenerStub() { + @Override + public void onGlobalStateChanged(Core core, GlobalState state, String message) { + Log.i("[Context] Global state is [", state, "]"); + + if (state == GlobalState.On) { + for (CoreStartedListener listener : mCoreStartedListeners) { + listener.onCoreStarted(); + } + } + } + + @Override + public void onConfiguringStatus( + Core core, ConfiguringState status, String message) { + Log.i("[Context] Configuring state is [", status, "]"); + + if (status == ConfiguringState.Successful) { + LinphonePreferences.instance() + .setPushNotificationEnabled( + LinphonePreferences.instance() + .isPushNotificationEnabled()); + } + } + @Override public void onCallStateChanged( Core core, Call call, Call.State state, String message) { + Log.i("[Context] Call state is [", state, "]"); + if (mContext.getResources().getBoolean(R.bool.enable_call_notification)) { mNotificationManager.displayCallNotification(call); } @@ -161,8 +192,7 @@ public class LinphoneContext { public void start(boolean isPush) { Log.i("[Context] Starting"); - mLinphoneManager.startLibLinphone(isPush); - LinphoneManager.getCore().addListener(mListener); + mLinphoneManager.startLibLinphone(isPush, mListener); mNotificationManager.onCoreReady(); @@ -176,6 +206,7 @@ public class LinphoneContext { if (mContactsManager.hasReadContactsAccess()) { mContactsManager.enableContactsAccess(); } + mContactsManager.initializeContactManager(); } @@ -236,6 +267,14 @@ public class LinphoneContext { return mContactsManager; } + public void addCoreStartedListener(CoreStartedListener listener) { + mCoreStartedListeners.add(listener); + } + + public void removeCoreStartedListener(CoreStartedListener listener) { + mCoreStartedListeners.remove(listener); + } + /* Log device related information */ private void dumpDeviceInformation() { @@ -285,4 +324,8 @@ public class LinphoneContext { intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); mContext.startActivity(intent); } + + public interface CoreStartedListener { + void onCoreStarted(); + } } diff --git a/app/src/main/java/org/linphone/LinphoneManager.java b/app/src/main/java/org/linphone/LinphoneManager.java index ea6e900df..fcbc0c57e 100644 --- a/app/src/main/java/org/linphone/LinphoneManager.java +++ b/app/src/main/java/org/linphone/LinphoneManager.java @@ -51,12 +51,11 @@ import org.linphone.core.AccountCreator; import org.linphone.core.AccountCreatorListenerStub; import org.linphone.core.Call; import org.linphone.core.Call.State; -import org.linphone.core.ConfiguringState; import org.linphone.core.Core; +import org.linphone.core.CoreListener; import org.linphone.core.CoreListenerStub; import org.linphone.core.Factory; import org.linphone.core.FriendList; -import org.linphone.core.GlobalState; import org.linphone.core.PresenceActivity; import org.linphone.core.PresenceBasicStatus; import org.linphone.core.PresenceModel; @@ -160,37 +159,6 @@ public class LinphoneManager implements SensorEventListener { mCoreListener = new CoreListenerStub() { - @Override - public void onGlobalStateChanged( - final Core core, final GlobalState state, final String message) { - Log.i("New global state [", state, "]"); - if (state == GlobalState.On) { - try { - initLiblinphone(core); - } catch (IllegalArgumentException iae) { - Log.e( - "[Manager] Global State Changed Illegal Argument Exception: " - + iae); - } - } - } - - @Override - public void onConfiguringStatus( - Core core, ConfiguringState state, String message) { - Log.d( - "[Manager] Remote provisioning status = " - + state.toString() - + " (" - + message - + ")"); - - LinphonePreferences prefs = LinphonePreferences.instance(); - if (state == ConfiguringState.Successful) { - prefs.setPushNotificationEnabled(prefs.isPushNotificationEnabled()); - } - } - @SuppressLint("Wakelock") @Override public void onCallStateChanged( @@ -198,7 +166,7 @@ public class LinphoneManager implements SensorEventListener { final Call call, final State state, final String message) { - Log.i("[Manager] New call state [", state, "]"); + Log.i("[Manager] Call state is [", state, "]"); if (state == State.IncomingReceived && !call.equals(core.getCurrentCall())) { if (call.getReplacedCall() != null) { @@ -429,7 +397,7 @@ public class LinphoneManager implements SensorEventListener { } } - public synchronized void startLibLinphone(boolean isPush) { + public synchronized void startLibLinphone(boolean isPush, CoreListener listener) { try { mCore = Factory.instance() @@ -437,6 +405,7 @@ public class LinphoneManager implements SensorEventListener { mPrefs.getLinphoneDefaultConfig(), mPrefs.getLinphoneFactoryConfig(), mContext); + mCore.addListener(listener); mCore.addListener(mCoreListener); if (isPush) { @@ -466,6 +435,8 @@ public class LinphoneManager implements SensorEventListener { /*use schedule instead of scheduleAtFixedRate to avoid iterate from being call in burst after cpu wake up*/ mTimer = new Timer("Linphone scheduler"); mTimer.schedule(lTask, 0, 20); + + initLiblinphone(mCore); } catch (Exception e) { Log.e(e, "[Manager] Cannot start linphone"); } diff --git a/app/src/main/java/org/linphone/contacts/AsyncContactsLoader.java b/app/src/main/java/org/linphone/contacts/AsyncContactsLoader.java index fe4bbf37e..8ad05b069 100644 --- a/app/src/main/java/org/linphone/contacts/AsyncContactsLoader.java +++ b/app/src/main/java/org/linphone/contacts/AsyncContactsLoader.java @@ -79,21 +79,6 @@ class AsyncContactsLoader extends AsyncTask androidContactsCache = new HashMap<>(); AsyncContactsData data = new AsyncContactsData(); List nativeIds = new ArrayList<>(); @@ -110,9 +95,12 @@ class AsyncContactsLoader extends AsyncTask contacts = androidContactsCache.values(); - Log.i("[Contacts Manager] Found " + contacts.size() + " contacts"); + // New friends count will be 0 after the first contacts fetch + Log.i( + "[Contacts Manager] Found " + + contacts.size() + + " native contacts plus " + + data.contacts.size() + + " new friends in the configuration file"); for (LinphoneContact contact : contacts) { if (isCancelled()) { Log.w("[Contacts Manager] Task cancelled"); diff --git a/app/src/main/java/org/linphone/contacts/ContactsManager.java b/app/src/main/java/org/linphone/contacts/ContactsManager.java index 82f9c890e..b3e18269a 100644 --- a/app/src/main/java/org/linphone/contacts/ContactsManager.java +++ b/app/src/main/java/org/linphone/contacts/ContactsManager.java @@ -55,7 +55,8 @@ import org.linphone.core.ProxyConfig; import org.linphone.core.tools.Log; import org.linphone.settings.LinphonePreferences; -public class ContactsManager extends ContentObserver implements FriendListListener { +public class ContactsManager extends ContentObserver + implements FriendListListener, LinphoneContext.CoreStartedListener { private List mContacts, mSipContacts; private final ArrayList mContactsUpdatedListeners; private MagicSearch mMagicSearch; @@ -79,6 +80,8 @@ public class ContactsManager extends ContentObserver implements FriendListListen mMagicSearch = LinphoneManager.getCore().createMagicSearch(); mMagicSearch.setLimitedSearch(false); // Do not limit the number of results } + + LinphoneContext.instance().addCoreStartedListener(this); } public void addContactsListener(ContactsUpdatedListener listener) { @@ -104,6 +107,13 @@ public class ContactsManager extends ContentObserver implements FriendListListen fetchContactsAsync(); } + @Override + public void onCoreStarted() { + // Core has been started, fetch contacts again in case there are some + // in the configuration file or remote provisioning + fetchContactsAsync(); + } + public synchronized List getContacts() { return mContacts; } @@ -122,6 +132,7 @@ public class ContactsManager extends ContentObserver implements FriendListListen public void destroy() { mContext.getContentResolver().unregisterContentObserver(this); + LinphoneContext.instance().removeCoreStartedListener(this); if (mLoadContactTask != null) { mLoadContactTask.cancel(true); @@ -149,10 +160,12 @@ public class ContactsManager extends ContentObserver implements FriendListListen if (mLoadContactTask != null) { mLoadContactTask.cancel(true); } + if (!hasReadContactsAccess()) { - Log.w("[Contacts Manager] Can't fetch contact without READ permission"); - return; + Log.w( + "[Contacts Manager] Can't fetch native contacts without READ_CONTACTS permission"); } + mLoadContactTask = new AsyncContactsLoader(mContext); mContactsFetchedOnce = true; mLoadContactTask.executeOnExecutor(THREAD_POOL_EXECUTOR); @@ -264,10 +277,6 @@ public class ContactsManager extends ContentObserver implements FriendListListen } } } - - if (mContext != null && getContacts().isEmpty() && hasReadContactsAccess()) { - fetchContactsAsync(); - } } private void makeContactAccountVisible() { diff --git a/app/src/main/java/org/linphone/history/HistoryFragment.java b/app/src/main/java/org/linphone/history/HistoryFragment.java index 6c86c3492..ea73d2054 100644 --- a/app/src/main/java/org/linphone/history/HistoryFragment.java +++ b/app/src/main/java/org/linphone/history/HistoryFragment.java @@ -35,6 +35,7 @@ import androidx.recyclerview.widget.RecyclerView; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import org.linphone.LinphoneContext; import org.linphone.LinphoneManager; import org.linphone.R; import org.linphone.contacts.ContactsManager; @@ -51,7 +52,8 @@ public class HistoryFragment extends Fragment OnItemClickListener, HistoryViewHolder.ClickListener, ContactsUpdatedListener, - SelectableHelper.DeleteListener { + SelectableHelper.DeleteListener, + LinphoneContext.CoreStartedListener { private RecyclerView mHistoryList; private TextView mNoCallHistory, mNoMissedCallHistory; private ImageView mMissedCalls, mAllCalls; @@ -101,19 +103,16 @@ public class HistoryFragment extends Fragment public void onResume() { super.onResume(); ContactsManager.getInstance().addContactsListener(this); + LinphoneContext.instance().addCoreStartedListener(this); - mLogs = Arrays.asList(LinphoneManager.getCore().getCallLogs()); - hideHistoryListAndDisplayMessageIfEmpty(); - mHistoryAdapter = - new HistoryAdapter((HistoryActivity) getActivity(), mLogs, this, mSelectionHelper); - mHistoryList.setAdapter(mHistoryAdapter); - mSelectionHelper.setAdapter(mHistoryAdapter); - mSelectionHelper.setDialogMessage(R.string.call_log_delete_dialog); + reloadData(); } @Override public void onPause() { ContactsManager.getInstance().removeContactsListener(this); + LinphoneContext.instance().removeCoreStartedListener(this); + super.onPause(); } @@ -125,6 +124,11 @@ public class HistoryFragment extends Fragment } } + @Override + public void onCoreStarted() { + reloadData(); + } + @Override public void onClick(View v) { int id = v.getId(); @@ -218,6 +222,16 @@ public class HistoryFragment extends Fragment } } + private void reloadData() { + mLogs = Arrays.asList(LinphoneManager.getCore().getCallLogs()); + hideHistoryListAndDisplayMessageIfEmpty(); + mHistoryAdapter = + new HistoryAdapter((HistoryActivity) getActivity(), mLogs, this, mSelectionHelper); + mHistoryList.setAdapter(mHistoryAdapter); + mSelectionHelper.setAdapter(mHistoryAdapter); + mSelectionHelper.setDialogMessage(R.string.call_log_delete_dialog); + } + private void removeNotMissedCallsFromLogs() { if (mOnlyDisplayMissedCalls) { List missedCalls = new ArrayList<>(); From 8226b53a2d37a69b9b97faedf53df1eaa5ce323c Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 15 Nov 2019 13:30:05 +0100 Subject: [PATCH 30/84] Move some things from MainActivity to LinphoneContext to prevent log pollution --- .../java/org/linphone/LinphoneContext.java | 19 +++++++++++++++++++ .../org/linphone/activities/MainActivity.java | 18 ------------------ 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/org/linphone/LinphoneContext.java b/app/src/main/java/org/linphone/LinphoneContext.java index c02c81a4d..eafd8299b 100644 --- a/app/src/main/java/org/linphone/LinphoneContext.java +++ b/app/src/main/java/org/linphone/LinphoneContext.java @@ -45,7 +45,9 @@ import org.linphone.core.tools.Log; import org.linphone.mediastream.Version; import org.linphone.notifications.NotificationsManager; import org.linphone.settings.LinphonePreferences; +import org.linphone.utils.DeviceUtils; import org.linphone.utils.LinphoneUtils; +import org.linphone.utils.PushNotificationUtils; public class LinphoneContext { private static LinphoneContext sInstance = null; @@ -188,6 +190,23 @@ public class LinphoneContext { mLinphoneManager = new LinphoneManager(context); mNotificationManager = new NotificationsManager(context); + + if (DeviceUtils.isAppUserRestricted(mContext)) { + // See https://firebase.google.com/docs/cloud-messaging/android/receive#restricted + Log.w( + "[Main Activity] Device has been restricted by user (Android 9+), push notifications won't work !"); + } + + int bucket = DeviceUtils.getAppStandbyBucket(mContext); + if (bucket > 0) { + Log.w( + "[Main Activity] Device is in bucket " + + Compatibility.getAppStandbyBucketNameFromValue(bucket)); + } + + if (!PushNotificationUtils.isAvailable(mContext)) { + Log.w("[Main Activity] Push notifications won't work !"); + } } public void start(boolean isPush) { diff --git a/app/src/main/java/org/linphone/activities/MainActivity.java b/app/src/main/java/org/linphone/activities/MainActivity.java index 15e9f5d35..0733202b1 100644 --- a/app/src/main/java/org/linphone/activities/MainActivity.java +++ b/app/src/main/java/org/linphone/activities/MainActivity.java @@ -73,7 +73,6 @@ import org.linphone.settings.LinphonePreferences; import org.linphone.settings.SettingsActivity; import org.linphone.utils.DeviceUtils; import org.linphone.utils.LinphoneUtils; -import org.linphone.utils.PushNotificationUtils; public abstract class MainActivity extends LinphoneGenericActivity implements StatusBarFragment.MenuClikedListener, SideMenuFragment.QuitClikedListener { @@ -275,23 +274,6 @@ public abstract class MainActivity extends LinphoneGenericActivity super.onStart(); requestRequiredPermissions(); - - if (DeviceUtils.isAppUserRestricted(this)) { - // See https://firebase.google.com/docs/cloud-messaging/android/receive#restricted - Log.w( - "[Main Activity] Device has been restricted by user (Android 9+), push notifications won't work !"); - } - - int bucket = DeviceUtils.getAppStandbyBucket(this); - if (bucket > 0) { - Log.w( - "[Main Activity] Device is in bucket " - + Compatibility.getAppStandbyBucketNameFromValue(bucket)); - } - - if (!PushNotificationUtils.isAvailable(this)) { - Log.w("[Main Activity] Push notifications won't work !"); - } } @Override From 1db05c01786bbdefe48169ea97da28f532822809 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 15 Nov 2019 13:55:17 +0100 Subject: [PATCH 31/84] Bumped version code --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 519c2103a..e40a82bd2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -88,7 +88,7 @@ android { defaultConfig { minSdkVersion 21 targetSdkVersion 29 - versionCode 4200 + versionCode 4201 versionName "${project.version}" applicationId getPackageName() multiDexEnabled true From 1cd6da3eea887ada5e8cb35ddc16b0cd795b2c59 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 18 Nov 2019 12:19:32 +0100 Subject: [PATCH 32/84] Account creator changes --- .../java/org/linphone/LinphoneManager.java | 23 +++-- .../AccountConnectionAssistantActivity.java | 27 +++--- .../linphone/assistant/AssistantActivity.java | 84 +++++++++---------- ...EmailAccountCreationAssistantActivity.java | 25 +++--- ...ailAccountValidationAssistantActivity.java | 8 +- .../GenericConnectionAssistantActivity.java | 22 ++--- ...PhoneAccountCreationAssistantActivity.java | 27 +++--- .../PhoneAccountLinkingAssistantActivity.java | 24 +++--- ...oneAccountValidationAssistantActivity.java | 15 ++-- app/src/main/res/values-fr/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + 11 files changed, 141 insertions(+), 116 deletions(-) diff --git a/app/src/main/java/org/linphone/LinphoneManager.java b/app/src/main/java/org/linphone/LinphoneManager.java index fcbc0c57e..7a6a14731 100644 --- a/app/src/main/java/org/linphone/LinphoneManager.java +++ b/app/src/main/java/org/linphone/LinphoneManager.java @@ -436,7 +436,7 @@ public class LinphoneManager implements SensorEventListener { mTimer = new Timer("Linphone scheduler"); mTimer.schedule(lTask, 0, 20); - initLiblinphone(mCore); + initLiblinphone(); } catch (Exception e) { Log.e(e, "[Manager] Cannot start linphone"); } @@ -445,8 +445,7 @@ public class LinphoneManager implements SensorEventListener { H264Helper.setH264Mode(H264Helper.MODE_AUTO, mCore); } - private synchronized void initLiblinphone(Core core) { - mCore = core; + private synchronized void initLiblinphone() { mAudioManager = new AndroidAudioManager(mContext); mCore.setZrtpSecretsFile(mBasePath + "/zrtp_secrets"); @@ -543,16 +542,28 @@ public class LinphoneManager implements SensorEventListener { /* Account linking */ + public AccountCreator getAccountCreator() { + if (mAccountCreator == null) { + Log.w("[Manager] Account creator shouldn't be null !"); + mAccountCreator = + mCore.createAccountCreator(LinphonePreferences.instance().getXmlrpcUrl()); + mAccountCreator.setListener(mAccountCreatorListener); + } + return mAccountCreator; + } + public void isAccountWithAlias() { if (mCore.getDefaultProxyConfig() != null) { long now = new Timestamp(new Date().getTime()).getTime(); - if (mAccountCreator != null && LinphonePreferences.instance().getLinkPopupTime() == null + AccountCreator accountCreator = getAccountCreator(); + if (LinphonePreferences.instance().getLinkPopupTime() == null || Long.parseLong(LinphonePreferences.instance().getLinkPopupTime()) < now) { - mAccountCreator.setUsername( + accountCreator.reset(); + accountCreator.setUsername( LinphonePreferences.instance() .getAccountUsername( LinphonePreferences.instance().getDefaultAccountIndex())); - mAccountCreator.isAccountExist(); + accountCreator.isAccountExist(); } } else { LinphonePreferences.instance().setLinkPopupTime(null); diff --git a/app/src/main/java/org/linphone/assistant/AccountConnectionAssistantActivity.java b/app/src/main/java/org/linphone/assistant/AccountConnectionAssistantActivity.java index 7e4ed53f0..32fa92154 100644 --- a/app/src/main/java/org/linphone/assistant/AccountConnectionAssistantActivity.java +++ b/app/src/main/java/org/linphone/assistant/AccountConnectionAssistantActivity.java @@ -72,17 +72,22 @@ public class AccountConnectionAssistantActivity extends AssistantActivity { new View.OnClickListener() { @Override public void onClick(View v) { + AccountCreator accountCreator = getAccountCreator(); + accountCreator.reset(); mConnect.setEnabled(false); if (mUsernameConnectionSwitch.isChecked()) { - mAccountCreator.setUsername(mUsername.getText().toString()); - mAccountCreator.setPassword(mPassword.getText().toString()); + accountCreator.setUsername(mUsername.getText().toString()); + accountCreator.setPassword(mPassword.getText().toString()); createProxyConfigAndLeaveAssistant(); } else { - mAccountCreator.setUsername(mPhoneNumber.getText().toString()); + accountCreator.setPhoneNumber( + mPhoneNumber.getText().toString(), + mPrefix.getText().toString()); + accountCreator.setUsername(accountCreator.getPhoneNumber()); - AccountCreator.Status status = mAccountCreator.recoverAccount(); + AccountCreator.Status status = accountCreator.recoverAccount(); if (status != AccountCreator.Status.RequestOk) { Log.e( "[Account Connection Assistant] recoverAccount returned " @@ -221,18 +226,18 @@ public class AccountConnectionAssistantActivity extends AssistantActivity { } } }; - - Core core = LinphoneManager.getCore(); - if (core != null) { - reloadLinphoneAccountCreatorConfig(); - } } @Override protected void onResume() { super.onResume(); - mAccountCreator.addListener(mListener); + Core core = LinphoneManager.getCore(); + if (core != null) { + reloadLinphoneAccountCreatorConfig(); + } + + getAccountCreator().addListener(mListener); DialPlan dp = getDialPlanForCurrentCountry(); displayDialPlan(dp); @@ -246,7 +251,7 @@ public class AccountConnectionAssistantActivity extends AssistantActivity { @Override protected void onPause() { super.onPause(); - mAccountCreator.removeListener(mListener); + getAccountCreator().removeListener(mListener); } @Override diff --git a/app/src/main/java/org/linphone/assistant/AssistantActivity.java b/app/src/main/java/org/linphone/assistant/AssistantActivity.java index 58852270e..32218c6f5 100644 --- a/app/src/main/java/org/linphone/assistant/AssistantActivity.java +++ b/app/src/main/java/org/linphone/assistant/AssistantActivity.java @@ -21,19 +21,18 @@ package org.linphone.assistant; import android.app.AlertDialog; import android.content.Intent; -import android.os.Bundle; import android.telephony.TelephonyManager; import android.view.View; import android.view.WindowManager; import android.widget.EditText; import android.widget.ImageView; +import java.util.Locale; import org.linphone.LinphoneContext; import org.linphone.LinphoneManager; import org.linphone.R; import org.linphone.activities.DialerActivity; import org.linphone.activities.LinphoneGenericActivity; import org.linphone.core.AccountCreator; -import org.linphone.core.Config; import org.linphone.core.Core; import org.linphone.core.DialPlan; import org.linphone.core.Factory; @@ -43,25 +42,11 @@ import org.linphone.settings.LinphonePreferences; public abstract class AssistantActivity extends LinphoneGenericActivity implements CountryPicker.CountryPickedListener { - static AccountCreator mAccountCreator; - protected ImageView mBack; private AlertDialog mCountryPickerDialog; private CountryPicker mCountryPicker; - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - if (mAccountCreator == null) { - String url = LinphonePreferences.instance().getXmlrpcUrl(); - Core core = LinphoneManager.getCore(); - core.loadConfigFromXml(LinphonePreferences.instance().getDefaultDynamicConfigFile()); - mAccountCreator = core.createAccountCreator(url); - } - } - @Override protected void onResume() { super.onResume(); @@ -105,18 +90,17 @@ public abstract class AssistantActivity extends LinphoneGenericActivity } } + public AccountCreator getAccountCreator() { + return LinphoneManager.getInstance().getAccountCreator(); + } + private void reloadAccountCreatorConfig(String path) { Core core = LinphoneManager.getCore(); if (core != null) { core.loadConfigFromXml(path); - if (mAccountCreator != null) { - // Below two settings are applied to account creator when it is built. - // Reloading Core config after won't change the account creator configuration, - // hence the manual reload - Config config = LinphonePreferences.instance().getConfig(); - mAccountCreator.setDomain(config.getString("assistant", "domain", null)); - mAccountCreator.setAlgorithm(config.getString("assistant", "algorithm", null)); - } + AccountCreator accountCreator = getAccountCreator(); + accountCreator.reset(); + accountCreator.setLanguage(Locale.getDefault().getLanguage()); } } @@ -131,28 +115,41 @@ public abstract class AssistantActivity extends LinphoneGenericActivity } void createProxyConfigAndLeaveAssistant() { + createProxyConfigAndLeaveAssistant(false); + } + + void createProxyConfigAndLeaveAssistant(boolean isGenericAccount) { Core core = LinphoneManager.getCore(); boolean useLinphoneDefaultValues = - getString(R.string.default_domain).equals(mAccountCreator.getDomain()); - if (useLinphoneDefaultValues) { - Log.i("[Assistant] Default domain found, reloading configuration"); - core.loadConfigFromXml(LinphonePreferences.instance().getLinphoneDynamicConfigFile()); - } else { - Log.i("[Assistant] Third party domain found, keeping default values"); + getString(R.string.default_domain).equals(getAccountCreator().getDomain()); + + if (isGenericAccount) { + if (useLinphoneDefaultValues) { + Log.i( + "[Assistant] Default domain found for generic connection, reloading configuration"); + core.loadConfigFromXml( + LinphonePreferences.instance().getLinphoneDynamicConfigFile()); + } else { + Log.i("[Assistant] Third party domain found, keeping default values"); + } } - ProxyConfig proxyConfig = mAccountCreator.createProxyConfig(); + ProxyConfig proxyConfig = getAccountCreator().createProxyConfig(); - if (useLinphoneDefaultValues) { - // Restore default values - Log.i("[Assistant] Restoring default assistant configuration"); - core.loadConfigFromXml(LinphonePreferences.instance().getDefaultDynamicConfigFile()); - } else { - // If this isn't a sip.linphone.org account, disable push notifications and enable - // service notification, otherwise incoming calls won't work (most probably) - Log.w("[Assistant] Unknown domain used, push probably won't work, enable service mode"); - LinphonePreferences.instance().setServiceNotificationVisibility(true); - LinphoneContext.instance().getNotificationManager().startForeground(); + if (isGenericAccount) { + if (useLinphoneDefaultValues) { + // Restore default values + Log.i("[Assistant] Restoring default assistant configuration"); + core.loadConfigFromXml( + LinphonePreferences.instance().getDefaultDynamicConfigFile()); + } else { + // If this isn't a sip.linphone.org account, disable push notifications and enable + // service notification, otherwise incoming calls won't work (most probably) + Log.w( + "[Assistant] Unknown domain used, push probably won't work, enable service mode"); + LinphonePreferences.instance().setServiceNotificationVisibility(true); + LinphoneContext.instance().getNotificationManager().startForeground(); + } } if (proxyConfig == null) { @@ -237,6 +234,9 @@ public abstract class AssistantActivity extends LinphoneGenericActivity case PhoneNumberOverused: message = getString(R.string.phone_number_overuse); break; + case AccountNotExist: + message = getString(R.string.account_doesnt_exist); + break; default: message = getString(R.string.error_unknown); break; @@ -302,7 +302,7 @@ public abstract class AssistantActivity extends LinphoneGenericActivity } String phoneNumber = phoneNumberEditText.getText().toString(); - return mAccountCreator.setPhoneNumber(phoneNumber, prefix); + return getAccountCreator().setPhoneNumber(phoneNumber, prefix); } String getErrorFromPhoneNumberStatus(int status) { diff --git a/app/src/main/java/org/linphone/assistant/EmailAccountCreationAssistantActivity.java b/app/src/main/java/org/linphone/assistant/EmailAccountCreationAssistantActivity.java index dc11d3fb0..91f5b4649 100644 --- a/app/src/main/java/org/linphone/assistant/EmailAccountCreationAssistantActivity.java +++ b/app/src/main/java/org/linphone/assistant/EmailAccountCreationAssistantActivity.java @@ -67,7 +67,7 @@ public class EmailAccountCreationAssistantActivity extends AssistantActivity { @Override public void afterTextChanged(Editable s) { AccountCreator.UsernameStatus status = - mAccountCreator.setUsername(s.toString()); + getAccountCreator().setUsername(s.toString()); mUsernameError.setVisibility( status == AccountCreator.UsernameStatus.Ok ? View.INVISIBLE @@ -90,7 +90,7 @@ public class EmailAccountCreationAssistantActivity extends AssistantActivity { @Override public void afterTextChanged(Editable s) { AccountCreator.PasswordStatus status = - mAccountCreator.setPassword(s.toString()); + getAccountCreator().setPassword(s.toString()); mPasswordError.setVisibility( status == AccountCreator.PasswordStatus.Ok ? View.INVISIBLE @@ -148,7 +148,8 @@ public class EmailAccountCreationAssistantActivity extends AssistantActivity { @Override public void afterTextChanged(Editable s) { - AccountCreator.EmailStatus status = mAccountCreator.setEmail(s.toString()); + AccountCreator.EmailStatus status = + getAccountCreator().setEmail(s.toString()); mEmailError.setVisibility( status == AccountCreator.EmailStatus.Ok ? View.INVISIBLE @@ -164,7 +165,7 @@ public class EmailAccountCreationAssistantActivity extends AssistantActivity { public void onClick(View v) { enableButtonsAndFields(false); - AccountCreator.Status status = mAccountCreator.isAccountExist(); + AccountCreator.Status status = getAccountCreator().isAccountExist(); if (status != AccountCreator.Status.RequestOk) { enableButtonsAndFields(true); Log.e( @@ -188,7 +189,7 @@ public class EmailAccountCreationAssistantActivity extends AssistantActivity { showAccountAlreadyExistsDialog(); enableButtonsAndFields(true); } else if (status.equals(AccountCreator.Status.AccountNotExist)) { - status = mAccountCreator.createAccount(); + status = getAccountCreator().createAccount(); if (status != AccountCreator.Status.RequestOk) { Log.e( "[Email Account Creation Assistant] createAccount returned " @@ -219,11 +220,6 @@ public class EmailAccountCreationAssistantActivity extends AssistantActivity { } } }; - - Core core = LinphoneManager.getCore(); - if (core != null) { - reloadLinphoneAccountCreatorConfig(); - } } private void enableButtonsAndFields(boolean enable) { @@ -249,7 +245,12 @@ public class EmailAccountCreationAssistantActivity extends AssistantActivity { protected void onResume() { super.onResume(); - mAccountCreator.addListener(mListener); + Core core = LinphoneManager.getCore(); + if (core != null) { + reloadLinphoneAccountCreatorConfig(); + } + + getAccountCreator().addListener(mListener); if (getResources().getBoolean(R.bool.pre_fill_email_in_assistant)) { Account[] accounts = AccountManager.get(this).getAccountsByType("com.google"); @@ -266,6 +267,6 @@ public class EmailAccountCreationAssistantActivity extends AssistantActivity { @Override protected void onPause() { super.onPause(); - mAccountCreator.removeListener(mListener); + getAccountCreator().removeListener(mListener); } } diff --git a/app/src/main/java/org/linphone/assistant/EmailAccountValidationAssistantActivity.java b/app/src/main/java/org/linphone/assistant/EmailAccountValidationAssistantActivity.java index 81d08f836..7d38e85d7 100644 --- a/app/src/main/java/org/linphone/assistant/EmailAccountValidationAssistantActivity.java +++ b/app/src/main/java/org/linphone/assistant/EmailAccountValidationAssistantActivity.java @@ -41,7 +41,7 @@ public class EmailAccountValidationAssistantActivity extends AssistantActivity { setContentView(R.layout.assistant_email_account_validation); TextView email = findViewById(R.id.send_email); - email.setText(mAccountCreator.getEmail()); + email.setText(getAccountCreator().getEmail()); mFinishCreation = findViewById(R.id.assistant_check); mFinishCreation.setOnClickListener( @@ -50,7 +50,7 @@ public class EmailAccountValidationAssistantActivity extends AssistantActivity { public void onClick(View v) { mFinishCreation.setEnabled(false); - AccountCreator.Status status = mAccountCreator.isAccountActivated(); + AccountCreator.Status status = getAccountCreator().isAccountActivated(); if (status != AccountCreator.Status.RequestOk) { Log.e( "[Email Account Validation Assistant] activateAccount returned " @@ -89,7 +89,7 @@ public class EmailAccountValidationAssistantActivity extends AssistantActivity { @Override protected void onResume() { super.onResume(); - mAccountCreator.addListener(mListener); + getAccountCreator().addListener(mListener); // Prevent user to go back, it won't be able to come back here after... mBack.setEnabled(false); @@ -98,6 +98,6 @@ public class EmailAccountValidationAssistantActivity extends AssistantActivity { @Override protected void onPause() { super.onPause(); - mAccountCreator.removeListener(mListener); + getAccountCreator().removeListener(mListener); } } diff --git a/app/src/main/java/org/linphone/assistant/GenericConnectionAssistantActivity.java b/app/src/main/java/org/linphone/assistant/GenericConnectionAssistantActivity.java index 3c029e3f1..9ecc21b68 100644 --- a/app/src/main/java/org/linphone/assistant/GenericConnectionAssistantActivity.java +++ b/app/src/main/java/org/linphone/assistant/GenericConnectionAssistantActivity.java @@ -29,6 +29,7 @@ import android.widget.TextView; import androidx.annotation.Nullable; import org.linphone.LinphoneManager; import org.linphone.R; +import org.linphone.core.AccountCreator; import org.linphone.core.Core; import org.linphone.core.TransportType; import org.linphone.core.tools.Log; @@ -63,33 +64,34 @@ public class GenericConnectionAssistantActivity extends AssistantActivity implem mDomain = findViewById(R.id.assistant_domain); mDomain.addTextChangedListener(this); mTransport = findViewById(R.id.assistant_transports); + } + private void configureAccount() { Core core = LinphoneManager.getCore(); if (core != null) { Log.i("[Generic Connection Assistant] Reloading configuration with default"); reloadDefaultAccountCreatorConfig(); } - } - private void configureAccount() { - mAccountCreator.setUsername(mUsername.getText().toString()); - mAccountCreator.setDomain(mDomain.getText().toString()); - mAccountCreator.setPassword(mPassword.getText().toString()); - mAccountCreator.setDisplayName(mDisplayName.getText().toString()); + AccountCreator accountCreator = getAccountCreator(); + accountCreator.setUsername(mUsername.getText().toString()); + accountCreator.setDomain(mDomain.getText().toString()); + accountCreator.setPassword(mPassword.getText().toString()); + accountCreator.setDisplayName(mDisplayName.getText().toString()); switch (mTransport.getCheckedRadioButtonId()) { case R.id.transport_udp: - mAccountCreator.setTransport(TransportType.Udp); + accountCreator.setTransport(TransportType.Udp); break; case R.id.transport_tcp: - mAccountCreator.setTransport(TransportType.Tcp); + accountCreator.setTransport(TransportType.Tcp); break; case R.id.transport_tls: - mAccountCreator.setTransport(TransportType.Tls); + accountCreator.setTransport(TransportType.Tls); break; } - createProxyConfigAndLeaveAssistant(); + createProxyConfigAndLeaveAssistant(true); } @Override diff --git a/app/src/main/java/org/linphone/assistant/PhoneAccountCreationAssistantActivity.java b/app/src/main/java/org/linphone/assistant/PhoneAccountCreationAssistantActivity.java index 424b934a0..90b600672 100644 --- a/app/src/main/java/org/linphone/assistant/PhoneAccountCreationAssistantActivity.java +++ b/app/src/main/java/org/linphone/assistant/PhoneAccountCreationAssistantActivity.java @@ -69,15 +69,16 @@ public class PhoneAccountCreationAssistantActivity extends AssistantActivity { new View.OnClickListener() { @Override public void onClick(View v) { + AccountCreator accountCreator = getAccountCreator(); enableButtonsAndFields(false); if (mUseUsernameInsteadOfPhoneNumber.isChecked()) { - mAccountCreator.setUsername(mUsername.getText().toString()); + accountCreator.setUsername(mUsername.getText().toString()); } else { - mAccountCreator.setUsername(mAccountCreator.getPhoneNumber()); + accountCreator.setUsername(accountCreator.getPhoneNumber()); } - AccountCreator.Status status = mAccountCreator.isAccountExist(); + AccountCreator.Status status = accountCreator.isAccountExist(); if (status != AccountCreator.Status.RequestOk) { Log.e( "[Phone Account Creation Assistant] isAccountExists returned " @@ -178,7 +179,7 @@ public class PhoneAccountCreationAssistantActivity extends AssistantActivity { showAccountAlreadyExistsDialog(); enableButtonsAndFields(true); } else if (status.equals(AccountCreator.Status.AccountNotExist)) { - status = mAccountCreator.createAccount(); + status = getAccountCreator().createAccount(); if (status != AccountCreator.Status.RequestOk) { Log.e( "[Phone Account Creation Assistant] createAccount returned " @@ -209,18 +210,18 @@ public class PhoneAccountCreationAssistantActivity extends AssistantActivity { } } }; - - Core core = LinphoneManager.getCore(); - if (core != null) { - reloadLinphoneAccountCreatorConfig(); - } } @Override protected void onResume() { super.onResume(); - mAccountCreator.addListener(mListener); + Core core = LinphoneManager.getCore(); + if (core != null) { + reloadLinphoneAccountCreatorConfig(); + } + + getAccountCreator().addListener(mListener); DialPlan dp = getDialPlanForCurrentCountry(); displayDialPlan(dp); @@ -234,7 +235,7 @@ public class PhoneAccountCreationAssistantActivity extends AssistantActivity { @Override protected void onPause() { super.onPause(); - mAccountCreator.removeListener(mListener); + getAccountCreator().removeListener(mListener); } @Override @@ -261,7 +262,7 @@ public class PhoneAccountCreationAssistantActivity extends AssistantActivity { if (status == AccountCreator.PhoneNumberStatus.Ok.toInt()) { if (mUseUsernameInsteadOfPhoneNumber.isChecked()) { AccountCreator.UsernameStatus usernameStatus = - mAccountCreator.setUsername(mUsername.getText().toString()); + getAccountCreator().setUsername(mUsername.getText().toString()); if (usernameStatus != AccountCreator.UsernameStatus.Ok) { mCreate.setEnabled(false); mError.setText(getErrorFromUsernameStatus(usernameStatus)); @@ -278,7 +279,7 @@ public class PhoneAccountCreationAssistantActivity extends AssistantActivity { if (mUseUsernameInsteadOfPhoneNumber.isChecked()) { username = mUsername.getText().toString(); } else { - username = mAccountCreator.getPhoneNumber(); + username = getAccountCreator().getPhoneNumber(); } if (username != null) { diff --git a/app/src/main/java/org/linphone/assistant/PhoneAccountLinkingAssistantActivity.java b/app/src/main/java/org/linphone/assistant/PhoneAccountLinkingAssistantActivity.java index 02f23f189..29aac4daa 100644 --- a/app/src/main/java/org/linphone/assistant/PhoneAccountLinkingAssistantActivity.java +++ b/app/src/main/java/org/linphone/assistant/PhoneAccountLinkingAssistantActivity.java @@ -63,6 +63,7 @@ public class PhoneAccountLinkingAssistantActivity extends AssistantActivity { ProxyConfig[] proxyConfigs = core.getProxyConfigList(); if (proxyConfigIndex >= 0 && proxyConfigIndex < proxyConfigs.length) { ProxyConfig mProxyConfig = proxyConfigs[proxyConfigIndex]; + AccountCreator accountCreator = getAccountCreator(); Address identity = mProxyConfig.getIdentityAddress(); if (identity == null) { @@ -75,14 +76,15 @@ public class PhoneAccountLinkingAssistantActivity extends AssistantActivity { + mProxyConfig.getDomain()); unexpectedError(); } - mAccountCreator.setUsername(identity.getUsername()); + accountCreator.setUsername(identity.getUsername()); AuthInfo authInfo = mProxyConfig.findAuthInfo(); if (authInfo == null) { Log.e("[Account Linking Assistant] Auth info not found"); unexpectedError(); } - mAccountCreator.setHa1(authInfo.getHa1()); + accountCreator.setHa1(authInfo.getHa1()); + accountCreator.setAlgorithm((authInfo.getAlgorithm())); } else { Log.e( "[Account Linking Assistant] Proxy config index out of bounds: " @@ -112,7 +114,7 @@ public class PhoneAccountLinkingAssistantActivity extends AssistantActivity { public void onClick(View v) { enableButtonsAndFields(false); - AccountCreator.Status status = mAccountCreator.isAliasUsed(); + AccountCreator.Status status = getAccountCreator().isAliasUsed(); if (status != AccountCreator.Status.RequestOk) { Log.e( "[Phone Account Linking Assistant] isAliasUsed returned " @@ -184,7 +186,7 @@ public class PhoneAccountLinkingAssistantActivity extends AssistantActivity { "[Phone Account Linking Assistant] onIsAliasUsed status is " + status); if (status.equals(AccountCreator.Status.AliasNotExist)) { - status = mAccountCreator.linkAccount(); + status = getAccountCreator().linkAccount(); if (status != AccountCreator.Status.RequestOk) { Log.e( "[Phone Account Linking Assistant] linkAccount returned " @@ -222,18 +224,18 @@ public class PhoneAccountLinkingAssistantActivity extends AssistantActivity { } } }; - - Core core = LinphoneManager.getCore(); - if (core != null) { - reloadLinphoneAccountCreatorConfig(); - } } @Override protected void onResume() { super.onResume(); - mAccountCreator.addListener(mListener); + Core core = LinphoneManager.getCore(); + if (core != null) { + reloadLinphoneAccountCreatorConfig(); + } + + getAccountCreator().addListener(mListener); DialPlan dp = getDialPlanForCurrentCountry(); displayDialPlan(dp); @@ -247,7 +249,7 @@ public class PhoneAccountLinkingAssistantActivity extends AssistantActivity { @Override protected void onPause() { super.onPause(); - mAccountCreator.removeListener(mListener); + getAccountCreator().removeListener(mListener); } @Override diff --git a/app/src/main/java/org/linphone/assistant/PhoneAccountValidationAssistantActivity.java b/app/src/main/java/org/linphone/assistant/PhoneAccountValidationAssistantActivity.java index aa54e7e93..857efd36c 100644 --- a/app/src/main/java/org/linphone/assistant/PhoneAccountValidationAssistantActivity.java +++ b/app/src/main/java/org/linphone/assistant/PhoneAccountValidationAssistantActivity.java @@ -64,7 +64,7 @@ public class PhoneAccountValidationAssistantActivity extends AssistantActivity { getResources().getInteger(R.integer.phone_number_validation_code_length); TextView phoneNumber = findViewById(R.id.phone_number); - phoneNumber.setText(mAccountCreator.getPhoneNumber()); + phoneNumber.setText(getAccountCreator().getPhoneNumber()); mSmsCode = findViewById(R.id.sms_code); mSmsCode.addTextChangedListener( @@ -88,16 +88,17 @@ public class PhoneAccountValidationAssistantActivity extends AssistantActivity { new View.OnClickListener() { @Override public void onClick(View v) { + AccountCreator accountCreator = getAccountCreator(); mFinishCreation.setEnabled(false); - mAccountCreator.setActivationCode(mSmsCode.getText().toString()); + accountCreator.setActivationCode(mSmsCode.getText().toString()); AccountCreator.Status status; if (mIsLinking) { - status = mAccountCreator.activateAlias(); + status = accountCreator.activateAlias(); } else if (mIsLogin) { - status = mAccountCreator.loginLinphoneAccount(); + status = accountCreator.loginLinphoneAccount(); } else { - status = mAccountCreator.activateAccount(); + status = accountCreator.activateAccount(); } if (status != AccountCreator.Status.RequestOk) { Log.e( @@ -173,7 +174,7 @@ public class PhoneAccountValidationAssistantActivity extends AssistantActivity { @Override protected void onResume() { super.onResume(); - mAccountCreator.addListener(mListener); + getAccountCreator().addListener(mListener); // Prevent user to go back, it won't be able to come back here after... mBack.setEnabled(false); @@ -182,7 +183,7 @@ public class PhoneAccountValidationAssistantActivity extends AssistantActivity { @Override protected void onPause() { super.onPause(); - mAccountCreator.removeListener(mListener); + getAccountCreator().removeListener(mListener); } private void onError(AccountCreator.Status status) { diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 4083d2aee..a0d4b1306 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -130,6 +130,7 @@ Vos amis pourront vous joindre plus facilement si vous associez votre compte à votre numéro de téléphone\n\nVous verrez dans votre carnet d\'adresses les contacts qui utilisent Linphone et vos amis sauront qu\'ils peuvent vous contacter.\n Vous ne pouvez associer votre numéro qu\'à un seul compte Linphone.\n\nSi vous avez déjà associé votre numéro à un autre compte mais préférez utiliser ce compte-ci, suivez la procédure d\'association et votre numéro sera automatiquement transféré à ce compte. Trop de SMS ont été envoyés vers ce numéro en un court laps de temps, veuillez attendre 24h avant de réessayer. + Ce compte n\'existe pas Mail non valide Ce compte existe déjà diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 169f146b4..ebd054773 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -134,6 +134,7 @@ \nYour friends will find you more easily if you link your account to your phone number\n\nYou will see in your address book who is using Linphone and your friends will know that they can reach you on Linphone as well.\n You can only use your phone number with one Linphone account.\n\nIf you had already linked your number to an other account but you prefer to use this one, simply link it now and your number will automatically be moved to this account. Too much SMS have been sent to this number in a short period of time, try again in 24 hours. + Account doesn\'t exist Invalid email From 98add9b2735c8c35a3e04c9e465c16c53cf9595e Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 18 Nov 2019 16:28:19 +0100 Subject: [PATCH 33/84] Bumped version code --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index e40a82bd2..bc255dd5b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -88,7 +88,7 @@ android { defaultConfig { minSdkVersion 21 targetSdkVersion 29 - versionCode 4201 + versionCode 4204 versionName "${project.version}" applicationId getPackageName() multiDexEnabled true From 2e89062239384246143a9af409accbff697e5c9d Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 19 Nov 2019 09:30:49 +0100 Subject: [PATCH 34/84] Updated Russian translation --- app/src/main/res/values-ru/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 7bc8e371a..16937ef3c 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -129,6 +129,7 @@ \nВашим друзьям будет проще связаться с вами, если вы свяжете свой аккаунт со своим номером телефона.\n\nВ вашей адресной книге вы увидите, кто использует Linphone, а ваши друзья смогут узнать, что вы также зарегистрированы в Linphone.\n Номер телефона можно использовать только с одним аккаунтом Linphone.\n\nЕсли ваш номер уже был связан с другим аккаунтом, но вы предпочитаете использовать его, просто свяжите его сейчас, и ваш номер будет автоматически перенесен в этот аккаунт. Слишком много SMS было отправлено на этот номер за короткий промежуток времени, повторите попытку через 24 часа. + Аккаунт не существует Недопустимый адрес электронной почты Аккаунт уже существует From 278fd99245cf917e4b6569c72fd576d3fe5c4a30 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 19 Nov 2019 10:00:55 +0100 Subject: [PATCH 35/84] Fixed double avatar on incoming call notification depending on the phone --- .../main/java/org/linphone/compatibility/ApiTwentyFourPlus.java | 1 - .../main/java/org/linphone/compatibility/ApiTwentySixPlus.java | 1 - 2 files changed, 2 deletions(-) diff --git a/app/src/main/java/org/linphone/compatibility/ApiTwentyFourPlus.java b/app/src/main/java/org/linphone/compatibility/ApiTwentyFourPlus.java index 2a2720be3..54a3812d4 100644 --- a/app/src/main/java/org/linphone/compatibility/ApiTwentyFourPlus.java +++ b/app/src/main/java/org/linphone/compatibility/ApiTwentyFourPlus.java @@ -140,7 +140,6 @@ class ApiTwentyFourPlus { return new Notification.Builder(context) .setStyle(new Notification.DecoratedCustomViewStyle()) .setSmallIcon(R.drawable.topbar_call_notification) - .setLargeIcon(contactIcon) .setContentTitle(contactName) .setContentText(context.getString(R.string.incall_notif_incoming)) .setContentIntent(intent) diff --git a/app/src/main/java/org/linphone/compatibility/ApiTwentySixPlus.java b/app/src/main/java/org/linphone/compatibility/ApiTwentySixPlus.java index 270408d3f..03aa2c732 100644 --- a/app/src/main/java/org/linphone/compatibility/ApiTwentySixPlus.java +++ b/app/src/main/java/org/linphone/compatibility/ApiTwentySixPlus.java @@ -191,7 +191,6 @@ class ApiTwentySixPlus { context, context.getString(R.string.notification_channel_id)) .setStyle(new Notification.DecoratedCustomViewStyle()) .setSmallIcon(R.drawable.topbar_call_notification) - .setLargeIcon(contactIcon) .setContentTitle(contactName) .setContentText(context.getString(R.string.incall_notif_incoming)) .setContentIntent(intent) From 383c54f817d45009c08822410e821d17bdc1a913 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 19 Nov 2019 10:10:42 +0100 Subject: [PATCH 36/84] Added some missing null checks --- .../linphone/contacts/LinphoneContact.java | 42 ++++++++++++------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/org/linphone/contacts/LinphoneContact.java b/app/src/main/java/org/linphone/contacts/LinphoneContact.java index f4ed675f5..b8d9ce427 100644 --- a/app/src/main/java/org/linphone/contacts/LinphoneContact.java +++ b/app/src/main/java/org/linphone/contacts/LinphoneContact.java @@ -195,7 +195,7 @@ public class LinphoneContact extends AndroidContact } private void setPhotoUri(Uri uri) { - if (uri.equals(mPhotoUri)) return; + if (uri != null && uri.equals(mPhotoUri)) return; mPhotoUri = uri; } @@ -204,7 +204,7 @@ public class LinphoneContact extends AndroidContact } private void setThumbnailUri(Uri uri) { - if (uri.equals(mThumbnailUri)) return; + if (uri != null && uri.equals(mThumbnailUri)) return; mThumbnailUri = uri; } @@ -216,14 +216,16 @@ public class LinphoneContact extends AndroidContact if (noa == null) return; boolean found = false; + String normalizedPhone = noa.getNormalizedPhone(); // Check for duplicated phone numbers but with different formats for (LinphoneNumberOrAddress number : mAddresses) { if (!number.isSIPAddress()) { if ((!noa.isSIPAddress() - && noa.getNormalizedPhone().equals(number.getNormalizedPhone())) + && normalizedPhone != null + && normalizedPhone.equals(number.getNormalizedPhone())) || (noa.isSIPAddress() && noa.getValue().equals(number.getNormalizedPhone())) - || (noa.getNormalizedPhone().equals(number.getValue()))) { + || (normalizedPhone != null && normalizedPhone.equals(number.getValue()))) { Log.d("[Linphone Contact] Duplicated entry detected: " + noa); found = true; break; @@ -247,7 +249,8 @@ public class LinphoneContact extends AndroidContact for (LinphoneNumberOrAddress noa : getNumbersOrAddresses()) { if (noa.isSIPAddress()) { String value = noa.getValue(); - if (address.startsWith(value) || value.equals("sip:" + address)) { + if (value != null + && (address.startsWith(value) || value.equals("sip:" + address))) { // Startswith is to workaround the fact that the // address may have a ;gruu= at the end... return true; @@ -274,7 +277,8 @@ public class LinphoneContact extends AndroidContact } LinphoneNumberOrAddress toRemove = null; for (LinphoneNumberOrAddress address : mAddresses) { - if (noa.getOldValue().equals(address.getValue()) + if (noa.getOldValue() != null + && noa.getOldValue().equals(address.getValue()) && noa.isSIPAddress() == address.isSIPAddress()) { toRemove = address; break; @@ -305,7 +309,8 @@ public class LinphoneContact extends AndroidContact } } for (LinphoneNumberOrAddress address : mAddresses) { - if (noa.getOldValue().equals(address.getValue()) + if (noa.getOldValue() != null + && noa.getOldValue().equals(address.getValue()) && noa.isSIPAddress() == address.isSIPAddress()) { address.setValue(noa.getValue()); break; @@ -428,7 +433,9 @@ public class LinphoneContact extends AndroidContact if (mFriend == null) return false; for (LinphoneNumberOrAddress noa : getNumbersOrAddresses()) { PresenceModel pm = mFriend.getPresenceModelForUriOrTel(noa.getValue()); - if (pm != null && pm.getBasicStatus().equals(PresenceBasicStatus.Open)) { + if (pm != null + && pm.getBasicStatus() != null + && pm.getBasicStatus().equals(PresenceBasicStatus.Open)) { return true; } } @@ -451,13 +458,18 @@ public class LinphoneContact extends AndroidContact public boolean hasPresenceModelForUriOrTelCapability(String uri, FriendCapability capability) { if (mFriend == null) return false; - if (mFriend.getPresenceModelForUriOrTel(uri) != null) { - return mFriend.getPresenceModelForUriOrTel(uri).hasCapability(capability); + + PresenceModel presence = mFriend.getPresenceModelForUriOrTel(uri); + if (presence != null) { + return presence.hasCapability(capability); } else { for (LinphoneNumberOrAddress noa : getNumbersOrAddresses()) { - if (getContactFromPresenceModelForUriOrTel(noa.getValue()).equals(uri)) { - return mFriend.getPresenceModelForUriOrTel(noa.getValue()) - .hasCapability(capability); + String contact = getContactFromPresenceModelForUriOrTel(noa.getValue()); + if (contact != null && contact.equals(uri)) { + presence = mFriend.getPresenceModelForUriOrTel(noa.getValue()); + if (presence != null) { + return presence.hasCapability(capability); + } } } } @@ -613,7 +625,9 @@ public class LinphoneContact extends AndroidContact // Test presence of the value PresenceModel pm = getFriend().getPresenceModelForUriOrTel(value); // If presence is not null - if (pm != null && pm.getBasicStatus().equals(PresenceBasicStatus.Open)) { + if (pm != null + && pm.getBasicStatus() != null + && pm.getBasicStatus().equals(PresenceBasicStatus.Open)) { Log.d("[Contact] Found presence information for phone number " + value); if (!isLinphoneAddressMimeEntryAlreadyExisting(value)) { // Do the action on the contact only once if it has not been done yet From b9c6abdeb53d5309c0b10983951b5ebc71f5a0f9 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 19 Nov 2019 13:52:27 +0100 Subject: [PATCH 37/84] Added a setting that prevents a user to edit a pure linphonefriend contact --- .../linphone/contacts/ContactDetailsFragment.java | 5 +++++ app/src/main/res/values/non_localizable_custom.xml | 14 ++++++++------ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/org/linphone/contacts/ContactDetailsFragment.java b/app/src/main/java/org/linphone/contacts/ContactDetailsFragment.java index 144fe408e..abbbcb358 100644 --- a/app/src/main/java/org/linphone/contacts/ContactDetailsFragment.java +++ b/app/src/main/java/org/linphone/contacts/ContactDetailsFragment.java @@ -90,6 +90,11 @@ public class ContactDetailsFragment extends Fragment implements ContactsUpdatedL } }); + if (mContact != null + && getResources().getBoolean(R.bool.forbid_pure_linphone_contacts_edition)) { + editContact.setVisibility(mContact.isAndroidContact() ? View.VISIBLE : View.GONE); + } + ImageView deleteContact = mView.findViewById(R.id.deleteContact); deleteContact.setOnClickListener( new OnClickListener() { diff --git a/app/src/main/res/values/non_localizable_custom.xml b/app/src/main/res/values/non_localizable_custom.xml index c68dd5ca1..9937cac61 100644 --- a/app/src/main/res/values/non_localizable_custom.xml +++ b/app/src/main/res/values/non_localizable_custom.xml @@ -117,6 +117,7 @@ true true true + true false @@ -125,16 +126,17 @@ false false - + true + 1000 + 7000 + + false + + true true 86400000 - 1000 - 7000 - - - false false From 4fd25bb1b0bb48018f6c9d25fdf1de85003cc74a Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 19 Nov 2019 14:40:44 +0100 Subject: [PATCH 38/84] Disable push notifications on non default domain accounts --- app/src/main/java/org/linphone/assistant/AssistantActivity.java | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/org/linphone/assistant/AssistantActivity.java b/app/src/main/java/org/linphone/assistant/AssistantActivity.java index 32218c6f5..b1b763b7a 100644 --- a/app/src/main/java/org/linphone/assistant/AssistantActivity.java +++ b/app/src/main/java/org/linphone/assistant/AssistantActivity.java @@ -145,6 +145,7 @@ public abstract class AssistantActivity extends LinphoneGenericActivity } else { // If this isn't a sip.linphone.org account, disable push notifications and enable // service notification, otherwise incoming calls won't work (most probably) + proxyConfig.setPushNotificationAllowed(false); Log.w( "[Assistant] Unknown domain used, push probably won't work, enable service mode"); LinphonePreferences.instance().setServiceNotificationVisibility(true); From 53a748409d289eab9fd91902b7b2687738f737ad Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 19 Nov 2019 16:06:38 +0100 Subject: [PATCH 39/84] Added logs & fixed some issues in contact removal --- .../org/linphone/contacts/AndroidContact.java | 1 + .../contacts/AsyncContactsLoader.java | 7 +++--- .../linphone/contacts/ContactsManager.java | 1 + .../linphone/contacts/LinphoneContact.java | 22 +++++++++++++++---- 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/org/linphone/contacts/AndroidContact.java b/app/src/main/java/org/linphone/contacts/AndroidContact.java index 4953d8f95..69239d0ce 100644 --- a/app/src/main/java/org/linphone/contacts/AndroidContact.java +++ b/app/src/main/java/org/linphone/contacts/AndroidContact.java @@ -146,6 +146,7 @@ class AndroidContact implements Serializable { } void deleteAndroidContact() { + Log.i("[Contact] Deleting Android contact ", this); ContactsManager.getInstance().delete(mAndroidId); } diff --git a/app/src/main/java/org/linphone/contacts/AsyncContactsLoader.java b/app/src/main/java/org/linphone/contacts/AsyncContactsLoader.java index 8ad05b069..d8614fabd 100644 --- a/app/src/main/java/org/linphone/contacts/AsyncContactsLoader.java +++ b/app/src/main/java/org/linphone/contacts/AsyncContactsLoader.java @@ -95,14 +95,13 @@ class AsyncContactsLoader extends AsyncTask ops = new ArrayList<>(); for (String id : ids) { + Log.i("[Contacts Manager] Adding Android contact id ", id, " to batch removal"); String[] args = new String[] {id}; ops.add( ContentProviderOperation.newDelete(ContactsContract.RawContacts.CONTENT_URI) diff --git a/app/src/main/java/org/linphone/contacts/LinphoneContact.java b/app/src/main/java/org/linphone/contacts/LinphoneContact.java index b8d9ce427..6c24b0594 100644 --- a/app/src/main/java/org/linphone/contacts/LinphoneContact.java +++ b/app/src/main/java/org/linphone/contacts/LinphoneContact.java @@ -401,12 +401,23 @@ public class LinphoneContact extends AndroidContact } public void deleteFriend() { + if (mFriend == null) return; Core core = LinphoneManager.getCore(); - if (mFriend != null && core != null) { - for (FriendList list : core.getFriendsLists()) { - list.removeFriend(mFriend); + if (core == null) return; + + boolean found = false; + Log.i("[Contact] Deleting friend ", mFriend.getName(), " for contact ", this); + for (FriendList list : core.getFriendsLists()) { + FriendList.Status status = list.removeFriend(mFriend); + if (status == FriendList.Status.OK) { + Log.w("[Contact] Friend found in list " + list.getDisplayName()); + found = true; } } + + if (!found) { + Log.w("[Contact] Friend removal failed, friend doesn't belong to any friend list"); + } } public void createOrUpdateFriendFromNativeContact() { @@ -645,7 +656,10 @@ public class LinphoneContact extends AndroidContact } public void delete() { - deleteAndroidContact(); + Log.i("[Contact] Deleting contact ", this); + if (isAndroidContact()) { + deleteAndroidContact(); + } if (isFriend()) { deleteFriend(); } From 260d38669e34e981e7d4db33fb346833ee00137d Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 20 Nov 2019 10:06:46 +0100 Subject: [PATCH 40/84] Moved some files around + added a max length to generated contact avatar + fixed possible crash --- .../linphone/activities/DialerActivity.java | 2 +- .../java/org/linphone/call/CallActivity.java | 2 +- .../linphone/call/CallIncomingActivity.java | 8 +-- .../linphone/call/CallOutgoingActivity.java | 2 +- .../org/linphone/call/CallStatsAdapter.java | 2 +- .../linphone/{ => call}/views/CallButton.java | 4 +- .../views/CallIncomingAnswerButton.java | 2 +- .../views/CallIncomingButtonListener.java | 2 +- .../views/CallIncomingDeclineButton.java | 2 +- .../linphone/chat/ChatMessageViewHolder.java | 2 +- .../chat/ChatRoomCreationFragment.java | 2 +- .../org/linphone/chat/ChatRoomViewHolder.java | 2 +- .../org/linphone/chat/DevicesAdapter.java | 2 +- .../org/linphone/chat/GroupInfoAdapter.java | 2 +- .../java/org/linphone/chat/ImdnFragment.java | 2 +- .../contacts/ContactDetailsFragment.java | 2 +- .../contacts/ContactEditorFragment.java | 2 +- .../linphone/contacts/ContactsAdapter.java | 2 +- .../linphone/contacts/ContactsManager.java | 5 ++ .../contacts/SearchContactsAdapter.java | 2 +- .../{ => contacts}/views/ContactAvatar.java | 32 ++---------- .../contacts/views/ContactAvatarHolder.java | 49 +++++++++++++++++++ .../views/ContactSelectView.java | 2 +- .../org/linphone/history/HistoryAdapter.java | 2 +- .../history/HistoryDetailFragment.java | 2 +- app/src/main/res/layout-land/dialer.xml | 6 +-- .../main/res/layout-sw533dp-land/dialer.xml | 6 +-- app/src/main/res/layout-sw533dp/dialer.xml | 6 +-- app/src/main/res/layout/call_incoming.xml | 4 +- app/src/main/res/layout/dialer.xml | 6 +-- 30 files changed, 99 insertions(+), 67 deletions(-) rename app/src/main/java/org/linphone/{ => call}/views/CallButton.java (96%) rename app/src/main/java/org/linphone/{ => call}/views/CallIncomingAnswerButton.java (99%) rename app/src/main/java/org/linphone/{ => call}/views/CallIncomingButtonListener.java (96%) rename app/src/main/java/org/linphone/{ => call}/views/CallIncomingDeclineButton.java (99%) rename app/src/main/java/org/linphone/{ => contacts}/views/ContactAvatar.java (87%) create mode 100644 app/src/main/java/org/linphone/contacts/views/ContactAvatarHolder.java rename app/src/main/java/org/linphone/{ => contacts}/views/ContactSelectView.java (98%) diff --git a/app/src/main/java/org/linphone/activities/DialerActivity.java b/app/src/main/java/org/linphone/activities/DialerActivity.java index 45ac4bb5f..02c850b98 100644 --- a/app/src/main/java/org/linphone/activities/DialerActivity.java +++ b/app/src/main/java/org/linphone/activities/DialerActivity.java @@ -37,6 +37,7 @@ import java.util.ArrayList; import java.util.Collection; import org.linphone.LinphoneManager; import org.linphone.R; +import org.linphone.call.views.CallButton; import org.linphone.contacts.ContactsActivity; import org.linphone.contacts.ContactsManager; import org.linphone.core.Call; @@ -45,7 +46,6 @@ import org.linphone.core.CoreListenerStub; import org.linphone.core.tools.Log; import org.linphone.settings.LinphonePreferences; import org.linphone.views.AddressText; -import org.linphone.views.CallButton; import org.linphone.views.Digit; import org.linphone.views.EraseButton; diff --git a/app/src/main/java/org/linphone/call/CallActivity.java b/app/src/main/java/org/linphone/call/CallActivity.java index bc902d08d..a56896d68 100644 --- a/app/src/main/java/org/linphone/call/CallActivity.java +++ b/app/src/main/java/org/linphone/call/CallActivity.java @@ -58,6 +58,7 @@ import org.linphone.compatibility.Compatibility; import org.linphone.contacts.ContactsManager; import org.linphone.contacts.ContactsUpdatedListener; import org.linphone.contacts.LinphoneContact; +import org.linphone.contacts.views.ContactAvatar; import org.linphone.core.Address; import org.linphone.core.Call; import org.linphone.core.ChatMessage; @@ -69,7 +70,6 @@ import org.linphone.core.tools.Log; import org.linphone.settings.LinphonePreferences; import org.linphone.utils.AndroidAudioManager; import org.linphone.utils.LinphoneUtils; -import org.linphone.views.ContactAvatar; public class CallActivity extends LinphoneGenericActivity implements CallStatusBarFragment.StatsClikedListener, diff --git a/app/src/main/java/org/linphone/call/CallIncomingActivity.java b/app/src/main/java/org/linphone/call/CallIncomingActivity.java index ee4e34ac9..db7b8d05e 100644 --- a/app/src/main/java/org/linphone/call/CallIncomingActivity.java +++ b/app/src/main/java/org/linphone/call/CallIncomingActivity.java @@ -36,9 +36,13 @@ import org.linphone.LinphoneContext; import org.linphone.LinphoneManager; import org.linphone.R; import org.linphone.activities.LinphoneGenericActivity; +import org.linphone.call.views.CallIncomingAnswerButton; +import org.linphone.call.views.CallIncomingButtonListener; +import org.linphone.call.views.CallIncomingDeclineButton; import org.linphone.compatibility.Compatibility; import org.linphone.contacts.ContactsManager; import org.linphone.contacts.LinphoneContact; +import org.linphone.contacts.views.ContactAvatar; import org.linphone.core.Address; import org.linphone.core.Call; import org.linphone.core.Call.State; @@ -47,10 +51,6 @@ import org.linphone.core.CoreListenerStub; import org.linphone.core.tools.Log; import org.linphone.settings.LinphonePreferences; import org.linphone.utils.LinphoneUtils; -import org.linphone.views.CallIncomingAnswerButton; -import org.linphone.views.CallIncomingButtonListener; -import org.linphone.views.CallIncomingDeclineButton; -import org.linphone.views.ContactAvatar; public class CallIncomingActivity extends LinphoneGenericActivity { private TextView mName, mNumber; diff --git a/app/src/main/java/org/linphone/call/CallOutgoingActivity.java b/app/src/main/java/org/linphone/call/CallOutgoingActivity.java index e797670b3..90d5c1e15 100644 --- a/app/src/main/java/org/linphone/call/CallOutgoingActivity.java +++ b/app/src/main/java/org/linphone/call/CallOutgoingActivity.java @@ -37,6 +37,7 @@ import org.linphone.R; import org.linphone.activities.LinphoneGenericActivity; import org.linphone.contacts.ContactsManager; import org.linphone.contacts.LinphoneContact; +import org.linphone.contacts.views.ContactAvatar; import org.linphone.core.Address; import org.linphone.core.Call; import org.linphone.core.Call.State; @@ -46,7 +47,6 @@ import org.linphone.core.Reason; import org.linphone.core.tools.Log; import org.linphone.settings.LinphonePreferences; import org.linphone.utils.LinphoneUtils; -import org.linphone.views.ContactAvatar; public class CallOutgoingActivity extends LinphoneGenericActivity implements OnClickListener { private TextView mName, mNumber; diff --git a/app/src/main/java/org/linphone/call/CallStatsAdapter.java b/app/src/main/java/org/linphone/call/CallStatsAdapter.java index 4e9223215..f963b0b75 100644 --- a/app/src/main/java/org/linphone/call/CallStatsAdapter.java +++ b/app/src/main/java/org/linphone/call/CallStatsAdapter.java @@ -29,9 +29,9 @@ import java.util.List; import org.linphone.R; import org.linphone.contacts.ContactsManager; import org.linphone.contacts.LinphoneContact; +import org.linphone.contacts.views.ContactAvatar; import org.linphone.core.Call; import org.linphone.utils.LinphoneUtils; -import org.linphone.views.ContactAvatar; public class CallStatsAdapter extends BaseExpandableListAdapter { private final Context mContext; diff --git a/app/src/main/java/org/linphone/views/CallButton.java b/app/src/main/java/org/linphone/call/views/CallButton.java similarity index 96% rename from app/src/main/java/org/linphone/views/CallButton.java rename to app/src/main/java/org/linphone/call/views/CallButton.java index 655577739..5fe29edd1 100644 --- a/app/src/main/java/org/linphone/views/CallButton.java +++ b/app/src/main/java/org/linphone/call/views/CallButton.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.linphone.views; +package org.linphone.call.views; import android.annotation.SuppressLint; import android.content.Context; @@ -31,6 +31,8 @@ import org.linphone.core.CallLog; import org.linphone.core.Core; import org.linphone.core.ProxyConfig; import org.linphone.settings.LinphonePreferences; +import org.linphone.views.AddressAware; +import org.linphone.views.AddressText; @SuppressLint("AppCompatCustomView") public class CallButton extends ImageView implements OnClickListener, AddressAware { diff --git a/app/src/main/java/org/linphone/views/CallIncomingAnswerButton.java b/app/src/main/java/org/linphone/call/views/CallIncomingAnswerButton.java similarity index 99% rename from app/src/main/java/org/linphone/views/CallIncomingAnswerButton.java rename to app/src/main/java/org/linphone/call/views/CallIncomingAnswerButton.java index d762d2c71..9645ac45d 100644 --- a/app/src/main/java/org/linphone/views/CallIncomingAnswerButton.java +++ b/app/src/main/java/org/linphone/call/views/CallIncomingAnswerButton.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.linphone.views; +package org.linphone.call.views; import android.content.Context; import android.util.AttributeSet; diff --git a/app/src/main/java/org/linphone/views/CallIncomingButtonListener.java b/app/src/main/java/org/linphone/call/views/CallIncomingButtonListener.java similarity index 96% rename from app/src/main/java/org/linphone/views/CallIncomingButtonListener.java rename to app/src/main/java/org/linphone/call/views/CallIncomingButtonListener.java index 1ec9752de..9127431ec 100644 --- a/app/src/main/java/org/linphone/views/CallIncomingButtonListener.java +++ b/app/src/main/java/org/linphone/call/views/CallIncomingButtonListener.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.linphone.views; +package org.linphone.call.views; public interface CallIncomingButtonListener { void onAction(); diff --git a/app/src/main/java/org/linphone/views/CallIncomingDeclineButton.java b/app/src/main/java/org/linphone/call/views/CallIncomingDeclineButton.java similarity index 99% rename from app/src/main/java/org/linphone/views/CallIncomingDeclineButton.java rename to app/src/main/java/org/linphone/call/views/CallIncomingDeclineButton.java index ddcee0294..65b422c34 100644 --- a/app/src/main/java/org/linphone/views/CallIncomingDeclineButton.java +++ b/app/src/main/java/org/linphone/call/views/CallIncomingDeclineButton.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.linphone.views; +package org.linphone.call.views; import android.content.Context; import android.util.AttributeSet; diff --git a/app/src/main/java/org/linphone/chat/ChatMessageViewHolder.java b/app/src/main/java/org/linphone/chat/ChatMessageViewHolder.java index 61fe7c994..59c0ee4b7 100644 --- a/app/src/main/java/org/linphone/chat/ChatMessageViewHolder.java +++ b/app/src/main/java/org/linphone/chat/ChatMessageViewHolder.java @@ -50,6 +50,7 @@ import java.util.List; import org.linphone.R; import org.linphone.contacts.ContactsManager; import org.linphone.contacts.LinphoneContact; +import org.linphone.contacts.views.ContactAvatar; import org.linphone.core.Address; import org.linphone.core.ChatMessage; import org.linphone.core.Content; @@ -57,7 +58,6 @@ import org.linphone.core.tools.Log; import org.linphone.utils.FileUtils; import org.linphone.utils.ImageUtils; import org.linphone.utils.LinphoneUtils; -import org.linphone.views.ContactAvatar; public class ChatMessageViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { diff --git a/app/src/main/java/org/linphone/chat/ChatRoomCreationFragment.java b/app/src/main/java/org/linphone/chat/ChatRoomCreationFragment.java index 56405f6c0..51b74362d 100644 --- a/app/src/main/java/org/linphone/chat/ChatRoomCreationFragment.java +++ b/app/src/main/java/org/linphone/chat/ChatRoomCreationFragment.java @@ -49,6 +49,7 @@ import org.linphone.contacts.ContactsUpdatedListener; import org.linphone.contacts.LinphoneContact; import org.linphone.contacts.SearchContactViewHolder; import org.linphone.contacts.SearchContactsAdapter; +import org.linphone.contacts.views.ContactSelectView; import org.linphone.core.Address; import org.linphone.core.ChatRoom; import org.linphone.core.ChatRoomBackend; @@ -61,7 +62,6 @@ import org.linphone.core.ProxyConfig; import org.linphone.core.SearchResult; import org.linphone.core.tools.Log; import org.linphone.settings.LinphonePreferences; -import org.linphone.views.ContactSelectView; import org.linphone.views.LinphoneLinearLayoutManager; public class ChatRoomCreationFragment extends Fragment diff --git a/app/src/main/java/org/linphone/chat/ChatRoomViewHolder.java b/app/src/main/java/org/linphone/chat/ChatRoomViewHolder.java index 6ffb1a893..0d0693542 100644 --- a/app/src/main/java/org/linphone/chat/ChatRoomViewHolder.java +++ b/app/src/main/java/org/linphone/chat/ChatRoomViewHolder.java @@ -28,6 +28,7 @@ import androidx.recyclerview.widget.RecyclerView; import org.linphone.R; import org.linphone.contacts.ContactsManager; import org.linphone.contacts.LinphoneContact; +import org.linphone.contacts.views.ContactAvatar; import org.linphone.core.Address; import org.linphone.core.ChatMessage; import org.linphone.core.ChatRoom; @@ -35,7 +36,6 @@ import org.linphone.core.ChatRoomCapabilities; import org.linphone.core.Content; import org.linphone.core.Participant; import org.linphone.utils.LinphoneUtils; -import org.linphone.views.ContactAvatar; public class ChatRoomViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener { diff --git a/app/src/main/java/org/linphone/chat/DevicesAdapter.java b/app/src/main/java/org/linphone/chat/DevicesAdapter.java index c2e4f8cbc..57ee8eb86 100644 --- a/app/src/main/java/org/linphone/chat/DevicesAdapter.java +++ b/app/src/main/java/org/linphone/chat/DevicesAdapter.java @@ -29,12 +29,12 @@ import java.util.List; import org.linphone.R; import org.linphone.contacts.ContactsManager; import org.linphone.contacts.LinphoneContact; +import org.linphone.contacts.views.ContactAvatar; import org.linphone.core.Address; import org.linphone.core.ChatRoomSecurityLevel; import org.linphone.core.Participant; import org.linphone.core.ParticipantDevice; import org.linphone.utils.LinphoneUtils; -import org.linphone.views.ContactAvatar; class DevicesAdapter extends BaseExpandableListAdapter { private final Context mContext; diff --git a/app/src/main/java/org/linphone/chat/GroupInfoAdapter.java b/app/src/main/java/org/linphone/chat/GroupInfoAdapter.java index 285e104f6..efbed24b5 100644 --- a/app/src/main/java/org/linphone/chat/GroupInfoAdapter.java +++ b/app/src/main/java/org/linphone/chat/GroupInfoAdapter.java @@ -30,9 +30,9 @@ import org.linphone.LinphoneContext; import org.linphone.R; import org.linphone.contacts.ContactAddress; import org.linphone.contacts.LinphoneContact; +import org.linphone.contacts.views.ContactAvatar; import org.linphone.core.ChatRoom; import org.linphone.core.Participant; -import org.linphone.views.ContactAvatar; class GroupInfoAdapter extends RecyclerView.Adapter { private List mItems; diff --git a/app/src/main/java/org/linphone/chat/ImdnFragment.java b/app/src/main/java/org/linphone/chat/ImdnFragment.java index 6daf78a69..149a6a96d 100644 --- a/app/src/main/java/org/linphone/chat/ImdnFragment.java +++ b/app/src/main/java/org/linphone/chat/ImdnFragment.java @@ -32,6 +32,7 @@ import org.linphone.LinphoneManager; import org.linphone.R; import org.linphone.contacts.ContactsManager; import org.linphone.contacts.LinphoneContact; +import org.linphone.contacts.views.ContactAvatar; import org.linphone.core.Address; import org.linphone.core.ChatMessage; import org.linphone.core.ChatMessageListenerStub; @@ -40,7 +41,6 @@ import org.linphone.core.Core; import org.linphone.core.Factory; import org.linphone.core.ParticipantImdnState; import org.linphone.utils.LinphoneUtils; -import org.linphone.views.ContactAvatar; public class ImdnFragment extends Fragment { private LayoutInflater mInflater; diff --git a/app/src/main/java/org/linphone/contacts/ContactDetailsFragment.java b/app/src/main/java/org/linphone/contacts/ContactDetailsFragment.java index abbbcb358..d36f76df9 100644 --- a/app/src/main/java/org/linphone/contacts/ContactDetailsFragment.java +++ b/app/src/main/java/org/linphone/contacts/ContactDetailsFragment.java @@ -36,6 +36,7 @@ import android.widget.TableLayout; import android.widget.TextView; import org.linphone.LinphoneManager; import org.linphone.R; +import org.linphone.contacts.views.ContactAvatar; import org.linphone.core.Address; import org.linphone.core.ChatRoom; import org.linphone.core.ChatRoomBackend; @@ -50,7 +51,6 @@ import org.linphone.core.ProxyConfig; import org.linphone.core.tools.Log; import org.linphone.settings.LinphonePreferences; import org.linphone.utils.LinphoneUtils; -import org.linphone.views.ContactAvatar; public class ContactDetailsFragment extends Fragment implements ContactsUpdatedListener { private LinphoneContact mContact; diff --git a/app/src/main/java/org/linphone/contacts/ContactEditorFragment.java b/app/src/main/java/org/linphone/contacts/ContactEditorFragment.java index 63d798460..9d7c34b7f 100644 --- a/app/src/main/java/org/linphone/contacts/ContactEditorFragment.java +++ b/app/src/main/java/org/linphone/contacts/ContactEditorFragment.java @@ -53,12 +53,12 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.linphone.R; +import org.linphone.contacts.views.ContactAvatar; import org.linphone.core.tools.Log; import org.linphone.mediastream.Version; import org.linphone.settings.LinphonePreferences; import org.linphone.utils.FileUtils; import org.linphone.utils.LinphoneUtils; -import org.linphone.views.ContactAvatar; public class ContactEditorFragment extends Fragment { private static final int ADD_PHOTO = 1337; diff --git a/app/src/main/java/org/linphone/contacts/ContactsAdapter.java b/app/src/main/java/org/linphone/contacts/ContactsAdapter.java index fc3a31684..af7f7d5b8 100644 --- a/app/src/main/java/org/linphone/contacts/ContactsAdapter.java +++ b/app/src/main/java/org/linphone/contacts/ContactsAdapter.java @@ -31,10 +31,10 @@ import java.util.List; import java.util.Locale; import java.util.Map; import org.linphone.R; +import org.linphone.contacts.views.ContactAvatar; import org.linphone.settings.LinphonePreferences; import org.linphone.utils.SelectableAdapter; import org.linphone.utils.SelectableHelper; -import org.linphone.views.ContactAvatar; public class ContactsAdapter extends SelectableAdapter implements SectionIndexer { diff --git a/app/src/main/java/org/linphone/contacts/ContactsManager.java b/app/src/main/java/org/linphone/contacts/ContactsManager.java index 9b202ac69..4d1d3dffa 100644 --- a/app/src/main/java/org/linphone/contacts/ContactsManager.java +++ b/app/src/main/java/org/linphone/contacts/ContactsManager.java @@ -375,6 +375,11 @@ public class ContactsManager extends ContentObserver } String username = address.getUsername(); + if (username == null) { + Log.w("[Contacts Manager] Address ", address.asString(), " doesn't have a username!"); + return null; + } + if (android.util.Patterns.PHONE.matcher(username).matches()) { return findContactFromPhoneNumber(username); } diff --git a/app/src/main/java/org/linphone/contacts/SearchContactsAdapter.java b/app/src/main/java/org/linphone/contacts/SearchContactsAdapter.java index 8c421c8cb..c41d6022f 100644 --- a/app/src/main/java/org/linphone/contacts/SearchContactsAdapter.java +++ b/app/src/main/java/org/linphone/contacts/SearchContactsAdapter.java @@ -30,13 +30,13 @@ import java.util.Objects; import org.linphone.LinphoneContext; import org.linphone.LinphoneManager; import org.linphone.R; +import org.linphone.contacts.views.ContactAvatar; import org.linphone.core.Address; import org.linphone.core.FriendCapability; import org.linphone.core.PresenceBasicStatus; import org.linphone.core.PresenceModel; import org.linphone.core.ProxyConfig; import org.linphone.core.SearchResult; -import org.linphone.views.ContactAvatar; public class SearchContactsAdapter extends RecyclerView.Adapter { private List mContacts; diff --git a/app/src/main/java/org/linphone/views/ContactAvatar.java b/app/src/main/java/org/linphone/contacts/views/ContactAvatar.java similarity index 87% rename from app/src/main/java/org/linphone/views/ContactAvatar.java rename to app/src/main/java/org/linphone/contacts/views/ContactAvatar.java index d2b890dd3..bcfdb0f47 100644 --- a/app/src/main/java/org/linphone/views/ContactAvatar.java +++ b/app/src/main/java/org/linphone/contacts/views/ContactAvatar.java @@ -17,49 +17,25 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.linphone.views; +package org.linphone.contacts.views; import android.graphics.Bitmap; import android.view.View; -import android.widget.ImageView; -import android.widget.TextView; import org.linphone.R; import org.linphone.contacts.LinphoneContact; import org.linphone.core.ChatRoomSecurityLevel; import org.linphone.utils.ImageUtils; -class ContactAvatarHolder { - public final ImageView contactPicture; - public final ImageView avatarBorder; - public final ImageView securityLevel; - public final TextView generatedAvatar; - public final ImageView generatedAvatarBackground; - - public ContactAvatarHolder(View v) { - contactPicture = v.findViewById(R.id.contact_picture); - securityLevel = v.findViewById(R.id.security_level); - generatedAvatar = v.findViewById(R.id.generated_avatar); - generatedAvatarBackground = v.findViewById(R.id.generated_avatar_background); - avatarBorder = v.findViewById(R.id.border); - } - - public void init() { - contactPicture.setVisibility(View.VISIBLE); - generatedAvatar.setVisibility(View.VISIBLE); - generatedAvatarBackground.setVisibility(View.VISIBLE); - securityLevel.setVisibility(View.GONE); - avatarBorder.setVisibility(View.GONE); - } -} - public class ContactAvatar { private static String generateAvatar(String displayName) { String[] names = displayName.split(" "); StringBuilder generatedAvatarText = new StringBuilder(); + int count = 0; for (String name : names) { - if (name != null && name.length() > 0) { + if (name != null && name.length() > 0 && count < 2) { generatedAvatarText.append(name.charAt(0)); + count += 1; } } return generatedAvatarText.toString().toUpperCase(); diff --git a/app/src/main/java/org/linphone/contacts/views/ContactAvatarHolder.java b/app/src/main/java/org/linphone/contacts/views/ContactAvatarHolder.java new file mode 100644 index 000000000..3ae8bce5c --- /dev/null +++ b/app/src/main/java/org/linphone/contacts/views/ContactAvatarHolder.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2010-2019 Belledonne Communications SARL. + * + * This file is part of linphone-android + * (see https://www.linphone.org). + * + * 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 3 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, see . + */ +package org.linphone.contacts.views; + +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; +import org.linphone.R; + +class ContactAvatarHolder { + public final ImageView contactPicture; + public final ImageView avatarBorder; + public final ImageView securityLevel; + public final TextView generatedAvatar; + public final ImageView generatedAvatarBackground; + + public ContactAvatarHolder(View v) { + contactPicture = v.findViewById(R.id.contact_picture); + securityLevel = v.findViewById(R.id.security_level); + generatedAvatar = v.findViewById(R.id.generated_avatar); + generatedAvatarBackground = v.findViewById(R.id.generated_avatar_background); + avatarBorder = v.findViewById(R.id.border); + } + + public void init() { + contactPicture.setVisibility(View.VISIBLE); + generatedAvatar.setVisibility(View.VISIBLE); + generatedAvatarBackground.setVisibility(View.VISIBLE); + securityLevel.setVisibility(View.GONE); + avatarBorder.setVisibility(View.GONE); + } +} diff --git a/app/src/main/java/org/linphone/views/ContactSelectView.java b/app/src/main/java/org/linphone/contacts/views/ContactSelectView.java similarity index 98% rename from app/src/main/java/org/linphone/views/ContactSelectView.java rename to app/src/main/java/org/linphone/contacts/views/ContactSelectView.java index 3507fb18b..60ba826d2 100644 --- a/app/src/main/java/org/linphone/views/ContactSelectView.java +++ b/app/src/main/java/org/linphone/contacts/views/ContactSelectView.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.linphone.views; +package org.linphone.contacts.views; import android.content.Context; import android.view.LayoutInflater; diff --git a/app/src/main/java/org/linphone/history/HistoryAdapter.java b/app/src/main/java/org/linphone/history/HistoryAdapter.java index d5f105ec3..e61d3596d 100644 --- a/app/src/main/java/org/linphone/history/HistoryAdapter.java +++ b/app/src/main/java/org/linphone/history/HistoryAdapter.java @@ -30,13 +30,13 @@ import java.util.List; import org.linphone.R; import org.linphone.contacts.ContactsManager; import org.linphone.contacts.LinphoneContact; +import org.linphone.contacts.views.ContactAvatar; import org.linphone.core.Address; import org.linphone.core.Call; import org.linphone.core.CallLog; import org.linphone.utils.LinphoneUtils; import org.linphone.utils.SelectableAdapter; import org.linphone.utils.SelectableHelper; -import org.linphone.views.ContactAvatar; public class HistoryAdapter extends SelectableAdapter { private final List mLogs; diff --git a/app/src/main/java/org/linphone/history/HistoryDetailFragment.java b/app/src/main/java/org/linphone/history/HistoryDetailFragment.java index c7e5753af..bcbaccd59 100644 --- a/app/src/main/java/org/linphone/history/HistoryDetailFragment.java +++ b/app/src/main/java/org/linphone/history/HistoryDetailFragment.java @@ -35,6 +35,7 @@ import org.linphone.LinphoneManager; import org.linphone.R; import org.linphone.contacts.ContactsManager; import org.linphone.contacts.LinphoneContact; +import org.linphone.contacts.views.ContactAvatar; import org.linphone.core.Address; import org.linphone.core.CallLog; import org.linphone.core.ChatRoom; @@ -48,7 +49,6 @@ import org.linphone.core.ProxyConfig; import org.linphone.core.tools.Log; import org.linphone.settings.LinphonePreferences; import org.linphone.utils.LinphoneUtils; -import org.linphone.views.ContactAvatar; public class HistoryDetailFragment extends Fragment { private ImageView mAddToContacts; diff --git a/app/src/main/res/layout-land/dialer.xml b/app/src/main/res/layout-land/dialer.xml index 2fa346af1..1951f879f 100644 --- a/app/src/main/res/layout-land/dialer.xml +++ b/app/src/main/res/layout-land/dialer.xml @@ -81,7 +81,7 @@ - - - - - - - - - - - - - - Date: Wed, 20 Nov 2019 10:12:40 +0100 Subject: [PATCH 41/84] Updated call layout to allow for secondary buttons to be visible above numpad --- app/src/main/res/layout-land/call.xml | 12 ++++++------ app/src/main/res/layout/call.xml | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/app/src/main/res/layout-land/call.xml b/app/src/main/res/layout-land/call.xml index 836374fce..e164b73f8 100644 --- a/app/src/main/res/layout-land/call.xml +++ b/app/src/main/res/layout-land/call.xml @@ -126,12 +126,6 @@ android:layout_alignParentBottom="true" android:layout_toLeftOf="@id/vertical_divider" /> - - + + diff --git a/app/src/main/res/layout/call.xml b/app/src/main/res/layout/call.xml index 32277a192..dd38eaaa9 100644 --- a/app/src/main/res/layout/call.xml +++ b/app/src/main/res/layout/call.xml @@ -118,12 +118,6 @@ android:layout_height="60dp" android:layout_alignParentBottom="true" /> - - + + From 8f9aeecf822bf2addcbb6d60b007f01bb0de3f5b Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 20 Nov 2019 10:14:58 +0100 Subject: [PATCH 42/84] Version code bumped --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index bc255dd5b..143916e4b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -88,7 +88,7 @@ android { defaultConfig { minSdkVersion 21 targetSdkVersion 29 - versionCode 4204 + versionCode 4205 versionName "${project.version}" applicationId getPackageName() multiDexEnabled true From 221707099581798636592af17237b5a3a6fd742b Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 20 Nov 2019 10:34:29 +0100 Subject: [PATCH 43/84] Reorganized code a bit more --- app/src/main/AndroidManifest.xml | 4 +- .../java/org/linphone/LinphoneContext.java | 1 + .../java/org/linphone/LinphoneManager.java | 2 +- .../activities/LinphoneGenericActivity.java | 2 +- .../activities/LinphoneLauncherActivity.java | 7 +- .../org/linphone/activities/MainActivity.java | 3 +- .../linphone/assistant/AssistantActivity.java | 2 +- .../{utils => call}/AndroidAudioManager.java | 2 +- .../java/org/linphone/call/CallActivity.java | 5 +- .../java/org/linphone/call/CallManager.java | 2 +- .../org/linphone/call/views/CallButton.java | 4 +- .../views/LinphoneGL2JNIViewOverlay.java | 2 +- .../views/LinphoneLinearLayoutManager.java | 2 +- .../{ => call}/views/LinphoneOverlay.java | 2 +- .../views/LinphoneTextureViewOverlay.java | 2 +- .../chat/ChatRoomCreationFragment.java | 2 +- .../org/linphone/chat/ChatRoomsFragment.java | 2 +- .../org/linphone/chat/GroupInfoFragment.java | 2 +- .../linphone/contacts/ContactsFragment.java | 2 +- .../DialerActivity.java | 9 +- .../{ => dialer}/views/AddressAware.java | 2 +- .../{ => dialer}/views/AddressText.java | 2 +- .../{ => dialer}/views/AddressType.java | 2 +- .../linphone/{ => dialer}/views/Digit.java | 2 +- .../{ => dialer}/views/EraseButton.java | 2 +- .../org/linphone/history/HistoryFragment.java | 2 +- .../notifications/NotificationsManager.java | 4 +- .../org/linphone/receivers/BootReceiver.java | 2 +- .../recording/RecordingsActivity.java | 2 +- .../{utils => service}/ActivityMonitor.java | 4 +- .../{ => service}/LinphoneService.java | 12 +- .../{utils => service}/ServiceWaitThread.java | 4 +- .../ServiceWaitThreadListener.java | 2 +- .../java/org/linphone/views/AsyncBitmap.java | 38 ---- .../org/linphone/views/BitmapWorkerTask.java | 166 ------------------ app/src/main/res/layout-land/dialer.xml | 4 +- .../main/res/layout-sw533dp-land/dialer.xml | 4 +- app/src/main/res/layout-sw533dp/dialer.xml | 4 +- app/src/main/res/layout/dialer.xml | 4 +- app/src/main/res/layout/numpad.xml | 24 +-- 40 files changed, 73 insertions(+), 272 deletions(-) rename app/src/main/java/org/linphone/{utils => call}/AndroidAudioManager.java (99%) rename app/src/main/java/org/linphone/{ => call}/views/LinphoneGL2JNIViewOverlay.java (99%) rename app/src/main/java/org/linphone/{ => call}/views/LinphoneLinearLayoutManager.java (98%) rename app/src/main/java/org/linphone/{ => call}/views/LinphoneOverlay.java (97%) rename app/src/main/java/org/linphone/{ => call}/views/LinphoneTextureViewOverlay.java (99%) rename app/src/main/java/org/linphone/{activities => dialer}/DialerActivity.java (98%) rename app/src/main/java/org/linphone/{ => dialer}/views/AddressAware.java (96%) rename app/src/main/java/org/linphone/{ => dialer}/views/AddressText.java (99%) rename app/src/main/java/org/linphone/{ => dialer}/views/AddressType.java (96%) rename app/src/main/java/org/linphone/{ => dialer}/views/Digit.java (99%) rename app/src/main/java/org/linphone/{ => dialer}/views/EraseButton.java (98%) rename app/src/main/java/org/linphone/{utils => service}/ActivityMonitor.java (98%) rename app/src/main/java/org/linphone/{ => service}/LinphoneService.java (95%) rename app/src/main/java/org/linphone/{utils => service}/ServiceWaitThread.java (95%) rename app/src/main/java/org/linphone/{utils => service}/ServiceWaitThreadListener.java (96%) delete mode 100644 app/src/main/java/org/linphone/views/AsyncBitmap.java delete mode 100644 app/src/main/java/org/linphone/views/BitmapWorkerTask.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a1d880262..039affcec 100755 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -81,7 +81,7 @@ @@ -211,7 +211,7 @@ . */ -package org.linphone.utils; +package org.linphone.call; import static android.media.AudioManager.MODE_RINGTONE; import static android.media.AudioManager.STREAM_RING; diff --git a/app/src/main/java/org/linphone/call/CallActivity.java b/app/src/main/java/org/linphone/call/CallActivity.java index a56896d68..8c52ba2a3 100644 --- a/app/src/main/java/org/linphone/call/CallActivity.java +++ b/app/src/main/java/org/linphone/call/CallActivity.java @@ -49,9 +49,7 @@ import androidx.core.content.ContextCompat; import androidx.drawerlayout.widget.DrawerLayout; import java.lang.ref.WeakReference; import org.linphone.LinphoneManager; -import org.linphone.LinphoneService; import org.linphone.R; -import org.linphone.activities.DialerActivity; import org.linphone.activities.LinphoneGenericActivity; import org.linphone.chat.ChatActivity; import org.linphone.compatibility.Compatibility; @@ -67,8 +65,9 @@ import org.linphone.core.Core; import org.linphone.core.CoreListener; import org.linphone.core.CoreListenerStub; import org.linphone.core.tools.Log; +import org.linphone.dialer.DialerActivity; +import org.linphone.service.LinphoneService; import org.linphone.settings.LinphonePreferences; -import org.linphone.utils.AndroidAudioManager; import org.linphone.utils.LinphoneUtils; public class CallActivity extends LinphoneGenericActivity diff --git a/app/src/main/java/org/linphone/call/CallManager.java b/app/src/main/java/org/linphone/call/CallManager.java index 2c82893aa..87c06a9f9 100644 --- a/app/src/main/java/org/linphone/call/CallManager.java +++ b/app/src/main/java/org/linphone/call/CallManager.java @@ -35,11 +35,11 @@ import org.linphone.core.Core; import org.linphone.core.MediaEncryption; import org.linphone.core.ProxyConfig; import org.linphone.core.tools.Log; +import org.linphone.dialer.views.AddressType; import org.linphone.mediastream.Version; import org.linphone.settings.LinphonePreferences; import org.linphone.utils.FileUtils; import org.linphone.utils.LinphoneUtils; -import org.linphone.views.AddressType; /** Handle call updating, reinvites. */ public class CallManager { diff --git a/app/src/main/java/org/linphone/call/views/CallButton.java b/app/src/main/java/org/linphone/call/views/CallButton.java index 5fe29edd1..347289b2d 100644 --- a/app/src/main/java/org/linphone/call/views/CallButton.java +++ b/app/src/main/java/org/linphone/call/views/CallButton.java @@ -30,9 +30,9 @@ import org.linphone.core.Call; import org.linphone.core.CallLog; import org.linphone.core.Core; import org.linphone.core.ProxyConfig; +import org.linphone.dialer.views.AddressAware; +import org.linphone.dialer.views.AddressText; import org.linphone.settings.LinphonePreferences; -import org.linphone.views.AddressAware; -import org.linphone.views.AddressText; @SuppressLint("AppCompatCustomView") public class CallButton extends ImageView implements OnClickListener, AddressAware { diff --git a/app/src/main/java/org/linphone/views/LinphoneGL2JNIViewOverlay.java b/app/src/main/java/org/linphone/call/views/LinphoneGL2JNIViewOverlay.java similarity index 99% rename from app/src/main/java/org/linphone/views/LinphoneGL2JNIViewOverlay.java rename to app/src/main/java/org/linphone/call/views/LinphoneGL2JNIViewOverlay.java index 210462340..b18e7165a 100644 --- a/app/src/main/java/org/linphone/views/LinphoneGL2JNIViewOverlay.java +++ b/app/src/main/java/org/linphone/call/views/LinphoneGL2JNIViewOverlay.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.linphone.views; +package org.linphone.call.views; import android.content.Context; import android.content.Intent; diff --git a/app/src/main/java/org/linphone/views/LinphoneLinearLayoutManager.java b/app/src/main/java/org/linphone/call/views/LinphoneLinearLayoutManager.java similarity index 98% rename from app/src/main/java/org/linphone/views/LinphoneLinearLayoutManager.java rename to app/src/main/java/org/linphone/call/views/LinphoneLinearLayoutManager.java index a0d32a9cd..4694ac63d 100644 --- a/app/src/main/java/org/linphone/views/LinphoneLinearLayoutManager.java +++ b/app/src/main/java/org/linphone/call/views/LinphoneLinearLayoutManager.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.linphone.views; +package org.linphone.call.views; import android.content.Context; import android.util.AttributeSet; diff --git a/app/src/main/java/org/linphone/views/LinphoneOverlay.java b/app/src/main/java/org/linphone/call/views/LinphoneOverlay.java similarity index 97% rename from app/src/main/java/org/linphone/views/LinphoneOverlay.java rename to app/src/main/java/org/linphone/call/views/LinphoneOverlay.java index e1cc70ec2..0172957d1 100644 --- a/app/src/main/java/org/linphone/views/LinphoneOverlay.java +++ b/app/src/main/java/org/linphone/call/views/LinphoneOverlay.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.linphone.views; +package org.linphone.call.views; import android.view.WindowManager; diff --git a/app/src/main/java/org/linphone/views/LinphoneTextureViewOverlay.java b/app/src/main/java/org/linphone/call/views/LinphoneTextureViewOverlay.java similarity index 99% rename from app/src/main/java/org/linphone/views/LinphoneTextureViewOverlay.java rename to app/src/main/java/org/linphone/call/views/LinphoneTextureViewOverlay.java index aa010d457..c5b30ab0d 100644 --- a/app/src/main/java/org/linphone/views/LinphoneTextureViewOverlay.java +++ b/app/src/main/java/org/linphone/call/views/LinphoneTextureViewOverlay.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.linphone.views; +package org.linphone.call.views; import android.content.Context; import android.content.Intent; diff --git a/app/src/main/java/org/linphone/chat/ChatRoomCreationFragment.java b/app/src/main/java/org/linphone/chat/ChatRoomCreationFragment.java index 51b74362d..23b6eb2c4 100644 --- a/app/src/main/java/org/linphone/chat/ChatRoomCreationFragment.java +++ b/app/src/main/java/org/linphone/chat/ChatRoomCreationFragment.java @@ -43,6 +43,7 @@ import java.util.ArrayList; import java.util.List; import org.linphone.LinphoneManager; import org.linphone.R; +import org.linphone.call.views.LinphoneLinearLayoutManager; import org.linphone.contacts.ContactAddress; import org.linphone.contacts.ContactsManager; import org.linphone.contacts.ContactsUpdatedListener; @@ -62,7 +63,6 @@ import org.linphone.core.ProxyConfig; import org.linphone.core.SearchResult; import org.linphone.core.tools.Log; import org.linphone.settings.LinphonePreferences; -import org.linphone.views.LinphoneLinearLayoutManager; public class ChatRoomCreationFragment extends Fragment implements View.OnClickListener, diff --git a/app/src/main/java/org/linphone/chat/ChatRoomsFragment.java b/app/src/main/java/org/linphone/chat/ChatRoomsFragment.java index e8fee018c..da96af6cc 100644 --- a/app/src/main/java/org/linphone/chat/ChatRoomsFragment.java +++ b/app/src/main/java/org/linphone/chat/ChatRoomsFragment.java @@ -35,6 +35,7 @@ import java.util.List; import org.linphone.LinphoneManager; import org.linphone.R; import org.linphone.activities.MainActivity; +import org.linphone.call.views.LinphoneLinearLayoutManager; import org.linphone.contacts.ContactsManager; import org.linphone.contacts.ContactsUpdatedListener; import org.linphone.core.ChatMessage; @@ -44,7 +45,6 @@ import org.linphone.core.Core; import org.linphone.core.CoreListenerStub; import org.linphone.core.ProxyConfig; import org.linphone.utils.SelectableHelper; -import org.linphone.views.LinphoneLinearLayoutManager; public class ChatRoomsFragment extends Fragment implements ContactsUpdatedListener, diff --git a/app/src/main/java/org/linphone/chat/GroupInfoFragment.java b/app/src/main/java/org/linphone/chat/GroupInfoFragment.java index 0b9d27741..1b9a0976f 100644 --- a/app/src/main/java/org/linphone/chat/GroupInfoFragment.java +++ b/app/src/main/java/org/linphone/chat/GroupInfoFragment.java @@ -42,6 +42,7 @@ import androidx.recyclerview.widget.RecyclerView; import java.util.ArrayList; import org.linphone.LinphoneManager; import org.linphone.R; +import org.linphone.call.views.LinphoneLinearLayoutManager; import org.linphone.contacts.ContactAddress; import org.linphone.contacts.ContactsManager; import org.linphone.contacts.LinphoneContact; @@ -56,7 +57,6 @@ import org.linphone.core.Factory; import org.linphone.core.Participant; import org.linphone.core.tools.Log; import org.linphone.utils.LinphoneUtils; -import org.linphone.views.LinphoneLinearLayoutManager; public class GroupInfoFragment extends Fragment { private ImageView mConfirmButton; diff --git a/app/src/main/java/org/linphone/contacts/ContactsFragment.java b/app/src/main/java/org/linphone/contacts/ContactsFragment.java index d5bfd0183..0d6028d75 100644 --- a/app/src/main/java/org/linphone/contacts/ContactsFragment.java +++ b/app/src/main/java/org/linphone/contacts/ContactsFragment.java @@ -39,8 +39,8 @@ import java.util.ArrayList; import java.util.List; import org.linphone.LinphoneManager; import org.linphone.R; +import org.linphone.call.views.LinphoneLinearLayoutManager; import org.linphone.utils.SelectableHelper; -import org.linphone.views.LinphoneLinearLayoutManager; public class ContactsFragment extends Fragment implements OnItemClickListener, diff --git a/app/src/main/java/org/linphone/activities/DialerActivity.java b/app/src/main/java/org/linphone/dialer/DialerActivity.java similarity index 98% rename from app/src/main/java/org/linphone/activities/DialerActivity.java rename to app/src/main/java/org/linphone/dialer/DialerActivity.java index 02c850b98..56e0999bd 100644 --- a/app/src/main/java/org/linphone/activities/DialerActivity.java +++ b/app/src/main/java/org/linphone/dialer/DialerActivity.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.linphone.activities; +package org.linphone.dialer; import android.Manifest; import android.content.Intent; @@ -37,6 +37,7 @@ import java.util.ArrayList; import java.util.Collection; import org.linphone.LinphoneManager; import org.linphone.R; +import org.linphone.activities.MainActivity; import org.linphone.call.views.CallButton; import org.linphone.contacts.ContactsActivity; import org.linphone.contacts.ContactsManager; @@ -44,10 +45,10 @@ import org.linphone.core.Call; import org.linphone.core.Core; import org.linphone.core.CoreListenerStub; import org.linphone.core.tools.Log; +import org.linphone.dialer.views.AddressText; +import org.linphone.dialer.views.Digit; +import org.linphone.dialer.views.EraseButton; import org.linphone.settings.LinphonePreferences; -import org.linphone.views.AddressText; -import org.linphone.views.Digit; -import org.linphone.views.EraseButton; public class DialerActivity extends MainActivity implements AddressText.AddressChangedListener { private static final String ACTION_CALL_LINPHONE = "org.linphone.intent.action.CallLaunched"; diff --git a/app/src/main/java/org/linphone/views/AddressAware.java b/app/src/main/java/org/linphone/dialer/views/AddressAware.java similarity index 96% rename from app/src/main/java/org/linphone/views/AddressAware.java rename to app/src/main/java/org/linphone/dialer/views/AddressAware.java index f43ba4af1..61aa2a63e 100644 --- a/app/src/main/java/org/linphone/views/AddressAware.java +++ b/app/src/main/java/org/linphone/dialer/views/AddressAware.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.linphone.views; +package org.linphone.dialer.views; public interface AddressAware { void setAddressWidget(AddressText address); diff --git a/app/src/main/java/org/linphone/views/AddressText.java b/app/src/main/java/org/linphone/dialer/views/AddressText.java similarity index 99% rename from app/src/main/java/org/linphone/views/AddressText.java rename to app/src/main/java/org/linphone/dialer/views/AddressText.java index 8cdce79ff..ea199cafc 100644 --- a/app/src/main/java/org/linphone/views/AddressText.java +++ b/app/src/main/java/org/linphone/dialer/views/AddressText.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.linphone.views; +package org.linphone.dialer.views; import android.annotation.SuppressLint; import android.content.Context; diff --git a/app/src/main/java/org/linphone/views/AddressType.java b/app/src/main/java/org/linphone/dialer/views/AddressType.java similarity index 96% rename from app/src/main/java/org/linphone/views/AddressType.java rename to app/src/main/java/org/linphone/dialer/views/AddressType.java index 9c15cd4c7..fd3088a4a 100644 --- a/app/src/main/java/org/linphone/views/AddressType.java +++ b/app/src/main/java/org/linphone/dialer/views/AddressType.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.linphone.views; +package org.linphone.dialer.views; public interface AddressType { CharSequence getText(); diff --git a/app/src/main/java/org/linphone/views/Digit.java b/app/src/main/java/org/linphone/dialer/views/Digit.java similarity index 99% rename from app/src/main/java/org/linphone/views/Digit.java rename to app/src/main/java/org/linphone/dialer/views/Digit.java index 409164ffd..951b71210 100644 --- a/app/src/main/java/org/linphone/views/Digit.java +++ b/app/src/main/java/org/linphone/dialer/views/Digit.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.linphone.views; +package org.linphone.dialer.views; import android.annotation.SuppressLint; import android.app.AlertDialog; diff --git a/app/src/main/java/org/linphone/views/EraseButton.java b/app/src/main/java/org/linphone/dialer/views/EraseButton.java similarity index 98% rename from app/src/main/java/org/linphone/views/EraseButton.java rename to app/src/main/java/org/linphone/dialer/views/EraseButton.java index a75688e34..0fc2645af 100644 --- a/app/src/main/java/org/linphone/views/EraseButton.java +++ b/app/src/main/java/org/linphone/dialer/views/EraseButton.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.linphone.views; +package org.linphone.dialer.views; import android.annotation.SuppressLint; import android.content.Context; diff --git a/app/src/main/java/org/linphone/history/HistoryFragment.java b/app/src/main/java/org/linphone/history/HistoryFragment.java index ea73d2054..ede322fb7 100644 --- a/app/src/main/java/org/linphone/history/HistoryFragment.java +++ b/app/src/main/java/org/linphone/history/HistoryFragment.java @@ -38,6 +38,7 @@ import java.util.List; import org.linphone.LinphoneContext; import org.linphone.LinphoneManager; import org.linphone.R; +import org.linphone.call.views.LinphoneLinearLayoutManager; import org.linphone.contacts.ContactsManager; import org.linphone.contacts.ContactsUpdatedListener; import org.linphone.core.Address; @@ -45,7 +46,6 @@ import org.linphone.core.Call; import org.linphone.core.CallLog; import org.linphone.core.Core; import org.linphone.utils.SelectableHelper; -import org.linphone.views.LinphoneLinearLayoutManager; public class HistoryFragment extends Fragment implements OnClickListener, diff --git a/app/src/main/java/org/linphone/notifications/NotificationsManager.java b/app/src/main/java/org/linphone/notifications/NotificationsManager.java index f960c6f54..c16001487 100644 --- a/app/src/main/java/org/linphone/notifications/NotificationsManager.java +++ b/app/src/main/java/org/linphone/notifications/NotificationsManager.java @@ -33,9 +33,7 @@ import android.service.notification.StatusBarNotification; import java.io.File; import java.util.HashMap; import org.linphone.LinphoneManager; -import org.linphone.LinphoneService; import org.linphone.R; -import org.linphone.activities.DialerActivity; import org.linphone.call.CallActivity; import org.linphone.call.CallIncomingActivity; import org.linphone.call.CallOutgoingActivity; @@ -54,7 +52,9 @@ import org.linphone.core.Core; import org.linphone.core.CoreListenerStub; import org.linphone.core.Reason; import org.linphone.core.tools.Log; +import org.linphone.dialer.DialerActivity; import org.linphone.history.HistoryActivity; +import org.linphone.service.LinphoneService; import org.linphone.settings.LinphonePreferences; import org.linphone.utils.DeviceUtils; import org.linphone.utils.FileUtils; diff --git a/app/src/main/java/org/linphone/receivers/BootReceiver.java b/app/src/main/java/org/linphone/receivers/BootReceiver.java index b7a3e53be..a990d871b 100644 --- a/app/src/main/java/org/linphone/receivers/BootReceiver.java +++ b/app/src/main/java/org/linphone/receivers/BootReceiver.java @@ -22,8 +22,8 @@ package org.linphone.receivers; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; -import org.linphone.LinphoneService; import org.linphone.compatibility.Compatibility; +import org.linphone.service.LinphoneService; import org.linphone.settings.LinphonePreferences; public class BootReceiver extends BroadcastReceiver { diff --git a/app/src/main/java/org/linphone/recording/RecordingsActivity.java b/app/src/main/java/org/linphone/recording/RecordingsActivity.java index 480e0e4c4..f1a270d0f 100644 --- a/app/src/main/java/org/linphone/recording/RecordingsActivity.java +++ b/app/src/main/java/org/linphone/recording/RecordingsActivity.java @@ -37,9 +37,9 @@ import java.util.List; import org.linphone.LinphoneManager; import org.linphone.R; import org.linphone.activities.MainActivity; +import org.linphone.call.views.LinphoneLinearLayoutManager; import org.linphone.utils.FileUtils; import org.linphone.utils.SelectableHelper; -import org.linphone.views.LinphoneLinearLayoutManager; public class RecordingsActivity extends MainActivity implements SelectableHelper.DeleteListener, RecordingViewHolder.ClickListener { diff --git a/app/src/main/java/org/linphone/utils/ActivityMonitor.java b/app/src/main/java/org/linphone/service/ActivityMonitor.java similarity index 98% rename from app/src/main/java/org/linphone/utils/ActivityMonitor.java rename to app/src/main/java/org/linphone/service/ActivityMonitor.java index 0a545a5d2..a5eef5e21 100644 --- a/app/src/main/java/org/linphone/utils/ActivityMonitor.java +++ b/app/src/main/java/org/linphone/service/ActivityMonitor.java @@ -17,15 +17,15 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.linphone.utils; +package org.linphone.service; import android.app.Activity; import android.app.Application; import android.os.Bundle; import java.util.ArrayList; import org.linphone.LinphoneManager; -import org.linphone.LinphoneService; import org.linphone.core.tools.Log; +import org.linphone.utils.LinphoneUtils; /** * Believe me or not, but knowing the application visibility state on Android is a nightmare. After diff --git a/app/src/main/java/org/linphone/LinphoneService.java b/app/src/main/java/org/linphone/service/LinphoneService.java similarity index 95% rename from app/src/main/java/org/linphone/LinphoneService.java rename to app/src/main/java/org/linphone/service/LinphoneService.java index 8920b4ad4..73c440809 100644 --- a/app/src/main/java/org/linphone/LinphoneService.java +++ b/app/src/main/java/org/linphone/service/LinphoneService.java @@ -17,22 +17,24 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.linphone; +package org.linphone.service; import android.app.Application; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.view.WindowManager; +import org.linphone.LinphoneContext; +import org.linphone.LinphoneManager; +import org.linphone.R; +import org.linphone.call.views.LinphoneGL2JNIViewOverlay; +import org.linphone.call.views.LinphoneOverlay; +import org.linphone.call.views.LinphoneTextureViewOverlay; import org.linphone.core.Call; import org.linphone.core.Core; import org.linphone.core.tools.Log; import org.linphone.mediastream.Version; import org.linphone.settings.LinphonePreferences; -import org.linphone.utils.ActivityMonitor; -import org.linphone.views.LinphoneGL2JNIViewOverlay; -import org.linphone.views.LinphoneOverlay; -import org.linphone.views.LinphoneTextureViewOverlay; public final class LinphoneService extends Service { private static LinphoneService sInstance; diff --git a/app/src/main/java/org/linphone/utils/ServiceWaitThread.java b/app/src/main/java/org/linphone/service/ServiceWaitThread.java similarity index 95% rename from app/src/main/java/org/linphone/utils/ServiceWaitThread.java rename to app/src/main/java/org/linphone/service/ServiceWaitThread.java index 817607796..60e767e83 100644 --- a/app/src/main/java/org/linphone/utils/ServiceWaitThread.java +++ b/app/src/main/java/org/linphone/service/ServiceWaitThread.java @@ -17,9 +17,9 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.linphone.utils; +package org.linphone.service; -import org.linphone.LinphoneService; +import org.linphone.utils.LinphoneUtils; public class ServiceWaitThread extends Thread { private ServiceWaitThreadListener mListener; diff --git a/app/src/main/java/org/linphone/utils/ServiceWaitThreadListener.java b/app/src/main/java/org/linphone/service/ServiceWaitThreadListener.java similarity index 96% rename from app/src/main/java/org/linphone/utils/ServiceWaitThreadListener.java rename to app/src/main/java/org/linphone/service/ServiceWaitThreadListener.java index 59a9762c4..3f4f19552 100644 --- a/app/src/main/java/org/linphone/utils/ServiceWaitThreadListener.java +++ b/app/src/main/java/org/linphone/service/ServiceWaitThreadListener.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.linphone.utils; +package org.linphone.service; public interface ServiceWaitThreadListener { void onServiceReady(); diff --git a/app/src/main/java/org/linphone/views/AsyncBitmap.java b/app/src/main/java/org/linphone/views/AsyncBitmap.java deleted file mode 100644 index 86ef3e676..000000000 --- a/app/src/main/java/org/linphone/views/AsyncBitmap.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2010-2019 Belledonne Communications SARL. - * - * This file is part of linphone-android - * (see https://www.linphone.org). - * - * 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 3 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, see . - */ -package org.linphone.views; - -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.drawable.BitmapDrawable; -import java.lang.ref.WeakReference; - -class AsyncBitmap extends BitmapDrawable { - private final WeakReference mBitmapWorkerTaskReference; - - public AsyncBitmap(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) { - super(res, bitmap); - mBitmapWorkerTaskReference = new WeakReference<>(bitmapWorkerTask); - } - - public BitmapWorkerTask getBitmapWorkerTask() { - return mBitmapWorkerTaskReference.get(); - } -} diff --git a/app/src/main/java/org/linphone/views/BitmapWorkerTask.java b/app/src/main/java/org/linphone/views/BitmapWorkerTask.java deleted file mode 100644 index 66004db8f..000000000 --- a/app/src/main/java/org/linphone/views/BitmapWorkerTask.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (c) 2010-2019 Belledonne Communications SARL. - * - * This file is part of linphone-android - * (see https://www.linphone.org). - * - * 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 3 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, see . - */ -package org.linphone.views; - -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.Matrix; -import android.graphics.drawable.Drawable; -import android.media.ExifInterface; -import android.net.Uri; -import android.os.AsyncTask; -import android.provider.MediaStore; -import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.RelativeLayout; -import java.io.IOException; -import java.lang.ref.WeakReference; -import org.linphone.LinphoneContext; -import org.linphone.core.tools.Log; -import org.linphone.utils.FileUtils; -import org.linphone.utils.ImageUtils; - -public class BitmapWorkerTask extends AsyncTask { - private String path; - - private final WeakReference mImageViewReference; - private final Bitmap mDefaultBitmap; - private final int mImageViewHeight; - - public BitmapWorkerTask(ImageView imageView, Bitmap defaultBitmap) { - mDefaultBitmap = defaultBitmap; - path = null; - // Use a WeakReference to ensure the ImageView can be garbage collected - mImageViewReference = new WeakReference<>(imageView); - mImageViewHeight = imageView.getMeasuredHeight(); - } - - private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) { - if (imageView != null) { - final Drawable drawable = imageView.getDrawable(); - if (drawable instanceof AsyncBitmap) { - final AsyncBitmap asyncDrawable = (AsyncBitmap) drawable; - return asyncDrawable.getBitmapWorkerTask(); - } - } - return null; - } - - private Bitmap scaleToFitHeight(Bitmap b, int height) { - float factor = height / (float) b.getHeight(); - int dstWidth = (int) (b.getWidth() * factor); - if (dstWidth > 0 && height > 0) { - return Bitmap.createScaledBitmap(b, dstWidth, height, true); - } - return b; - } - - // Decode image in background. - @Override - protected Bitmap doInBackground(String... params) { - Context context = LinphoneContext.instance().getApplicationContext(); - path = params[0]; - Bitmap bm = null; - Bitmap thumbnail = null; - if (FileUtils.isExtensionImage(path)) { - if (path.startsWith("content")) { - try { - bm = - MediaStore.Images.Media.getBitmap( - context.getContentResolver(), Uri.parse(path)); - } catch (IOException e) { - Log.e(e); - } - } else { - bm = BitmapFactory.decodeFile(path); - } - - ImageView imageView = mImageViewReference.get(); - - try { - // Rotate the bitmap if possible/needed, using EXIF data - Matrix matrix = new Matrix(); - ExifInterface exif = new ExifInterface(path); - int width = bm.getWidth(); - int height = bm.getHeight(); - - int pictureOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0); - if (pictureOrientation == 6 || pictureOrientation == 3 || pictureOrientation == 8) { - if (imageView != null) { - float factor = (float) mImageViewHeight / height; - matrix.postScale(factor, factor); - } - if (pictureOrientation == 6) { - matrix.preRotate(90); - } else if (pictureOrientation == 3) { - matrix.preRotate(180); - } else { - matrix.preRotate(270); - } - thumbnail = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, true); - if (thumbnail != bm) { - bm.recycle(); - bm = null; - } - } - } catch (Exception e) { - Log.e(e); - } - - if (thumbnail == null && bm != null) { - if (imageView == null) return bm; - thumbnail = scaleToFitHeight(bm, mImageViewHeight); - if (thumbnail != bm) { - bm.recycle(); - } - } - return thumbnail; - } else { - return mDefaultBitmap; - } - } - - // Once complete, see if ImageView is still around and set bitmap. - @Override - protected void onPostExecute(Bitmap bitmap) { - if (isCancelled()) { - bitmap.recycle(); - bitmap = null; - } - if (mImageViewReference != null && bitmap != null) { - Context context = LinphoneContext.instance().getApplicationContext(); - final ImageView imageView = mImageViewReference.get(); - final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView); - if (this == bitmapWorkerTask && imageView != null) { - imageView.setImageBitmap(bitmap); - if (bitmap.getWidth() > ImageUtils.dpToPixels(context, 300)) { - RelativeLayout.LayoutParams params = - new RelativeLayout.LayoutParams( - bitmap.getWidth(), ViewGroup.LayoutParams.WRAP_CONTENT); - int margin = (int) ImageUtils.dpToPixels(context, 5); - params.setMargins(margin, margin, margin, margin); - imageView.setLayoutParams(params); - imageView.invalidate(); - } - } - } - } -} diff --git a/app/src/main/res/layout-land/dialer.xml b/app/src/main/res/layout-land/dialer.xml index 1951f879f..341bf2ee8 100644 --- a/app/src/main/res/layout-land/dialer.xml +++ b/app/src/main/res/layout-land/dialer.xml @@ -11,7 +11,7 @@ android:layout_marginBottom="10dp" android:background="?attr/lighToolbarBackgroundColor"> - - - - - - - - - - - - - - - - - - - - Date: Wed, 20 Nov 2019 14:41:12 +0100 Subject: [PATCH 44/84] Auto reload of history views when a call ends --- .../history/HistoryDetailFragment.java | 23 +++++++++++++++++++ .../org/linphone/history/HistoryFragment.java | 16 +++++++++++++ 2 files changed, 39 insertions(+) diff --git a/app/src/main/java/org/linphone/history/HistoryDetailFragment.java b/app/src/main/java/org/linphone/history/HistoryDetailFragment.java index bcbaccd59..611c2cd5e 100644 --- a/app/src/main/java/org/linphone/history/HistoryDetailFragment.java +++ b/app/src/main/java/org/linphone/history/HistoryDetailFragment.java @@ -37,12 +37,14 @@ import org.linphone.contacts.ContactsManager; import org.linphone.contacts.LinphoneContact; import org.linphone.contacts.views.ContactAvatar; import org.linphone.core.Address; +import org.linphone.core.Call; import org.linphone.core.CallLog; import org.linphone.core.ChatRoom; import org.linphone.core.ChatRoomBackend; import org.linphone.core.ChatRoomListenerStub; import org.linphone.core.ChatRoomParams; import org.linphone.core.Core; +import org.linphone.core.CoreListenerStub; import org.linphone.core.Factory; import org.linphone.core.FriendCapability; import org.linphone.core.ProxyConfig; @@ -60,6 +62,7 @@ public class HistoryDetailFragment extends Fragment { private ChatRoom mChatRoom; private ChatRoomListenerStub mChatRoomCreationListener; private ListView mLogsList; + private CoreListenerStub mListener; @Override public View onCreateView( @@ -167,14 +170,34 @@ public class HistoryDetailFragment extends Fragment { mLogsList = view.findViewById(R.id.logs_list); displayHistory(); + mListener = + new CoreListenerStub() { + @Override + public void onCallStateChanged( + Core core, Call call, Call.State state, String message) { + if (state == Call.State.End || state == Call.State.Error) { + displayHistory(); + } + } + }; + return view; } + @Override + public void onResume() { + super.onResume(); + + LinphoneManager.getCore().addListener(mListener); + } + @Override public void onPause() { if (mChatRoom != null) { mChatRoom.removeListener(mChatRoomCreationListener); } + LinphoneManager.getCore().removeListener(mListener); + super.onPause(); } diff --git a/app/src/main/java/org/linphone/history/HistoryFragment.java b/app/src/main/java/org/linphone/history/HistoryFragment.java index ede322fb7..cdffb6414 100644 --- a/app/src/main/java/org/linphone/history/HistoryFragment.java +++ b/app/src/main/java/org/linphone/history/HistoryFragment.java @@ -45,6 +45,7 @@ import org.linphone.core.Address; import org.linphone.core.Call; import org.linphone.core.CallLog; import org.linphone.core.Core; +import org.linphone.core.CoreListenerStub; import org.linphone.utils.SelectableHelper; public class HistoryFragment extends Fragment @@ -62,6 +63,7 @@ public class HistoryFragment extends Fragment private List mLogs; private HistoryAdapter mHistoryAdapter; private SelectableHelper mSelectionHelper; + private CoreListenerStub mListener; @Override public View onCreateView( @@ -96,14 +98,27 @@ public class HistoryFragment extends Fragment mAllCalls.setEnabled(false); mOnlyDisplayMissedCalls = false; + mListener = + new CoreListenerStub() { + @Override + public void onCallStateChanged( + Core core, Call call, Call.State state, String message) { + if (state == Call.State.End || state == Call.State.Error) { + reloadData(); + } + } + }; + return view; } @Override public void onResume() { super.onResume(); + ContactsManager.getInstance().addContactsListener(this); LinphoneContext.instance().addCoreStartedListener(this); + LinphoneManager.getCore().addListener(mListener); reloadData(); } @@ -112,6 +127,7 @@ public class HistoryFragment extends Fragment public void onPause() { ContactsManager.getInstance().removeContactsListener(this); LinphoneContext.instance().removeCoreStartedListener(this); + LinphoneManager.getCore().removeListener(mListener); super.onPause(); } From eca542ae280a5038910950f7f151ef211739a98e Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 20 Nov 2019 16:22:24 +0100 Subject: [PATCH 45/84] Fixed back button on chat room group info during creation process --- .../java/org/linphone/chat/ChatActivity.java | 14 +++++++- .../org/linphone/chat/ChatRoomsFragment.java | 4 +-- .../org/linphone/chat/GroupInfoFragment.java | 35 +++++++------------ 3 files changed, 28 insertions(+), 25 deletions(-) diff --git a/app/src/main/java/org/linphone/chat/ChatActivity.java b/app/src/main/java/org/linphone/chat/ChatActivity.java index 2db78e9b9..0b72c846c 100644 --- a/app/src/main/java/org/linphone/chat/ChatActivity.java +++ b/app/src/main/java/org/linphone/chat/ChatActivity.java @@ -20,6 +20,7 @@ package org.linphone.chat; import android.app.Fragment; +import android.app.FragmentManager; import android.content.Intent; import android.net.Uri; import android.os.Bundle; @@ -258,7 +259,18 @@ public class ChatActivity extends MainActivity { ArrayList participants, String subject, boolean encrypted, - boolean isGroupChatRoom) { + boolean isGroupChatRoom, + boolean cleanBackStack) { + if (cleanBackStack) { + FragmentManager fm = getFragmentManager(); + while (fm.getBackStackEntryCount() > 0) { + fm.popBackStackImmediate(); + } + if (isTablet()) { + showEmptyChildFragment(); + } + } + Bundle extras = new Bundle(); if (peerAddress != null) { extras.putSerializable("RemoteSipUri", peerAddress.asStringUriOnly()); diff --git a/app/src/main/java/org/linphone/chat/ChatRoomsFragment.java b/app/src/main/java/org/linphone/chat/ChatRoomsFragment.java index da96af6cc..63866eb37 100644 --- a/app/src/main/java/org/linphone/chat/ChatRoomsFragment.java +++ b/app/src/main/java/org/linphone/chat/ChatRoomsFragment.java @@ -108,7 +108,7 @@ public class ChatRoomsFragment extends Fragment @Override public void onClick(View v) { ((ChatActivity) getActivity()) - .showChatRoomCreation(null, null, null, false, false); + .showChatRoomCreation(null, null, null, false, false, false); } }); @@ -117,7 +117,7 @@ public class ChatRoomsFragment extends Fragment @Override public void onClick(View v) { ((ChatActivity) getActivity()) - .showChatRoomCreation(null, null, null, false, true); + .showChatRoomCreation(null, null, null, false, true, false); } }); diff --git a/app/src/main/java/org/linphone/chat/GroupInfoFragment.java b/app/src/main/java/org/linphone/chat/GroupInfoFragment.java index 1b9a0976f..bfb632412 100644 --- a/app/src/main/java/org/linphone/chat/GroupInfoFragment.java +++ b/app/src/main/java/org/linphone/chat/GroupInfoFragment.java @@ -23,7 +23,6 @@ import static android.content.Context.INPUT_METHOD_SERVICE; import android.app.Dialog; import android.app.Fragment; -import android.app.FragmentManager; import android.os.Bundle; import android.text.Editable; import android.text.TextWatcher; @@ -146,7 +145,11 @@ public class GroupInfoFragment extends Fragment { new View.OnClickListener() { @Override public void onClick(View view) { - ((ChatActivity) getActivity()).goBack(); + if (mIsAlreadyCreatedGroup) { + ((ChatActivity) getActivity()).goBack(); + } else { + goBackToChatCreationFragment(); + } } }); @@ -300,26 +303,14 @@ public class GroupInfoFragment extends Fragment { } private void goBackToChatCreationFragment() { - boolean previousFragmentInBackStackIsChatRoomCreation = false; - FragmentManager fragmentManager = getActivity().getFragmentManager(); - int count = fragmentManager.getBackStackEntryCount(); - if (count > 1) { - FragmentManager.BackStackEntry entry = fragmentManager.getBackStackEntryAt(count - 1); - if ("Chat room creation".equals(entry.getName())) { - previousFragmentInBackStackIsChatRoomCreation = true; - ((ChatActivity) getActivity()).goBack(); - } - } - - if (!previousFragmentInBackStackIsChatRoomCreation) { - ((ChatActivity) getActivity()) - .showChatRoomCreation( - mGroupChatRoomAddress, - mParticipants, - mSubject, - mIsEncryptionEnabled, - true); - } + ((ChatActivity) getActivity()) + .showChatRoomCreation( + mGroupChatRoomAddress, + mParticipants, + mSubject, + mIsEncryptionEnabled, + true, + !mIsAlreadyCreatedGroup); } private void refreshParticipantsList() { From a2e12406416b42b0c32c4341dd445f0e19039927 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 21 Nov 2019 10:28:28 +0100 Subject: [PATCH 46/84] Improved permissions request for calls --- .../java/org/linphone/call/CallActivity.java | 104 +++++++++++++++--- .../linphone/call/CallIncomingActivity.java | 4 +- .../linphone/call/CallOutgoingActivity.java | 3 +- 3 files changed, 91 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/org/linphone/call/CallActivity.java b/app/src/main/java/org/linphone/call/CallActivity.java index 8c52ba2a3..e2fd861e1 100644 --- a/app/src/main/java/org/linphone/call/CallActivity.java +++ b/app/src/main/java/org/linphone/call/CallActivity.java @@ -48,6 +48,7 @@ import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import androidx.drawerlayout.widget.DrawerLayout; import java.lang.ref.WeakReference; +import java.util.ArrayList; import org.linphone.LinphoneManager; import org.linphone.R; import org.linphone.activities.LinphoneGenericActivity; @@ -81,6 +82,7 @@ public class CallActivity extends LinphoneGenericActivity private static final int MIC_TO_DISABLE_MUTE = 1; private static final int WRITE_EXTERNAL_STORAGE_FOR_RECORDING = 2; private static final int CAMERA_TO_ACCEPT_UPDATE = 3; + private static final int ALL_PERMISSIONS = 4; private static class HideControlsRunnable implements Runnable { private WeakReference mWeakCallActivity; @@ -451,6 +453,11 @@ public class CallActivity extends LinphoneGenericActivity protected void onStart() { super.onStart(); + // This also must be done here in case of an outgoing call accepted + // before user granted or denied permissions + // or if an incoming call was answer from the notification + checkAndRequestCallPermissions(); + mCore = LinphoneManager.getCore(); if (mCore != null) { mCore.setNativeVideoWindowId(mRemoteVideo); @@ -581,23 +588,37 @@ public class CallActivity extends LinphoneGenericActivity public void onRequestPermissionsResult( int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { // Permission not granted, won't change anything - if (grantResults[0] != PackageManager.PERMISSION_GRANTED) return; - switch (requestCode) { - case CAMERA_TO_TOGGLE_VIDEO: - LinphoneUtils.reloadVideoDevices(); - toggleVideo(); - break; - case MIC_TO_DISABLE_MUTE: - toggleMic(); - break; - case WRITE_EXTERNAL_STORAGE_FOR_RECORDING: - toggleRecording(); - break; - case CAMERA_TO_ACCEPT_UPDATE: - LinphoneUtils.reloadVideoDevices(); - acceptCallUpdate(true); - break; + if (requestCode == ALL_PERMISSIONS) { + for (int index = 0; index < permissions.length; index++) { + int granted = grantResults[index]; + if (granted == PackageManager.PERMISSION_GRANTED) { + String permission = permissions[index]; + if (Manifest.permission.RECORD_AUDIO.equals(permission)) { + toggleMic(); + } else if (Manifest.permission.CAMERA.equals(permission)) { + LinphoneUtils.reloadVideoDevices(); + } + } + } + } else { + if (grantResults[0] != PackageManager.PERMISSION_GRANTED) return; + switch (requestCode) { + case CAMERA_TO_TOGGLE_VIDEO: + LinphoneUtils.reloadVideoDevices(); + toggleVideo(); + break; + case MIC_TO_DISABLE_MUTE: + toggleMic(); + break; + case WRITE_EXTERNAL_STORAGE_FOR_RECORDING: + toggleRecording(); + break; + case CAMERA_TO_ACCEPT_UPDATE: + LinphoneUtils.reloadVideoDevices(); + acceptCallUpdate(true); + break; + } } } @@ -620,6 +641,57 @@ public class CallActivity extends LinphoneGenericActivity return true; } + private void checkAndRequestCallPermissions() { + ArrayList permissionsList = new ArrayList<>(); + + int recordAudio = + getPackageManager() + .checkPermission(Manifest.permission.RECORD_AUDIO, getPackageName()); + Log.i( + "[Permission] Record audio permission is " + + (recordAudio == PackageManager.PERMISSION_GRANTED + ? "granted" + : "denied")); + int camera = + getPackageManager().checkPermission(Manifest.permission.CAMERA, getPackageName()); + Log.i( + "[Permission] Camera permission is " + + (camera == PackageManager.PERMISSION_GRANTED ? "granted" : "denied")); + + int readPhoneState = + getPackageManager() + .checkPermission(Manifest.permission.READ_PHONE_STATE, getPackageName()); + Log.i( + "[Permission] Read phone state permission is " + + (camera == PackageManager.PERMISSION_GRANTED ? "granted" : "denied")); + + if (recordAudio != PackageManager.PERMISSION_GRANTED) { + Log.i("[Permission] Asking for record audio"); + permissionsList.add(Manifest.permission.RECORD_AUDIO); + } + if (readPhoneState != PackageManager.PERMISSION_GRANTED) { + Log.i("[Permission] Asking for read phone state"); + permissionsList.add(Manifest.permission.READ_PHONE_STATE); + } + + Call call = mCore.getCurrentCall(); + if (LinphonePreferences.instance().shouldInitiateVideoCall() + || (LinphonePreferences.instance().shouldAutomaticallyAcceptVideoRequests() + && call != null + && call.getRemoteParams().videoEnabled())) { + if (camera != PackageManager.PERMISSION_GRANTED) { + Log.i("[Permission] Asking for camera"); + permissionsList.add(Manifest.permission.CAMERA); + } + } + + if (permissionsList.size() > 0) { + String[] permissions = new String[permissionsList.size()]; + permissions = permissionsList.toArray(permissions); + ActivityCompat.requestPermissions(this, permissions, ALL_PERMISSIONS); + } + } + @Override public void onContactsUpdated() { setCurrentCallContactInformation(); diff --git a/app/src/main/java/org/linphone/call/CallIncomingActivity.java b/app/src/main/java/org/linphone/call/CallIncomingActivity.java index db7b8d05e..238eb5d52 100644 --- a/app/src/main/java/org/linphone/call/CallIncomingActivity.java +++ b/app/src/main/java/org/linphone/call/CallIncomingActivity.java @@ -277,8 +277,8 @@ public class CallIncomingActivity extends LinphoneGenericActivity { Log.i("[Permission] Asking for read phone state"); permissionsList.add(Manifest.permission.READ_PHONE_STATE); } - if (LinphonePreferences.instance().shouldInitiateVideoCall() - || LinphonePreferences.instance().shouldAutomaticallyAcceptVideoRequests()) { + if (LinphonePreferences.instance().shouldAutomaticallyAcceptVideoRequests() + && mCall.getRemoteParams().videoEnabled()) { if (camera != PackageManager.PERMISSION_GRANTED) { Log.i("[Permission] Asking for camera"); permissionsList.add(Manifest.permission.CAMERA); diff --git a/app/src/main/java/org/linphone/call/CallOutgoingActivity.java b/app/src/main/java/org/linphone/call/CallOutgoingActivity.java index 90d5c1e15..0bc10864e 100644 --- a/app/src/main/java/org/linphone/call/CallOutgoingActivity.java +++ b/app/src/main/java/org/linphone/call/CallOutgoingActivity.java @@ -283,8 +283,7 @@ public class CallOutgoingActivity extends LinphoneGenericActivity implements OnC Log.i("[Permission] Asking for read phone state"); permissionsList.add(Manifest.permission.READ_PHONE_STATE); } - if (LinphonePreferences.instance().shouldInitiateVideoCall() - || LinphonePreferences.instance().shouldAutomaticallyAcceptVideoRequests()) { + if (LinphonePreferences.instance().shouldInitiateVideoCall()) { if (camera != PackageManager.PERMISSION_GRANTED) { Log.i("[Permission] Asking for camera"); permissionsList.add(Manifest.permission.CAMERA); From 28caf7a5b042ec1c91cd57612fdb3544eae86297 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 20 Nov 2019 17:31:26 +0100 Subject: [PATCH 47/84] Fixed group chat room creation issues --- .../chat/ChatRoomCreationFragment.java | 4 ++-- .../org/linphone/chat/GroupInfoFragment.java | 4 +++- .../contacts/SearchContactViewHolder.java | 4 +++- .../contacts/SearchContactsAdapter.java | 24 +++++++++++-------- 4 files changed, 22 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/org/linphone/chat/ChatRoomCreationFragment.java b/app/src/main/java/org/linphone/chat/ChatRoomCreationFragment.java index 23b6eb2c4..aa4e3eaa9 100644 --- a/app/src/main/java/org/linphone/chat/ChatRoomCreationFragment.java +++ b/app/src/main/java/org/linphone/chat/ChatRoomCreationFragment.java @@ -143,8 +143,8 @@ public class ChatRoomCreationFragment extends Fragment if (mChatRoomAddress == null && mChatRoomSubject == null) { mContactsSelectedLayout.removeAllViews(); } else { - // Pop the back stack twice so we don't have in stack Group -> Creation - // -> Group + // Pop the back stack twice so we don't have in stack + // Group -> Creation -> Group getFragmentManager().popBackStack(); getFragmentManager().popBackStack(); } diff --git a/app/src/main/java/org/linphone/chat/GroupInfoFragment.java b/app/src/main/java/org/linphone/chat/GroupInfoFragment.java index bfb632412..02126b2c9 100644 --- a/app/src/main/java/org/linphone/chat/GroupInfoFragment.java +++ b/app/src/main/java/org/linphone/chat/GroupInfoFragment.java @@ -476,7 +476,9 @@ public class GroupInfoFragment extends Fragment { } Address[] participantsToAdd = new Address[toAdd.size()]; toAdd.toArray(participantsToAdd); - mChatRoom.addParticipants(participantsToAdd); + if (!mChatRoom.addParticipants(participantsToAdd)) { + // TODO error + } // Pop back stack to go back to the Messages fragment getFragmentManager().popBackStack(); } diff --git a/app/src/main/java/org/linphone/contacts/SearchContactViewHolder.java b/app/src/main/java/org/linphone/contacts/SearchContactViewHolder.java index 89a47050e..8085860e6 100644 --- a/app/src/main/java/org/linphone/contacts/SearchContactViewHolder.java +++ b/app/src/main/java/org/linphone/contacts/SearchContactViewHolder.java @@ -54,7 +54,9 @@ public class SearchContactViewHolder extends RecyclerView.ViewHolder @Override public void onClick(View view) { if (mListener != null) { - mListener.onItemClicked(getAdapterPosition()); + if (disabled.getVisibility() == View.GONE) { + mListener.onItemClicked(getAdapterPosition()); + } } } diff --git a/app/src/main/java/org/linphone/contacts/SearchContactsAdapter.java b/app/src/main/java/org/linphone/contacts/SearchContactsAdapter.java index c41d6022f..c0e67e03e 100644 --- a/app/src/main/java/org/linphone/contacts/SearchContactsAdapter.java +++ b/app/src/main/java/org/linphone/contacts/SearchContactsAdapter.java @@ -32,6 +32,7 @@ import org.linphone.LinphoneManager; import org.linphone.R; import org.linphone.contacts.views.ContactAvatar; import org.linphone.core.Address; +import org.linphone.core.Core; import org.linphone.core.FriendCapability; import org.linphone.core.PresenceBasicStatus; import org.linphone.core.PresenceModel; @@ -118,8 +119,20 @@ public class SearchContactsAdapter extends RecyclerView.Adapter Date: Wed, 20 Nov 2019 14:52:26 +0100 Subject: [PATCH 48/84] Use new method to delete linphone friend --- .../java/org/linphone/contacts/LinphoneContact.java | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/app/src/main/java/org/linphone/contacts/LinphoneContact.java b/app/src/main/java/org/linphone/contacts/LinphoneContact.java index 6c24b0594..e1d86e244 100644 --- a/app/src/main/java/org/linphone/contacts/LinphoneContact.java +++ b/app/src/main/java/org/linphone/contacts/LinphoneContact.java @@ -405,19 +405,8 @@ public class LinphoneContact extends AndroidContact Core core = LinphoneManager.getCore(); if (core == null) return; - boolean found = false; Log.i("[Contact] Deleting friend ", mFriend.getName(), " for contact ", this); - for (FriendList list : core.getFriendsLists()) { - FriendList.Status status = list.removeFriend(mFriend); - if (status == FriendList.Status.OK) { - Log.w("[Contact] Friend found in list " + list.getDisplayName()); - found = true; - } - } - - if (!found) { - Log.w("[Contact] Friend removal failed, friend doesn't belong to any friend list"); - } + mFriend.remove(); } public void createOrUpdateFriendFromNativeContact() { From 76e2d3bf9776fe621aba53f1b33f573e17f14fdd Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 21 Nov 2019 14:51:08 +0100 Subject: [PATCH 49/84] Minor improvements --- app/src/main/java/org/linphone/LinphoneManager.java | 5 +++-- app/src/main/java/org/linphone/call/CallStatsFragment.java | 4 ++-- .../main/java/org/linphone/chat/ChatMessagesFragment.java | 2 +- app/src/main/java/org/linphone/contacts/LinphoneContact.java | 1 - 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/org/linphone/LinphoneManager.java b/app/src/main/java/org/linphone/LinphoneManager.java index fd5c49ca3..7161c49e9 100644 --- a/app/src/main/java/org/linphone/LinphoneManager.java +++ b/app/src/main/java/org/linphone/LinphoneManager.java @@ -356,6 +356,7 @@ public class LinphoneManager implements SensorEventListener { } public void restartCore() { + Log.w("[Manager] Restarting Core"); mCore.stop(); mCore.start(); } @@ -363,8 +364,8 @@ public class LinphoneManager implements SensorEventListener { private void destroyCore() { Log.w("[Manager] Destroying Core"); if (LinphonePreferences.instance() != null) { - // We set network reachable at false before destroy LC to not send register with expires - // at 0 + // We set network reachable at false before destroying the Core + // to not send a register with expires at 0 if (LinphonePreferences.instance().isPushNotificationEnabled()) { Log.w( "[Manager] Setting network reachability to False to prevent unregister and allow incoming push notifications"); diff --git a/app/src/main/java/org/linphone/call/CallStatsFragment.java b/app/src/main/java/org/linphone/call/CallStatsFragment.java index d088baf71..504a99e87 100644 --- a/app/src/main/java/org/linphone/call/CallStatsFragment.java +++ b/app/src/main/java/org/linphone/call/CallStatsFragment.java @@ -55,8 +55,8 @@ public class CallStatsFragment extends Fragment { new CoreListenerStub() { @Override public void onCallStateChanged( - Core lc, Call call, Call.State cstate, String message) { - if (cstate == Call.State.End || cstate == Call.State.Error) { + Core core, Call call, Call.State state, String message) { + if (state == Call.State.End || state == Call.State.Error) { mAdapter.updateListItems( Arrays.asList(LinphoneManager.getCore().getCalls())); } diff --git a/app/src/main/java/org/linphone/chat/ChatMessagesFragment.java b/app/src/main/java/org/linphone/chat/ChatMessagesFragment.java index 11abad297..ad3885033 100644 --- a/app/src/main/java/org/linphone/chat/ChatMessagesFragment.java +++ b/app/src/main/java/org/linphone/chat/ChatMessagesFragment.java @@ -349,7 +349,7 @@ public class ChatMessagesFragment extends Fragment new CoreListenerStub() { @Override public void onCallStateChanged( - Core lc, Call call, Call.State state, String message) { + Core core, Call call, Call.State state, String message) { displayChatRoomHeader(); } }; diff --git a/app/src/main/java/org/linphone/contacts/LinphoneContact.java b/app/src/main/java/org/linphone/contacts/LinphoneContact.java index e1d86e244..b1e91479c 100644 --- a/app/src/main/java/org/linphone/contacts/LinphoneContact.java +++ b/app/src/main/java/org/linphone/contacts/LinphoneContact.java @@ -33,7 +33,6 @@ import org.linphone.core.Address; import org.linphone.core.Core; import org.linphone.core.Friend; import org.linphone.core.FriendCapability; -import org.linphone.core.FriendList; import org.linphone.core.PresenceBasicStatus; import org.linphone.core.PresenceModel; import org.linphone.core.SubscribePolicy; From 7d5ead8ba0aa058a69f5e81066eff9de1c1c697c Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 22 Nov 2019 16:12:56 +0100 Subject: [PATCH 50/84] Fixed call transfer button --- .../main/java/org/linphone/call/CallActivity.java | 5 ----- .../java/org/linphone/dialer/DialerActivity.java | 15 +++++++++------ 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/org/linphone/call/CallActivity.java b/app/src/main/java/org/linphone/call/CallActivity.java index e2fd861e1..f2948d69b 100644 --- a/app/src/main/java/org/linphone/call/CallActivity.java +++ b/app/src/main/java/org/linphone/call/CallActivity.java @@ -564,11 +564,6 @@ public class CallActivity extends LinphoneGenericActivity super.onDestroy(); } - @Override - protected void onNewIntent(Intent intent) { - super.onNewIntent(intent); - } - @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (mAudioManager.onKeyVolumeAdjust(keyCode)) return true; diff --git a/app/src/main/java/org/linphone/dialer/DialerActivity.java b/app/src/main/java/org/linphone/dialer/DialerActivity.java index 56e0999bd..2a60f7297 100644 --- a/app/src/main/java/org/linphone/dialer/DialerActivity.java +++ b/app/src/main/java/org/linphone/dialer/DialerActivity.java @@ -67,6 +67,8 @@ public class DialerActivity extends MainActivity implements AddressText.AddressC super.onCreate(savedInstanceState); mInterfaceLoaded = false; + mIsTransfer = false; + // Uses the fragment container layout to inflate the dialer view instead of using a fragment new AsyncLayoutInflater(this) .inflate( @@ -122,6 +124,8 @@ public class DialerActivity extends MainActivity implements AddressText.AddressC @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); + + setIntent(intent); handleIntentParams(intent); } @@ -207,12 +211,6 @@ public class DialerActivity extends MainActivity implements AddressText.AddressC } }); - mIsTransfer = false; - if (getIntent() != null) { - mIsTransfer = getIntent().getBooleanExtra("Transfer", false); - mAddress.setText(getIntent().getStringExtra("SipUri")); - } - setUpNumpad(view); updateLayout(); enableVideoPreviewIfTablet(true); @@ -282,6 +280,11 @@ public class DialerActivity extends MainActivity implements AddressText.AddressC } } + if (getIntent() != null) { + mIsTransfer = getIntent().getBooleanExtra("Transfer", false); + mAddress.setText(getIntent().getStringExtra("SipUri")); + } + mBackToCall.setVisibility(atLeastOneCall ? View.VISIBLE : View.GONE); mAddCall.setVisibility(atLeastOneCall && !mIsTransfer ? View.VISIBLE : View.GONE); mTransferCall.setVisibility(atLeastOneCall && mIsTransfer ? View.VISIBLE : View.GONE); From 9a928fbb410362c948ca059e66e36e7f167ef8c0 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 22 Nov 2019 16:32:59 +0100 Subject: [PATCH 51/84] Added more logs for BT SCO process + refresh audio routes while in call if BT headset connects/disconnects --- .../org/linphone/call/AndroidAudioManager.java | 13 ++++++++++--- .../java/org/linphone/dialer/DialerActivity.java | 15 ++++++--------- .../org/linphone/receivers/BluetoothReceiver.java | 9 +++++++++ 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/org/linphone/call/AndroidAudioManager.java b/app/src/main/java/org/linphone/call/AndroidAudioManager.java index 3c20d6ead..ce561c13d 100644 --- a/app/src/main/java/org/linphone/call/AndroidAudioManager.java +++ b/app/src/main/java/org/linphone/call/AndroidAudioManager.java @@ -438,6 +438,7 @@ public class AndroidAudioManager { public synchronized void bluetoothHeadetConnectionChanged(boolean connected) { mIsBluetoothHeadsetConnected = connected; mAudioManager.setBluetoothScoOn(connected); + LinphoneManager.getCallManager().refreshInCallActions(); } public synchronized void bluetoothHeadetAudioConnectionChanged(boolean connected) { @@ -485,8 +486,10 @@ public class AndroidAudioManager { new Thread() { @Override public void run() { - boolean resultAcknoledged; + Log.i("[Audio Manager] [Bluetooth] SCO start/stop thread started"); + boolean resultAcknowledged; int retries = 0; + do { try { Thread.sleep(200); @@ -506,10 +509,10 @@ public class AndroidAudioManager { + retries); mAudioManager.stopBluetoothSco(); } - resultAcknoledged = isUsingBluetoothAudioRoute() == enable; + resultAcknowledged = isUsingBluetoothAudioRoute() == enable; retries++; } - } while (!resultAcknoledged && retries < 10); + } while (!resultAcknowledged && retries < 10); } }.start(); } @@ -523,6 +526,7 @@ public class AndroidAudioManager { } else { Log.w("[Audio Manager] [Bluetooth] SCO not available off call !"); } + if (mBluetoothAdapter.isEnabled()) { Log.i("[Audio Manager] [Bluetooth] Adapter enabled"); mBluetoothReceiver = new BluetoothReceiver(); @@ -557,6 +561,8 @@ public class AndroidAudioManager { Intent sticky = mContext.registerReceiver(mBluetoothReceiver, filter); + Log.i( + "[Audio Manager] [Bluetooth] Bluetooth receiver registered"); int state = sticky.getIntExtra( AudioManager.EXTRA_SCO_AUDIO_STATE, @@ -593,6 +599,7 @@ public class AndroidAudioManager { } } }; + mBluetoothAdapter.getProfileProxy( mContext, bluetoothServiceListener, BluetoothProfile.HEADSET); } diff --git a/app/src/main/java/org/linphone/dialer/DialerActivity.java b/app/src/main/java/org/linphone/dialer/DialerActivity.java index 2a60f7297..56e0999bd 100644 --- a/app/src/main/java/org/linphone/dialer/DialerActivity.java +++ b/app/src/main/java/org/linphone/dialer/DialerActivity.java @@ -67,8 +67,6 @@ public class DialerActivity extends MainActivity implements AddressText.AddressC super.onCreate(savedInstanceState); mInterfaceLoaded = false; - mIsTransfer = false; - // Uses the fragment container layout to inflate the dialer view instead of using a fragment new AsyncLayoutInflater(this) .inflate( @@ -124,8 +122,6 @@ public class DialerActivity extends MainActivity implements AddressText.AddressC @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); - - setIntent(intent); handleIntentParams(intent); } @@ -211,6 +207,12 @@ public class DialerActivity extends MainActivity implements AddressText.AddressC } }); + mIsTransfer = false; + if (getIntent() != null) { + mIsTransfer = getIntent().getBooleanExtra("Transfer", false); + mAddress.setText(getIntent().getStringExtra("SipUri")); + } + setUpNumpad(view); updateLayout(); enableVideoPreviewIfTablet(true); @@ -280,11 +282,6 @@ public class DialerActivity extends MainActivity implements AddressText.AddressC } } - if (getIntent() != null) { - mIsTransfer = getIntent().getBooleanExtra("Transfer", false); - mAddress.setText(getIntent().getStringExtra("SipUri")); - } - mBackToCall.setVisibility(atLeastOneCall ? View.VISIBLE : View.GONE); mAddCall.setVisibility(atLeastOneCall && !mIsTransfer ? View.VISIBLE : View.GONE); mTransferCall.setVisibility(atLeastOneCall && mIsTransfer ? View.VISIBLE : View.GONE); diff --git a/app/src/main/java/org/linphone/receivers/BluetoothReceiver.java b/app/src/main/java/org/linphone/receivers/BluetoothReceiver.java index d2e677e1a..fee24a678 100644 --- a/app/src/main/java/org/linphone/receivers/BluetoothReceiver.java +++ b/app/src/main/java/org/linphone/receivers/BluetoothReceiver.java @@ -28,9 +28,16 @@ import org.linphone.LinphoneManager; import org.linphone.core.tools.Log; public class BluetoothReceiver extends BroadcastReceiver { + public BluetoothReceiver() { + super(); + Log.i("[Bluetooth] Bluetooth receiver created"); + } + @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); + Log.i("[Bluetooth] Bluetooth broadcast received"); + if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) { int state = intent.getIntExtra( @@ -55,6 +62,8 @@ public class BluetoothReceiver extends BroadcastReceiver { } else if (state == BluetoothHeadset.STATE_AUDIO_DISCONNECTED) { Log.i("[Bluetooth] Bluetooth headset audio disconnected"); LinphoneManager.getAudioManager().bluetoothHeadetAudioConnectionChanged(false); + } else if (state == BluetoothHeadset.STATE_AUDIO_CONNECTING) { + Log.i("[Bluetooth] Bluetooth headset audio connecting"); } else { Log.w("[Bluetooth] Bluetooth headset unknown audio state changed: " + state); } From 92b3832ab8dcddf4b05ac6e43ada2f53fb41d196 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 26 Nov 2019 14:54:56 +0100 Subject: [PATCH 52/84] Fixed incoming call activity not finished if cancelled by remote while at least a call is running --- app/src/main/java/org/linphone/call/CallIncomingActivity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/linphone/call/CallIncomingActivity.java b/app/src/main/java/org/linphone/call/CallIncomingActivity.java index 238eb5d52..ff11a0d7e 100644 --- a/app/src/main/java/org/linphone/call/CallIncomingActivity.java +++ b/app/src/main/java/org/linphone/call/CallIncomingActivity.java @@ -128,7 +128,7 @@ public class CallIncomingActivity extends LinphoneGenericActivity { } } - if (LinphoneManager.getCore().getCallsNb() == 0) { + if (state == State.End || state == State.Released) { finish(); } } From e550efc094fe8df6cfdd98faa44401d2a173766c Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 27 Nov 2019 11:11:57 +0100 Subject: [PATCH 53/84] Fixed minor contact related issues --- .../contacts/ContactEditorFragment.java | 28 +++++++++---------- .../linphone/contacts/LinphoneContact.java | 3 +- .../org/linphone/dialer/DialerActivity.java | 8 ++++-- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/org/linphone/contacts/ContactEditorFragment.java b/app/src/main/java/org/linphone/contacts/ContactEditorFragment.java index 9d7c34b7f..9c49daab9 100644 --- a/app/src/main/java/org/linphone/contacts/ContactEditorFragment.java +++ b/app/src/main/java/org/linphone/contacts/ContactEditorFragment.java @@ -136,12 +136,15 @@ public class ContactEditorFragment extends Fragment { if (mIsNewContact) { boolean areAllFielsEmpty = true; for (LinphoneNumberOrAddress nounoa : mNumbersAndAddresses) { - if (nounoa.getValue() != null && !nounoa.getValue().equals("")) { + String value = nounoa.getValue(); + if (value != null && !value.trim().isEmpty()) { areAllFielsEmpty = false; break; } } if (areAllFielsEmpty) { + Log.i( + "[Contact Editor] All SIP and phone fields are empty, aborting"); getFragmentManager().popBackStackImmediate(); return; } @@ -158,27 +161,24 @@ public class ContactEditorFragment extends Fragment { } for (LinphoneNumberOrAddress noa : mNumbersAndAddresses) { - if (noa.getValue() == null || noa.getValue().isEmpty()) { - if (noa.getOldValue() != null && !noa.getOldValue().isEmpty()) { - Log.i("[Contact Editor] Removing number " + noa.getOldValue()); + String value = noa.getValue(); + String oldValue = noa.getOldValue(); + + if (value == null || value.trim().isEmpty()) { + if (oldValue != null && !oldValue.isEmpty()) { + Log.i("[Contact Editor] Removing number " + oldValue); mContact.removeNumberOrAddress(noa); } } else { - if (noa.getOldValue() != null - && noa.getOldValue().equals(noa.getValue())) { - Log.i( - "[Contact Editor] Keeping existing number " - + noa.getValue()); + if (oldValue != null && oldValue.equals(value)) { + Log.i("[Contact Editor] Keeping existing number " + value); continue; } if (noa.isSIPAddress()) { - - noa.setValue( - LinphoneUtils.getFullAddressFromUsername( - noa.getValue())); + noa.setValue(LinphoneUtils.getFullAddressFromUsername(value)); } - Log.i("[Contact Editor] Adding new number " + noa.getValue()); + Log.i("[Contact Editor] Adding new number " + value); mContact.addOrUpdateNumberOrAddress(noa); } diff --git a/app/src/main/java/org/linphone/contacts/LinphoneContact.java b/app/src/main/java/org/linphone/contacts/LinphoneContact.java index b1e91479c..d9dee45fe 100644 --- a/app/src/main/java/org/linphone/contacts/LinphoneContact.java +++ b/app/src/main/java/org/linphone/contacts/LinphoneContact.java @@ -559,7 +559,8 @@ public class LinphoneContact extends AndroidContact String data3 = c.getString(c.getColumnIndex("data3")); String data4 = c.getString(c.getColumnIndex("data4")); - if (getFullName() == null) { + String fullName = getFullName(); + if (fullName == null || !fullName.equals(displayName)) { Log.d("[Linphone Contact] Setting display name " + displayName); setFullName(displayName); } diff --git a/app/src/main/java/org/linphone/dialer/DialerActivity.java b/app/src/main/java/org/linphone/dialer/DialerActivity.java index 56e0999bd..6e1e3a534 100644 --- a/app/src/main/java/org/linphone/dialer/DialerActivity.java +++ b/app/src/main/java/org/linphone/dialer/DialerActivity.java @@ -221,14 +221,15 @@ public class DialerActivity extends MainActivity implements AddressText.AddressC private void enableVideoPreviewIfTablet(boolean enable) { Core core = LinphoneManager.getCore(); TextureView preview = findViewById(R.id.video_preview); - if (preview != null && core != null) { + ImageView changeCamera = findViewById(R.id.video_preview_change_camera); + + if (preview != null && changeCamera != null && core != null) { if (enable && isTablet() && LinphonePreferences.instance().isVideoPreviewEnabled()) { preview.setVisibility(View.VISIBLE); core.setNativePreviewWindowId(preview); core.enableVideoPreview(true); - ImageView changeCamera = findViewById(R.id.video_preview_change_camera); - if (changeCamera != null && core.getVideoDevicesList().length > 1) { + if (core.getVideoDevicesList().length > 1) { changeCamera.setVisibility(View.VISIBLE); changeCamera.setOnClickListener( new View.OnClickListener() { @@ -240,6 +241,7 @@ public class DialerActivity extends MainActivity implements AddressText.AddressC } } else { preview.setVisibility(View.GONE); + changeCamera.setVisibility(View.GONE); core.setNativePreviewWindowId(null); core.enableVideoPreview(false); } From 006737b18bfe900c3d9a197770f066772fefde02 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 27 Nov 2019 11:24:15 +0100 Subject: [PATCH 54/84] Disable chat message content click action if edition mode enabled --- .../linphone/chat/ChatMessageViewHolder.java | 19 ++++++++++++++----- .../linphone/chat/ChatMessagesAdapter.java | 1 + 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/org/linphone/chat/ChatMessageViewHolder.java b/app/src/main/java/org/linphone/chat/ChatMessageViewHolder.java index 59c0ee4b7..5c59fa274 100644 --- a/app/src/main/java/org/linphone/chat/ChatMessageViewHolder.java +++ b/app/src/main/java/org/linphone/chat/ChatMessageViewHolder.java @@ -82,6 +82,7 @@ public class ChatMessageViewHolder extends RecyclerView.ViewHolder implements Vi private final RelativeLayout singleFileContent; public final CheckBox delete; + public boolean isEditionEnabled; private Context mContext; private ChatMessageViewHolderClickListener mListener; @@ -275,7 +276,11 @@ public class ChatMessageViewHolder extends RecyclerView.ViewHolder implements Vi new View.OnClickListener() { @Override public void onClick(View v) { - openFile(filePath); + if (isEditionEnabled) { + ChatMessageViewHolder.this.onClick(v); + } else { + openFile(filePath); + } } }); } else { @@ -315,11 +320,15 @@ public class ChatMessageViewHolder extends RecyclerView.ViewHolder implements Vi new View.OnClickListener() { @Override public void onClick(View v) { - Content c = (Content) v.getTag(); - if (!message.isFileTransferInProgress()) { - message.downloadContent(c); + if (isEditionEnabled) { + ChatMessageViewHolder.this.onClick(v); } else { - message.cancelFileTransfer(); + Content c = (Content) v.getTag(); + if (!message.isFileTransferInProgress()) { + message.downloadContent(c); + } else { + message.cancelFileTransfer(); + } } } }); diff --git a/app/src/main/java/org/linphone/chat/ChatMessagesAdapter.java b/app/src/main/java/org/linphone/chat/ChatMessagesAdapter.java index 7fc4e7718..c4d5ff848 100644 --- a/app/src/main/java/org/linphone/chat/ChatMessagesAdapter.java +++ b/app/src/main/java/org/linphone/chat/ChatMessagesAdapter.java @@ -119,6 +119,7 @@ public class ChatMessagesAdapter extends SelectableAdapter Date: Wed, 27 Nov 2019 11:25:25 +0100 Subject: [PATCH 55/84] Fixed 1-1 chat room devices view title --- .../org/linphone/chat/DevicesFragment.java | 26 ------------------- 1 file changed, 26 deletions(-) diff --git a/app/src/main/java/org/linphone/chat/DevicesFragment.java b/app/src/main/java/org/linphone/chat/DevicesFragment.java index 35ad77cd6..72d3f1d18 100644 --- a/app/src/main/java/org/linphone/chat/DevicesFragment.java +++ b/app/src/main/java/org/linphone/chat/DevicesFragment.java @@ -26,16 +26,12 @@ import android.view.View; import android.view.ViewGroup; import android.widget.ExpandableListView; import android.widget.ImageView; -import android.widget.TextView; import androidx.annotation.Nullable; import java.util.ArrayList; import org.linphone.LinphoneManager; import org.linphone.R; -import org.linphone.contacts.ContactsManager; -import org.linphone.contacts.LinphoneContact; import org.linphone.core.Address; import org.linphone.core.ChatRoom; -import org.linphone.core.ChatRoomCapabilities; import org.linphone.core.Core; import org.linphone.core.Factory; import org.linphone.core.Participant; @@ -43,7 +39,6 @@ import org.linphone.core.ParticipantDevice; import org.linphone.utils.LinphoneUtils; public class DevicesFragment extends Fragment { - private TextView mTitle; private ExpandableListView mExpandableList; private DevicesAdapter mAdapter; @@ -114,9 +109,6 @@ public class DevicesFragment extends Fragment { initChatRoom(); - mTitle = view.findViewById(R.id.title); - initHeader(); - ImageView backButton = view.findViewById(R.id.back); backButton.setOnClickListener( new View.OnClickListener() { @@ -146,24 +138,6 @@ public class DevicesFragment extends Fragment { mRoom = core.getChatRoom(mRoomAddr, mLocalSipAddr); } - private void initHeader() { - if (mRoom.hasCapability(ChatRoomCapabilities.OneToOne.toInt())) { - Address remoteParticipantAddr = mRoomAddr; - if (mRoom.getParticipants().length > 0) { - remoteParticipantAddr = mRoom.getParticipants()[0].getAddress(); - } - LinphoneContact c = - ContactsManager.getInstance().findContactFromAddress(remoteParticipantAddr); - String displayName; - if (c != null) { - displayName = c.getFullName(); - } else { - displayName = LinphoneUtils.getAddressDisplayName(remoteParticipantAddr); - } - mTitle.setText(getString(R.string.chat_room_devices).replace("%s", displayName)); - } - } - private void initValues() { if (mAdapter == null) { mAdapter = new DevicesAdapter(getActivity()); From ba4a0afb7a6f0f3833c78dc4eec315696dbc757a Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 27 Nov 2019 11:30:57 +0100 Subject: [PATCH 56/84] Reset pending contact creation/edition values when leaving contacts activity --- .../java/org/linphone/contacts/ContactsActivity.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/src/main/java/org/linphone/contacts/ContactsActivity.java b/app/src/main/java/org/linphone/contacts/ContactsActivity.java index a4236d1d4..5559e19c8 100644 --- a/app/src/main/java/org/linphone/contacts/ContactsActivity.java +++ b/app/src/main/java/org/linphone/contacts/ContactsActivity.java @@ -102,6 +102,15 @@ public class ContactsActivity extends MainActivity { mContactsSelected.setVisibility(View.VISIBLE); } + @Override + protected void onPause() { + // From the moment this activity is leaved, clear these values + mEditDisplayName = null; + mEditSipUri = null; + mEditOnClick = false; + super.onPause(); + } + @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); From 3d1f4a69c4790c3f0a5de6ec0ee13f65af0c4ce4 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 27 Nov 2019 11:57:42 +0100 Subject: [PATCH 57/84] Fixed basic chat room creation with another account --- .../main/java/org/linphone/chat/ChatRoomCreationFragment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/linphone/chat/ChatRoomCreationFragment.java b/app/src/main/java/org/linphone/chat/ChatRoomCreationFragment.java index aa4e3eaa9..dda1fcd84 100644 --- a/app/src/main/java/org/linphone/chat/ChatRoomCreationFragment.java +++ b/app/src/main/java/org/linphone/chat/ChatRoomCreationFragment.java @@ -448,7 +448,7 @@ public class ChatRoomCreationFragment extends Fragment mChatRoom.getLocalAddress(), mChatRoom.getPeerAddress()); } } else { - ChatRoom chatRoom = core.getChatRoom(address); + ChatRoom chatRoom = core.getChatRoom(address, lpc.getIdentityAddress()); if (chatRoom != null) { // Pop back stack so back button takes to the chat rooms list getFragmentManager().popBackStack(); From 60b4265aef78bad03294404cd11b9cb8e5009576 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 27 Nov 2019 12:57:16 +0100 Subject: [PATCH 58/84] Have device back button behave like one in top bar --- .../java/org/linphone/assistant/AssistantActivity.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/src/main/java/org/linphone/assistant/AssistantActivity.java b/app/src/main/java/org/linphone/assistant/AssistantActivity.java index b404dac4d..996f356e5 100644 --- a/app/src/main/java/org/linphone/assistant/AssistantActivity.java +++ b/app/src/main/java/org/linphone/assistant/AssistantActivity.java @@ -22,6 +22,7 @@ package org.linphone.assistant; import android.app.AlertDialog; import android.content.Intent; import android.telephony.TelephonyManager; +import android.view.KeyEvent; import android.view.View; import android.view.WindowManager; import android.widget.EditText; @@ -90,6 +91,14 @@ public abstract class AssistantActivity extends LinphoneGenericActivity } } + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (!mBack.isEnabled()) return true; + } + return super.onKeyDown(keyCode, event); + } + public AccountCreator getAccountCreator() { return LinphoneManager.getInstance().getAccountCreator(); } From d2b488f59813cc6fc9d8b4edd162f2a6a9debe4a Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 27 Nov 2019 13:01:22 +0100 Subject: [PATCH 59/84] Fixed auto reload of history while in details view --- .../main/java/org/linphone/history/HistoryDetailFragment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/linphone/history/HistoryDetailFragment.java b/app/src/main/java/org/linphone/history/HistoryDetailFragment.java index 611c2cd5e..699edb9ee 100644 --- a/app/src/main/java/org/linphone/history/HistoryDetailFragment.java +++ b/app/src/main/java/org/linphone/history/HistoryDetailFragment.java @@ -168,7 +168,6 @@ public class HistoryDetailFragment extends Fragment { }; mLogsList = view.findViewById(R.id.logs_list); - displayHistory(); mListener = new CoreListenerStub() { @@ -189,6 +188,7 @@ public class HistoryDetailFragment extends Fragment { super.onResume(); LinphoneManager.getCore().addListener(mListener); + displayHistory(); } @Override From 7f2d427f8a5b57f335ef3905c37c76565836834c Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 27 Nov 2019 13:18:21 +0100 Subject: [PATCH 60/84] Added missing callbacks in group info to refresh view on participant event --- .../main/java/org/linphone/chat/GroupInfoFragment.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/src/main/java/org/linphone/chat/GroupInfoFragment.java b/app/src/main/java/org/linphone/chat/GroupInfoFragment.java index 02126b2c9..331200c2d 100644 --- a/app/src/main/java/org/linphone/chat/GroupInfoFragment.java +++ b/app/src/main/java/org/linphone/chat/GroupInfoFragment.java @@ -265,6 +265,16 @@ public class GroupInfoFragment extends Fragment { public void onSubjectChanged(ChatRoom cr, EventLog event_log) { mSubjectField.setText(event_log.getSubject()); } + + @Override + public void onParticipantAdded(ChatRoom cr, EventLog eventLog) { + refreshParticipantsList(); + } + + @Override + public void onParticipantRemoved(ChatRoom cr, EventLog eventLog) { + refreshParticipantsList(); + } }; if (mChatRoom != null) { From 2e6355289f6f176ce70bbfbc466d78b579eea2be Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 27 Nov 2019 13:24:47 +0100 Subject: [PATCH 61/84] Scroll chat rooms list to top when a new one is created to ensure it is visible --- app/src/main/java/org/linphone/chat/ChatRoomsFragment.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/src/main/java/org/linphone/chat/ChatRoomsFragment.java b/app/src/main/java/org/linphone/chat/ChatRoomsFragment.java index 63866eb37..f70bcb3f2 100644 --- a/app/src/main/java/org/linphone/chat/ChatRoomsFragment.java +++ b/app/src/main/java/org/linphone/chat/ChatRoomsFragment.java @@ -157,6 +157,7 @@ public class ChatRoomsFragment extends Fragment Core core, ChatRoom cr, ChatRoom.State state) { if (state == ChatRoom.State.Created) { refreshChatRoom(cr); + scrollToTop(); } } }; @@ -263,6 +264,10 @@ public class ChatRoomsFragment extends Fragment } } + private void scrollToTop() { + mChatRoomsList.getLayoutManager().scrollToPosition(0); + } + private void refreshChatRoom(ChatRoom cr) { ChatRoomViewHolder holder = (ChatRoomViewHolder) cr.getUserData(); if (holder != null) { From 53d8788cb1f44c5bcff8449691a8b81ee8e11d5d Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 27 Nov 2019 13:30:54 +0100 Subject: [PATCH 62/84] Fixed issues with video settings visibility --- .../org/linphone/settings/VideoSettingsFragment.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/app/src/main/java/org/linphone/settings/VideoSettingsFragment.java b/app/src/main/java/org/linphone/settings/VideoSettingsFragment.java index fd2662c93..fa520575e 100644 --- a/app/src/main/java/org/linphone/settings/VideoSettingsFragment.java +++ b/app/src/main/java/org/linphone/settings/VideoSettingsFragment.java @@ -312,6 +312,7 @@ public class VideoSettingsFragment extends SettingsFragment { : View.GONE); mAutoInitiate.setVisibility(show ? View.VISIBLE : View.GONE); mAutoAccept.setVisibility(show ? View.VISIBLE : View.GONE); + mCameraDevices.setVisibility(show ? View.VISIBLE : View.GONE); mOverlay.setVisibility(show ? View.VISIBLE : View.GONE); mBandwidth.setVisibility(show ? View.VISIBLE : View.GONE); mPreset.setVisibility(show ? View.VISIBLE : View.GONE); @@ -319,6 +320,17 @@ public class VideoSettingsFragment extends SettingsFragment { mFps.setVisibility(show ? View.VISIBLE : View.GONE); mVideoCodecs.setVisibility(show ? View.VISIBLE : View.GONE); mVideoCodecsHeader.setVisibility(show ? View.VISIBLE : View.GONE); + + if (show) { + if (Version.sdkAboveOrEqual(Version.API26_O_80) + && getResources().getBoolean(R.bool.allow_pip_while_video_call)) { + // Disable overlay and use PIP feature + mOverlay.setVisibility(View.GONE); + } + mBandwidth.setVisibility( + mPrefs.getVideoPreset().equals("custom") ? View.VISIBLE : View.GONE); + mFps.setVisibility(mPrefs.getVideoPreset().equals("custom") ? View.VISIBLE : View.GONE); + } } private void initCameraDevicesList() { From 7192d09048ab8df954bd6a5f8bf1972e4ac09e67 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 27 Nov 2019 13:32:00 +0100 Subject: [PATCH 63/84] Version code bumped --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 143916e4b..df8b74789 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -88,7 +88,7 @@ android { defaultConfig { minSdkVersion 21 targetSdkVersion 29 - versionCode 4205 + versionCode 4206 versionName "${project.version}" applicationId getPackageName() multiDexEnabled true From 165e9a8f7669024401441189319a3a747407e8ad Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 27 Nov 2019 16:04:56 +0100 Subject: [PATCH 64/84] Fixed various call related UI issues --- .../main/java/org/linphone/call/CallActivity.java | 15 +++++++++++---- .../org/linphone/call/CallOutgoingActivity.java | 2 +- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/org/linphone/call/CallActivity.java b/app/src/main/java/org/linphone/call/CallActivity.java index f2948d69b..c3fdf5b65 100644 --- a/app/src/main/java/org/linphone/call/CallActivity.java +++ b/app/src/main/java/org/linphone/call/CallActivity.java @@ -388,6 +388,8 @@ public class CallActivity extends LinphoneGenericActivity if (state == Call.State.End || state == Call.State.Released) { if (core.getCallsNb() == 0) { finish(); + } else { + showVideoControls(false); } } else if (state == Call.State.PausedByRemote) { if (core.getCurrentCall() != null) { @@ -1092,7 +1094,7 @@ public class CallActivity extends LinphoneGenericActivity mConferenceList.removeAllViews(); for (Call call : mCore.getCalls()) { - if (call.getConference() != null) { + if (call != null && call.getConference() != null) { if (mCore.isInConference()) { displayConferenceCall(call); conferenceDisplayed = true; @@ -1100,9 +1102,14 @@ public class CallActivity extends LinphoneGenericActivity displayPausedConference(); pausedConferenceDisplayed = true; } - } else if (call != currentCall) { - displayPausedCall(call); - callThatIsNotCurrentFound = true; + } else if (call != null && call != currentCall) { + Call.State state = call.getState(); + if (state == Call.State.Paused + || state == Call.State.PausedByRemote + || state == Call.State.Pausing) { + displayPausedCall(call); + callThatIsNotCurrentFound = true; + } } } diff --git a/app/src/main/java/org/linphone/call/CallOutgoingActivity.java b/app/src/main/java/org/linphone/call/CallOutgoingActivity.java index 0bc10864e..d538de46d 100644 --- a/app/src/main/java/org/linphone/call/CallOutgoingActivity.java +++ b/app/src/main/java/org/linphone/call/CallOutgoingActivity.java @@ -130,7 +130,7 @@ public class CallOutgoingActivity extends LinphoneGenericActivity implements OnC // CallActivity.class)); } - if (LinphoneManager.getCore().getCallsNb() == 0) { + if (state == State.End || state == State.Released) { finish(); } } From c7aecaa1d76723fc65bf3cc20ec61d453d618311 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 27 Nov 2019 17:23:26 +0100 Subject: [PATCH 65/84] Fixed contact picture edition --- .../contacts/ContactEditorFragment.java | 71 ++++++------------- .../contacts/views/ContactAvatar.java | 26 +++++-- .../java/org/linphone/utils/ImageUtils.java | 2 +- 3 files changed, 45 insertions(+), 54 deletions(-) diff --git a/app/src/main/java/org/linphone/contacts/ContactEditorFragment.java b/app/src/main/java/org/linphone/contacts/ContactEditorFragment.java index 9c49daab9..905fe5f22 100644 --- a/app/src/main/java/org/linphone/contacts/ContactEditorFragment.java +++ b/app/src/main/java/org/linphone/contacts/ContactEditorFragment.java @@ -58,6 +58,7 @@ import org.linphone.core.tools.Log; import org.linphone.mediastream.Version; import org.linphone.settings.LinphonePreferences; import org.linphone.utils.FileUtils; +import org.linphone.utils.ImageUtils; import org.linphone.utils.LinphoneUtils; public class ContactEditorFragment extends Fragment { @@ -426,10 +427,12 @@ public class ContactEditorFragment extends Fragment { } } - if (mContact != null) { - ContactAvatar.displayAvatar(mContact, mView.findViewById(R.id.avatar_layout)); - } else { - ContactAvatar.displayAvatar("", mView.findViewById(R.id.avatar_layout)); + if (mPhotoToAdd == null) { + if (mContact != null) { + ContactAvatar.displayAvatar(mContact, mView.findViewById(R.id.avatar_layout)); + } else { + ContactAvatar.displayAvatar("", mView.findViewById(R.id.avatar_layout)); + } } mSipAddresses = initSipAddressFields(mContact); @@ -438,27 +441,24 @@ public class ContactEditorFragment extends Fragment { private void pickImage() { mPickedPhotoForContactUri = null; - final List cameraIntents = new ArrayList<>(); - final Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); + List cameraIntents = new ArrayList<>(); + + // Handles image & video picking + Intent galleryIntent = new Intent(Intent.ACTION_PICK); + galleryIntent.setType("image/*"); + + // Allows to capture directly from the camera + Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); File file = new File( FileUtils.getStorageDirectory(getActivity()), - getString(R.string.temp_photo_name)); + getString(R.string.temp_photo_name_with_date) + .replace("%s", System.currentTimeMillis() + ".jpeg")); mPickedPhotoForContactUri = Uri.fromFile(file); - captureIntent.putExtra("outputX", PHOTO_SIZE); - captureIntent.putExtra("outputY", PHOTO_SIZE); - captureIntent.putExtra("aspectX", 0); - captureIntent.putExtra("aspectY", 0); - captureIntent.putExtra("scale", true); - captureIntent.putExtra("return-data", false); captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mPickedPhotoForContactUri); cameraIntents.add(captureIntent); - final Intent galleryIntent = new Intent(); - galleryIntent.setType("image/*"); - galleryIntent.setAction(Intent.ACTION_GET_CONTENT); - - final Intent chooserIntent = + Intent chooserIntent = Intent.createChooser(galleryIntent, getString(R.string.image_picker_title)); chooserIntent.putExtra( Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[] {})); @@ -471,40 +471,13 @@ public class ContactEditorFragment extends Fragment { image = BitmapFactory.decodeFile(filePath); } - Bitmap scaledPhoto; - int size = getThumbnailSize(); - if (size > 0) { - scaledPhoto = Bitmap.createScaledBitmap(image, size, size, false); - } else { - scaledPhoto = Bitmap.createBitmap(image); - } - image.recycle(); - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - scaledPhoto.compress(Bitmap.CompressFormat.PNG, 0, stream); - mContactPicture.setImageBitmap(scaledPhoto); + image.compress(Bitmap.CompressFormat.JPEG, 100, stream); mPhotoToAdd = stream.toByteArray(); - } - private int getThumbnailSize() { - int value = -1; - Cursor c = - getActivity() - .getContentResolver() - .query( - DisplayPhoto.CONTENT_MAX_DIMENSIONS_URI, - new String[] {DisplayPhoto.THUMBNAIL_MAX_DIM}, - null, - null, - null); - try { - c.moveToFirst(); - value = c.getInt(0); - } catch (Exception e) { - Log.e(e); - } - c.close(); - return value; + Bitmap roundPicture = ImageUtils.getRoundBitmap(image); + ContactAvatar.displayAvatar(roundPicture, mView.findViewById(R.id.avatar_layout)); + image.recycle(); } private LinearLayout initNumbersFields(final LinphoneContact contact) { diff --git a/app/src/main/java/org/linphone/contacts/views/ContactAvatar.java b/app/src/main/java/org/linphone/contacts/views/ContactAvatar.java index bcfdb0f47..d2fd5fbc6 100644 --- a/app/src/main/java/org/linphone/contacts/views/ContactAvatar.java +++ b/app/src/main/java/org/linphone/contacts/views/ContactAvatar.java @@ -137,10 +137,7 @@ public class ContactAvatar { Bitmap bm = ImageUtils.getRoundBitmapFromUri(v.getContext(), contact.getThumbnailUri()); if (bm != null) { - holder.contactPicture.setImageBitmap(bm); - holder.contactPicture.setVisibility(View.VISIBLE); - holder.generatedAvatar.setVisibility(View.GONE); - holder.generatedAvatarBackground.setVisibility(View.GONE); + displayAvatar(bm, holder); } else if (generated_avatars) { holder.generatedAvatar.setVisibility(View.VISIBLE); holder.generatedAvatarBackground.setVisibility(View.VISIBLE); @@ -151,6 +148,27 @@ public class ContactAvatar { } } + private static void displayAvatar(Bitmap bm, ContactAvatarHolder holder) { + holder.contactPicture.setImageBitmap(bm); + holder.contactPicture.setVisibility(View.VISIBLE); + holder.generatedAvatar.setVisibility(View.GONE); + holder.generatedAvatarBackground.setVisibility(View.GONE); + } + + public static void displayAvatar(Bitmap bm, View v) { + if (bm == null || v == null) return; + + ContactAvatarHolder holder = new ContactAvatarHolder(v); + holder.init(); + + holder.generatedAvatar.setVisibility(View.GONE); + holder.generatedAvatarBackground.setVisibility(View.GONE); + holder.contactPicture.setVisibility(View.VISIBLE); + holder.securityLevel.setVisibility(View.GONE); + + displayAvatar(bm, holder); + } + public static void displayAvatar(LinphoneContact contact, View v) { displayAvatar(contact, v, false); } diff --git a/app/src/main/java/org/linphone/utils/ImageUtils.java b/app/src/main/java/org/linphone/utils/ImageUtils.java index d519b9b33..844bfd781 100644 --- a/app/src/main/java/org/linphone/utils/ImageUtils.java +++ b/app/src/main/java/org/linphone/utils/ImageUtils.java @@ -55,7 +55,7 @@ public class ImageUtils { return bm; } - private static Bitmap getRoundBitmap(Bitmap bitmap) { + public static Bitmap getRoundBitmap(Bitmap bitmap) { Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(output); From 67637f82674ff0848700398d372906efc458c9c4 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 28 Nov 2019 12:08:44 +0100 Subject: [PATCH 66/84] Fixed chat room not updated in list when subject changes + fixed chat room removal UI issue on tablet --- .../org/linphone/chat/ChatRoomsFragment.java | 16 ++++++++++++---- .../linphone/contacts/ContactEditorFragment.java | 2 -- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/org/linphone/chat/ChatRoomsFragment.java b/app/src/main/java/org/linphone/chat/ChatRoomsFragment.java index f70bcb3f2..b463c9bd8 100644 --- a/app/src/main/java/org/linphone/chat/ChatRoomsFragment.java +++ b/app/src/main/java/org/linphone/chat/ChatRoomsFragment.java @@ -137,8 +137,13 @@ public class ChatRoomsFragment extends Fragment } @Override - public void onMessageReceived(Core core, ChatRoom cr, ChatMessage message) { - refreshChatRoom(cr); + public void onMessageReceived(Core core, ChatRoom room, ChatMessage message) { + refreshChatRoom(room); + } + + @Override + public void onChatRoomSubjectChanged(Core core, ChatRoom room) { + refreshChatRoom(room); } @Override @@ -154,9 +159,9 @@ public class ChatRoomsFragment extends Fragment @Override public void onChatRoomStateChanged( - Core core, ChatRoom cr, ChatRoom.State state) { + Core core, ChatRoom room, ChatRoom.State state) { if (state == ChatRoom.State.Created) { - refreshChatRoom(cr); + refreshChatRoom(room); scrollToTop(); } } @@ -254,6 +259,9 @@ public class ChatRoomsFragment extends Fragment mWaitLayout.setVisibility(View.VISIBLE); } ((ChatActivity) getActivity()).displayMissedChats(); + + if (getResources().getBoolean(R.bool.isTablet)) + ((ChatActivity) getActivity()).showEmptyChildFragment(); } @Override diff --git a/app/src/main/java/org/linphone/contacts/ContactEditorFragment.java b/app/src/main/java/org/linphone/contacts/ContactEditorFragment.java index 905fe5f22..23c654d0d 100644 --- a/app/src/main/java/org/linphone/contacts/ContactEditorFragment.java +++ b/app/src/main/java/org/linphone/contacts/ContactEditorFragment.java @@ -26,13 +26,11 @@ import android.app.Dialog; import android.app.Fragment; import android.content.Context; import android.content.Intent; -import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.os.Bundle; import android.os.Parcelable; -import android.provider.ContactsContract.DisplayPhoto; import android.provider.MediaStore; import android.text.Editable; import android.text.InputType; From 4c468a7042fd4a5bc7f489014718a2742ae22beb Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 29 Nov 2019 11:05:06 +0100 Subject: [PATCH 67/84] Version code bumped --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index df8b74789..303fcc45b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -88,7 +88,7 @@ android { defaultConfig { minSdkVersion 21 targetSdkVersion 29 - versionCode 4206 + versionCode 4207 versionName "${project.version}" applicationId getPackageName() multiDexEnabled true From 25d9af1c189151f56857936ee74ad64114260b06 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 2 Dec 2019 12:11:26 +0100 Subject: [PATCH 68/84] Call startForeground quicker when service is started by boot receiver --- .../java/org/linphone/service/LinphoneService.java | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/org/linphone/service/LinphoneService.java b/app/src/main/java/org/linphone/service/LinphoneService.java index 73c440809..b08aa85b1 100644 --- a/app/src/main/java/org/linphone/service/LinphoneService.java +++ b/app/src/main/java/org/linphone/service/LinphoneService.java @@ -77,8 +77,12 @@ public final class LinphoneService extends Service { } sInstance = this; - if (LinphonePreferences.instance().getServiceNotificationVisibility()) { + if (LinphonePreferences.instance().getServiceNotificationVisibility() + || (Version.sdkAboveOrEqual(Version.API26_O_80) + && intent != null + && intent.getBooleanExtra("ForceStartForeground", false))) { Log.i("[Service] Background service mode enabled, displaying notification"); + // We need to call this asap after the Service can be accessed through it's singleton LinphoneContext.instance().getNotificationManager().startForeground(); } @@ -88,14 +92,7 @@ public final class LinphoneService extends Service { LinphoneContext.instance().updateContext(this); } - if (Version.sdkAboveOrEqual(Version.API26_O_80) - && intent != null - && intent.getBooleanExtra("ForceStartForeground", false)) { - // We need to call this asap after the Service can be accessed through it's singleton - LinphoneContext.instance().getNotificationManager().startForeground(); - } Log.i("[Service] Started"); - return START_STICKY; } From d20379a4846ba23ba6d4b9c32b9fee93569b6061 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 2 Dec 2019 13:19:19 +0100 Subject: [PATCH 69/84] Fixed bluetooth UI not shown if bluetooth adapter is turned on after app started --- .../linphone/call/AndroidAudioManager.java | 155 +++++++++--------- .../linphone/receivers/BluetoothReceiver.java | 26 ++- 2 files changed, 105 insertions(+), 76 deletions(-) diff --git a/app/src/main/java/org/linphone/call/AndroidAudioManager.java b/app/src/main/java/org/linphone/call/AndroidAudioManager.java index ce561c13d..0bc609fe4 100644 --- a/app/src/main/java/org/linphone/call/AndroidAudioManager.java +++ b/app/src/main/java/org/linphone/call/AndroidAudioManager.java @@ -517,6 +517,82 @@ public class AndroidAudioManager { }.start(); } + public void bluetoothAdapterStateChanged() { + if (mBluetoothAdapter.isEnabled()) { + Log.i("[Audio Manager] [Bluetooth] Adapter enabled"); + mIsBluetoothHeadsetConnected = false; + mIsBluetoothHeadsetScoConnected = false; + + BluetoothProfile.ServiceListener bluetoothServiceListener = + new BluetoothProfile.ServiceListener() { + public void onServiceConnected(int profile, BluetoothProfile proxy) { + if (profile == BluetoothProfile.HEADSET) { + Log.i("[Audio Manager] [Bluetooth] HEADSET profile connected"); + mBluetoothHeadset = (BluetoothHeadset) proxy; + + List devices = + mBluetoothHeadset.getConnectedDevices(); + if (devices.size() > 0) { + Log.i( + "[Audio Manager] [Bluetooth] A device is already connected"); + bluetoothHeadetConnectionChanged(true); + } + + Log.i("[Audio Manager] [Bluetooth] Registering bluetooth receiver"); + + IntentFilter filter = new IntentFilter(); + filter.addAction(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED); + filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED); + filter.addAction(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED); + filter.addAction( + BluetoothHeadset.ACTION_VENDOR_SPECIFIC_HEADSET_EVENT); + + Intent sticky = + mContext.registerReceiver(mBluetoothReceiver, filter); + Log.i("[Audio Manager] [Bluetooth] Bluetooth receiver registered"); + int state = + sticky.getIntExtra( + AudioManager.EXTRA_SCO_AUDIO_STATE, + AudioManager.SCO_AUDIO_STATE_DISCONNECTED); + if (state == AudioManager.SCO_AUDIO_STATE_CONNECTED) { + Log.i( + "[Audio Manager] [Bluetooth] Bluetooth headset SCO connected"); + bluetoothHeadetScoConnectionChanged(true); + } else if (state == AudioManager.SCO_AUDIO_STATE_DISCONNECTED) { + Log.i( + "[Audio Manager] [Bluetooth] Bluetooth headset SCO disconnected"); + bluetoothHeadetScoConnectionChanged(false); + } else if (state == AudioManager.SCO_AUDIO_STATE_CONNECTING) { + Log.i( + "[Audio Manager] [Bluetooth] Bluetooth headset SCO connecting"); + } else if (state == AudioManager.SCO_AUDIO_STATE_ERROR) { + Log.i( + "[Audio Manager] [Bluetooth] Bluetooth headset SCO connection error"); + } else { + Log.w( + "[Audio Manager] [Bluetooth] Bluetooth headset unknown SCO state changed: " + + state); + } + } + } + + public void onServiceDisconnected(int profile) { + if (profile == BluetoothProfile.HEADSET) { + Log.i("[Audio Manager] [Bluetooth] HEADSET profile disconnected"); + mBluetoothHeadset = null; + mIsBluetoothHeadsetConnected = false; + mIsBluetoothHeadsetScoConnected = false; + } + } + }; + + mBluetoothAdapter.getProfileProxy( + mContext, bluetoothServiceListener, BluetoothProfile.HEADSET); + } else { + Log.w("[Audio Manager] [Bluetooth] Adapter disabled"); + } + } + private void startBluetooth() { mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); if (mBluetoothAdapter != null) { @@ -527,82 +603,11 @@ public class AndroidAudioManager { Log.w("[Audio Manager] [Bluetooth] SCO not available off call !"); } - if (mBluetoothAdapter.isEnabled()) { - Log.i("[Audio Manager] [Bluetooth] Adapter enabled"); - mBluetoothReceiver = new BluetoothReceiver(); - mIsBluetoothHeadsetConnected = false; - mIsBluetoothHeadsetScoConnected = false; + mBluetoothReceiver = new BluetoothReceiver(); + IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED); + mContext.registerReceiver(mBluetoothReceiver, filter); - BluetoothProfile.ServiceListener bluetoothServiceListener = - new BluetoothProfile.ServiceListener() { - public void onServiceConnected(int profile, BluetoothProfile proxy) { - if (profile == BluetoothProfile.HEADSET) { - Log.i("[Audio Manager] [Bluetooth] HEADSET profile connected"); - mBluetoothHeadset = (BluetoothHeadset) proxy; - - List devices = - mBluetoothHeadset.getConnectedDevices(); - if (devices.size() > 0) { - Log.i( - "[Audio Manager] [Bluetooth] A device is already connected"); - bluetoothHeadetConnectionChanged(true); - } - - Log.i( - "[Audio Manager] [Bluetooth] Registering bluetooth receiver"); - - IntentFilter filter = new IntentFilter(); - filter.addAction(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED); - filter.addAction( - BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED); - filter.addAction(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED); - filter.addAction( - BluetoothHeadset.ACTION_VENDOR_SPECIFIC_HEADSET_EVENT); - - Intent sticky = - mContext.registerReceiver(mBluetoothReceiver, filter); - Log.i( - "[Audio Manager] [Bluetooth] Bluetooth receiver registered"); - int state = - sticky.getIntExtra( - AudioManager.EXTRA_SCO_AUDIO_STATE, - AudioManager.SCO_AUDIO_STATE_DISCONNECTED); - if (state == AudioManager.SCO_AUDIO_STATE_CONNECTED) { - Log.i( - "[Audio Manager] [Bluetooth] Bluetooth headset SCO connected"); - bluetoothHeadetScoConnectionChanged(true); - } else if (state == AudioManager.SCO_AUDIO_STATE_DISCONNECTED) { - Log.i( - "[Audio Manager] [Bluetooth] Bluetooth headset SCO disconnected"); - bluetoothHeadetScoConnectionChanged(false); - } else if (state == AudioManager.SCO_AUDIO_STATE_CONNECTING) { - Log.i( - "[Audio Manager] [Bluetooth] Bluetooth headset SCO connecting"); - } else if (state == AudioManager.SCO_AUDIO_STATE_ERROR) { - Log.i( - "[Audio Manager] [Bluetooth] Bluetooth headset SCO connection error"); - } else { - Log.w( - "[Audio Manager] [Bluetooth] Bluetooth headset unknown SCO state changed: " - + state); - } - } - } - - public void onServiceDisconnected(int profile) { - if (profile == BluetoothProfile.HEADSET) { - Log.i( - "[Audio Manager] [Bluetooth] HEADSET profile disconnected"); - mBluetoothHeadset = null; - mIsBluetoothHeadsetConnected = false; - mIsBluetoothHeadsetScoConnected = false; - } - } - }; - - mBluetoothAdapter.getProfileProxy( - mContext, bluetoothServiceListener, BluetoothProfile.HEADSET); - } + bluetoothAdapterStateChanged(); } } diff --git a/app/src/main/java/org/linphone/receivers/BluetoothReceiver.java b/app/src/main/java/org/linphone/receivers/BluetoothReceiver.java index fee24a678..16cbe6b60 100644 --- a/app/src/main/java/org/linphone/receivers/BluetoothReceiver.java +++ b/app/src/main/java/org/linphone/receivers/BluetoothReceiver.java @@ -19,6 +19,7 @@ */ package org.linphone.receivers; +import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothHeadset; import android.content.BroadcastReceiver; import android.content.Context; @@ -38,7 +39,30 @@ public class BluetoothReceiver extends BroadcastReceiver { String action = intent.getAction(); Log.i("[Bluetooth] Bluetooth broadcast received"); - if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) { + if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { + int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR); + switch (state) { + case BluetoothAdapter.STATE_OFF: + Log.w("[Bluetooth] Adapter has been turned off"); + break; + case BluetoothAdapter.STATE_TURNING_OFF: + Log.w("[Bluetooth] Adapter is being turned off"); + break; + case BluetoothAdapter.STATE_ON: + Log.i("[Bluetooth] Adapter has been turned on"); + LinphoneManager.getAudioManager().bluetoothAdapterStateChanged(); + break; + case BluetoothAdapter.STATE_TURNING_ON: + Log.i("[Bluetooth] Adapter is being turned on"); + break; + case BluetoothAdapter.ERROR: + Log.e("[Bluetooth] Adapter is in error state !"); + break; + default: + Log.w("[Bluetooth] Unknown adapter state: ", state); + break; + } + } else if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) { int state = intent.getIntExtra( BluetoothHeadset.EXTRA_STATE, BluetoothHeadset.STATE_DISCONNECTED); From 82ced1a397600e4e8aaf0763ab7701d287dbf732 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 3 Dec 2019 09:30:49 +0100 Subject: [PATCH 70/84] Updated Ukrainian translations from transifex --- app/src/main/res/values-uk/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 3db27da5e..bc704dbc3 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -129,6 +129,7 @@ \nВашим друзям буде простіше зконтактуватися з вами, якщо ви зв\'яжете свою обліківку зі своїм номером телефону.\n\nУ вашій адресній книзі ви побачите, хто використовує Linphone, а ваші друзі зможуть дізнатися, що ви також зареєстровані в Linphone.\n Номер телефону можна використовувати лише з однією обліківкою Linphone.\n\nЯкщо ваш номер вже був зв\'язаний з иншою обліківкою, але ви волієте використовувати його, просто зв\'яжіть його зараз, й ваш номер буде автоматично перенесено в цю обліківку. Забагато SMS було відправлено на цей номер за короткий проміжок часу, повторіть спробу через 24 години. + Обліківки не існує Неприпустима адреса електронної пошти Обліківка вже існує @@ -243,6 +244,7 @@ Стягнути Оберіть бесіду або створіть нову У довірі було відмовлено. Зробіть виклик, аби почати процес автентифікації знову. + Не вдається відкрити файл, немає додатків для цього формату. З\'єднано Не з\'єднано @@ -399,6 +401,7 @@ Кодеки Відео + Камера Накладення відео Показувати відеовиклик накладуванням на сторонньому застосунку Використовувати фронтальну камеру From 8268b01c9948839080871fbad6772dd077730ec8 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 3 Dec 2019 14:25:18 +0100 Subject: [PATCH 71/84] Prevents crash + added logs --- .../contacts/ContactEditorFragment.java | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/linphone/contacts/ContactEditorFragment.java b/app/src/main/java/org/linphone/contacts/ContactEditorFragment.java index 23c654d0d..a73ca269d 100644 --- a/app/src/main/java/org/linphone/contacts/ContactEditorFragment.java +++ b/app/src/main/java/org/linphone/contacts/ContactEditorFragment.java @@ -156,6 +156,7 @@ public class ContactEditorFragment extends Fragment { true); if (mPhotoToAdd != null) { + Log.i("[Contact Editor] Found picture to set to contact"); mContact.setPhoto(mPhotoToAdd); } @@ -165,25 +166,26 @@ public class ContactEditorFragment extends Fragment { if (value == null || value.trim().isEmpty()) { if (oldValue != null && !oldValue.isEmpty()) { - Log.i("[Contact Editor] Removing number " + oldValue); + Log.i("[Contact Editor] Removing number: ", oldValue); mContact.removeNumberOrAddress(noa); } } else { if (oldValue != null && oldValue.equals(value)) { - Log.i("[Contact Editor] Keeping existing number " + value); + Log.i("[Contact Editor] Keeping existing number: ", value); continue; } if (noa.isSIPAddress()) { noa.setValue(LinphoneUtils.getFullAddressFromUsername(value)); } - Log.i("[Contact Editor] Adding new number " + value); + Log.i("[Contact Editor] Adding new number: ", value); mContact.addOrUpdateNumberOrAddress(noa); } } if (!mOrganization.getText().toString().isEmpty() || !mIsNewContact) { + Log.i("[Contact Editor] Setting organization field: ", mOrganization); mContact.setOrganization(mOrganization.getText().toString(), true); } @@ -193,6 +195,8 @@ public class ContactEditorFragment extends Fragment { // Ensure fetch will be done so the new contact appears in the contacts // list: contacts content observer may not be notified if contacts sync // is disabled at system level + Log.i( + "[Contact Editor] New contact created, starting fetch contacts task"); ContactsManager.getInstance().fetchContactsAsync(); } @@ -466,8 +470,21 @@ public class ContactEditorFragment extends Fragment { private void editContactPicture(String filePath, Bitmap image) { if (image == null) { + Log.i( + "[Contact Editor] Bitmap is null, trying to decode image from file [", + filePath, + "]"); image = BitmapFactory.decodeFile(filePath); } + if (image == null) { + Log.e( + "[Contact Editor] Couldn't get bitmap from either filePath [", + filePath, + "] nor image [", + image, + "]"); + return; + } ByteArrayOutputStream stream = new ByteArrayOutputStream(); image.compress(Bitmap.CompressFormat.JPEG, 100, stream); From 7caff1175f9c403d6d7e4631912218445b5e0c3c Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 3 Dec 2019 14:45:45 +0100 Subject: [PATCH 72/84] Fixed missing permission before updating contact picture --- .../org/linphone/activities/MainActivity.java | 8 ++++++++ .../linphone/contacts/ContactEditorFragment.java | 15 ++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/linphone/activities/MainActivity.java b/app/src/main/java/org/linphone/activities/MainActivity.java index a15109d27..ca1d15f46 100644 --- a/app/src/main/java/org/linphone/activities/MainActivity.java +++ b/app/src/main/java/org/linphone/activities/MainActivity.java @@ -477,6 +477,14 @@ public abstract class MainActivity extends LinphoneGenericActivity return granted == PackageManager.PERMISSION_GRANTED; } + public boolean checkPermissions(String[] permissions) { + boolean allGranted = true; + for (String permission : permissions) { + allGranted &= checkPermission(permission); + } + return allGranted; + } + public void requestPermissionIfNotGranted(String permission) { if (!checkPermission(permission)) { Log.i("[Permission] Requesting " + permission + " permission"); diff --git a/app/src/main/java/org/linphone/contacts/ContactEditorFragment.java b/app/src/main/java/org/linphone/contacts/ContactEditorFragment.java index a73ca269d..00f2465ab 100644 --- a/app/src/main/java/org/linphone/contacts/ContactEditorFragment.java +++ b/app/src/main/java/org/linphone/contacts/ContactEditorFragment.java @@ -309,9 +309,18 @@ public class ContactEditorFragment extends Fragment { new OnClickListener() { @Override public void onClick(View view) { - pickImage(); - ((ContactsActivity) getActivity()) - .requestPermissionIfNotGranted(Manifest.permission.CAMERA); + ContactsActivity contactsActivity = ((ContactsActivity) getActivity()); + if (contactsActivity != null) { + String[] permissions = { + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.CAMERA + }; + if (contactsActivity.checkPermissions(permissions)) { + pickImage(); + } else { + contactsActivity.requestPermissionsIfNotGranted(permissions); + } + } } }); From ac12b1a7eafd2d9137887181a75ab9e0f2813bd6 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 3 Dec 2019 15:57:54 +0100 Subject: [PATCH 73/84] Fixed contact picture edition quality & rotation --- .../org/linphone/contacts/AndroidContact.java | 72 ++++++++++++------- .../contacts/ContactEditorFragment.java | 57 +++++++++++---- .../linphone/contacts/LinphoneContact.java | 4 ++ .../java/org/linphone/utils/ImageUtils.java | 11 +++ 4 files changed, 107 insertions(+), 37 deletions(-) diff --git a/app/src/main/java/org/linphone/contacts/AndroidContact.java b/app/src/main/java/org/linphone/contacts/AndroidContact.java index 69239d0ce..fba283b2c 100644 --- a/app/src/main/java/org/linphone/contacts/AndroidContact.java +++ b/app/src/main/java/org/linphone/contacts/AndroidContact.java @@ -23,6 +23,7 @@ import android.content.ContentProviderOperation; import android.content.ContentProviderResult; import android.content.ContentResolver; import android.content.ContentUris; +import android.content.res.AssetFileDescriptor; import android.database.Cursor; import android.net.Uri; import android.provider.ContactsContract; @@ -30,6 +31,8 @@ import android.provider.ContactsContract.CommonDataKinds; import android.provider.ContactsContract.Contacts; import android.provider.ContactsContract.Data; import android.provider.ContactsContract.RawContacts; +import java.io.IOException; +import java.io.OutputStream; import java.io.Serializable; import java.util.ArrayList; import org.linphone.LinphoneContext; @@ -41,10 +44,12 @@ class AndroidContact implements Serializable { private String mAndroidRawId; private boolean isAndroidRawIdLinphone; private final transient ArrayList mChangesToCommit; + private byte[] mTempPicture; AndroidContact() { mChangesToCommit = new ArrayList<>(); isAndroidRawIdLinphone = false; + mTempPicture = null; } String getAndroidId() { @@ -78,6 +83,12 @@ class AndroidContact implements Serializable { String rawId = String.valueOf(ContentUris.parseId(results[0].uri)); if (mAndroidId == null) { Log.i("[Contact] Contact created with RAW ID " + rawId); + mAndroidRawId = rawId; + if (mTempPicture != null) { + Log.i( + "[Contact] Contact has been created, raw is is available, time to set the photo"); + setPhoto(mTempPicture); + } final String[] projection = new String[] {ContactsContract.RawContacts.CONTACT_ID}; @@ -551,33 +562,44 @@ class AndroidContact implements Serializable { return; } - if (mAndroidId == null) { - Log.i("[Contact] Setting picture to new contact."); - addChangesToCommit( - ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) - .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) - .withValue( - ContactsContract.Data.MIMETYPE, - ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE) - .withValue(ContactsContract.CommonDataKinds.Photo.PHOTO, photo) - .build()); + if (mAndroidRawId == null) { + Log.w("[Contact] Can't set picture for not already created contact, will do it later"); + mTempPicture = photo; } else { Log.i( - "[Contact] Setting picture to existing contact " - + mAndroidId - + " (" - + mAndroidRawId - + ")"); - addChangesToCommit( - ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) - .withValue(ContactsContract.Data.RAW_CONTACT_ID, mAndroidRawId) - .withValue( - ContactsContract.Data.MIMETYPE, - ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE) - .withValue(ContactsContract.CommonDataKinds.Photo.PHOTO, photo) - .withValue(ContactsContract.Data.IS_PRIMARY, 1) - .withValue(ContactsContract.Data.IS_SUPER_PRIMARY, 1) - .build()); + "[Contact] Setting picture to an already created raw contact [", + mAndroidRawId, + "]"); + try { + long rawId = Long.parseLong(mAndroidRawId); + + Uri rawContactPhotoUri = + Uri.withAppendedPath( + ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawId), + RawContacts.DisplayPhoto.CONTENT_DIRECTORY); + + if (rawContactPhotoUri != null) { + ContentResolver resolver = + LinphoneContext.instance().getApplicationContext().getContentResolver(); + AssetFileDescriptor fd = + resolver.openAssetFileDescriptor(rawContactPhotoUri, "rw"); + OutputStream os = fd.createOutputStream(); + os.write(photo); + os.close(); + fd.close(); + } else { + Log.e( + "[Contact] Failed to get raw contact photo URI for raw contact id [", + rawId, + "], aborting"); + } + } catch (NumberFormatException nfe) { + Log.e("[Contact] Couldn't parse raw id [", mAndroidId, "], aborting"); + } catch (IOException ioe) { + Log.e("[Contact] Couldn't set picture, IO error: ", ioe); + } catch (Exception e) { + Log.e("[Contact] Couldn't set picture, unknown error: ", e); + } } } diff --git a/app/src/main/java/org/linphone/contacts/ContactEditorFragment.java b/app/src/main/java/org/linphone/contacts/ContactEditorFragment.java index 00f2465ab..238681f51 100644 --- a/app/src/main/java/org/linphone/contacts/ContactEditorFragment.java +++ b/app/src/main/java/org/linphone/contacts/ContactEditorFragment.java @@ -28,6 +28,7 @@ import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.media.ExifInterface; import android.net.Uri; import android.os.Bundle; import android.os.Parcelable; @@ -398,15 +399,18 @@ public class ContactEditorFragment extends Fragment { editContactPicture(null, bm); } else if (data != null && data.getData() != null) { Uri selectedImageUri = data.getData(); - try { - Bitmap selectedImage = - MediaStore.Images.Media.getBitmap( - getActivity().getContentResolver(), selectedImageUri); - selectedImage = - Bitmap.createScaledBitmap(selectedImage, PHOTO_SIZE, PHOTO_SIZE, false); - editContactPicture(null, selectedImage); - } catch (IOException e) { - Log.e(e); + String filePath = FileUtils.getRealPathFromURI(getActivity(), selectedImageUri); + if (filePath != null) { + editContactPicture(filePath, null); + } else { + try { + Bitmap selectedImage = + MediaStore.Images.Media.getBitmap( + getActivity().getContentResolver(), selectedImageUri); + editContactPicture(null, selectedImage); + } catch (IOException e) { + Log.e("[Contact Editor] IO error: ", e); + } } } else if (mPickedPhotoForContactUri != null) { String filePath = mPickedPhotoForContactUri.getPath(); @@ -478,23 +482,52 @@ public class ContactEditorFragment extends Fragment { } private void editContactPicture(String filePath, Bitmap image) { + int orientation = ExifInterface.ORIENTATION_NORMAL; + if (image == null) { Log.i( "[Contact Editor] Bitmap is null, trying to decode image from file [", filePath, "]"); image = BitmapFactory.decodeFile(filePath); + + try { + ExifInterface ei = new ExifInterface(filePath); + orientation = + ei.getAttributeInt( + ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED); + Log.i("[Contact Editor] Exif rotation is ", orientation); + } catch (IOException e) { + Log.e("[Contact Editor] Failed to get Exif rotation, error is ", e); + } + } else { + } if (image == null) { Log.e( "[Contact Editor] Couldn't get bitmap from either filePath [", filePath, - "] nor image [", - image, - "]"); + "] nor image"); return; } + switch (orientation) { + case ExifInterface.ORIENTATION_ROTATE_90: + image = ImageUtils.rotateImage(image, 90); + break; + case ExifInterface.ORIENTATION_ROTATE_180: + image = ImageUtils.rotateImage(image, 180); + break; + case ExifInterface.ORIENTATION_ROTATE_270: + image = ImageUtils.rotateImage(image, 270); + break; + case ExifInterface.ORIENTATION_NORMAL: + // Nothing to do + break; + default: + Log.w("[Contact Editor] Unexpected orientation ", orientation); + } + ByteArrayOutputStream stream = new ByteArrayOutputStream(); image.compress(Bitmap.CompressFormat.JPEG, 100, stream); mPhotoToAdd = stream.toByteArray(); diff --git a/app/src/main/java/org/linphone/contacts/LinphoneContact.java b/app/src/main/java/org/linphone/contacts/LinphoneContact.java index d9dee45fe..b4641b986 100644 --- a/app/src/main/java/org/linphone/contacts/LinphoneContact.java +++ b/app/src/main/java/org/linphone/contacts/LinphoneContact.java @@ -640,6 +640,10 @@ public class LinphoneContact extends AndroidContact public void save() { saveChangesCommited(); + if (getAndroidId() != null) { + setThumbnailUri(getContactThumbnailPictureUri()); + setPhotoUri(getContactPictureUri()); + } syncValuesFromAndroidContact(LinphoneContext.instance().getApplicationContext()); createOrUpdateFriend(); } diff --git a/app/src/main/java/org/linphone/utils/ImageUtils.java b/app/src/main/java/org/linphone/utils/ImageUtils.java index 844bfd781..0053af9e1 100644 --- a/app/src/main/java/org/linphone/utils/ImageUtils.java +++ b/app/src/main/java/org/linphone/utils/ImageUtils.java @@ -22,6 +22,7 @@ package org.linphone.utils; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; +import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; @@ -85,4 +86,14 @@ public class ImageUtils { / ((float) context.getResources().getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT); } + + public static Bitmap rotateImage(Bitmap source, float angle) { + Matrix matrix = new Matrix(); + matrix.postRotate(angle); + Bitmap rotatedBitmap = + Bitmap.createBitmap( + source, 0, 0, source.getWidth(), source.getHeight(), matrix, true); + source.recycle(); + return rotatedBitmap; + } } From 82b6acff27990828a792fd631ee1f2cb33a305f6 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 4 Dec 2019 10:53:36 +0100 Subject: [PATCH 74/84] Added logs --- .../java/org/linphone/LinphoneContext.java | 22 +++++-------------- .../java/org/linphone/LinphoneManager.java | 7 ++++-- .../activities/LinphoneGenericActivity.java | 3 +++ .../linphone/firebase/FirebaseMessaging.java | 2 +- 4 files changed, 14 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/org/linphone/LinphoneContext.java b/app/src/main/java/org/linphone/LinphoneContext.java index 075049ef3..30442ac61 100644 --- a/app/src/main/java/org/linphone/LinphoneContext.java +++ b/app/src/main/java/org/linphone/LinphoneContext.java @@ -21,7 +21,6 @@ package org.linphone; import static android.content.Intent.ACTION_MAIN; -import android.app.Activity; import android.content.Context; import android.content.Intent; import android.os.Build; @@ -84,7 +83,6 @@ public class LinphoneContext { private NotificationsManager mNotificationManager; private LinphoneManager mLinphoneManager; private ContactsManager mContactsManager; - private Class mIncomingReceivedActivity = CallIncomingActivity.class; private final ArrayList mCoreStartedListeners; public static boolean isReady() { @@ -108,15 +106,6 @@ public class LinphoneContext { dumpDeviceInformation(); dumpLinphoneInformation(); - String incomingReceivedActivityName = - LinphonePreferences.instance().getActivityToLaunchOnIncomingReceived(); - try { - mIncomingReceivedActivity = - (Class) Class.forName(incomingReceivedActivityName); - } catch (ClassNotFoundException e) { - Log.e(e); - } - sInstance = this; Log.i("[Context] Ready"); @@ -195,23 +184,23 @@ public class LinphoneContext { if (DeviceUtils.isAppUserRestricted(mContext)) { // See https://firebase.google.com/docs/cloud-messaging/android/receive#restricted Log.w( - "[Main Activity] Device has been restricted by user (Android 9+), push notifications won't work !"); + "[Context] Device has been restricted by user (Android 9+), push notifications won't work !"); } int bucket = DeviceUtils.getAppStandbyBucket(mContext); if (bucket > 0) { Log.w( - "[Main Activity] Device is in bucket " + "[Context] Device is in bucket " + Compatibility.getAppStandbyBucketNameFromValue(bucket)); } if (!PushNotificationUtils.isAvailable(mContext)) { - Log.w("[Main Activity] Push notifications won't work !"); + Log.w("[Context] Push notifications won't work !"); } } public void start(boolean isPush) { - Log.i("[Context] Starting"); + Log.i("[Context] Starting, push status is ", isPush); mLinphoneManager.startLibLinphone(isPush, mListener); mNotificationManager.onCoreReady(); @@ -226,7 +215,6 @@ public class LinphoneContext { if (mContactsManager.hasReadContactsAccess()) { mContactsManager.enableContactsAccess(); } - mContactsManager.initializeContactManager(); } @@ -325,7 +313,7 @@ public class LinphoneContext { /* Call activities */ private void onIncomingReceived() { - Intent intent = new Intent().setClass(mContext, mIncomingReceivedActivity); + Intent intent = new Intent(mContext, CallIncomingActivity.class); // This flag is required to start an Activity from a Service context intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); mContext.startActivity(intent); diff --git a/app/src/main/java/org/linphone/LinphoneManager.java b/app/src/main/java/org/linphone/LinphoneManager.java index 7161c49e9..0f184b6f9 100644 --- a/app/src/main/java/org/linphone/LinphoneManager.java +++ b/app/src/main/java/org/linphone/LinphoneManager.java @@ -437,7 +437,7 @@ public class LinphoneManager implements SensorEventListener { mTimer = new Timer("Linphone scheduler"); mTimer.schedule(lTask, 0, 20); - initLiblinphone(); + configureCore(); } catch (Exception e) { Log.e(e, "[Manager] Cannot start linphone"); } @@ -446,7 +446,8 @@ public class LinphoneManager implements SensorEventListener { H264Helper.setH264Mode(H264Helper.MODE_AUTO, mCore); } - private synchronized void initLiblinphone() { + private synchronized void configureCore() { + Log.i("[Manager] Configuring Core"); mAudioManager = new AndroidAudioManager(mContext); mCore.setZrtpSecretsFile(mBasePath + "/zrtp_secrets"); @@ -515,6 +516,8 @@ public class LinphoneManager implements SensorEventListener { mAccountCreator = mCore.createAccountCreator(LinphonePreferences.instance().getXmlrpcUrl()); mAccountCreator.setListener(mAccountCreatorListener); mCallGsmON = false; + + Log.i("[Manager] Core configured"); } public void resetCameraFromPreferences() { diff --git a/app/src/main/java/org/linphone/activities/LinphoneGenericActivity.java b/app/src/main/java/org/linphone/activities/LinphoneGenericActivity.java index 23b5438ec..1a218083f 100644 --- a/app/src/main/java/org/linphone/activities/LinphoneGenericActivity.java +++ b/app/src/main/java/org/linphone/activities/LinphoneGenericActivity.java @@ -80,7 +80,10 @@ public abstract class LinphoneGenericActivity extends ThemeableActivity { if (!LinphoneContext.isReady()) { new LinphoneContext(getApplicationContext()); LinphoneContext.instance().start(false); + Log.i("[Generic Activity] Context created & started"); } + + Log.i("[Generic Activity] Starting Service"); startService(new Intent().setClass(this, LinphoneService.class)); } } diff --git a/app/src/main/java/org/linphone/firebase/FirebaseMessaging.java b/app/src/main/java/org/linphone/firebase/FirebaseMessaging.java index 123fc0b32..959fca4d7 100644 --- a/app/src/main/java/org/linphone/firebase/FirebaseMessaging.java +++ b/app/src/main/java/org/linphone/firebase/FirebaseMessaging.java @@ -37,7 +37,7 @@ public class FirebaseMessaging extends FirebaseMessagingService { android.util.Log.i( "FirebaseMessaging", "[Push Notification] Starting context"); new LinphoneContext(getApplicationContext()); - LinphoneContext.instance().start(false); + LinphoneContext.instance().start(true); } else { Log.i("[Push Notification] Notifying Core"); if (LinphoneManager.getInstance() != null) { From 267fe040e275c091450a498bdd72de049aba12a4 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 4 Dec 2019 13:06:25 +0100 Subject: [PATCH 75/84] Ignore sticky headset broadcast --- .../java/org/linphone/receivers/HeadsetReceiver.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/linphone/receivers/HeadsetReceiver.java b/app/src/main/java/org/linphone/receivers/HeadsetReceiver.java index cf59918a1..07cac4ff4 100644 --- a/app/src/main/java/org/linphone/receivers/HeadsetReceiver.java +++ b/app/src/main/java/org/linphone/receivers/HeadsetReceiver.java @@ -29,9 +29,15 @@ import org.linphone.core.tools.Log; public class HeadsetReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { + if (isInitialStickyBroadcast()) { + Log.i("[Headset] Received broadcast from sticky cache, ignoring..."); + return; + } + String action = intent.getAction(); if (action.equals(AudioManager.ACTION_HEADSET_PLUG)) { // This happens when the user plugs a Jack headset to the device for example + // https://developer.android.com/reference/android/media/AudioManager.html#ACTION_HEADSET_PLUG int state = intent.getIntExtra("state", 0); String name = intent.getStringExtra("name"); int hasMicrophone = intent.getIntExtra("microphone", 0); @@ -44,7 +50,7 @@ public class HeadsetReceiver extends BroadcastReceiver { Log.i("[Headset] Headset " + name + " has a microphone"); } } else { - Log.w("[Headset] Unknow headset plugged state: " + state); + Log.w("[Headset] Unknown headset plugged state: " + state); } LinphoneManager.getAudioManager().routeAudioToEarPiece(); @@ -55,7 +61,7 @@ public class HeadsetReceiver extends BroadcastReceiver { LinphoneManager.getAudioManager().routeAudioToEarPiece(); LinphoneManager.getCallManager().refreshInCallActions(); } else { - Log.w("[Headset] Unknow action: " + action); + Log.w("[Headset] Unknown action: " + action); } } } From 481b704c1c8e91708007b206cae9e87b2318781c Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 4 Dec 2019 16:36:02 +0100 Subject: [PATCH 76/84] Version code bumped --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 303fcc45b..2ae1bfe17 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -88,7 +88,7 @@ android { defaultConfig { minSdkVersion 21 targetSdkVersion 29 - versionCode 4207 + versionCode 4208 versionName "${project.version}" applicationId getPackageName() multiDexEnabled true From 5bf110afb9ca54e4f66c952d6e9a38216b4bf29b Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 5 Dec 2019 09:33:18 +0100 Subject: [PATCH 77/84] Keep screen ON while incoming call activity is shown --- app/src/main/java/org/linphone/call/CallIncomingActivity.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/org/linphone/call/CallIncomingActivity.java b/app/src/main/java/org/linphone/call/CallIncomingActivity.java index ff11a0d7e..37ec97182 100644 --- a/app/src/main/java/org/linphone/call/CallIncomingActivity.java +++ b/app/src/main/java/org/linphone/call/CallIncomingActivity.java @@ -27,6 +27,7 @@ import android.os.Bundle; import android.view.KeyEvent; import android.view.TextureView; import android.view.View; +import android.view.WindowManager; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; @@ -63,6 +64,7 @@ public class CallIncomingActivity extends LinphoneGenericActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); Compatibility.setShowWhenLocked(this, true); Compatibility.setTurnScreenOn(this, true); From 30168a6fdbb14ddff28919f05ba1d05585a30ee7 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 5 Dec 2019 10:43:57 +0100 Subject: [PATCH 78/84] Fixed various crashes reported on play store --- .../java/org/linphone/LinphoneManager.java | 2 +- .../activities/LinphoneGenericActivity.java | 6 +- .../org/linphone/activities/MainActivity.java | 2 +- .../linphone/assistant/AssistantActivity.java | 4 +- .../linphone/call/CallIncomingActivity.java | 1 + .../contacts/AsyncContactsLoader.java | 40 ++++++---- .../linphone/contacts/ContactsManager.java | 11 ++- .../linphone/contacts/LinphoneContact.java | 15 ++-- .../settings/LinphonePreferences.java | 80 +++++++++++++++++++ .../java/org/linphone/utils/DeviceUtils.java | 17 +++- 10 files changed, 145 insertions(+), 33 deletions(-) diff --git a/app/src/main/java/org/linphone/LinphoneManager.java b/app/src/main/java/org/linphone/LinphoneManager.java index 0f184b6f9..624f6aa1b 100644 --- a/app/src/main/java/org/linphone/LinphoneManager.java +++ b/app/src/main/java/org/linphone/LinphoneManager.java @@ -825,7 +825,7 @@ public class LinphoneManager implements SensorEventListener { public void setCallGsmON(boolean on) { mCallGsmON = on; - if (on) { + if (on && mCore != null) { mCore.pauseAllCalls(); } } diff --git a/app/src/main/java/org/linphone/activities/LinphoneGenericActivity.java b/app/src/main/java/org/linphone/activities/LinphoneGenericActivity.java index 1a218083f..100fe0c41 100644 --- a/app/src/main/java/org/linphone/activities/LinphoneGenericActivity.java +++ b/app/src/main/java/org/linphone/activities/LinphoneGenericActivity.java @@ -84,7 +84,11 @@ public abstract class LinphoneGenericActivity extends ThemeableActivity { } Log.i("[Generic Activity] Starting Service"); - startService(new Intent().setClass(this, LinphoneService.class)); + try { + startService(new Intent().setClass(this, LinphoneService.class)); + } catch (IllegalStateException ise) { + Log.e("[Generic Activity] Couldn't start service, exception: ", ise); + } } } } diff --git a/app/src/main/java/org/linphone/activities/MainActivity.java b/app/src/main/java/org/linphone/activities/MainActivity.java index ca1d15f46..694878b8d 100644 --- a/app/src/main/java/org/linphone/activities/MainActivity.java +++ b/app/src/main/java/org/linphone/activities/MainActivity.java @@ -424,8 +424,8 @@ public abstract class MainActivity extends LinphoneGenericActivity } private void quit() { - goHomeAndClearStack(); stopService(new Intent(Intent.ACTION_MAIN).setClass(this, LinphoneService.class)); + goHomeAndClearStack(); /*ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); am.killBackgroundProcesses(getString(R.string.sync_account_type)); android.os.Process.killProcess(android.os.Process.myPid());*/ diff --git a/app/src/main/java/org/linphone/assistant/AssistantActivity.java b/app/src/main/java/org/linphone/assistant/AssistantActivity.java index 996f356e5..a18883829 100644 --- a/app/src/main/java/org/linphone/assistant/AssistantActivity.java +++ b/app/src/main/java/org/linphone/assistant/AssistantActivity.java @@ -154,7 +154,9 @@ public abstract class AssistantActivity extends LinphoneGenericActivity } else { // If this isn't a sip.linphone.org account, disable push notifications and enable // service notification, otherwise incoming calls won't work (most probably) - proxyConfig.setPushNotificationAllowed(false); + if (proxyConfig != null) { + proxyConfig.setPushNotificationAllowed(false); + } Log.w( "[Assistant] Unknown domain used, push probably won't work, enable service mode"); LinphonePreferences.instance().setServiceNotificationVisibility(true); diff --git a/app/src/main/java/org/linphone/call/CallIncomingActivity.java b/app/src/main/java/org/linphone/call/CallIncomingActivity.java index 37ec97182..a21d50187 100644 --- a/app/src/main/java/org/linphone/call/CallIncomingActivity.java +++ b/app/src/main/java/org/linphone/call/CallIncomingActivity.java @@ -280,6 +280,7 @@ public class CallIncomingActivity extends LinphoneGenericActivity { permissionsList.add(Manifest.permission.READ_PHONE_STATE); } if (LinphonePreferences.instance().shouldAutomaticallyAcceptVideoRequests() + && mCall != null && mCall.getRemoteParams().videoEnabled()) { if (camera != PackageManager.PERMISSION_GRANTED) { Log.i("[Permission] Asking for camera"); diff --git a/app/src/main/java/org/linphone/contacts/AsyncContactsLoader.java b/app/src/main/java/org/linphone/contacts/AsyncContactsLoader.java index d8614fabd..c4941371a 100644 --- a/app/src/main/java/org/linphone/contacts/AsyncContactsLoader.java +++ b/app/src/main/java/org/linphone/contacts/AsyncContactsLoader.java @@ -144,25 +144,31 @@ class AsyncContactsLoader extends AsyncTask Date: Thu, 5 Dec 2019 13:37:27 +0100 Subject: [PATCH 79/84] Version bumped --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 2ae1bfe17..bc3d9fdb8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -88,7 +88,7 @@ android { defaultConfig { minSdkVersion 21 targetSdkVersion 29 - versionCode 4208 + versionCode 4209 versionName "${project.version}" applicationId getPackageName() multiDexEnabled true From 813504bb85b77c460a63eda6edaa1e351765e9a0 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 5 Dec 2019 14:13:20 +0100 Subject: [PATCH 80/84] Fixed mistake in previous commit regarding quit button --- app/build.gradle | 2 +- app/src/main/java/org/linphone/activities/MainActivity.java | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index bc3d9fdb8..dfe04d587 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -88,7 +88,7 @@ android { defaultConfig { minSdkVersion 21 targetSdkVersion 29 - versionCode 4209 + versionCode 4210 versionName "${project.version}" applicationId getPackageName() multiDexEnabled true diff --git a/app/src/main/java/org/linphone/activities/MainActivity.java b/app/src/main/java/org/linphone/activities/MainActivity.java index 694878b8d..ca509dd24 100644 --- a/app/src/main/java/org/linphone/activities/MainActivity.java +++ b/app/src/main/java/org/linphone/activities/MainActivity.java @@ -69,7 +69,6 @@ import org.linphone.fragments.EmptyFragment; import org.linphone.fragments.StatusBarFragment; import org.linphone.history.HistoryActivity; import org.linphone.menu.SideMenuFragment; -import org.linphone.service.LinphoneService; import org.linphone.settings.LinphonePreferences; import org.linphone.settings.SettingsActivity; import org.linphone.utils.DeviceUtils; @@ -424,11 +423,7 @@ public abstract class MainActivity extends LinphoneGenericActivity } private void quit() { - stopService(new Intent(Intent.ACTION_MAIN).setClass(this, LinphoneService.class)); goHomeAndClearStack(); - /*ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); - am.killBackgroundProcesses(getString(R.string.sync_account_type)); - android.os.Process.killProcess(android.os.Process.myPid());*/ } // Tab, Top and Status bars From 807c279e8853a1b1c4c0533bd5a666d0da9a1500 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 5 Dec 2019 14:49:20 +0100 Subject: [PATCH 81/84] Fixed crash when creating a chat room without default proxy config --- app/build.gradle | 2 +- .../java/org/linphone/chat/ChatRoomCreationFragment.java | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index dfe04d587..9639e93ee 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -88,7 +88,7 @@ android { defaultConfig { minSdkVersion 21 targetSdkVersion 29 - versionCode 4210 + versionCode 4211 versionName "${project.version}" applicationId getPackageName() multiDexEnabled true diff --git a/app/src/main/java/org/linphone/chat/ChatRoomCreationFragment.java b/app/src/main/java/org/linphone/chat/ChatRoomCreationFragment.java index dda1fcd84..bce06962a 100644 --- a/app/src/main/java/org/linphone/chat/ChatRoomCreationFragment.java +++ b/app/src/main/java/org/linphone/chat/ChatRoomCreationFragment.java @@ -448,7 +448,10 @@ public class ChatRoomCreationFragment extends Fragment mChatRoom.getLocalAddress(), mChatRoom.getPeerAddress()); } } else { - ChatRoom chatRoom = core.getChatRoom(address, lpc.getIdentityAddress()); + ChatRoom chatRoom = null; + if (lpc != null) chatRoom = core.getChatRoom(address, lpc.getIdentityAddress()); + else chatRoom = core.getChatRoom(address); + if (chatRoom != null) { // Pop back stack so back button takes to the chat rooms list getFragmentManager().popBackStack(); From b0407645e791c009504af4d0e74bccd0526ac81b Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 5 Dec 2019 15:16:24 +0100 Subject: [PATCH 82/84] Fixed crash if trying to create a chat room from contact or history without proxy config --- app/build.gradle | 2 +- .../contacts/ContactDetailsFragment.java | 14 +++ .../history/HistoryDetailFragment.java | 90 +++++++++++-------- 3 files changed, 70 insertions(+), 36 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 9639e93ee..8921c6669 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -88,7 +88,7 @@ android { defaultConfig { minSdkVersion 21 targetSdkVersion 29 - versionCode 4211 + versionCode 4212 versionName "${project.version}" applicationId getPackageName() multiDexEnabled true diff --git a/app/src/main/java/org/linphone/contacts/ContactDetailsFragment.java b/app/src/main/java/org/linphone/contacts/ContactDetailsFragment.java index d36f76df9..04f253a0a 100644 --- a/app/src/main/java/org/linphone/contacts/ContactDetailsFragment.java +++ b/app/src/main/java/org/linphone/contacts/ContactDetailsFragment.java @@ -364,6 +364,8 @@ public class ContactDetailsFragment extends Fragment implements ContactsUpdatedL private void goToChat(String tag, boolean isSecured) { Core core = LinphoneManager.getCore(); + if (core == null) return; + Address participant = Factory.instance().createAddress(tag); ProxyConfig defaultProxyConfig = core.getDefaultProxyConfig(); @@ -409,6 +411,18 @@ public class ContactDetailsFragment extends Fragment implements ContactsUpdatedL } } } + } else { + if (isSecured) { + Log.e( + "[Contact Details Fragment] Can't create a secured chat room without proxy config"); + return; + } + + ChatRoom room = core.getChatRoom(participant); + if (room != null) { + ((ContactsActivity) getActivity()) + .showChatRoom(room.getLocalAddress(), room.getPeerAddress()); + } } } } diff --git a/app/src/main/java/org/linphone/history/HistoryDetailFragment.java b/app/src/main/java/org/linphone/history/HistoryDetailFragment.java index 699edb9ee..624adddac 100644 --- a/app/src/main/java/org/linphone/history/HistoryDetailFragment.java +++ b/app/src/main/java/org/linphone/history/HistoryDetailFragment.java @@ -160,7 +160,7 @@ public class HistoryDetailFragment extends Fragment { mWaitLayout.setVisibility(View.GONE); ((HistoryActivity) getActivity()).displayChatRoomError(); Log.e( - "Group mChat room for address " + "[History Detail Fragment] Group mChat room for address " + cr.getPeerAddress() + " has failed !"); } @@ -257,45 +257,65 @@ public class HistoryDetailFragment extends Fragment { private void goToChat(boolean isSecured) { Core core = LinphoneManager.getCore(); + if (core == null) return; + Address participant = Factory.instance().createAddress(mSipUri); - ChatRoom room = - core.findOneToOneChatRoom( - core.getDefaultProxyConfig().getContact(), participant, isSecured); - if (room != null) { - ((HistoryActivity) getActivity()) - .showChatRoom(room.getLocalAddress(), room.getPeerAddress()); - } else { - ProxyConfig lpc = core.getDefaultProxyConfig(); - if (lpc != null - && lpc.getConferenceFactoryUri() != null - && (isSecured || !LinphonePreferences.instance().useBasicChatRoomFor1To1())) { - mWaitLayout.setVisibility(View.VISIBLE); + ProxyConfig defaultProxyConfig = core.getDefaultProxyConfig(); - ChatRoomParams params = core.createDefaultChatRoomParams(); - params.enableEncryption(isSecured); - params.enableGroup(false); - // We don't want a basic chat room - params.setBackend(ChatRoomBackend.FlexisipChat); - - Address[] participants = new Address[1]; - participants[0] = participant; - - mChatRoom = - core.createChatRoom( - params, getString(R.string.dummy_group_chat_subject), participants); - if (mChatRoom != null) { - mChatRoom.addListener(mChatRoomCreationListener); - } else { - Log.w("[History Detail Fragment] createChatRoom returned null..."); - mWaitLayout.setVisibility(View.GONE); - } + if (defaultProxyConfig != null) { + ChatRoom room = + core.findOneToOneChatRoom( + defaultProxyConfig.getContact(), participant, isSecured); + if (room != null) { + ((HistoryActivity) getActivity()) + .showChatRoom(room.getLocalAddress(), room.getPeerAddress()); } else { - room = core.getChatRoom(participant); - if (room != null) { - ((HistoryActivity) getActivity()) - .showChatRoom(room.getLocalAddress(), room.getPeerAddress()); + if (defaultProxyConfig.getConferenceFactoryUri() != null + && (isSecured + || !LinphonePreferences.instance().useBasicChatRoomFor1To1())) { + mWaitLayout.setVisibility(View.VISIBLE); + + ChatRoomParams params = core.createDefaultChatRoomParams(); + params.enableEncryption(isSecured); + params.enableGroup(false); + // We don't want a basic chat room, + // so if isSecured is false we have to set this manually + params.setBackend(ChatRoomBackend.FlexisipChat); + + Address[] participants = new Address[1]; + participants[0] = participant; + + mChatRoom = + core.createChatRoom( + params, + getString(R.string.dummy_group_chat_subject), + participants); + if (mChatRoom != null) { + mChatRoom.addListener(mChatRoomCreationListener); + } else { + Log.w("[History Detail Fragment] createChatRoom returned null..."); + mWaitLayout.setVisibility(View.GONE); + } + } else { + room = core.getChatRoom(participant); + if (room != null) { + ((HistoryActivity) getActivity()) + .showChatRoom(room.getLocalAddress(), room.getPeerAddress()); + } } } + } else { + if (isSecured) { + Log.e( + "[History Detail Fragment] Can't create a secured chat room without proxy config"); + return; + } + + ChatRoom room = core.getChatRoom(participant); + if (room != null) { + ((HistoryActivity) getActivity()) + .showChatRoom(room.getLocalAddress(), room.getPeerAddress()); + } } } } From bb89582033240d290a56192ce2cbe044c843a4a7 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 9 Dec 2019 10:05:11 +0100 Subject: [PATCH 83/84] Fixed call recording on Android 10 + version bumped + updated gradle plugin + other crash fix --- app/build.gradle | 2 +- app/src/main/AndroidManifest.xml | 3 ++- .../PhoneAccountLinkingAssistantActivity.java | 6 ++++++ .../org/linphone/history/HistoryFragment.java | 21 +++++++++++-------- build.gradle | 2 +- 5 files changed, 22 insertions(+), 12 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 8921c6669..9c043d493 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -88,7 +88,7 @@ android { defaultConfig { minSdkVersion 21 targetSdkVersion 29 - versionCode 4212 + versionCode 4213 versionName "${project.version}" applicationId getPackageName() multiDexEnabled true diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 039affcec..403bcdf2b 100755 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -64,7 +64,8 @@ android:largeHeap="true" android:roundIcon="@mipmap/ic_launcher_round" android:resizeableActivity="true" - android:theme="@style/LinphoneStyle"> + android:theme="@style/LinphoneStyle" + android:requestLegacyExternalStorage="true"> diff --git a/app/src/main/java/org/linphone/assistant/PhoneAccountLinkingAssistantActivity.java b/app/src/main/java/org/linphone/assistant/PhoneAccountLinkingAssistantActivity.java index 29aac4daa..c768a346f 100644 --- a/app/src/main/java/org/linphone/assistant/PhoneAccountLinkingAssistantActivity.java +++ b/app/src/main/java/org/linphone/assistant/PhoneAccountLinkingAssistantActivity.java @@ -58,6 +58,7 @@ public class PhoneAccountLinkingAssistantActivity extends AssistantActivity { if (core == null) { Log.e("[Account Linking Assistant] Core not available"); unexpectedError(); + return; } ProxyConfig[] proxyConfigs = core.getProxyConfigList(); @@ -69,12 +70,14 @@ public class PhoneAccountLinkingAssistantActivity extends AssistantActivity { if (identity == null) { Log.e("[Account Linking Assistant] Proxy doesn't have an identity address"); unexpectedError(); + return; } if (!mProxyConfig.getDomain().equals(getString(R.string.default_domain))) { Log.e( "[Account Linking Assistant] Can't link account on domain " + mProxyConfig.getDomain()); unexpectedError(); + return; } accountCreator.setUsername(identity.getUsername()); @@ -82,6 +85,7 @@ public class PhoneAccountLinkingAssistantActivity extends AssistantActivity { if (authInfo == null) { Log.e("[Account Linking Assistant] Auth info not found"); unexpectedError(); + return; } accountCreator.setHa1(authInfo.getHa1()); accountCreator.setAlgorithm((authInfo.getAlgorithm())); @@ -90,10 +94,12 @@ public class PhoneAccountLinkingAssistantActivity extends AssistantActivity { "[Account Linking Assistant] Proxy config index out of bounds: " + proxyConfigIndex); unexpectedError(); + return; } } else { Log.e("[Account Linking Assistant] Proxy config index not found"); unexpectedError(); + return; } mCountryPicker = findViewById(R.id.select_country); diff --git a/app/src/main/java/org/linphone/history/HistoryFragment.java b/app/src/main/java/org/linphone/history/HistoryFragment.java index cdffb6414..f2f150a09 100644 --- a/app/src/main/java/org/linphone/history/HistoryFragment.java +++ b/app/src/main/java/org/linphone/history/HistoryFragment.java @@ -197,15 +197,18 @@ public class HistoryFragment extends Fragment if (mHistoryAdapter.isEditionEnabled()) { mHistoryAdapter.toggleSelection(position); } else { - CallLog log = mLogs.get(position); - Address address; - if (log.getDir() == Call.Dir.Incoming) { - address = log.getFromAddress(); - } else { - address = log.getToAddress(); - } - if (address != null) { - LinphoneManager.getCallManager().newOutgoingCall(address.asStringUriOnly(), null); + if (position >= 0 && position < mLogs.size()) { + CallLog log = mLogs.get(position); + Address address; + if (log.getDir() == Call.Dir.Incoming) { + address = log.getFromAddress(); + } else { + address = log.getToAddress(); + } + if (address != null) { + LinphoneManager.getCallManager() + .newOutgoingCall(address.asStringUriOnly(), null); + } } } } diff --git a/build.gradle b/build.gradle index e2b619b41..fa0a6b06f 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ buildscript { } } dependencies { - classpath 'com.android.tools.build:gradle:3.5.2' + classpath 'com.android.tools.build:gradle:3.5.3' classpath 'com.google.gms:google-services:4.3.2' classpath "com.diffplug.spotless:spotless-plugin-gradle:3.24.2" From 9a28a6273a92569c4bfb05995c93048034681509 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 9 Dec 2019 10:21:50 +0100 Subject: [PATCH 84/84] Updated Changelog --- CHANGELOG.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 603346a55..83ca3e742 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,14 @@ Group changes to describe their impact on the project, as follows: ## [Unreleased] +### Added +- + +### Changed +- + +## [4.2.0] - 2019-12-09 + ### Added - Added shortcuts to contacts' latest chat rooms - Improved device's do not disturb policy compliance @@ -25,7 +33,7 @@ Group changes to describe their impact on the project, as follows: - Restart service if foreground service setting is on when app is updated - Change bluetooth volume while in call if BT device connected and used -## Changed +### Changed - Improved performances to reduce startup time - Call statistics are now available for each call & conference - Added our own devices in LIME encrypted chatrooms' security view