Huge code refactoring using google tool

This commit is contained in:
Sylvain Berfini 2018-11-30 10:31:22 +01:00
parent 60feb938d4
commit 1f6d92b92a
279 changed files with 26953 additions and 23641 deletions

View file

@ -1,112 +1,114 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="org.linphone"
xmlns:android="http://schemas.android.com/apk/res/android"
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.linphone"
android:installLocation="auto">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<!-- Needed to allow Linphone to install on tablets, since android.permission.CALL_PHONE implies android.hardware.telephony is required -->
<uses-feature
android:name="android.hardware.telephony"
android:required="false"/>
android:required="false" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.CAMERA" />
<!-- Needed to allow Linphone to install on tablets, since android.permission.CAMERA implies android.hardware.camera and android.hardware.camera.autofocus are required -->
<uses-feature
android:name="android.hardware.camera"
android:required="false"/>
android:required="false" />
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- Needed to store received images if the user wants to -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- Needed to use our own Contact editor -->
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<!-- Needed to route the audio to the bluetooth headset if available -->
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BROADCAST_STICKY"/>
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
<!-- Needed to pre fill the wizard email field (only if enabled in custom settings) -->
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS"/>
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS"/>
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
<!-- Needed for in-app purchase -->
<!-- <uses-permission android:name="com.android.vending.BILLING"/> -->
<!-- Needed for overlay widget and floating notifications -->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<!-- Needed for kill application yourself -->
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<supports-screens
android:anyDensity="true"
android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true"
android:xlargeScreens="true"/>
android:xlargeScreens="true" />
<application
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:label="@string/app_name"
android:largeHeap="true">
android:largeHeap="true"
android:roundIcon="@mipmap/ic_launcher_round">
<activity
android:name=".LinphoneLauncherActivity"
android:exported="true"
android:launchMode="singleTask"
android:label="@string/app_name"
android:theme="@style/NoTitle"
android:launchMode="singleTask"
android:noHistory="true"
android:theme="@style/NoTitle"
android:windowSoftInputMode="adjustPan|stateHidden">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER"/>
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.CALL"/>
<action android:name="android.intent.action.CALL_PRIVILEGED"/>
<action android:name="android.intent.action.CALL" />
<action android:name="android.intent.action.CALL_PRIVILEGED" />
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="tel"/>
<data android:scheme="sip"/>
<data android:scheme="tel" />
<data android:scheme="sip" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SENDTO"/>
<action android:name="android.intent.action.SENDTO" />
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="sip"/>
<data android:scheme="imto"/>
<data android:scheme="sip" />
<data android:scheme="imto" />
</intent-filter>
<intent-filter>
<data android:mimeType="@string/sync_mimetype"/>
<action android:name="android.intent.action.VIEW"/>
<data android:mimeType="@string/sync_mimetype" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.OPENABLE"/>
<data android:mimeType="text/*"/>
<data android:mimeType="image/*"/>
<data android:mimeType="audio/*"/>
<data android:mimeType="video/*"/>
<data android:mimeType="application/*"/>
<category android:name="android.intent.category.OPENABLE" />
<data android:mimeType="text/*" />
<data android:mimeType="image/*" />
<data android:mimeType="audio/*" />
<data android:mimeType="video/*" />
<data android:mimeType="application/*" />
</intent-filter>
<intent-filter>
<action android:name="org.linphone.intent.action.CallLaunched" />
@ -118,7 +120,7 @@
android:launchMode="singleTask"
android:theme="@style/NoTitle">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
<activity
@ -127,7 +129,7 @@
android:noHistory="true"
android:theme="@style/NoTitle">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
<activity
@ -136,7 +138,7 @@
android:noHistory="true"
android:theme="@style/NoTitle">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
<activity
@ -145,7 +147,7 @@
android:noHistory="true"
android:theme="@style/FullScreen">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
<!--
<intent-filter>
@ -161,7 +163,7 @@
android:screenOrientation="behind"
android:theme="@style/NoTitle">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
<activity
@ -169,7 +171,7 @@
android:screenOrientation="nosensor"
android:theme="@style/NoTitle">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
<activity
@ -177,7 +179,7 @@
android:screenOrientation="nosensor"
android:theme="@style/NoTitle">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
<activity
@ -185,78 +187,78 @@
android:screenOrientation="nosensor"
android:theme="@style/NoTitle">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
<intent-filter>
<data android:scheme="linphone-config"/> <!-- Change if needed -->
<action android:name="android.intent.action.VIEW"/>
<data android:scheme="linphone-config" /> <!-- Change if needed -->
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<service
android:name=".LinphoneService"
android:label="@string/service_name"/>
android:label="@string/service_name" />
<service
android:name=".sync.SyncService"
android:exported="true">
<intent-filter>
<action android:name="android.content.SyncAdapter"/>
<action android:name="android.content.SyncAdapter" />
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="@xml/syncadapter"/>
android:resource="@xml/syncadapter" />
<meta-data
android:name="android.provider.CONTACTS_STRUCTURE"
android:resource="@xml/contacts"/>
android:resource="@xml/contacts" />
</service>
<service android:name=".sync.AuthenticationService">
<intent-filter>
<action android:name="android.accounts.AccountAuthenticator"/>
<action android:name="android.accounts.AccountAuthenticator" />
</intent-filter>
<meta-data
android:name="android.accounts.AccountAuthenticator"
android:resource="@xml/authenticator"/>
android:resource="@xml/authenticator" />
</service>
<receiver android:name=".receivers.NetworkManager">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
<receiver
android:name=".receivers.BluetoothManager"
android:enabled="false">
</receiver>
android:enabled="false"></receiver>
<receiver android:name=".receivers.BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.ACTION_SHUTDOWN"/>
<action android:name="android.intent.action.ACTION_SHUTDOWN" />
</intent-filter>
</receiver>
<receiver android:name=".receivers.PhoneStateChangedReceiver">
<intent-filter android:priority="999">
<action android:name="android.intent.action.PHONE_STATE"/>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
<!-- This one needs to be registered from application -->
<receiver android:name=".receivers.KeepAliveReceiver"/>
<receiver android:name=".receivers.KeepAliveReceiver" />
<receiver android:name=".receivers.HookReceiver" >
<receiver android:name=".receivers.HookReceiver">
<intent-filter>
<action android:name="com.base.module.phone.HOOKEVENT" />
</intent-filter>
</receiver>
<receiver android:name=".receivers.OutgoingCallReceiver"
android:permission="android.permission.PROCESS_OUTGOING_CALLS">
<receiver
android:name=".receivers.OutgoingCallReceiver"
android:permission="android.permission.PROCESS_OUTGOING_CALLS">
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
@ -266,18 +268,20 @@
android:name=".receivers.AccountEnableReceiver"
android:permission="android.permission.USE_SIP">
<intent-filter>
<action android:name="org.linphone.intent.ACCOUNTACTIVATE"/>
<action android:name="org.linphone.intent.ACCOUNTACTIVATE" />
</intent-filter>
</receiver>
<service android:name=".firebase.FirebaseIdService" android:exported="true">
<service
android:name=".firebase.FirebaseIdService"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
<service android:name=".firebase.FirebaseMessaging">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
@ -288,10 +292,10 @@
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
android:resource="@xml/provider_paths" />
</provider>
<activity android:name=".utils.LinphoneGenericActivity"/>
<activity android:name=".utils.LinphoneGenericActivity" />
<receiver
android:name=".notifications.NotificationBroadcastReceiver"

File diff suppressed because it is too large Load diff

View file

@ -19,6 +19,8 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import static android.content.Intent.ACTION_MAIN;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
@ -26,19 +28,13 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import org.linphone.settings.LinphonePreferences;
import org.linphone.assistant.RemoteProvisioningActivity;
import org.linphone.call.CallActivity;
import org.linphone.contacts.ContactsManager;
import org.linphone.settings.LinphonePreferences;
import org.linphone.utils.FileUtils;
import org.linphone.utils.LinphoneUtils;
import static android.content.Intent.ACTION_MAIN;
/**
* Launch Linphone main activity when Service is ready.
*/
/** Launch Linphone main activity when Service is ready. */
public class LinphoneLauncherActivity extends Activity {
private final String ACTION_CALL_LINPHONE = "org.linphone.intent.action.CallLaunched";
@ -75,7 +71,10 @@ public class LinphoneLauncherActivity extends Activity {
}
} else if (Intent.ACTION_VIEW.equals(action)) {
if (LinphoneService.isReady()) {
addressToCall = ContactsManager.getInstance().getAddressOrNumberForAndroidContact(getContentResolver(), intent.getData());
addressToCall =
ContactsManager.getInstance()
.getAddressOrNumberForAndroidContact(
getContentResolver(), intent.getData());
} else {
uriToResolve = intent.getData();
}
@ -104,72 +103,90 @@ public class LinphoneLauncherActivity extends Activity {
protected void onServiceReady() {
final Class<? extends Activity> classToStart;
/*if (getResources().getBoolean(R.bool.show_tutorials_instead_of_app)) {
classToStart = TutorialLauncherActivity.class;
} else */
if (getResources().getBoolean(R.bool.display_sms_remote_provisioning_activity) && LinphonePreferences.instance().isFirstRemoteProvisioning()) {
/*if (getResources().getBoolean(R.bool.show_tutorials_instead_of_app)) {
classToStart = TutorialLauncherActivity.class;
} else */
if (getResources().getBoolean(R.bool.display_sms_remote_provisioning_activity)
&& LinphonePreferences.instance().isFirstRemoteProvisioning()) {
classToStart = RemoteProvisioningActivity.class;
} else {
classToStart = LinphoneActivity.class;
}
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
Intent newIntent = new Intent(LinphoneLauncherActivity.this, classToStart);
Intent intent = getIntent();
String stringFileShared = null;
String stringUriFileShared = null;
Uri fileUri = null;
if (intent != null) {
String action = intent.getAction();
String type = intent.getType();
newIntent.setData(intent.getData());
if (Intent.ACTION_SEND.equals(action) && type != null) {
if (("text/plain").equals(type) && (String) intent.getStringExtra(Intent.EXTRA_TEXT) != null) {
stringFileShared = intent.getStringExtra(Intent.EXTRA_TEXT);
newIntent.putExtra("msgShared", stringFileShared);
} else {
fileUri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);
stringUriFileShared = FileUtils.getFilePath(getBaseContext(), fileUri);
newIntent.putExtra("fileShared", stringUriFileShared);
mHandler.postDelayed(
new Runnable() {
@Override
public void run() {
Intent newIntent = new Intent(LinphoneLauncherActivity.this, classToStart);
Intent intent = getIntent();
String stringFileShared = null;
String stringUriFileShared = null;
Uri fileUri = null;
if (intent != null) {
String action = intent.getAction();
String type = intent.getType();
newIntent.setData(intent.getData());
if (Intent.ACTION_SEND.equals(action) && type != null) {
if (("text/plain").equals(type)
&& (String) intent.getStringExtra(Intent.EXTRA_TEXT)
!= null) {
stringFileShared = intent.getStringExtra(Intent.EXTRA_TEXT);
newIntent.putExtra("msgShared", stringFileShared);
} else {
fileUri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);
stringUriFileShared =
FileUtils.getFilePath(getBaseContext(), fileUri);
newIntent.putExtra("fileShared", stringUriFileShared);
}
} else if (Intent.ACTION_SEND_MULTIPLE.equals(action) && type != null) {
if (type.startsWith("image/")) {
// TODO : Manage multiple files sharing
}
} else if (ACTION_CALL_LINPHONE.equals(action)
&& (intent.getStringExtra("NumberToCall") != null)) {
String numberToCall = intent.getStringExtra("NumberToCall");
if (CallActivity.isInstanciated()) {
CallActivity.instance().startIncomingCallActivity();
} else {
LinphoneManager.getInstance()
.newOutgoingCall(numberToCall, null);
}
}
}
} else if (Intent.ACTION_SEND_MULTIPLE.equals(action) && type != null) {
if (type.startsWith("image/")) {
//TODO : Manage multiple files sharing
if (uriToResolve != null) {
addressToCall =
ContactsManager.getInstance()
.getAddressOrNumberForAndroidContact(
getContentResolver(), uriToResolve);
Log.i(
"LinphoneLauncher",
"Intent has uri to resolve : " + uriToResolve.toString());
uriToResolve = null;
}
} else if (ACTION_CALL_LINPHONE.equals(action) && (intent.getStringExtra("NumberToCall") != null)) {
String numberToCall = intent.getStringExtra("NumberToCall");
if (CallActivity.isInstanciated()) {
CallActivity.instance().startIncomingCallActivity();
} else {
LinphoneManager.getInstance().newOutgoingCall(numberToCall, null);
if (addressToCall != null) {
newIntent.putExtra("SipUriOrNumber", addressToCall);
Log.i(
"LinphoneLauncher",
"Intent has address to call : " + addressToCall);
addressToCall = null;
}
startActivity(newIntent);
if (classToStart == LinphoneActivity.class
&& LinphoneActivity.isInstanciated()
&& (stringFileShared != null || fileUri != null)) {
if (stringFileShared != null) {
LinphoneActivity.instance()
.displayChat(null, stringFileShared, null);
} else if (fileUri != null) {
LinphoneActivity.instance()
.displayChat(null, null, stringUriFileShared);
}
}
}
}
if (uriToResolve != null) {
addressToCall = ContactsManager.getInstance().getAddressOrNumberForAndroidContact(getContentResolver(), uriToResolve);
Log.i("LinphoneLauncher", "Intent has uri to resolve : " + uriToResolve.toString());
uriToResolve = null;
}
if (addressToCall != null) {
newIntent.putExtra("SipUriOrNumber", addressToCall);
Log.i("LinphoneLauncher", "Intent has address to call : " + addressToCall);
addressToCall = null;
}
startActivity(newIntent);
if (classToStart == LinphoneActivity.class && LinphoneActivity.isInstanciated() && (stringFileShared != null || fileUri != null)) {
if (stringFileShared != null) {
LinphoneActivity.instance().displayChat(null, stringFileShared, null);
} else if (fileUri != null) {
LinphoneActivity.instance().displayChat(null, null, stringUriFileShared);
}
}
}
}, 1000);
},
1000);
}
private class ServiceWaitThread extends Thread {
public void run() {
while (!LinphoneService.isReady()) {
@ -179,16 +196,14 @@ public class LinphoneLauncherActivity extends Activity {
throw new RuntimeException("waiting thread sleep() has been interrupted");
}
}
mHandler.post(new Runnable() {
@Override
public void run() {
onServiceReady();
}
});
mHandler.post(
new Runnable() {
@Override
public void run() {
onServiceReady();
}
});
mServiceThread = null;
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -35,7 +35,7 @@ import android.os.IBinder;
import android.os.SystemClock;
import android.provider.ContactsContract;
import android.view.WindowManager;
import java.util.ArrayList;
import org.linphone.contacts.ContactsManager;
import org.linphone.core.Call;
import org.linphone.core.Call.State;
@ -51,19 +51,19 @@ import org.linphone.notifications.NotificationsManager;
import org.linphone.receivers.BluetoothManager;
import org.linphone.receivers.KeepAliveReceiver;
import org.linphone.settings.LinphonePreferences;
import org.linphone.views.LinphoneOverlay;
import org.linphone.utils.LinphoneUtils;
import java.util.ArrayList;
import org.linphone.views.LinphoneOverlay;
/**
* Linphone service, reacting to Incoming calls, ...<br />
* <p>
* Roles include:<ul>
* <li>Initializing LinphoneManager</li>
* <li>Starting C libLinphone through LinphoneManager</li>
* <li>Reacting to LinphoneManager state changes</li>
* <li>Delegating GUI state change actions to GUI listener</li>
* Linphone service, reacting to Incoming calls, ...<br>
*
* <p>Roles include:
*
* <ul>
* <li>Initializing LinphoneManager
* <li>Starting C libLinphone through LinphoneManager
* <li>Reacting to LinphoneManager state changes
* <li>Delegating GUI state change actions to GUI listener
*/
public final class LinphoneService extends Service {
/* Listener needs to be implemented in the Service as it calls
@ -72,6 +72,15 @@ public final class LinphoneService extends Service {
public static final String START_LINPHONE_LOGS = " ==== Phone information dump ====";
private static LinphoneService instance;
public Handler mHandler = new Handler();
private boolean mTestDelayElapsed = true;
private CoreListenerStub mListener;
private WindowManager mWindowManager;
private LinphoneOverlay mOverlay;
private Application.ActivityLifecycleCallbacks mActivityCallbacks;
private NotificationsManager mNotificationManager;
private String incomingReceivedActivityName;
private Class<? extends Activity> incomingReceivedActivity = LinphoneActivity.class;
public static boolean isReady() {
return instance != null && instance.mTestDelayElapsed;
@ -83,17 +92,6 @@ public final class LinphoneService extends Service {
throw new RuntimeException("LinphoneService not instantiated yet");
}
public Handler mHandler = new Handler();
private boolean mTestDelayElapsed = true;
private CoreListenerStub mListener;
private WindowManager mWindowManager;
private LinphoneOverlay mOverlay;
private Application.ActivityLifecycleCallbacks mActivityCallbacks;
private NotificationsManager mNotificationManager;
private String incomingReceivedActivityName;
private Class<? extends Activity> incomingReceivedActivity = LinphoneActivity.class;
public NotificationsManager getNotificationManager() {
return mNotificationManager;
}
@ -110,7 +108,8 @@ public final class LinphoneService extends Service {
protected void onBackgroundMode() {
Log.i("App has entered background mode");
if (LinphonePreferences.instance() != null && LinphonePreferences.instance().isFriendlistsubscriptionEnabled()) {
if (LinphonePreferences.instance() != null
&& LinphonePreferences.instance().isFriendlistsubscriptionEnabled()) {
if (LinphoneManager.isInstanciated())
LinphoneManager.getInstance().subscribeFriendList(false);
}
@ -121,7 +120,8 @@ public final class LinphoneService extends Service {
protected void onForegroundMode() {
Log.i("App has left background mode");
if (LinphonePreferences.instance() != null && LinphonePreferences.instance().isFriendlistsubscriptionEnabled()) {
if (LinphonePreferences.instance() != null
&& LinphonePreferences.instance().isFriendlistsubscriptionEnabled()) {
if (LinphoneManager.isInstanciated())
LinphoneManager.getInstance().subscribeFriendList(true);
}
@ -132,7 +132,8 @@ public final class LinphoneService extends Service {
private void setupActivityMonitor() {
if (mActivityCallbacks != null) return;
getApplication().registerActivityLifecycleCallbacks(mActivityCallbacks = new ActivityMonitor());
getApplication()
.registerActivityLifecycleCallbacks(mActivityCallbacks = new ActivityMonitor());
}
@Override
@ -152,69 +153,101 @@ public final class LinphoneService extends Service {
instance = this; // instance is ready once linphone manager has been created
mNotificationManager = new NotificationsManager(this);
LinphoneManager.getLc().addListener(mListener = new CoreListenerStub() {
@Override
public void onCallStateChanged(Core lc, Call call, Call.State state, String message) {
if (instance == null) {
Log.i("Service not ready, discarding call state change to ", state.toString());
return;
}
LinphoneManager.getLc()
.addListener(
mListener =
new CoreListenerStub() {
@Override
public void onCallStateChanged(
Core lc, Call call, Call.State state, String message) {
if (instance == null) {
Log.i(
"Service not ready, discarding call state change to ",
state.toString());
return;
}
if (getResources().getBoolean(R.bool.enable_call_notification)) {
mNotificationManager.displayCallNotification(call);
}
if (getResources()
.getBoolean(R.bool.enable_call_notification)) {
mNotificationManager.displayCallNotification(call);
}
if (state == Call.State.IncomingReceived) {
if (!LinphoneManager.getInstance().getCallGsmON())
onIncomingReceived();
}
if (state == Call.State.IncomingReceived) {
if (!LinphoneManager.getInstance().getCallGsmON())
onIncomingReceived();
}
if (state == State.End || state == State.Released || state == State.Error) {
destroyOverlay();
}
if (state == State.End
|| state == State.Released
|| state == State.Error) {
destroyOverlay();
}
if (state == State.Released && call.getCallLog().getStatus() == Call.Status.Missed) {
mNotificationManager.displayMissedCallNotification(call);
}
}
if (state == State.Released
&& call.getCallLog().getStatus()
== Call.Status.Missed) {
mNotificationManager.displayMissedCallNotification(
call);
}
}
@Override
public void onGlobalStateChanged(Core lc, GlobalState state, String message) {
//TODO global state if ON
}
@Override
public void onGlobalStateChanged(
Core lc, GlobalState state, String message) {
// TODO global state if ON
}
@Override
public void onRegistrationStateChanged(Core lc, ProxyConfig cfg, RegistrationState state, String smessage) {
//TODO registration status
}
});
@Override
public void onRegistrationStateChanged(
Core lc,
ProxyConfig cfg,
RegistrationState state,
String smessage) {
// TODO registration status
}
});
if (Version.sdkAboveOrEqual(Version.API26_O_80) && intent.getBooleanExtra("ForceStartForeground", false)) {
if (Version.sdkAboveOrEqual(Version.API26_O_80)
&& intent.getBooleanExtra("ForceStartForeground", false)) {
mNotificationManager.startForeground();
}
if (!Version.sdkAboveOrEqual(Version.API26_O_80)
|| (ContactsManager.getInstance() != null && ContactsManager.getInstance().hasContactsAccess())) {
getContentResolver().registerContentObserver(ContactsContract.Contacts.CONTENT_URI, true, ContactsManager.getInstance());
|| (ContactsManager.getInstance() != null
&& ContactsManager.getInstance().hasContactsAccess())) {
getContentResolver()
.registerContentObserver(
ContactsContract.Contacts.CONTENT_URI,
true,
ContactsManager.getInstance());
}
if (!mTestDelayElapsed) {
// Only used when testing. Simulates a 5 seconds delay for launching service
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mTestDelayElapsed = true;
}
}, 5000);
mHandler.postDelayed(
new Runnable() {
@Override
public void run() {
mTestDelayElapsed = true;
}
},
5000);
}
//make sure the application will at least wakes up every 10 mn
if (LinphonePreferences.instance().isBackgroundModeEnabled() &&
(!LinphonePreferences.instance().isPushNotificationEnabled() || !LinphoneManager.getInstance().hasLinphoneAccount())) {
// make sure the application will at least wakes up every 10 mn
if (LinphonePreferences.instance().isBackgroundModeEnabled()
&& (!LinphonePreferences.instance().isPushNotificationEnabled()
|| !LinphoneManager.getInstance().hasLinphoneAccount())) {
Intent keepAliveIntent = new Intent(this, KeepAliveReceiver.class);
PendingIntent keepAlivePendingIntent = PendingIntent.getBroadcast(this, 0, keepAliveIntent, PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager = ((AlarmManager) this.getSystemService(Context.ALARM_SERVICE));
alarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 600000, keepAlivePendingIntent);
PendingIntent keepAlivePendingIntent =
PendingIntent.getBroadcast(
this, 0, keepAliveIntent, PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager =
((AlarmManager) this.getSystemService(Context.ALARM_SERVICE));
alarmManager.setExact(
AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + 600000,
keepAlivePendingIntent);
}
BluetoothManager.getInstance().initBluetooth();
@ -240,9 +273,11 @@ public final class LinphoneService extends Service {
dumpDeviceInformation();
dumpInstalledLinphoneInformation();
incomingReceivedActivityName = LinphonePreferences.instance().getActivityToLaunchOnIncomingReceived();
incomingReceivedActivityName =
LinphonePreferences.instance().getActivityToLaunchOnIncomingReceived();
try {
incomingReceivedActivity = (Class<? extends Activity>) Class.forName(incomingReceivedActivityName);
incomingReceivedActivity =
(Class<? extends Activity>) Class.forName(incomingReceivedActivityName);
} catch (ClassNotFoundException e) {
Log.e(e);
}
@ -356,17 +391,19 @@ public final class LinphoneService extends Service {
try {
incomingReceivedActivity = (Class<? extends Activity>) Class.forName(activityName);
incomingReceivedActivityName = activityName;
LinphonePreferences.instance().setActivityToLaunchOnIncomingReceived(incomingReceivedActivityName);
LinphonePreferences.instance()
.setActivityToLaunchOnIncomingReceived(incomingReceivedActivityName);
} catch (ClassNotFoundException e) {
Log.e(e);
}
}
protected void onIncomingReceived() {
//wakeup linphone
startActivity(new Intent()
.setClass(this, incomingReceivedActivity)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
// wakeup linphone
startActivity(
new Intent()
.setClass(this, incomingReceivedActivity)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
/*Believe me or not, but knowing the application visibility state on Android is a nightmare.
@ -376,34 +413,12 @@ public final class LinphoneService extends Service {
private ArrayList<Activity> activities = new ArrayList<>();
private boolean mActive = false;
private int mRunningActivities = 0;
class InactivityChecker implements Runnable {
private boolean isCanceled;
public void cancel() {
isCanceled = true;
}
@Override
public void run() {
synchronized (LinphoneService.this) {
if (!isCanceled) {
if (ActivityMonitor.this.mRunningActivities == 0 && mActive) {
mActive = false;
LinphoneService.this.onBackgroundMode();
}
}
}
}
}
private InactivityChecker mLastChecker;
@Override
public synchronized void onActivityCreated(Activity activity, Bundle savedInstanceState) {
Log.i("Activity created:" + activity);
if (!activities.contains(activity))
activities.add(activity);
if (!activities.contains(activity)) activities.add(activity);
}
@Override
@ -419,7 +434,6 @@ public final class LinphoneService extends Service {
Log.i("runningActivities=" + mRunningActivities);
checkActivity();
}
}
@Override
@ -430,7 +444,6 @@ public final class LinphoneService extends Service {
Log.i("runningActivities=" + mRunningActivities);
checkActivity();
}
}
@Override
@ -439,9 +452,7 @@ public final class LinphoneService extends Service {
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {}
@Override
public synchronized void onActivityDestroyed(Activity activity) {
@ -471,6 +482,25 @@ public final class LinphoneService extends Service {
}
}
}
class InactivityChecker implements Runnable {
private boolean isCanceled;
public void cancel() {
isCanceled = true;
}
@Override
public void run() {
synchronized (LinphoneService.this) {
if (!isCanceled) {
if (ActivityMonitor.this.mRunningActivities == 0 && mActive) {
mActive = false;
LinphoneService.this.onBackgroundMode();
}
}
}
}
}
}
}

View file

@ -36,8 +36,6 @@ import android.content.pm.PackageManager;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
@ -51,15 +49,16 @@ import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import org.linphone.LinphoneManager;
import org.linphone.settings.LinphonePreferences;
import org.linphone.settings.LinphonePreferences.AccountBuilder;
import org.linphone.LinphoneService;
import org.linphone.utils.LinphoneUtils;
import org.linphone.R;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.linphone.LinphoneActivity;
import org.linphone.LinphoneLauncherActivity;
import org.linphone.LinphoneManager;
import org.linphone.LinphoneService;
import org.linphone.R;
import org.linphone.core.AccountCreator;
import org.linphone.core.AccountCreatorListener;
import org.linphone.core.Address;
@ -77,13 +76,19 @@ import org.linphone.core.tools.OpenH264DownloadHelper;
import org.linphone.fragments.StatusFragment;
import org.linphone.mediastream.Log;
import org.linphone.mediastream.Version;
import org.linphone.settings.LinphonePreferences;
import org.linphone.settings.LinphonePreferences.AccountBuilder;
import org.linphone.utils.LinphoneUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class AssistantActivity extends Activity implements OnClickListener, ActivityCompat.OnRequestPermissionsResultCallback, AccountCreatorListener {
public class AssistantActivity extends Activity
implements OnClickListener,
ActivityCompat.OnRequestPermissionsResultCallback,
AccountCreatorListener {
private static final int PERMISSIONS_REQUEST_RECORD_AUDIO = 201;
private static AssistantActivity instance;
public DialPlan country;
public String phone_number;
public String email;
private ImageView back, cancel;
private AssistantFragmentsEnum currentFragment;
private AssistantFragmentsEnum lastFragment;
@ -98,13 +103,12 @@ public class AssistantActivity extends Activity implements OnClickListener, Acti
private Dialog dialog;
private boolean remoteProvisioningInProgress;
private boolean echoCancellerAlreadyDone;
private static final int PERMISSIONS_REQUEST_RECORD_AUDIO = 201;
private AccountCreator mAccountCreator;
private CountryListAdapter countryListAdapter;
public DialPlan country;
public String phone_number;
public String email;
public static AssistantActivity instance() {
return instance;
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -118,20 +122,29 @@ public class AssistantActivity extends Activity implements OnClickListener, Acti
if (getIntent().getBooleanExtra("LinkPhoneNumber", false)) {
isLink = true;
if (getIntent().getBooleanExtra("FromPref", false))
fromPref = true;
if (getIntent().getBooleanExtra("FromPref", false)) fromPref = true;
displayCreateAccount();
} else {
firstFragment = getResources().getBoolean(R.bool.assistant_use_linphone_login_as_first_fragment) ? AssistantFragmentsEnum.LINPHONE_LOGIN : AssistantFragmentsEnum.WELCOME;
firstFragment =
getResources().getBoolean(R.bool.assistant_use_linphone_login_as_first_fragment)
? AssistantFragmentsEnum.LINPHONE_LOGIN
: AssistantFragmentsEnum.WELCOME;
if (firstFragment == AssistantFragmentsEnum.WELCOME) {
firstFragment = getResources().getBoolean(R.bool.assistant_use_create_linphone_account_as_first_fragment) ? AssistantFragmentsEnum.CREATE_ACCOUNT : AssistantFragmentsEnum.WELCOME;
firstFragment =
getResources()
.getBoolean(
R.bool.assistant_use_create_linphone_account_as_first_fragment)
? AssistantFragmentsEnum.CREATE_ACCOUNT
: AssistantFragmentsEnum.WELCOME;
}
if (findViewById(R.id.fragment_container) != null) {
if (savedInstanceState == null) {
display(firstFragment);
} else {
currentFragment = (AssistantFragmentsEnum) savedInstanceState.getSerializable("CurrentFragment");
currentFragment =
(AssistantFragmentsEnum)
savedInstanceState.getSerializable("CurrentFragment");
}
}
}
@ -144,56 +157,70 @@ public class AssistantActivity extends Activity implements OnClickListener, Acti
status.enableSideMenu(false);
if (LinphoneManager.getLcIfManagerNotDestroyedOrNull() != null) {
mAccountCreator = LinphoneManager.getLc().createAccountCreator(LinphonePreferences.instance().getXmlrpcUrl());
mAccountCreator =
LinphoneManager.getLc()
.createAccountCreator(LinphonePreferences.instance().getXmlrpcUrl());
mAccountCreator.setListener(this);
}
countryListAdapter = new CountryListAdapter(getApplicationContext());
mListener = new CoreListenerStub() {
mListener =
new CoreListenerStub() {
@Override
public void onConfiguringStatus(Core lc, final ConfiguringState state, String message) {
if (progress != null) progress.dismiss();
if (state == ConfiguringState.Successful) {
goToLinphoneActivity();
} else if (state == ConfiguringState.Failed) {
Toast.makeText(AssistantActivity.instance(), getString(R.string.remote_provisioning_failure), Toast.LENGTH_LONG).show();
}
}
@Override
public void onRegistrationStateChanged(Core lc, ProxyConfig cfg, RegistrationState state, String smessage) {
if (remoteProvisioningInProgress) {
if (progress != null) progress.dismiss();
if (state == RegistrationState.Ok) {
remoteProvisioningInProgress = false;
success();
}
} else if (accountCreated && !newAccount) {
if (address != null && address.asString().equals(cfg.getIdentityAddress().asString())) {
if (state == RegistrationState.Ok) {
if (progress != null) progress.dismiss();
if (getResources().getBoolean(R.bool.use_phone_number_validation)
&& cfg.getDomain().equals(getString(R.string.default_domain))
&& LinphoneManager.getLc().getDefaultProxyConfig() != null) {
loadAccountCreator(cfg).isAccountExist();
} else {
success();
}
} else if (state == RegistrationState.Failed) {
if (progress != null) progress.dismiss();
if (dialog == null || !dialog.isShowing()) {
dialog = createErrorDialog(cfg, smessage);
dialog.setCancelable(false);
dialog.show();
}
} else if (!(state == RegistrationState.Progress)) {
if (progress != null) progress.dismiss();
@Override
public void onConfiguringStatus(
Core lc, final ConfiguringState state, String message) {
if (progress != null) progress.dismiss();
if (state == ConfiguringState.Successful) {
goToLinphoneActivity();
} else if (state == ConfiguringState.Failed) {
Toast.makeText(
AssistantActivity.instance(),
getString(R.string.remote_provisioning_failure),
Toast.LENGTH_LONG)
.show();
}
}
}
}
};
@Override
public void onRegistrationStateChanged(
Core lc, ProxyConfig cfg, RegistrationState state, String smessage) {
if (remoteProvisioningInProgress) {
if (progress != null) progress.dismiss();
if (state == RegistrationState.Ok) {
remoteProvisioningInProgress = false;
success();
}
} else if (accountCreated && !newAccount) {
if (address != null
&& address.asString()
.equals(cfg.getIdentityAddress().asString())) {
if (state == RegistrationState.Ok) {
if (progress != null) progress.dismiss();
if (getResources()
.getBoolean(R.bool.use_phone_number_validation)
&& cfg.getDomain()
.equals(getString(R.string.default_domain))
&& LinphoneManager.getLc().getDefaultProxyConfig()
!= null) {
loadAccountCreator(cfg).isAccountExist();
} else {
success();
}
} else if (state == RegistrationState.Failed) {
if (progress != null) progress.dismiss();
if (dialog == null || !dialog.isShowing()) {
dialog = createErrorDialog(cfg, smessage);
dialog.setCancelable(false);
dialog.show();
}
} else if (!(state == RegistrationState.Progress)) {
if (progress != null) progress.dismiss();
}
}
}
}
};
instance = this;
}
@ -224,10 +251,6 @@ public class AssistantActivity extends Activity implements OnClickListener, Acti
super.onSaveInstanceState(outState);
}
public static AssistantActivity instance() {
return instance;
}
public void updateStatusFragment(StatusFragment fragment) {
status = fragment;
}
@ -315,7 +338,8 @@ public class AssistantActivity extends Activity implements OnClickListener, Acti
}
public void hideKeyboard() {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
InputMethodManager imm =
(InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
View view = this.getCurrentFocus();
if (imm != null && view != null) {
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
@ -328,20 +352,34 @@ public class AssistantActivity extends Activity implements OnClickListener, Acti
public void checkAndRequestPermission(String permission, int result) {
int permissionGranted = getPackageManager().checkPermission(permission, getPackageName());
Log.i("[Permission] " + permission + " is " + (permissionGranted == PackageManager.PERMISSION_GRANTED ? "granted" : "denied"));
Log.i(
"[Permission] "
+ permission
+ " is "
+ (permissionGranted == PackageManager.PERMISSION_GRANTED
? "granted"
: "denied"));
if (permissionGranted != PackageManager.PERMISSION_GRANTED) {
if (LinphonePreferences.instance().firstTimeAskingForPermission(permission) || ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) {
if (LinphonePreferences.instance().firstTimeAskingForPermission(permission)
|| ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) {
Log.i("[Permission] Asking for " + permission);
ActivityCompat.requestPermissions(this, new String[]{permission}, result);
ActivityCompat.requestPermissions(this, new String[] {permission}, result);
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
public void onRequestPermissionsResult(
int requestCode, String[] permissions, int[] grantResults) {
for (int i = 0; i < permissions.length; i++) {
Log.i("[Permission] " + permissions[i] + " is " + (grantResults[i] == PackageManager.PERMISSION_GRANTED ? "granted" : "denied"));
Log.i(
"[Permission] "
+ permissions[i]
+ " is "
+ (grantResults[i] == PackageManager.PERMISSION_GRANTED
? "granted"
: "denied"));
}
if (requestCode == PERMISSIONS_REQUEST_RECORD_AUDIO) {
@ -354,8 +392,14 @@ public class AssistantActivity extends Activity implements OnClickListener, Acti
}
private void launchEchoCancellerCalibration(boolean sendEcCalibrationResult) {
int recordAudio = getPackageManager().checkPermission(Manifest.permission.RECORD_AUDIO, getPackageName());
Log.i("[Permission] Record audio permission is " + (recordAudio == PackageManager.PERMISSION_GRANTED ? "granted" : "denied"));
int recordAudio =
getPackageManager()
.checkPermission(Manifest.permission.RECORD_AUDIO, getPackageName());
Log.i(
"[Permission] Record audio permission is "
+ (recordAudio == PackageManager.PERMISSION_GRANTED
? "granted"
: "denied"));
if (recordAudio == PackageManager.PERMISSION_GRANTED) {
EchoCancellerCalibrationFragment fragment = new EchoCancellerCalibrationFragment();
@ -385,22 +429,23 @@ public class AssistantActivity extends Activity implements OnClickListener, Acti
address = addr;
proxyConfig.edit();
proxyConfig.setIdentityAddress(addr);
if (accountCreator.getPhoneNumber() != null && accountCreator.getPhoneNumber().length() > 0)
proxyConfig.setDialPrefix(org.linphone.core.Utils.getPrefixFromE164(accountCreator.getPhoneNumber()));
proxyConfig.setDialPrefix(
org.linphone.core.Utils.getPrefixFromE164(accountCreator.getPhoneNumber()));
proxyConfig.done();
authInfo = Factory.instance().createAuthInfo(
accountCreator.getUsername(),
null,
accountCreator.getPassword(),
accountCreator.getHa1(),
proxyConfig.getRealm(),
proxyConfig.getDomain());
authInfo =
Factory.instance()
.createAuthInfo(
accountCreator.getUsername(),
null,
accountCreator.getPassword(),
accountCreator.getHa1(),
proxyConfig.getRealm(),
proxyConfig.getDomain());
lc.addProxyConfig(proxyConfig);
@ -412,9 +457,11 @@ public class AssistantActivity extends Activity implements OnClickListener, Acti
LinphonePreferences.instance().setPushNotificationEnabled(true);
if (LinphonePreferences.instance() != null)
mPrefs.enabledFriendlistSubscription(getResources().getBoolean(R.bool.use_friendlist_subscription));
mPrefs.enabledFriendlistSubscription(
getResources().getBoolean(R.bool.use_friendlist_subscription));
LinphoneManager.getInstance().subscribeFriendList(getResources().getBoolean(R.bool.use_friendlist_subscription));
LinphoneManager.getInstance()
.subscribeFriendList(getResources().getBoolean(R.bool.use_friendlist_subscription));
if (!newAccount) {
displayRegistrationInProgressDialog();
@ -423,12 +470,22 @@ public class AssistantActivity extends Activity implements OnClickListener, Acti
}
public void linphoneLogIn(AccountCreator accountCreator) {
LinphoneManager.getLc().getConfig().loadFromXmlFile(LinphoneManager.getInstance().getmDynamicConfigFile());
LinphoneManager.getLc()
.getConfig()
.loadFromXmlFile(LinphoneManager.getInstance().getmDynamicConfigFile());
configureProxyConfig(accountCreator);
}
public void genericLogIn(String username, String userid, String password, String displayname, String prefix, String domain, TransportType transport) {
saveCreatedAccount(username, userid, password, displayname, null, prefix, domain, transport);
public void genericLogIn(
String username,
String userid,
String password,
String displayname,
String prefix,
String domain,
TransportType transport) {
saveCreatedAccount(
username, userid, password, displayname, null, prefix, domain, transport);
}
private void display(AssistantFragmentsEnum fragment) {
@ -503,15 +560,17 @@ public class AssistantActivity extends Activity implements OnClickListener, Acti
private void launchDownloadCodec() {
if (OpenH264DownloadHelper.isOpenH264DownloadEnabled()) {
OpenH264DownloadHelper downloadHelper = Factory.instance().createOpenH264DownloadHelper(this);
if (Version.getCpuAbis().contains("armeabi-v7a") && !Version.getCpuAbis().contains("x86") && !downloadHelper.isCodecFound()) {
OpenH264DownloadHelper downloadHelper =
Factory.instance().createOpenH264DownloadHelper(this);
if (Version.getCpuAbis().contains("armeabi-v7a")
&& !Version.getCpuAbis().contains("x86")
&& !downloadHelper.isCodecFound()) {
CodecDownloaderFragment codecFragment = new CodecDownloaderFragment();
changeFragment(codecFragment);
currentFragment = AssistantFragmentsEnum.DOWNLOAD_CODEC;
back.setVisibility(View.VISIBLE);
cancel.setEnabled(false);
} else
goToLinphoneActivity();
} else goToLinphoneActivity();
} else {
goToLinphoneActivity();
}
@ -523,11 +582,20 @@ public class AssistantActivity extends Activity implements OnClickListener, Acti
public String getPhoneWithCountry() {
if (country == null || phone_number == null) return "";
String phoneNumberWithCountry = country.getCountryCallingCode() + phone_number.replace("\\D", "");
String phoneNumberWithCountry =
country.getCountryCallingCode() + phone_number.replace("\\D", "");
return phoneNumberWithCountry;
}
public void saveCreatedAccount(String username, String userid, String password, String displayname, String ha1, String prefix, String domain, TransportType transport) {
public void saveCreatedAccount(
String username,
String userid,
String password,
String displayname,
String ha1,
String prefix,
String domain,
TransportType transport) {
username = LinphoneUtils.getDisplayableUsernameFromAddress(username);
domain = LinphoneUtils.getDisplayableUsernameFromAddress(domain);
@ -535,13 +603,14 @@ public class AssistantActivity extends Activity implements OnClickListener, Acti
String identity = "sip:" + username + "@" + domain;
address = Factory.instance().createAddress(identity);
AccountBuilder builder = new AccountBuilder(LinphoneManager.getLc())
.setUsername(username)
.setDomain(domain)
.setHa1(ha1)
.setUserid(userid)
.setDisplayName(displayname)
.setPassword(password);
AccountBuilder builder =
new AccountBuilder(LinphoneManager.getLc())
.setUsername(username)
.setDomain(domain)
.setHa1(ha1)
.setUserid(userid)
.setDisplayName(displayname)
.setPassword(password);
if (prefix != null) {
builder.setPrefix(prefix);
@ -549,9 +618,7 @@ public class AssistantActivity extends Activity implements OnClickListener, Acti
String forcedProxy = "";
if (!TextUtils.isEmpty(forcedProxy)) {
builder.setServerAddr(forcedProxy)
.setOutboundProxyEnabled(true)
.setAvpfRrInterval(5);
builder.setServerAddr(forcedProxy).setOutboundProxyEnabled(true).setAvpfRrInterval(5);
}
if (transport != null) {
builder.setTransport(transport);
@ -573,7 +640,10 @@ public class AssistantActivity extends Activity implements OnClickListener, Acti
progress = ProgressDialog.show(this, null, null);
Drawable d = new ColorDrawable(ContextCompat.getColor(this, R.color.colorE));
d.setAlpha(200);
progress.getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
progress.getWindow()
.setLayout(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT);
progress.getWindow().setBackgroundDrawable(d);
progress.setContentView(R.layout.progress_dialog);
progress.show();
@ -586,7 +656,10 @@ public class AssistantActivity extends Activity implements OnClickListener, Acti
progress = ProgressDialog.show(this, null, null);
Drawable d = new ColorDrawable(ContextCompat.getColor(this, R.color.colorE));
d.setAlpha(200);
progress.getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
progress.getWindow()
.setLayout(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT);
progress.getWindow().setBackgroundDrawable(d);
progress.setContentView(R.layout.progress_dialog);
progress.show();
@ -606,7 +679,8 @@ public class AssistantActivity extends Activity implements OnClickListener, Acti
back.setVisibility(View.INVISIBLE);
}
public void displayAssistantCodeConfirm(String username, String phone, String dialcode, boolean recoverAccount) {
public void displayAssistantCodeConfirm(
String username, String phone, String dialcode, boolean recoverAccount) {
CreateAccountCodeActivationFragment fragment = new CreateAccountCodeActivationFragment();
newAccount = true;
Bundle extras = new Bundle();
@ -636,7 +710,8 @@ public class AssistantActivity extends Activity implements OnClickListener, Acti
}
public void isAccountVerified(String username) {
Toast.makeText(this, getString(R.string.assistant_account_validated), Toast.LENGTH_LONG).show();
Toast.makeText(this, getString(R.string.assistant_account_validated), Toast.LENGTH_LONG)
.show();
hideKeyboard();
success();
}
@ -652,19 +727,25 @@ public class AssistantActivity extends Activity implements OnClickListener, Acti
}
builder.setMessage(message)
.setTitle(proxy.getState().toString())
.setPositiveButton(getString(R.string.continue_text), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
success();
}
})
.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
LinphoneManager.getLc().removeProxyConfig(LinphoneManager.getLc().getDefaultProxyConfig());
LinphonePreferences.instance().resetDefaultProxyConfig();
LinphoneManager.getLc().refreshRegisters();
dialog.dismiss();
}
});
.setPositiveButton(
getString(R.string.continue_text),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
success();
}
})
.setNegativeButton(
getString(R.string.cancel),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
LinphoneManager.getLc()
.removeProxyConfig(
LinphoneManager.getLc().getDefaultProxyConfig());
LinphonePreferences.instance().resetDefaultProxyConfig();
LinphoneManager.getLc().refreshRegisters();
dialog.dismiss();
}
});
return builder.show();
}
@ -679,7 +760,10 @@ public class AssistantActivity extends Activity implements OnClickListener, Acti
private void goToLinphoneActivity() {
mPrefs.firstLaunchSuccessful();
startActivity(new Intent().setClass(this, LinphoneActivity.class).putExtra("isNewProxyConfig", true));
startActivity(
new Intent()
.setClass(this, LinphoneActivity.class)
.putExtra("isNewProxyConfig", true));
finish();
}
@ -697,7 +781,12 @@ public class AssistantActivity extends Activity implements OnClickListener, Acti
mPrefs.firstLaunchSuccessful();
Intent mStartActivity = new Intent(this, LinphoneLauncherActivity.class);
PendingIntent mPendingIntent = PendingIntent.getActivity(this, (int) System.currentTimeMillis(), mStartActivity, PendingIntent.FLAG_CANCEL_CURRENT);
PendingIntent mPendingIntent =
PendingIntent.getActivity(
this,
(int) System.currentTimeMillis(),
mStartActivity,
PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager mgr = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 500, mPendingIntent);
@ -709,7 +798,8 @@ public class AssistantActivity extends Activity implements OnClickListener, Acti
}
@Override
public void onIsAccountExist(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
public void onIsAccountExist(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {
if (status.equals(AccountCreator.Status.AccountExistWithAlias)) {
success();
} else {
@ -720,57 +810,48 @@ public class AssistantActivity extends Activity implements OnClickListener, Acti
}
@Override
public void onCreateAccount(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onCreateAccount(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onActivateAccount(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onActivateAccount(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onLinkAccount(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onLinkAccount(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onActivateAlias(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onActivateAlias(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onIsAccountActivated(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onIsAccountActivated(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onRecoverAccount(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onRecoverAccount(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onIsAccountLinked(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onIsAccountLinked(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onIsAliasUsed(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onIsAliasUsed(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onUpdateAccount(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onUpdateAccount(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
public CountryListAdapter getCountryListAdapter() {
return countryListAdapter;
}
/**
* This class reads a JSON file containing Country-specific phone number description,
* and allows to present them into a ListView
* This class reads a JSON file containing Country-specific phone number description, and allows
* to present them into a ListView
*/
public class CountryListAdapter extends BaseAdapter implements Filterable {
@ -789,12 +870,10 @@ public class AssistantActivity extends Activity implements OnClickListener, Acti
mInflater = inf;
}
public DialPlan getCountryFromCountryCode(String countryCode) {
countryCode = (countryCode.startsWith("+")) ? countryCode.substring(1) : countryCode;
for (DialPlan c : allCountries) {
if (c.getCountryCallingCode().compareTo(countryCode) == 0)
return c;
if (c.getCountryCallingCode().compareTo(countryCode) == 0) return c;
}
return null;
}
@ -831,7 +910,10 @@ public class AssistantActivity extends Activity implements OnClickListener, Acti
TextView dial_code = (TextView) view.findViewById(R.id.country_prefix);
if (context != null)
dial_code.setText(String.format(context.getString(R.string.country_code), c.getCountryCallingCode()));
dial_code.setText(
String.format(
context.getString(R.string.country_code),
c.getCountryCallingCode()));
view.setTag(c);
return view;

View file

@ -29,7 +29,6 @@ import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import org.linphone.LinphoneManager;
import org.linphone.R;
import org.linphone.core.PayloadType;
@ -48,8 +47,8 @@ public class CodecDownloaderFragment extends Fragment {
private TextView downloadingInfo;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.assistant_codec_downloader, container, false);
question = view.findViewById(R.id.question);
@ -61,101 +60,112 @@ public class CodecDownloaderFragment extends Fragment {
bar = view.findViewById(R.id.progressBar);
downloadingInfo = view.findViewById(R.id.downloadingInfo);
final OpenH264DownloadHelper codecDownloader = LinphoneManager.getInstance().getOpenH264DownloadHelper();
final OpenH264DownloadHelperListener codecListener = new OpenH264DownloadHelperListener() {
final OpenH264DownloadHelper codecDownloader =
LinphoneManager.getInstance().getOpenH264DownloadHelper();
final OpenH264DownloadHelperListener codecListener =
new OpenH264DownloadHelperListener() {
@Override
public void OnProgress(final int current, final int max) {
mHandler.post(new Runnable() {
@Override
public void run() {
if (current <= max) {
hideAllItems();
downloadingInfo.setText(current + " / " + max);
downloadingInfo.setVisibility(View.VISIBLE);
downloading.setVisibility(View.VISIBLE);
bar.setMax(max);
bar.setProgress(current);
bar.setVisibility(View.VISIBLE);
} else {
hideAllItems();
downloaded.setVisibility(View.VISIBLE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
enabledH264(true);
LinphoneManager.getLc().reloadMsPlugins(AssistantActivity.instance().getApplicationInfo().nativeLibraryDir);
AssistantActivity.instance().endDownloadCodec();
} else {
// We need to restart due to bad android linker
AssistantActivity.instance().restartApplication();
}
}
public void OnProgress(final int current, final int max) {
mHandler.post(
new Runnable() {
@Override
public void run() {
if (current <= max) {
hideAllItems();
downloadingInfo.setText(current + " / " + max);
downloadingInfo.setVisibility(View.VISIBLE);
downloading.setVisibility(View.VISIBLE);
bar.setMax(max);
bar.setProgress(current);
bar.setVisibility(View.VISIBLE);
} else {
hideAllItems();
downloaded.setVisibility(View.VISIBLE);
if (Build.VERSION.SDK_INT
>= Build.VERSION_CODES.LOLLIPOP_MR1) {
enabledH264(true);
LinphoneManager.getLc()
.reloadMsPlugins(
AssistantActivity.instance()
.getApplicationInfo()
.nativeLibraryDir);
AssistantActivity.instance().endDownloadCodec();
} else {
// We need to restart due to bad android linker
AssistantActivity.instance().restartApplication();
}
}
}
});
}
@Override
public void OnError(final String error) {
mHandler.post(
new Runnable() {
@Override
public void run() {
hideAllItems();
downloaded.setText("Sorry an error has occurred.");
downloaded.setVisibility(View.VISIBLE);
ok.setVisibility(View.VISIBLE);
enabledH264(false);
AssistantActivity.instance().endDownloadCodec();
}
});
}
};
codecDownloader.setOpenH264HelperListener(codecListener);
yes.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
hideAllItems();
bar.setVisibility(View.VISIBLE);
codecDownloader.downloadCodec();
}
});
}
@Override
public void OnError(final String error) {
mHandler.post(new Runnable() {
no.setOnClickListener(
new View.OnClickListener() {
@Override
public void run() {
hideAllItems();
downloaded.setText("Sorry an error has occurred.");
downloaded.setVisibility(View.VISIBLE);
ok.setVisibility(View.VISIBLE);
public void onClick(View v) {
enabledH264(false);
AssistantActivity.instance().endDownloadCodec();
}
});
}
};
codecDownloader.setOpenH264HelperListener(codecListener);
yes.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
hideAllItems();
bar.setVisibility(View.VISIBLE);
codecDownloader.downloadCodec();
}
});
no.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
enabledH264(false);
AssistantActivity.instance().endDownloadCodec();
}
});
hideAllItems();
if (savedInstanceState != null) {
if (savedInstanceState.containsKey("question"))
question.setVisibility((Integer) savedInstanceState.getSerializable("question"));
else
question.setVisibility(View.VISIBLE);
else question.setVisibility(View.VISIBLE);
if (savedInstanceState.containsKey("yes"))
yes.setVisibility((Integer) savedInstanceState.getSerializable("yes"));
else
yes.setVisibility(View.VISIBLE);
else yes.setVisibility(View.VISIBLE);
if (savedInstanceState.containsKey("no"))
no.setVisibility((Integer) savedInstanceState.getSerializable("no"));
else
no.setVisibility(View.VISIBLE);
else no.setVisibility(View.VISIBLE);
if (savedInstanceState.containsKey("downloading"))
downloading.setVisibility((Integer) savedInstanceState.getSerializable("downloading"));
downloading.setVisibility(
(Integer) savedInstanceState.getSerializable("downloading"));
if (savedInstanceState.containsKey("downloaded"))
downloaded.setVisibility((Integer) savedInstanceState.getSerializable("downloaded"));
downloaded.setVisibility(
(Integer) savedInstanceState.getSerializable("downloaded"));
if (savedInstanceState.containsKey("context_bar"))
bar.setVisibility((Integer) savedInstanceState.getSerializable("context_bar"));
if (savedInstanceState.containsKey("downloadingInfo"))
downloadingInfo.setVisibility((Integer) savedInstanceState.getSerializable("downloadingInfo"));
downloadingInfo.setVisibility(
(Integer) savedInstanceState.getSerializable("downloadingInfo"));
if (savedInstanceState.containsKey("ok"))
ok.setVisibility((Integer) savedInstanceState.getSerializable("ok"));

View file

@ -30,19 +30,19 @@ import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import org.linphone.R;
import org.linphone.core.DialPlan;
public class CountryListFragment extends Fragment implements AdapterView.OnItemClickListener, View.OnClickListener {
public class CountryListFragment extends Fragment
implements AdapterView.OnItemClickListener, View.OnClickListener {
private ListView list;
private EditText search;
private ImageView clearSearchField;
private AssistantActivity.CountryListAdapter adapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.assistant_country_list, container, false);
adapter = AssistantActivity.instance().getCountryListAdapter();
@ -56,21 +56,20 @@ public class CountryListFragment extends Fragment implements AdapterView.OnItemC
list.setAdapter(adapter);
list.setOnItemClickListener(this);
search.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
search.addTextChangedListener(
new TextWatcher() {
@Override
public void beforeTextChanged(
CharSequence s, int start, int count, int after) {}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
adapter.getFilter().filter(s);
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
adapter.getFilter().filter(s);
}
@Override
public void afterTextChanged(Editable s) {
}
});
@Override
public void afterTextChanged(Editable s) {}
});
search.setText("");
return view;

View file

@ -27,25 +27,29 @@ import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import org.linphone.LinphoneManager;
import org.linphone.settings.LinphonePreferences;
import org.linphone.R;
import org.linphone.core.AccountCreator;
import org.linphone.core.AccountCreatorListener;
import org.linphone.settings.LinphonePreferences;
public class CreateAccountActivationFragment extends Fragment implements OnClickListener, AccountCreatorListener {
public class CreateAccountActivationFragment extends Fragment
implements OnClickListener, AccountCreatorListener {
private String username, password;
private Button checkAccount;
private TextView email;
private AccountCreator accountCreator;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.assistant_account_creation_email_activation, container, false);
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view =
inflater.inflate(
R.layout.assistant_account_creation_email_activation, container, false);
accountCreator = LinphoneManager.getLc().createAccountCreator(LinphonePreferences.instance().getXmlrpcUrl());
accountCreator =
LinphoneManager.getLc()
.createAccountCreator(LinphonePreferences.instance().getXmlrpcUrl());
accountCreator.setListener(this);
username = getArguments().getString("Username");
@ -72,55 +76,63 @@ public class CreateAccountActivationFragment extends Fragment implements OnClick
}
@Override
public void onIsAccountExist(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onIsAccountExist(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onCreateAccount(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onCreateAccount(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onActivateAccount(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onActivateAccount(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onLinkAccount(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onLinkAccount(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onActivateAlias(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onActivateAlias(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onIsAccountActivated(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
public void onIsAccountActivated(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {
if (AssistantActivity.instance() == null) {
return;
}
if (status.equals(AccountCreator.Status.AccountNotActivated)) {
Toast.makeText(getActivity(), getString(R.string.assistant_account_not_validated), Toast.LENGTH_LONG).show();
Toast.makeText(
getActivity(),
getString(R.string.assistant_account_not_validated),
Toast.LENGTH_LONG)
.show();
} else if (status.equals(AccountCreator.Status.AccountActivated)) {
AssistantActivity.instance().linphoneLogIn(accountCreator);
AssistantActivity.instance().isAccountVerified(username);
} else {
Toast.makeText(getActivity(), getString(R.string.wizard_server_unavailable), Toast.LENGTH_LONG).show();
Toast.makeText(
getActivity(),
getString(R.string.wizard_server_unavailable),
Toast.LENGTH_LONG)
.show();
}
checkAccount.setEnabled(true);
}
@Override
public void onRecoverAccount(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onRecoverAccount(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onIsAccountLinked(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onIsAccountLinked(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onIsAliasUsed(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onIsAliasUsed(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onUpdateAccount(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onUpdateAccount(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
}

View file

@ -31,14 +31,14 @@ import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import org.linphone.LinphoneManager;
import org.linphone.settings.LinphonePreferences;
import org.linphone.R;
import org.linphone.core.AccountCreator;
import org.linphone.core.AccountCreatorListener;
import org.linphone.settings.LinphonePreferences;
public class CreateAccountCodeActivationFragment extends Fragment implements AccountCreatorListener {
public class CreateAccountCodeActivationFragment extends Fragment
implements AccountCreatorListener {
private String username, phone, dialcode;
private TextView title, phonenumber;
private EditText code;
@ -49,9 +49,11 @@ public class CreateAccountCodeActivationFragment extends Fragment implements Acc
private AccountCreator accountCreator;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.assistant_account_creation_code_activation, container, false);
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view =
inflater.inflate(
R.layout.assistant_account_creation_code_activation, container, false);
username = getArguments().getString("Username");
phone = getArguments().getString("Phone");
@ -61,14 +63,15 @@ public class CreateAccountCodeActivationFragment extends Fragment implements Acc
accountNumber = getArguments().getInt("AccountNumber");
code_length = LinphonePreferences.instance().getCodeLength();
accountCreator = LinphoneManager.getLc().createAccountCreator(LinphonePreferences.instance().getXmlrpcUrl());
accountCreator =
LinphoneManager.getLc()
.createAccountCreator(LinphonePreferences.instance().getXmlrpcUrl());
accountCreator.setListener(this);
accountCreator.setUsername(username);
accountCreator.setPhoneNumber(phone, dialcode);
back = view.findViewById(R.id.back);
if (back != null)
back.setVisibility(Button.INVISIBLE);
if (back != null) back.setVisibility(Button.INVISIBLE);
title = view.findViewById(R.id.title_account_activation);
if (linkAccount) {
@ -81,46 +84,47 @@ public class CreateAccountCodeActivationFragment extends Fragment implements Acc
phonenumber.setText(accountCreator.getPhoneNumber());
code = view.findViewById(R.id.assistant_code);
code.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
code.addTextChangedListener(
new TextWatcher() {
@Override
public void beforeTextChanged(
CharSequence s, int start, int count, int after) {}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
@Override
public void afterTextChanged(Editable s) {
if (s.length() == code_length) {
checkAccount.setEnabled(true);
} else {
checkAccount.setEnabled(false);
}
}
});
@Override
public void afterTextChanged(Editable s) {
if (s.length() == code_length) {
checkAccount.setEnabled(true);
} else {
checkAccount.setEnabled(false);
}
}
});
checkAccount = view.findViewById(R.id.assistant_check);
checkAccount.setEnabled(false);
checkAccount.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
checkAccount.setEnabled(false);
accountCreator.setActivationCode(code.getText().toString());
if (linkAccount) {
linkAccount();
} else {
activateAccount();
}
}
});
checkAccount.setOnClickListener(
new OnClickListener() {
@Override
public void onClick(View v) {
checkAccount.setEnabled(false);
accountCreator.setActivationCode(code.getText().toString());
if (linkAccount) {
linkAccount();
} else {
activateAccount();
}
}
});
return view;
}
private void linkAccount() {
accountCreator.setUsername(LinphonePreferences.instance().getAccountUsername(accountNumber));
accountCreator.setUsername(
LinphonePreferences.instance().getAccountUsername(accountNumber));
accountCreator.setHa1(LinphonePreferences.instance().getAccountHa1(accountNumber));
accountCreator.activateAlias();
}
@ -133,15 +137,16 @@ public class CreateAccountCodeActivationFragment extends Fragment implements Acc
}
@Override
public void onIsAccountExist(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onIsAccountExist(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onCreateAccount(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onCreateAccount(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onActivateAccount(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
public void onActivateAccount(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {
if (AssistantActivity.instance() == null) {
return;
}
@ -163,25 +168,37 @@ public class CreateAccountCodeActivationFragment extends Fragment implements Acc
}
}
} else if (status.equals(AccountCreator.Status.RequestFailed)) {
Toast.makeText(getActivity(), getString(R.string.wizard_server_unavailable), Toast.LENGTH_LONG).show();
Toast.makeText(
getActivity(),
getString(R.string.wizard_server_unavailable),
Toast.LENGTH_LONG)
.show();
} else {
Toast.makeText(getActivity(), getString(R.string.assistant_error_confirmation_code), Toast.LENGTH_LONG).show();
Toast.makeText(
getActivity(),
getString(R.string.assistant_error_confirmation_code),
Toast.LENGTH_LONG)
.show();
AssistantActivity.instance().displayAssistantLinphoneLogin(phone, dialcode);
}
}
@Override
public void onLinkAccount(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onLinkAccount(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onActivateAlias(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
public void onActivateAlias(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {
if (AssistantActivity.instance() == null) {
return;
}
if (status.equals(AccountCreator.Status.AccountActivated)) {
LinphonePreferences.instance().setPrefix(accountNumber, org.linphone.core.Utils.getPrefixFromE164(accountCreator.getPhoneNumber()));
LinphonePreferences.instance()
.setPrefix(
accountNumber,
org.linphone.core.Utils.getPrefixFromE164(
accountCreator.getPhoneNumber()));
LinphonePreferences.instance().setLinkPopupTime("");
AssistantActivity.instance().hideKeyboard();
AssistantActivity.instance().success();
@ -189,26 +206,22 @@ public class CreateAccountCodeActivationFragment extends Fragment implements Acc
}
@Override
public void onIsAccountActivated(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onIsAccountActivated(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onRecoverAccount(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onRecoverAccount(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onIsAccountLinked(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onIsAccountLinked(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onIsAliasUsed(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onIsAliasUsed(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onUpdateAccount(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onUpdateAccount(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
}

View file

@ -40,25 +40,36 @@ import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.linphone.LinphoneManager;
import org.linphone.settings.LinphonePreferences;
import org.linphone.utils.LinphoneUtils;
import org.linphone.R;
import org.linphone.core.AccountCreator;
import org.linphone.core.AccountCreator.Status;
import org.linphone.core.AccountCreatorListener;
import org.linphone.core.DialPlan;
import org.linphone.settings.LinphonePreferences;
import org.linphone.utils.LinphoneUtils;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class CreateAccountFragment extends Fragment implements CompoundButton.OnCheckedChangeListener, OnClickListener, AccountCreatorListener {
private EditText phoneNumberEdit, usernameEdit, passwordEdit, passwordConfirmEdit, emailEdit, dialCode;
private TextView phoneNumberError, passwordError, passwordConfirmError, emailError, assisstantTitle, sipUri, skip, instruction;
public class CreateAccountFragment extends Fragment
implements CompoundButton.OnCheckedChangeListener, OnClickListener, AccountCreatorListener {
private final Pattern UPPER_CASE_REGEX = Pattern.compile("[A-Z]");
private EditText phoneNumberEdit,
usernameEdit,
passwordEdit,
passwordConfirmEdit,
emailEdit,
dialCode;
private TextView phoneNumberError,
passwordError,
passwordConfirmError,
emailError,
assisstantTitle,
sipUri,
skip,
instruction;
private ImageView phoneNumberInfo;
private boolean passwordOk = false;
private boolean emailOk = false;
private boolean confirmPasswordOk = false;
@ -67,16 +78,22 @@ public class CreateAccountFragment extends Fragment implements CompoundButton.On
private CheckBox useUsername, useEmail;
private String addressSip = "";
private int countryCode;
private LinearLayout phoneNumberLayout, usernameLayout, emailLayout, passwordLayout, passwordConfirmLayout;
private final Pattern UPPER_CASE_REGEX = Pattern.compile("[A-Z]");
private LinearLayout phoneNumberLayout,
usernameLayout,
emailLayout,
passwordLayout,
passwordConfirmLayout;
private AccountCreator accountCreator;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.assistant_account_creation, container, false);
//Initialize accountCreator
accountCreator = LinphoneManager.getLc().createAccountCreator(LinphonePreferences.instance().getXmlrpcUrl());
// Initialize accountCreator
accountCreator =
LinphoneManager.getLc()
.createAccountCreator(LinphonePreferences.instance().getXmlrpcUrl());
accountCreator.setListener(this);
instruction = view.findViewById(R.id.message_create_account);
@ -115,13 +132,15 @@ public class CreateAccountFragment extends Fragment implements CompoundButton.On
skip = view.findViewById(R.id.assistant_skip);
//Phone number
// Phone number
if (getResources().getBoolean(R.bool.use_phone_number_validation)) {
getActivity().getApplicationContext();
//Automatically get the country code from the phone
// Automatically get the country code from the phone
TelephonyManager tm =
(TelephonyManager) getActivity().getApplicationContext().getSystemService(
Context.TELEPHONY_SERVICE);
(TelephonyManager)
getActivity()
.getApplicationContext()
.getSystemService(Context.TELEPHONY_SERVICE);
String countryIso = tm.getNetworkCountryIso();
countryCode = org.linphone.core.Utils.getCccFromIso(countryIso.toUpperCase());
@ -137,19 +156,25 @@ public class CreateAccountFragment extends Fragment implements CompoundButton.On
DialPlan c = AssistantActivity.instance().country;
if (c != null) {
selectCountry.setText(c.getCountry());
dialCode.setText(c.getCountryCallingCode().contains("+") ?
c.getCountryCallingCode() : "+" + c.getCountryCallingCode());
dialCode.setText(
c.getCountryCallingCode().contains("+")
? c.getCountryCallingCode()
: "+" + c.getCountryCallingCode());
} else {
c = AssistantActivity.instance().getCountryListAdapter()
.getCountryFromCountryCode(String.valueOf(countryCode));
c =
AssistantActivity.instance()
.getCountryListAdapter()
.getCountryFromCountryCode(String.valueOf(countryCode));
if (c != null) {
selectCountry.setText(c.getCountry());
dialCode.setText(c.getCountryCallingCode().contains("+") ?
c.getCountryCallingCode() : "+" + c.getCountryCallingCode());
dialCode.setText(
c.getCountryCallingCode().contains("+")
? c.getCountryCallingCode()
: "+" + c.getCountryCallingCode());
}
}
//Allow user to enter a username instead use the phone number as username
// Allow user to enter a username instead use the phone number as username
if (getResources().getBoolean(R.bool.assistant_allow_username)) {
useUsername.setVisibility(View.VISIBLE);
useUsername.setOnCheckedChangeListener(this);
@ -158,14 +183,15 @@ public class CreateAccountFragment extends Fragment implements CompoundButton.On
addPhoneNumberHandler(dialCode, null);
}
//Password & email address
// Password & email address
if (getResources().getBoolean(R.bool.isTablet)
|| !getResources().getBoolean(R.bool.use_phone_number_validation)) {
useEmail.setVisibility(View.VISIBLE);
useEmail.setOnCheckedChangeListener(this);
if (getResources().getBoolean(R.bool.pre_fill_email_in_assistant)) {
Account[] accounts = AccountManager.get(getActivity()).getAccountsByType("com.google");
Account[] accounts =
AccountManager.get(getActivity()).getAccountsByType("com.google");
for (Account account : accounts) {
if (isEmailCorrect(account.name)) {
@ -183,7 +209,7 @@ public class CreateAccountFragment extends Fragment implements CompoundButton.On
addEmailHandler(emailEdit, null);
}
//Hide phone number and display username/email/password
// Hide phone number and display username/email/password
if (!getResources().getBoolean(R.bool.use_phone_number_validation)) {
useEmail.setVisibility(View.GONE);
useUsername.setVisibility(View.GONE);
@ -194,7 +220,7 @@ public class CreateAccountFragment extends Fragment implements CompoundButton.On
emailLayout.setVisibility(View.VISIBLE);
}
//Link account with phone number
// Link account with phone number
if (getArguments().getBoolean("LinkPhoneNumber")) {
linkAccount = true;
useEmail.setVisibility(View.GONE);
@ -296,8 +322,12 @@ public class CreateAccountFragment extends Fragment implements CompoundButton.On
if (linkAccount) {
new AlertDialog.Builder(getActivity())
.setTitle(getString(R.string.phone_number_info_title))
.setMessage(getString(R.string.phone_number_link_info_content) + "\n"
+ getString(R.string.phone_number_link_info_content_already_account))
.setMessage(
getString(R.string.phone_number_link_info_content)
+ "\n"
+ getString(
R.string
.phone_number_link_info_content_already_account))
.show();
} else {
new AlertDialog.Builder(getActivity())
@ -312,11 +342,15 @@ public class CreateAccountFragment extends Fragment implements CompoundButton.On
} else {
if (useEmail.isChecked()) accountCreator.setPhoneNumber(null, null);
if (!getResources().getBoolean(R.bool.isTablet) || getUsername().length() > 0) {
LinphoneManager.getLc().getConfig().loadFromXmlFile(LinphoneManager.getInstance().getmDynamicConfigFile());
LinphoneManager.getLc()
.getConfig()
.loadFromXmlFile(LinphoneManager.getInstance().getmDynamicConfigFile());
accountCreator.isAccountExist();
} else {
LinphoneUtils.displayErrorAlert(LinphoneUtils.errorForUsernameStatus(AccountCreator.UsernameStatus.TooShort)
, AssistantActivity.instance());
LinphoneUtils.displayErrorAlert(
LinphoneUtils.errorForUsernameStatus(
AccountCreator.UsernameStatus.TooShort),
AssistantActivity.instance());
createAccount.setEnabled(true);
}
}
@ -333,23 +367,29 @@ public class CreateAccountFragment extends Fragment implements CompoundButton.On
}
private void addAlias() {
accountCreator.setUsername(LinphonePreferences.instance().getAccountUsername(
LinphonePreferences.instance().getDefaultAccountIndex())
);
int status = accountCreator.setPhoneNumber(
phoneNumberEdit.getText().toString(), LinphoneUtils.getCountryCode(dialCode));
accountCreator.setUsername(
LinphonePreferences.instance()
.getAccountUsername(
LinphonePreferences.instance().getDefaultAccountIndex()));
int status =
accountCreator.setPhoneNumber(
phoneNumberEdit.getText().toString(),
LinphoneUtils.getCountryCode(dialCode));
boolean isOk = status == AccountCreator.PhoneNumberStatus.Ok.toInt();
if (isOk) {
accountCreator.linkAccount();
} else {
createAccount.setEnabled(true);
LinphoneUtils.displayErrorAlert(LinphoneUtils.errorForPhoneNumberStatus(status), AssistantActivity.instance());
LinphoneUtils.displayError(isOk, phoneNumberError, LinphoneUtils.errorForPhoneNumberStatus(status));
LinphoneUtils.displayErrorAlert(
LinphoneUtils.errorForPhoneNumberStatus(status), AssistantActivity.instance());
LinphoneUtils.displayError(
isOk, phoneNumberError, LinphoneUtils.errorForPhoneNumberStatus(status));
}
}
private void createAccount() {
if ((getResources().getBoolean(R.bool.isTablet) || !getResources().getBoolean(R.bool.use_phone_number_validation))
if ((getResources().getBoolean(R.bool.isTablet)
|| !getResources().getBoolean(R.bool.use_phone_number_validation))
&& useEmail.isChecked()) {
AccountCreator.EmailStatus emailStatus;
AccountCreator.PasswordStatus passwordStatus;
@ -358,16 +398,23 @@ public class CreateAccountFragment extends Fragment implements CompoundButton.On
emailStatus = accountCreator.setEmail(emailEdit.getText().toString());
if (!emailOk) {
LinphoneUtils.displayError(false, emailError, LinphoneUtils.errorForEmailStatus(emailStatus));
LinphoneUtils.displayErrorAlert(LinphoneUtils.errorForEmailStatus(emailStatus)
, AssistantActivity.instance());
LinphoneUtils.displayError(
false, emailError, LinphoneUtils.errorForEmailStatus(emailStatus));
LinphoneUtils.displayErrorAlert(
LinphoneUtils.errorForEmailStatus(emailStatus),
AssistantActivity.instance());
} else if (!passwordOk) {
LinphoneUtils.displayError(false, passwordError, LinphoneUtils.errorForPasswordStatus(passwordStatus));
LinphoneUtils.displayErrorAlert(LinphoneUtils.errorForPasswordStatus(passwordStatus)
, AssistantActivity.instance());
LinphoneUtils.displayError(
false, passwordError, LinphoneUtils.errorForPasswordStatus(passwordStatus));
LinphoneUtils.displayErrorAlert(
LinphoneUtils.errorForPasswordStatus(passwordStatus),
AssistantActivity.instance());
} else if (!confirmPasswordOk) {
String msg;
if (passwordConfirmEdit.getText().toString().equals(passwordEdit.getText().toString())) {
if (passwordConfirmEdit
.getText()
.toString()
.equals(passwordEdit.getText().toString())) {
msg = getString(R.string.wizard_password_incorrect);
} else {
msg = getString(R.string.wizard_passwords_unmatched);
@ -381,8 +428,10 @@ public class CreateAccountFragment extends Fragment implements CompoundButton.On
if (phoneNumberEdit.length() > 0 || dialCode.length() > 1) {
int phoneStatus;
boolean isOk;
phoneStatus = accountCreator.setPhoneNumber(
phoneNumberEdit.getText().toString(), LinphoneUtils.getCountryCode(dialCode));
phoneStatus =
accountCreator.setPhoneNumber(
phoneNumberEdit.getText().toString(),
LinphoneUtils.getCountryCode(dialCode));
isOk = phoneStatus == AccountCreator.PhoneNumberStatus.Ok.toInt();
if (!useUsername.isChecked() && accountCreator.getUsername() == null) {
accountCreator.setUsername(accountCreator.getPhoneNumber());
@ -394,22 +443,28 @@ public class CreateAccountFragment extends Fragment implements CompoundButton.On
if (isOk) {
accountCreator.createAccount();
} else {
LinphoneUtils.displayErrorAlert(LinphoneUtils.errorForPhoneNumberStatus(phoneStatus)
, AssistantActivity.instance());
LinphoneUtils.displayError(isOk, phoneNumberError
, LinphoneUtils.errorForPhoneNumberStatus(phoneStatus));
LinphoneUtils.displayErrorAlert(
LinphoneUtils.errorForPhoneNumberStatus(phoneStatus),
AssistantActivity.instance());
LinphoneUtils.displayError(
isOk,
phoneNumberError,
LinphoneUtils.errorForPhoneNumberStatus(phoneStatus));
}
} else {
LinphoneUtils.displayErrorAlert(getString(R.string.assistant_create_account_part_1)
, AssistantActivity.instance());
LinphoneUtils.displayErrorAlert(
getString(R.string.assistant_create_account_part_1),
AssistantActivity.instance());
}
}
createAccount.setEnabled(true);
}
private int getPhoneNumberStatus() {
int status = accountCreator.setPhoneNumber(
phoneNumberEdit.getText().toString(), LinphoneUtils.getCountryCode(dialCode));
int status =
accountCreator.setPhoneNumber(
phoneNumberEdit.getText().toString(),
LinphoneUtils.getCountryCode(dialCode));
addressSip = accountCreator.getPhoneNumber();
return status;
}
@ -418,13 +473,16 @@ public class CreateAccountFragment extends Fragment implements CompoundButton.On
String msg = "";
accountCreator.setUsername(getUsername());
if (!useEmail.isChecked() && getResources().getBoolean(R.bool.use_phone_number_validation)) {
if (!useEmail.isChecked()
&& getResources().getBoolean(R.bool.use_phone_number_validation)) {
int status = getPhoneNumberStatus();
boolean isOk = (status == AccountCreator.PhoneNumberStatus.Ok.toInt());
LinphoneUtils.displayError(isOk, phoneNumberError, LinphoneUtils.errorForPhoneNumberStatus(status));
LinphoneUtils.displayError(
isOk, phoneNumberError, LinphoneUtils.errorForPhoneNumberStatus(status));
// Username or phone number
if (getResources().getBoolean(R.bool.assistant_allow_username) && useUsername.isChecked()) {
if (getResources().getBoolean(R.bool.assistant_allow_username)
&& useUsername.isChecked()) {
addressSip = getUsername();
}
@ -441,133 +499,168 @@ public class CreateAccountFragment extends Fragment implements CompoundButton.On
dialCode.setBackgroundResource(R.drawable.resizable_textfield);
phoneNumberEdit.setBackgroundResource(R.drawable.resizable_textfield);
if (!linkAccount && addressSip.length() > 0) {
msg = getResources().getString(R.string.assistant_create_account_phone_number_address)
+ " <" + addressSip + "@" + getResources().getString(R.string.default_domain) + ">";
msg =
getResources()
.getString(
R.string
.assistant_create_account_phone_number_address)
+ " <"
+ addressSip
+ "@"
+ getResources().getString(R.string.default_domain)
+ ">";
}
}
} else {
addressSip = getUsername();
if (addressSip.length() > 0) {
msg = getResources().getString(R.string.assistant_create_account_phone_number_address)
+ " <sip:" + addressSip + "@" + getResources().getString(R.string.default_domain) + ">";
msg =
getResources()
.getString(
R.string
.assistant_create_account_phone_number_address)
+ " <sip:"
+ addressSip
+ "@"
+ getResources().getString(R.string.default_domain)
+ ">";
}
}
sipUri.setText(msg);
}
private void addPhoneNumberHandler(final EditText field, final ImageView icon) {
field.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
if (field.equals(dialCode)) {
DialPlan c = AssistantActivity.instance().getCountryListAdapter()
.getCountryFromCountryCode(dialCode.getText().toString());
if (c != null) {
AssistantActivity.instance().country = c;
selectCountry.setText(c.getCountry());
} else {
selectCountry.setText(R.string.select_your_country);
field.addTextChangedListener(
new TextWatcher() {
public void afterTextChanged(Editable s) {
if (field.equals(dialCode)) {
DialPlan c =
AssistantActivity.instance()
.getCountryListAdapter()
.getCountryFromCountryCode(
dialCode.getText().toString());
if (c != null) {
AssistantActivity.instance().country = c;
selectCountry.setText(c.getCountry());
} else {
selectCountry.setText(R.string.select_your_country);
}
}
}
}
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void beforeTextChanged(
CharSequence s, int start, int count, int after) {}
public void onTextChanged(CharSequence s, int start, int count, int after) {
onTextChanged2();
}
});
public void onTextChanged(CharSequence s, int start, int count, int after) {
onTextChanged2();
}
});
}
private void addUsernameHandler(final EditText field, final ImageView icon) {
field.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
Matcher matcher = UPPER_CASE_REGEX.matcher(s);
while (matcher.find()) {
CharSequence upperCaseRegion = s.subSequence(matcher.start(), matcher.end());
s.replace(matcher.start(), matcher.end(), upperCaseRegion.toString().toLowerCase());
}
}
field.addTextChangedListener(
new TextWatcher() {
public void afterTextChanged(Editable s) {
Matcher matcher = UPPER_CASE_REGEX.matcher(s);
while (matcher.find()) {
CharSequence upperCaseRegion =
s.subSequence(matcher.start(), matcher.end());
s.replace(
matcher.start(),
matcher.end(),
upperCaseRegion.toString().toLowerCase());
}
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void beforeTextChanged(
CharSequence s, int start, int count, int after) {}
public void onTextChanged(CharSequence s, int start, int count, int after) {
onTextChanged2();
}
});
public void onTextChanged(CharSequence s, int start, int count, int after) {
onTextChanged2();
}
});
}
private void addEmailHandler(final EditText field, final ImageView icon) {
field.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
emailOk = false;
AccountCreator.EmailStatus status = accountCreator.setEmail(field.getText().toString());
if (status.equals(AccountCreator.EmailStatus.Ok)) {
emailOk = true;
LinphoneUtils.displayError(emailOk, emailError, "");
} else {
LinphoneUtils.displayError(emailOk
, emailError, LinphoneUtils.errorForEmailStatus(status));
}
}
field.addTextChangedListener(
new TextWatcher() {
public void afterTextChanged(Editable s) {
emailOk = false;
AccountCreator.EmailStatus status =
accountCreator.setEmail(field.getText().toString());
if (status.equals(AccountCreator.EmailStatus.Ok)) {
emailOk = true;
LinphoneUtils.displayError(emailOk, emailError, "");
} else {
LinphoneUtils.displayError(
emailOk, emailError, LinphoneUtils.errorForEmailStatus(status));
}
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void beforeTextChanged(
CharSequence s, int start, int count, int after) {}
public void onTextChanged(CharSequence s, int start, int count, int after) {
}
});
public void onTextChanged(CharSequence s, int start, int count, int after) {}
});
}
private void addPasswordHandler(final EditText field1, final ImageView icon) {
TextWatcher passwordListener = new TextWatcher() {
public void afterTextChanged(Editable s) {
passwordOk = false;
AccountCreator.PasswordStatus status = accountCreator.setPassword(field1.getText().toString());
if (isPasswordCorrect(field1.getText().toString())) {
passwordOk = true;
LinphoneUtils.displayError(passwordOk, passwordError, "");
} else {
LinphoneUtils.displayError(passwordOk
, passwordError, LinphoneUtils.errorForPasswordStatus(status));
}
}
TextWatcher passwordListener =
new TextWatcher() {
public void afterTextChanged(Editable s) {
passwordOk = false;
AccountCreator.PasswordStatus status =
accountCreator.setPassword(field1.getText().toString());
if (isPasswordCorrect(field1.getText().toString())) {
passwordOk = true;
LinphoneUtils.displayError(passwordOk, passwordError, "");
} else {
LinphoneUtils.displayError(
passwordOk,
passwordError,
LinphoneUtils.errorForPasswordStatus(status));
}
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void beforeTextChanged(
CharSequence s, int start, int count, int after) {}
public void onTextChanged(CharSequence s, int start, int count, int after) {
}
};
public void onTextChanged(CharSequence s, int start, int count, int after) {}
};
field1.addTextChangedListener(passwordListener);
}
private void addConfirmPasswordHandler(final EditText field1, final EditText field2, final ImageView icon) {
TextWatcher passwordListener = new TextWatcher() {
public void afterTextChanged(Editable s) {
confirmPasswordOk = false;
if (field1.getText().toString().equals(field2.getText().toString())) {
confirmPasswordOk = true;
if (!isPasswordCorrect(field1.getText().toString())) {
LinphoneUtils.displayError(passwordOk
, passwordError, getString(R.string.wizard_password_incorrect));
} else {
LinphoneUtils.displayError(confirmPasswordOk, passwordConfirmError, "");
private void addConfirmPasswordHandler(
final EditText field1, final EditText field2, final ImageView icon) {
TextWatcher passwordListener =
new TextWatcher() {
public void afterTextChanged(Editable s) {
confirmPasswordOk = false;
if (field1.getText().toString().equals(field2.getText().toString())) {
confirmPasswordOk = true;
if (!isPasswordCorrect(field1.getText().toString())) {
LinphoneUtils.displayError(
passwordOk,
passwordError,
getString(R.string.wizard_password_incorrect));
} else {
LinphoneUtils.displayError(
confirmPasswordOk, passwordConfirmError, "");
}
} else {
LinphoneUtils.displayError(
confirmPasswordOk,
passwordConfirmError,
getString(R.string.wizard_passwords_unmatched));
}
}
} else {
LinphoneUtils.displayError(confirmPasswordOk
, passwordConfirmError, getString(R.string.wizard_passwords_unmatched));
}
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void beforeTextChanged(
CharSequence s, int start, int count, int after) {}
public void onTextChanged(CharSequence s, int start, int count, int after) {
}
};
public void onTextChanged(CharSequence s, int start, int count, int after) {}
};
field1.addTextChangedListener(passwordListener);
field2.addTextChangedListener(passwordListener);
}
@ -577,10 +670,12 @@ public class CreateAccountFragment extends Fragment implements CompoundButton.On
if (status.equals(Status.AccountExist) || status.equals(Status.AccountExistWithAlias)) {
if (useEmail.isChecked()) {
createAccount.setEnabled(true);
LinphoneUtils.displayErrorAlert(LinphoneUtils.errorForStatus(status)
, AssistantActivity.instance());
LinphoneUtils.displayErrorAlert(
LinphoneUtils.errorForStatus(status), AssistantActivity.instance());
} else {
LinphoneManager.getLc().getConfig().loadFromXmlFile(LinphoneManager.getInstance().getmDynamicConfigFile());
LinphoneManager.getLc()
.getConfig()
.loadFromXmlFile(LinphoneManager.getInstance().getmDynamicConfigFile());
accountCreator.isAliasUsed();
}
} else {
@ -591,24 +686,30 @@ public class CreateAccountFragment extends Fragment implements CompoundButton.On
@Override
public void onCreateAccount(AccountCreator accountCreator, Status status, String resp) {
if (status.equals(Status.AccountCreated)) {
if (useEmail.isChecked() || !getResources().getBoolean(R.bool.use_phone_number_validation)) {
AssistantActivity.instance().displayAssistantConfirm(getUsername()
, passwordEdit.getText().toString(), emailEdit.getText().toString());
if (useEmail.isChecked()
|| !getResources().getBoolean(R.bool.use_phone_number_validation)) {
AssistantActivity.instance()
.displayAssistantConfirm(
getUsername(),
passwordEdit.getText().toString(),
emailEdit.getText().toString());
} else {
AssistantActivity.instance().displayAssistantCodeConfirm(getUsername()
, phoneNumberEdit.getText().toString()
, LinphoneUtils.getCountryCode(dialCode), false);
AssistantActivity.instance()
.displayAssistantCodeConfirm(
getUsername(),
phoneNumberEdit.getText().toString(),
LinphoneUtils.getCountryCode(dialCode),
false);
}
} else {
createAccount.setEnabled(true);
LinphoneUtils.displayErrorAlert(LinphoneUtils.errorForStatus(status)
, AssistantActivity.instance());
LinphoneUtils.displayErrorAlert(
LinphoneUtils.errorForStatus(status), AssistantActivity.instance());
}
}
@Override
public void onActivateAccount(AccountCreator accountCreator, Status status, String resp) {
}
public void onActivateAccount(AccountCreator accountCreator, Status status, String resp) {}
@Override
public void onLinkAccount(AccountCreator accountCreator, Status status, String resp) {
@ -616,9 +717,12 @@ public class CreateAccountFragment extends Fragment implements CompoundButton.On
return;
}
if (status.equals(Status.RequestOk)) {
AssistantActivity.instance().displayAssistantCodeConfirm(getUsername()
, phoneNumberEdit.getText().toString()
, LinphoneUtils.getCountryCode(dialCode), false);
AssistantActivity.instance()
.displayAssistantCodeConfirm(
getUsername(),
phoneNumberEdit.getText().toString(),
LinphoneUtils.getCountryCode(dialCode),
false);
}
}
@ -628,9 +732,12 @@ public class CreateAccountFragment extends Fragment implements CompoundButton.On
return;
}
if (status.equals(Status.RequestOk)) {
AssistantActivity.instance().displayAssistantCodeConfirm(getUsername()
, phoneNumberEdit.getText().toString()
, LinphoneUtils.getCountryCode(dialCode), false);
AssistantActivity.instance()
.displayAssistantCodeConfirm(
getUsername(),
phoneNumberEdit.getText().toString(),
LinphoneUtils.getCountryCode(dialCode),
false);
}
}
@ -642,14 +749,14 @@ public class CreateAccountFragment extends Fragment implements CompoundButton.On
if (status.equals(Status.AccountNotActivated)) {
if (getResources().getBoolean(R.bool.isTablet)
|| !getResources().getBoolean(R.bool.use_phone_number_validation)) {
//accountCreator.activateAccount(); // Resend email TODO
// accountCreator.activateAccount(); // Resend email TODO
} else {
accountCreator.recoverAccount(); // Resend SMS
}
} else {
createAccount.setEnabled(true);
LinphoneUtils.displayErrorAlert(LinphoneUtils.errorForStatus(status)
, AssistantActivity.instance());
LinphoneUtils.displayErrorAlert(
LinphoneUtils.errorForStatus(status), AssistantActivity.instance());
}
}
@ -659,19 +766,22 @@ public class CreateAccountFragment extends Fragment implements CompoundButton.On
return;
}
if (status.equals(Status.RequestOk)) {
AssistantActivity.instance().displayAssistantCodeConfirm(getUsername()
, phoneNumberEdit.getText().toString(), dialCode.getText().toString(), false);
AssistantActivity.instance()
.displayAssistantCodeConfirm(
getUsername(),
phoneNumberEdit.getText().toString(),
dialCode.getText().toString(),
false);
} else {
createAccount.setEnabled(true);
//SMS error
LinphoneUtils.displayErrorAlert(getString(R.string.request_failed)
, AssistantActivity.instance());
// SMS error
LinphoneUtils.displayErrorAlert(
getString(R.string.request_failed), AssistantActivity.instance());
}
}
@Override
public void onIsAccountLinked(AccountCreator accountCreator, Status status, String resp) {
}
public void onIsAccountLinked(AccountCreator accountCreator, Status status, String resp) {}
@Override
public void onIsAliasUsed(AccountCreator ac, Status status, String resp) {
@ -679,13 +789,15 @@ public class CreateAccountFragment extends Fragment implements CompoundButton.On
return;
}
if (status.equals(Status.AliasIsAccount) || status.equals(Status.AliasExist)) {
if (accountCreator.getPhoneNumber() != null && accountCreator.getUsername() != null
&& accountCreator.getPhoneNumber().compareTo(accountCreator.getUsername()) == 0) {
if (accountCreator.getPhoneNumber() != null
&& accountCreator.getUsername() != null
&& accountCreator.getPhoneNumber().compareTo(accountCreator.getUsername())
== 0) {
accountCreator.isAccountActivated();
} else {
createAccount.setEnabled(true);
LinphoneUtils.displayErrorAlert(LinphoneUtils.errorForStatus(status)
, AssistantActivity.instance());
LinphoneUtils.displayErrorAlert(
LinphoneUtils.errorForStatus(status), AssistantActivity.instance());
}
} else {
accountCreator.isAccountActivated();
@ -693,7 +805,5 @@ public class CreateAccountFragment extends Fragment implements CompoundButton.On
}
@Override
public void onUpdateAccount(AccountCreator accountCreator, Status status, String resp) {
}
public void onUpdateAccount(AccountCreator accountCreator, Status status, String resp) {}
}

View file

@ -26,9 +26,7 @@ import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import org.linphone.LinphoneManager;
import org.linphone.settings.LinphonePreferences;
import org.linphone.R;
import org.linphone.core.Core;
import org.linphone.core.CoreException;
@ -39,6 +37,7 @@ import org.linphone.core.XmlRpcRequest;
import org.linphone.core.XmlRpcRequestListener;
import org.linphone.core.XmlRpcSession;
import org.linphone.mediastream.Log;
import org.linphone.settings.LinphonePreferences;
public class EchoCancellerCalibrationFragment extends Fragment implements XmlRpcRequestListener {
private Handler mHandler = new Handler();
@ -49,30 +48,36 @@ public class EchoCancellerCalibrationFragment extends Fragment implements XmlRpc
private Runnable runFinished;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.assistant_ec_calibration, container, false);
mListener = new CoreListenerStub() {
@Override
public void onEcCalibrationResult(Core lc, EcCalibratorStatus status, int delay_ms) {
lc.removeListener(mListener);
LinphoneManager.getInstance().routeAudioToReceiver();
if (mSendEcCalibrationResult) {
sendEcCalibrationResult(status, delay_ms);
} else {
AssistantActivity.instance().isEchoCalibrationFinished();
}
}
};
runFinished = new Runnable() {
public void run() {
AssistantActivity.instance().isEchoCalibrationFinished();
}
};
mListener =
new CoreListenerStub() {
@Override
public void onEcCalibrationResult(
Core lc, EcCalibratorStatus status, int delay_ms) {
lc.removeListener(mListener);
LinphoneManager.getInstance().routeAudioToReceiver();
if (mSendEcCalibrationResult) {
sendEcCalibrationResult(status, delay_ms);
} else {
AssistantActivity.instance().isEchoCalibrationFinished();
}
}
};
runFinished =
new Runnable() {
public void run() {
AssistantActivity.instance().isEchoCalibrationFinished();
}
};
xmlRpcSession = LinphoneManager.getLcIfManagerNotDestroyedOrNull().createXmlRpcSession(LinphonePreferences.instance().getXmlrpcUrl());
xmlRpcRequest = xmlRpcSession.createRequest(XmlRpcArgType.None, "add_ec_calibration_result");
xmlRpcSession =
LinphoneManager.getLcIfManagerNotDestroyedOrNull()
.createXmlRpcSession(LinphonePreferences.instance().getXmlrpcUrl());
xmlRpcRequest =
xmlRpcSession.createRequest(XmlRpcArgType.None, "add_ec_calibration_result");
xmlRpcRequest.setListener(this);
try {
@ -96,7 +101,18 @@ public class EchoCancellerCalibrationFragment extends Fragment implements XmlRpc
private void sendEcCalibrationResult(EcCalibratorStatus status, int delayMs) {
Boolean hasBuiltInEchoCanceler = LinphoneManager.getLc().hasBuiltinEchoCanceller();
Log.i("Add echo canceller calibration result: manufacturer=" + Build.MANUFACTURER + " model=" + Build.MODEL + " status=" + status + " delay=" + delayMs + "ms" + " hasBuiltInEchoCanceler " + hasBuiltInEchoCanceler);
Log.i(
"Add echo canceller calibration result: manufacturer="
+ Build.MANUFACTURER
+ " model="
+ Build.MODEL
+ " status="
+ status
+ " delay="
+ delayMs
+ "ms"
+ " hasBuiltInEchoCanceler "
+ hasBuiltInEchoCanceler);
xmlRpcRequest.addStringArg(Build.MANUFACTURER);
xmlRpcRequest.addStringArg(Build.MODEL);
xmlRpcRequest.addStringArg(status.toString());

View file

@ -39,18 +39,20 @@ import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.Locale;
import org.linphone.LinphoneManager;
import org.linphone.settings.LinphonePreferences;
import org.linphone.utils.LinphoneUtils;
import org.linphone.R;
import org.linphone.core.AccountCreator;
import org.linphone.core.AccountCreatorListener;
import org.linphone.core.DialPlan;
import org.linphone.settings.LinphonePreferences;
import org.linphone.utils.LinphoneUtils;
import java.util.Locale;
public class LinphoneLoginFragment extends Fragment implements CompoundButton.OnCheckedChangeListener, OnClickListener, TextWatcher, AccountCreatorListener {
public class LinphoneLoginFragment extends Fragment
implements CompoundButton.OnCheckedChangeListener,
OnClickListener,
TextWatcher,
AccountCreatorListener {
private EditText login, password, phoneNumberEdit, dialCode;
private Button apply, selectCountry;
private CheckBox useUsername;
@ -63,11 +65,13 @@ public class LinphoneLoginFragment extends Fragment implements CompoundButton.On
private ImageView phoneNumberInfo;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.assistant_linphone_login, container, false);
accountCreator = LinphoneManager.getLc().createAccountCreator(LinphonePreferences.instance().getXmlrpcUrl());
accountCreator =
LinphoneManager.getLc()
.createAccountCreator(LinphonePreferences.instance().getXmlrpcUrl());
accountCreator.setListener(this);
String url = "http://linphone.org/free-sip-service.html&action=recover";
@ -98,33 +102,40 @@ public class LinphoneLoginFragment extends Fragment implements CompoundButton.On
apply.setEnabled(true);
apply.setOnClickListener(this);
//Phone number
// Phone number
if (getResources().getBoolean(R.bool.use_phone_number_validation)) {
messagePhoneNumber.setText(getString(R.string.assistant_create_account_part_1));
phone = getArguments().getString("Phone");
dialcode = getArguments().getString("Dialcode");
getActivity().getApplicationContext();
//Automatically get the country code from the phone
// Automatically get the country code from the phone
TelephonyManager tm =
(TelephonyManager) getActivity().getApplicationContext().getSystemService(
Context.TELEPHONY_SERVICE);
(TelephonyManager)
getActivity()
.getApplicationContext()
.getSystemService(Context.TELEPHONY_SERVICE);
String countryIso = tm.getNetworkCountryIso();
countryCode = org.linphone.core.Utils.getCccFromIso(countryIso.toUpperCase());
DialPlan c = AssistantActivity.instance().country;
if (c != null) {
selectCountry.setText(c.getCountry());
dialCode.setText(c.getCountryCallingCode().contains("+") ?
c.getCountryCallingCode() : "+" + c.getCountryCallingCode());
dialCode.setText(
c.getCountryCallingCode().contains("+")
? c.getCountryCallingCode()
: "+" + c.getCountryCallingCode());
} else {
c = AssistantActivity.instance().getCountryListAdapter()
.getCountryFromCountryCode(String.valueOf(countryCode));
c =
AssistantActivity.instance()
.getCountryListAdapter()
.getCountryFromCountryCode(String.valueOf(countryCode));
if (c != null) {
selectCountry.setText(c.getCountry());
dialCode.setText(c.getCountryCallingCode().contains("+") ?
c.getCountryCallingCode() : "+" + c.getCountryCallingCode());
dialCode.setText(
c.getCountryCallingCode().contains("+")
? c.getCountryCallingCode()
: "+" + c.getCountryCallingCode());
}
}
@ -137,27 +148,31 @@ public class LinphoneLoginFragment extends Fragment implements CompoundButton.On
phoneNumberEdit.setText(previousPhone);
}
//Allow user to enter a username instead use the phone number as username
// Allow user to enter a username instead use the phone number as username
if (getResources().getBoolean(R.bool.assistant_allow_username)) {
useUsername.setVisibility(View.VISIBLE);
useUsername.setOnCheckedChangeListener(this);
}
if (phone != null)
phoneNumberEdit.setText(phone);
if (dialcode != null)
dialCode.setText("+" + dialcode);
if (phone != null) phoneNumberEdit.setText(phone);
if (dialcode != null) dialCode.setText("+" + dialcode);
}
if (getResources().getBoolean(R.bool.assistant_allow_username)) {
useUsername.setVisibility(View.VISIBLE);
useUsername.setOnCheckedChangeListener(this);
password.addTextChangedListener(this);
forgotPassword.setText(Html.fromHtml("<a href=\"" + url + "\"'>" + getString(R.string.forgot_password) + "</a>"));
forgotPassword.setText(
Html.fromHtml(
"<a href=\""
+ url
+ "\"'>"
+ getString(R.string.forgot_password)
+ "</a>"));
forgotPassword.setMovementMethod(LinkMovementMethod.getInstance());
}
//Hide phone number and display username/email/password
// Hide phone number and display username/email/password
if (!getResources().getBoolean(R.bool.use_phone_number_validation)) {
phoneNumberLayout.setVisibility(View.GONE);
useUsername.setVisibility(View.GONE);
@ -187,8 +202,13 @@ public class LinphoneLoginFragment extends Fragment implements CompoundButton.On
}
public void linphoneLogIn() {
if (login.getText() == null || login.length() == 0 || password.getText() == null || password.length() == 0) {
LinphoneUtils.displayErrorAlert(getString(R.string.first_launch_no_login_password), AssistantActivity.instance());
if (login.getText() == null
|| login.length() == 0
|| password.getText() == null
|| password.length() == 0) {
LinphoneUtils.displayErrorAlert(
getString(R.string.first_launch_no_login_password),
AssistantActivity.instance());
apply.setEnabled(true);
return;
}
@ -198,39 +218,43 @@ public class LinphoneLoginFragment extends Fragment implements CompoundButton.On
}
private int getPhoneNumberStatus() {
return accountCreator.setPhoneNumber(phoneNumberEdit.getText().toString(), LinphoneUtils.getCountryCode(dialCode));
return accountCreator.setPhoneNumber(
phoneNumberEdit.getText().toString(), LinphoneUtils.getCountryCode(dialCode));
}
private void addPhoneNumberHandler(final EditText field, final ImageView icon) {
field.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
if (field.equals(dialCode)) {
DialPlan c = AssistantActivity.instance().getCountryListAdapter().getCountryFromCountryCode(dialCode.getText().toString());
if (c != null) {
AssistantActivity.instance().country = c;
selectCountry.setText(c.getCountry());
} else {
selectCountry.setText(R.string.select_your_country);
field.addTextChangedListener(
new TextWatcher() {
public void afterTextChanged(Editable s) {
if (field.equals(dialCode)) {
DialPlan c =
AssistantActivity.instance()
.getCountryListAdapter()
.getCountryFromCountryCode(
dialCode.getText().toString());
if (c != null) {
AssistantActivity.instance().country = c;
selectCountry.setText(c.getCountry());
} else {
selectCountry.setText(R.string.select_your_country);
}
}
}
}
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void beforeTextChanged(
CharSequence s, int start, int count, int after) {}
public void onTextChanged(CharSequence s, int start, int count, int after) {
onTextChanged2();
}
});
public void onTextChanged(CharSequence s, int start, int count, int after) {
onTextChanged2();
}
});
}
@Override
public void onResume() {
super.onResume();
if (useUsername != null && useUsername.isChecked())
recoverAccount = false;
else
recoverAccount = true;
if (useUsername != null && useUsername.isChecked()) recoverAccount = false;
else recoverAccount = true;
}
@Override
@ -251,7 +275,6 @@ public class LinphoneLoginFragment extends Fragment implements CompoundButton.On
} else if (id == R.id.select_country) {
AssistantActivity.instance().displayCountryChooser();
}
}
private void recoverAccount() {
@ -259,29 +282,34 @@ public class LinphoneLoginFragment extends Fragment implements CompoundButton.On
int status = getPhoneNumberStatus();
boolean isOk = status == AccountCreator.PhoneNumberStatus.Ok.toInt();
if (isOk) {
LinphoneManager.getLc().getConfig().loadFromXmlFile(LinphoneManager.getInstance().getmDynamicConfigFile());
LinphoneManager.getLc()
.getConfig()
.loadFromXmlFile(LinphoneManager.getInstance().getmDynamicConfigFile());
accountCreator.isAliasUsed();
} else {
apply.setEnabled(true);
LinphoneUtils.displayErrorAlert(LinphoneUtils.errorForPhoneNumberStatus(status),
LinphoneUtils.displayErrorAlert(
LinphoneUtils.errorForPhoneNumberStatus(status),
AssistantActivity.instance());
LinphoneUtils.displayError(isOk, phoneNumberError,
LinphoneUtils.errorForPhoneNumberStatus(status));
LinphoneUtils.displayError(
isOk, phoneNumberError, LinphoneUtils.errorForPhoneNumberStatus(status));
}
} else {
apply.setEnabled(true);
LinphoneUtils.displayErrorAlert(getString(R.string.assistant_create_account_part_1), AssistantActivity.instance());
LinphoneUtils.displayErrorAlert(
getString(R.string.assistant_create_account_part_1),
AssistantActivity.instance());
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void onTextChanged2() {
int status = getPhoneNumberStatus();
boolean isOk = status == AccountCreator.PhoneNumberStatus.Ok.toInt();
LinphoneUtils.displayError(isOk, phoneNumberError, LinphoneUtils.errorForPhoneNumberStatus(status));
LinphoneUtils.displayError(
isOk, phoneNumberError, LinphoneUtils.errorForPhoneNumberStatus(status));
if (!isOk) {
if ((1 == (status & AccountCreator.PhoneNumberStatus.InvalidCountryCode.toInt()))) {
dialCode.setBackgroundResource(R.drawable.resizable_textfield_error);
@ -291,7 +319,8 @@ public class LinphoneLoginFragment extends Fragment implements CompoundButton.On
phoneNumberEdit.setBackgroundResource(R.drawable.resizable_textfield_error);
}
} else {
accountCreator.setPhoneNumber(phoneNumberEdit.getText().toString(), dialCode.getText().toString());
accountCreator.setPhoneNumber(
phoneNumberEdit.getText().toString(), dialCode.getText().toString());
dialCode.setBackgroundResource(R.drawable.resizable_textfield);
phoneNumberEdit.setBackgroundResource(R.drawable.resizable_textfield);
}
@ -303,8 +332,7 @@ public class LinphoneLoginFragment extends Fragment implements CompoundButton.On
}
@Override
public void afterTextChanged(Editable s) {
}
public void afterTextChanged(Editable s) {}
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
@ -328,73 +356,86 @@ public class LinphoneLoginFragment extends Fragment implements CompoundButton.On
}
@Override
public void onIsAccountExist(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
public void onIsAccountExist(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {
if (AssistantActivity.instance() == null) {
apply.setEnabled(true);
return;
}
if (status.equals(AccountCreator.Status.AccountExist) || status.equals(AccountCreator.Status.AccountExistWithAlias)) {
if (status.equals(AccountCreator.Status.AccountExist)
|| status.equals(AccountCreator.Status.AccountExistWithAlias)) {
AssistantActivity.instance().linphoneLogIn(accountCreator);
} else {
LinphoneUtils.displayErrorAlert(LinphoneUtils.errorForStatus(status), AssistantActivity.instance());
LinphoneUtils.displayErrorAlert(
LinphoneUtils.errorForStatus(status), AssistantActivity.instance());
}
apply.setEnabled(true);
}
@Override
public void onCreateAccount(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onCreateAccount(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onActivateAccount(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onActivateAccount(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onLinkAccount(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onLinkAccount(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onActivateAlias(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onActivateAlias(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onIsAccountActivated(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onIsAccountActivated(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onRecoverAccount(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
public void onRecoverAccount(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {
if (AssistantActivity.instance() == null) {
apply.setEnabled(true);
return;
}
if (status.equals(AccountCreator.Status.ServerError)) {
LinphoneUtils.displayErrorAlert(LinphoneUtils.errorForStatus(AccountCreator.Status.RequestFailed), AssistantActivity.instance());
LinphoneUtils.displayErrorAlert(
LinphoneUtils.errorForStatus(AccountCreator.Status.RequestFailed),
AssistantActivity.instance());
apply.setEnabled(true);
} else {
AssistantActivity.instance().displayAssistantCodeConfirm(accountCreator.getUsername(), phoneNumberEdit.getText().toString(), LinphoneUtils.getCountryCode(dialCode), true);
AssistantActivity.instance()
.displayAssistantCodeConfirm(
accountCreator.getUsername(),
phoneNumberEdit.getText().toString(),
LinphoneUtils.getCountryCode(dialCode),
true);
}
}
@Override
public void onIsAccountLinked(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onIsAccountLinked(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onIsAliasUsed(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
public void onIsAliasUsed(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {
if (AssistantActivity.instance() == null) {
apply.setEnabled(true);
return;
}
if (status.equals(AccountCreator.Status.AliasIsAccount) || status.equals(AccountCreator.Status.AliasExist)) {
if (status.equals(AccountCreator.Status.AliasIsAccount)
|| status.equals(AccountCreator.Status.AliasExist)) {
accountCreator.recoverAccount();
} else {
apply.setEnabled(true);
LinphoneUtils.displayErrorAlert(LinphoneUtils.errorForStatus(status), AssistantActivity.instance());
LinphoneUtils.displayErrorAlert(
LinphoneUtils.errorForStatus(status), AssistantActivity.instance());
}
}
@Override
public void onUpdateAccount(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onUpdateAccount(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
}

View file

@ -30,7 +30,6 @@ import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioGroup;
import android.widget.Toast;
import org.linphone.R;
import org.linphone.core.TransportType;
@ -40,8 +39,8 @@ public class LoginFragment extends Fragment implements OnClickListener, TextWatc
private Button apply;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.assistant_login, container, false);
login = view.findViewById(R.id.assistant_username);
@ -67,8 +66,17 @@ public class LoginFragment extends Fragment implements OnClickListener, TextWatc
int id = v.getId();
if (id == R.id.assistant_apply) {
if (login.getText() == null || login.length() == 0 || password.getText() == null || password.length() == 0 || domain.getText() == null || domain.length() == 0) {
Toast.makeText(getActivity(), getString(R.string.first_launch_no_login_password), Toast.LENGTH_LONG).show();
if (login.getText() == null
|| login.length() == 0
|| password.getText() == null
|| password.length() == 0
|| domain.getText() == null
|| domain.length() == 0) {
Toast.makeText(
getActivity(),
getString(R.string.first_launch_no_login_password),
Toast.LENGTH_LONG)
.show();
return;
}
@ -84,24 +92,34 @@ public class LoginFragment extends Fragment implements OnClickListener, TextWatc
}
if (domain.getText().toString().compareTo(getString(R.string.default_domain)) == 0) {
AssistantActivity.instance().displayLoginLinphone(login.getText().toString(), password.getText().toString());
AssistantActivity.instance()
.displayLoginLinphone(
login.getText().toString(), password.getText().toString());
} else {
AssistantActivity.instance().genericLogIn(login.getText().toString(), userid.getText().toString(), password.getText().toString(), displayName.getText().toString(), null, domain.getText().toString(), transport);
AssistantActivity.instance()
.genericLogIn(
login.getText().toString(),
userid.getText().toString(),
password.getText().toString(),
displayName.getText().toString(),
null,
domain.getText().toString(),
transport);
}
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
apply.setEnabled(!login.getText().toString().isEmpty() && !password.getText().toString().isEmpty() && !domain.getText().toString().isEmpty());
apply.setEnabled(
!login.getText().toString().isEmpty()
&& !password.getText().toString().isEmpty()
&& !domain.getText().toString().isEmpty());
}
@Override
public void afterTextChanged(Editable s) {
}
public void afterTextChanged(Editable s) {}
}

View file

@ -28,19 +28,17 @@ import android.os.Handler;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.Toast;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import org.linphone.LinphoneLauncherActivity;
import org.linphone.LinphoneManager;
import org.linphone.settings.LinphonePreferences;
import org.linphone.LinphoneService;
import org.linphone.R;
import org.linphone.LinphoneLauncherActivity;
import org.linphone.core.ConfiguringState;
import org.linphone.core.Core;
import org.linphone.core.CoreListenerStub;
import org.linphone.mediastream.Log;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import org.linphone.settings.LinphonePreferences;
public class RemoteProvisioningActivity extends Activity {
private Handler mHandler = new Handler();
@ -54,17 +52,23 @@ public class RemoteProvisioningActivity extends Activity {
setContentView(R.layout.remote_provisioning);
spinner = findViewById(R.id.spinner);
mListener = new CoreListenerStub() {
@Override
public void onConfiguringStatus(Core lc, final ConfiguringState state, String message) {
if (spinner != null) spinner.setVisibility(View.GONE);
if (state == ConfiguringState.Successful) {
goToLinphoneActivity();
} else if (state == ConfiguringState.Failed) {
Toast.makeText(RemoteProvisioningActivity.this, R.string.remote_provisioning_failure, Toast.LENGTH_LONG).show();
}
}
};
mListener =
new CoreListenerStub() {
@Override
public void onConfiguringStatus(
Core lc, final ConfiguringState state, String message) {
if (spinner != null) spinner.setVisibility(View.GONE);
if (state == ConfiguringState.Successful) {
goToLinphoneActivity();
} else if (state == ConfiguringState.Failed) {
Toast.makeText(
RemoteProvisioningActivity.this,
R.string.remote_provisioning_failure,
Toast.LENGTH_LONG)
.show();
}
}
};
}
@Override
@ -100,75 +104,97 @@ public class RemoteProvisioningActivity extends Activity {
}
private void checkIntentForConfigUri(final Intent intent) {
new Thread(new Runnable() {
new Thread(
new Runnable() {
@Override
public void run() {
Uri openUri = intent.getData();
if (openUri != null) {
// We expect something like linphone-config://http://linphone.org/config.xml
configUriParam = openUri.getEncodedSchemeSpecificPart().substring(2); // Removes the linphone-config://
try {
configUriParam = URLDecoder.decode(configUriParam, "UTF-8");
} catch (UnsupportedEncodingException e) {
Log.e(e);
}
Log.d("Using config uri: " + configUriParam);
}
@Override
public void run() {
Uri openUri = intent.getData();
if (openUri != null) {
// We expect something like
// linphone-config://http://linphone.org/config.xml
configUriParam =
openUri.getEncodedSchemeSpecificPart()
.substring(2); // Removes the linphone-config://
try {
configUriParam = URLDecoder.decode(configUriParam, "UTF-8");
} catch (UnsupportedEncodingException e) {
Log.e(e);
}
Log.d("Using config uri: " + configUriParam);
}
if (configUriParam == null) {
if (!LinphonePreferences.instance().isFirstRemoteProvisioning()) {
mHandler.post(new Runnable() {
@Override
public void run() {
goToLinphoneActivity();
if (configUriParam == null) {
if (!LinphonePreferences.instance()
.isFirstRemoteProvisioning()) {
mHandler.post(
new Runnable() {
@Override
public void run() {
goToLinphoneActivity();
}
});
} else if (!getResources()
.getBoolean(
R.bool.forbid_app_usage_until_remote_provisioning_completed)) {
// Show this view for a few seconds then go to the dialer
mHandler.postDelayed(
new Runnable() {
@Override
public void run() {
goToLinphoneActivity();
}
},
1500);
} // else we do nothing if there is no config uri parameter and
// if user not allowed to leave this screen
} else {
if (getResources()
.getBoolean(
R.bool.display_confirmation_popup_after_first_configuration)
&& !LinphonePreferences.instance()
.isFirstRemoteProvisioning()) {
mHandler.post(
new Runnable() {
@Override
public void run() {
displayDialogConfirmation();
}
});
} else {
mHandler.post(
new Runnable() {
@Override
public void run() {
setRemoteProvisioningAddressAndRestart(
configUriParam);
}
});
}
}
}
});
} else if (!getResources().getBoolean(R.bool.forbid_app_usage_until_remote_provisioning_completed)) {
// Show this view for a few seconds then go to the dialer
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
goToLinphoneActivity();
}
}, 1500);
} // else we do nothing if there is no config uri parameter and if user not allowed to leave this screen
} else {
if (getResources().getBoolean(R.bool.display_confirmation_popup_after_first_configuration)
&& !LinphonePreferences.instance().isFirstRemoteProvisioning()) {
mHandler.post(new Runnable() {
@Override
public void run() {
displayDialogConfirmation();
}
});
} else {
mHandler.post(new Runnable() {
@Override
public void run() {
setRemoteProvisioningAddressAndRestart(configUriParam);
}
});
}
}
}
}).start();
})
.start();
}
private void displayDialogConfirmation() {
new AlertDialog.Builder(RemoteProvisioningActivity.this)
.setTitle(getString(R.string.remote_provisioning_again_title))
.setMessage(getString(R.string.remote_provisioning_again_message))
.setPositiveButton(R.string.accept, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
setRemoteProvisioningAddressAndRestart(configUriParam);
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
goToLinphoneActivity();
}
})
.setPositiveButton(
R.string.accept,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
setRemoteProvisioningAddressAndRestart(configUriParam);
}
})
.setNegativeButton(
R.string.cancel,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
goToLinphoneActivity();
}
})
.show();
}
@ -178,22 +204,24 @@ public class RemoteProvisioningActivity extends Activity {
LinphonePreferences.instance().setContext(this); // Needed, else the next call will crash
LinphonePreferences.instance().setRemoteProvisioningUrl(configUri);
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
LinphoneManager.getInstance().restartCore();
}
}, 1000);
mHandler.postDelayed(
new Runnable() {
@Override
public void run() {
LinphoneManager.getInstance().restartCore();
}
},
1000);
}
private void goToLinphoneActivity() {
if (LinphoneService.isReady()) {
LinphoneService.instance().setActivityToLaunchOnIncomingReceived("org.linphone.LinphoneLauncherActivity");
//finish(); // To prevent the user to come back to this page using back button
LinphoneService.instance()
.setActivityToLaunchOnIncomingReceived("org.linphone.LinphoneLauncherActivity");
// finish(); // To prevent the user to come back to this page using back button
startActivity(new Intent().setClass(this, LinphoneLauncherActivity.class));
} else {
finish();
}
}
}

View file

@ -28,18 +28,17 @@ import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import org.linphone.LinphoneManager;
import org.linphone.settings.LinphonePreferences;
import org.linphone.R;
import org.linphone.settings.LinphonePreferences;
public class RemoteProvisioningFragment extends Fragment implements OnClickListener, TextWatcher {
private EditText remoteProvisioningUrl;
private Button apply;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.assistant_remote_provisioning, container, false);
remoteProvisioningUrl = view.findViewById(R.id.assistant_remote_provisioning_url);
@ -66,9 +65,7 @@ public class RemoteProvisioningFragment extends Fragment implements OnClickListe
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
@ -76,7 +73,5 @@ public class RemoteProvisioningFragment extends Fragment implements OnClickListe
}
@Override
public void afterTextChanged(Editable s) {
}
public void afterTextChanged(Editable s) {}
}

View file

@ -25,13 +25,12 @@ import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import org.linphone.LinphoneManager;
import org.linphone.settings.LinphonePreferences;
import org.linphone.R;
import org.linphone.core.ConfiguringState;
import org.linphone.core.Core;
import org.linphone.core.CoreListenerStub;
import org.linphone.settings.LinphonePreferences;
import org.linphone.xmlrpc.XmlRpcHelper;
import org.linphone.xmlrpc.XmlRpcListenerBase;
@ -58,20 +57,28 @@ public class RemoteProvisioningLoginActivity extends Activity implements OnClick
domain.setEnabled(false);
}
mListener = new CoreListenerStub() {
@Override
public void onConfiguringStatus(Core lc, final ConfiguringState state, String message) {
if (state == ConfiguringState.Successful) {
//TODO
} else if (state == ConfiguringState.Failed) {
Toast.makeText(RemoteProvisioningLoginActivity.this, R.string.remote_provisioning_failure, Toast.LENGTH_LONG).show();
}
}
};
mListener =
new CoreListenerStub() {
@Override
public void onConfiguringStatus(
Core lc, final ConfiguringState state, String message) {
if (state == ConfiguringState.Successful) {
// TODO
} else if (state == ConfiguringState.Failed) {
Toast.makeText(
RemoteProvisioningLoginActivity.this,
R.string.remote_provisioning_failure,
Toast.LENGTH_LONG)
.show();
}
}
};
}
private void cancelWizard(boolean bypassCheck) {
if (bypassCheck || getResources().getBoolean(R.bool.allow_cancel_remote_provisioning_login_activity)) {
if (bypassCheck
|| getResources()
.getBoolean(R.bool.allow_cancel_remote_provisioning_login_activity)) {
LinphonePreferences.instance().disableProvisioningLoginView();
setResult(bypassCheck ? Activity.RESULT_OK : Activity.RESULT_CANCELED);
finish();
@ -80,13 +87,17 @@ public class RemoteProvisioningLoginActivity extends Activity implements OnClick
private boolean storeAccount(String username, String password, String domain) {
XmlRpcHelper xmlRpcHelper = new XmlRpcHelper();
xmlRpcHelper.getRemoteProvisioningFilenameAsync(new XmlRpcListenerBase() {
@Override
public void onRemoteProvisioningFilenameSent(String result) {
LinphonePreferences.instance().setRemoteProvisioningUrl(result);
LinphoneManager.getInstance().restartCore();
}
}, username.toString(), password.toString(), domain.toString());
xmlRpcHelper.getRemoteProvisioningFilenameAsync(
new XmlRpcListenerBase() {
@Override
public void onRemoteProvisioningFilenameSent(String result) {
LinphonePreferences.instance().setRemoteProvisioningUrl(result);
LinphoneManager.getInstance().restartCore();
}
},
username.toString(),
password.toString(),
domain.toString());
LinphonePreferences.instance().firstLaunchSuccessful();
setResult(Activity.RESULT_OK);
@ -120,7 +131,10 @@ public class RemoteProvisioningLoginActivity extends Activity implements OnClick
cancelWizard(false);
}
if (id == R.id.assistant_connect) {
storeAccount(login.getText().toString(), password.getText().toString(), domain.getText().toString());
storeAccount(
login.getText().toString(),
password.getText().toString(),
domain.getText().toString());
}
}

View file

@ -25,15 +25,14 @@ import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import org.linphone.R;
public class WelcomeFragment extends Fragment implements OnClickListener {
private Button createAccount, logLinphoneAccount, logGenericAccount, remoteProvisioning;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.assistant_welcome, container, false);
createAccount = view.findViewById(R.id.create_account);

View file

@ -32,12 +32,6 @@ public class BandwidthManager {
private int currentProfile = HIGH_RESOLUTION;
public static final synchronized BandwidthManager getInstance() {
if (instance == null) instance = new BandwidthManager();
return instance;
}
private BandwidthManager() {
// FIXME register a listener on NetworkManager to get notified of network state
// FIXME register a listener on Preference to get notified of change in video enable value
@ -45,6 +39,10 @@ public class BandwidthManager {
// FIXME initially get those values
}
public static final synchronized BandwidthManager getInstance() {
if (instance == null) instance = new BandwidthManager();
return instance;
}
public void updateWithProfileSettings(Core lc, CallParams callParams) {
if (callParams != null) { // in call

File diff suppressed because it is too large Load diff

View file

@ -24,15 +24,14 @@ import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import org.linphone.R;
public class CallAudioFragment extends Fragment {
private CallActivity incallActvityInstance;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.audio, container, false);
return view;
}

View file

@ -26,37 +26,33 @@ import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import androidx.core.app.ActivityCompat;
import android.view.KeyEvent;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import org.linphone.LinphoneManager;
import org.linphone.settings.LinphonePreferences;
import org.linphone.LinphoneService;
import org.linphone.utils.ImageUtils;
import org.linphone.utils.LinphoneUtils;
import org.linphone.R;
import androidx.core.app.ActivityCompat;
import java.util.ArrayList;
import org.linphone.LinphoneActivity;
import org.linphone.utils.LinphoneGenericActivity;
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.Call;
import org.linphone.core.Call.State;
import org.linphone.core.CallParams;
import org.linphone.core.Core;
import org.linphone.core.CoreListenerStub;
import org.linphone.mediastream.Log;
import org.linphone.settings.LinphonePreferences;
import org.linphone.utils.ImageUtils;
import org.linphone.utils.LinphoneGenericActivity;
import org.linphone.utils.LinphoneUtils;
import org.linphone.views.CallIncomingAnswerButton;
import org.linphone.views.CallIncomingButtonListener;
import org.linphone.views.CallIncomingDeclineButton;
import java.util.ArrayList;
public class CallIncomingActivity extends LinphoneGenericActivity {
private static CallIncomingActivity instance;
@ -95,7 +91,10 @@ public class CallIncomingActivity extends LinphoneGenericActivity {
contactPicture = findViewById(R.id.contact_picture);
// set this flag so this activity will stay in front of the keyguard
int flags = WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
int flags =
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
getWindow().addFlags(flags);
acceptUnlock = findViewById(R.id.acceptUnlock);
@ -106,14 +105,19 @@ public class CallIncomingActivity extends LinphoneGenericActivity {
acceptIcon = findViewById(R.id.acceptIcon);
lookupCurrentCall();
if (LinphonePreferences.instance() != null && mCall != null && mCall.getRemoteParams() != null &&
LinphonePreferences.instance().shouldAutomaticallyAcceptVideoRequests() &&
mCall.getRemoteParams().videoEnabled()) {
if (LinphonePreferences.instance() != null
&& mCall != null
&& mCall.getRemoteParams() != null
&& LinphonePreferences.instance().shouldAutomaticallyAcceptVideoRequests()
&& mCall.getRemoteParams().videoEnabled()) {
acceptIcon.setImageResource(R.drawable.call_video_start);
}
mKeyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
boolean doNotUseSliders = getResources().getBoolean(R.bool.do_not_use_sliders_to_answer_hangup_call_if_phone_unlocked);
boolean doNotUseSliders =
getResources()
.getBoolean(
R.bool.do_not_use_sliders_to_answer_hangup_call_if_phone_unlocked);
if (doNotUseSliders && !mKeyguardManager.inKeyguardRestrictedInputMode()) {
accept.setSliderMode(false);
decline.setSliderMode(false);
@ -123,33 +127,43 @@ public class CallIncomingActivity extends LinphoneGenericActivity {
accept.setDeclineButton(decline);
decline.setAnswerButton(accept);
}
accept.setListener(new CallIncomingButtonListener() {
@Override
public void onAction() {
answer();
}
});
decline.setListener(new CallIncomingButtonListener() {
@Override
public void onAction() {
decline();
}
});
accept.setListener(
new CallIncomingButtonListener() {
@Override
public void onAction() {
answer();
}
});
decline.setListener(
new CallIncomingButtonListener() {
@Override
public void onAction() {
decline();
}
});
mListener = new CoreListenerStub() {
@Override
public void onCallStateChanged(Core lc, Call call, State state, String message) {
if (call == mCall && State.End == state) {
finish();
} else if (state == State.Connected) {
startActivity(new Intent(CallIncomingActivity.this, CallActivity.class));
} else if (state == State.StreamsRunning) {
Log.e("CallIncommingActivity - onCreate - State.StreamsRunning - speaker = " + LinphoneManager.getInstance().isSpeakerEnabled());
// The following should not be needed except some devices need it (e.g. Galaxy S).
LinphoneManager.getInstance().enableSpeaker(LinphoneManager.getInstance().isSpeakerEnabled());
}
}
};
mListener =
new CoreListenerStub() {
@Override
public void onCallStateChanged(
Core lc, Call call, State state, String message) {
if (call == mCall && State.End == state) {
finish();
} else if (state == State.Connected) {
startActivity(
new Intent(CallIncomingActivity.this, CallActivity.class));
} else if (state == State.StreamsRunning) {
Log.e(
"CallIncommingActivity - onCreate - State.StreamsRunning - speaker = "
+ LinphoneManager.getInstance().isSpeakerEnabled());
// The following should not be needed except some devices need it (e.g.
// Galaxy S).
LinphoneManager.getInstance()
.enableSpeaker(
LinphoneManager.getInstance().isSpeakerEnabled());
}
}
};
super.onCreate(savedInstanceState);
instance = this;
@ -170,17 +184,17 @@ public class CallIncomingActivity extends LinphoneGenericActivity {
// Only one call ringing at a time is allowed
lookupCurrentCall();
if (mCall == null) {
//The incoming call no longer exists.
// The incoming call no longer exists.
Log.d("Couldn't find incoming call");
finish();
return;
}
Address address = mCall.getRemoteAddress();
LinphoneContact contact = ContactsManager.getInstance().findContactFromAddress(address);
if (contact != null) {
ImageUtils.setImagePictureFromUri(this, contactPicture, contact.getPhotoUri(), contact.getThumbnailUri());
ImageUtils.setImagePictureFromUri(
this, contactPicture, contact.getPhotoUri(), contact.getThumbnailUri());
name.setText(contact.getFullName());
} else {
name.setText(LinphoneUtils.getAddressDisplayName(address));
@ -211,7 +225,8 @@ public class CallIncomingActivity extends LinphoneGenericActivity {
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (LinphoneManager.isInstanciated() && (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_HOME)) {
if (LinphoneManager.isInstanciated()
&& (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_HOME)) {
LinphoneManager.getLc().terminateCall(mCall);
finish();
}
@ -260,20 +275,36 @@ public class CallIncomingActivity extends LinphoneGenericActivity {
private void checkAndRequestCallPermissions() {
ArrayList<String> permissionsList = new ArrayList<String>();
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 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"));
if (recordAudio != PackageManager.PERMISSION_GRANTED) {
if (LinphonePreferences.instance().firstTimeAskingForPermission(Manifest.permission.RECORD_AUDIO) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.RECORD_AUDIO)) {
if (LinphonePreferences.instance()
.firstTimeAskingForPermission(Manifest.permission.RECORD_AUDIO)
|| ActivityCompat.shouldShowRequestPermissionRationale(
this, Manifest.permission.RECORD_AUDIO)) {
Log.i("[Permission] Asking for record audio");
permissionsList.add(Manifest.permission.RECORD_AUDIO);
}
}
if (LinphonePreferences.instance().shouldInitiateVideoCall() || LinphonePreferences.instance().shouldAutomaticallyAcceptVideoRequests()) {
if (LinphonePreferences.instance().shouldInitiateVideoCall()
|| LinphonePreferences.instance().shouldAutomaticallyAcceptVideoRequests()) {
if (camera != PackageManager.PERMISSION_GRANTED) {
if (LinphonePreferences.instance().firstTimeAskingForPermission(Manifest.permission.CAMERA) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
if (LinphonePreferences.instance()
.firstTimeAskingForPermission(Manifest.permission.CAMERA)
|| ActivityCompat.shouldShowRequestPermissionRationale(
this, Manifest.permission.CAMERA)) {
Log.i("[Permission] Asking for camera");
permissionsList.add(Manifest.permission.CAMERA);
}
@ -288,9 +319,16 @@ public class CallIncomingActivity extends LinphoneGenericActivity {
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
public void onRequestPermissionsResult(
int requestCode, String[] permissions, int[] grantResults) {
for (int i = 0; i < permissions.length; i++) {
Log.i("[Permission] " + permissions[i] + " is " + (grantResults[i] == PackageManager.PERMISSION_GRANTED ? "granted" : "denied"));
Log.i(
"[Permission] "
+ permissions[i]
+ " is "
+ (grantResults[i] == PackageManager.PERMISSION_GRANTED
? "granted"
: "denied"));
}
}
}
}

View file

@ -20,23 +20,20 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import org.linphone.LinphoneManager;
import org.linphone.utils.FileUtils;
import org.linphone.core.Address;
import org.linphone.core.Call;
import org.linphone.core.CallParams;
import org.linphone.core.Core;
import org.linphone.core.CoreException;
import org.linphone.mediastream.Log;
import org.linphone.utils.FileUtils;
/**
* Handle call updating, reinvites.
*/
/** Handle call updating, reinvites. */
public class CallManager {
private static CallManager instance;
private CallManager() {
}
private CallManager() {}
public static final synchronized CallManager getInstance() {
if (instance == null) instance = new CallManager();
@ -47,7 +44,8 @@ public class CallManager {
return BandwidthManager.getInstance();
}
public void inviteAddress(Address lAddress, boolean videoEnabled, boolean lowBandwidth) throws CoreException {
public void inviteAddress(Address lAddress, boolean videoEnabled, boolean lowBandwidth)
throws CoreException {
Core lc = LinphoneManager.getLc();
CallParams params = lc.createCallParams(null);
@ -64,16 +62,17 @@ public class CallManager {
Log.d("Low bandwidth enabled in call params");
}
String recordFile = FileUtils.getCallRecordingFilename(LinphoneManager.getInstance().getContext(), lAddress);
String recordFile =
FileUtils.getCallRecordingFilename(
LinphoneManager.getInstance().getContext(), lAddress);
params.setRecordFile(recordFile);
lc.inviteAddressWithParams(lAddress, params);
}
/**
* Add video to a currently running voice only call.
* No re-invite is sent if the current call is already video
* or if the bandwidth settings are too low.
* Add video to a currently running voice only call. No re-invite is sent if the current call is
* already video or if the bandwidth settings are too low.
*
* @return if updateCall called
*/
@ -88,7 +87,6 @@ public class CallManager {
if (params.videoEnabled()) return false;
// Check if video possible regarding bandwidth limitations
bm().updateWithProfileSettings(lc, params);
@ -104,8 +102,8 @@ public class CallManager {
/**
* Change the preferred video size used by linphone core. (impact landscape/portrait buffer).
* Update current call, without reinvite.
* The camera will be restarted when mediastreamer chain is recreated and setParameters is called.
* Update current call, without reinvite. The camera will be restarted when mediastreamer chain
* is recreated and setParameters is called.
*/
public void updateCall() {
Core lc = LinphoneManager.getLc();
@ -118,5 +116,4 @@ public class CallManager {
bm().updateWithProfileSettings(lc, params);
lc.updateCall(lCall, null);
}
}

View file

@ -23,7 +23,6 @@ import android.Manifest;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import androidx.core.app.ActivityCompat;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@ -34,14 +33,11 @@ import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import org.linphone.LinphoneManager;
import org.linphone.settings.LinphonePreferences;
import org.linphone.utils.ImageUtils;
import org.linphone.utils.LinphoneUtils;
import org.linphone.R;
import androidx.core.app.ActivityCompat;
import java.util.ArrayList;
import org.linphone.LinphoneActivity;
import org.linphone.utils.LinphoneGenericActivity;
import org.linphone.LinphoneManager;
import org.linphone.R;
import org.linphone.contacts.ContactsManager;
import org.linphone.contacts.LinphoneContact;
import org.linphone.core.Address;
@ -51,8 +47,10 @@ import org.linphone.core.Core;
import org.linphone.core.CoreListenerStub;
import org.linphone.core.Reason;
import org.linphone.mediastream.Log;
import java.util.ArrayList;
import org.linphone.settings.LinphonePreferences;
import org.linphone.utils.ImageUtils;
import org.linphone.utils.LinphoneGenericActivity;
import org.linphone.utils.LinphoneUtils;
public class CallOutgoingActivity extends LinphoneGenericActivity implements OnClickListener {
private static CallOutgoingActivity instance;
@ -95,53 +93,69 @@ public class CallOutgoingActivity extends LinphoneGenericActivity implements OnC
speaker.setOnClickListener(this);
// set this flag so this activity will stay in front of the keyguard
int flags = WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
int flags =
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
getWindow().addFlags(flags);
hangUp = findViewById(R.id.outgoing_hang_up);
hangUp.setOnClickListener(this);
mListener = new CoreListenerStub() {
@Override
public void onCallStateChanged(Core lc, Call call, Call.State state, String message) {
if (call == mCall && State.Connected == state) {
if (!LinphoneActivity.isInstanciated()) {
return;
}
LinphoneActivity.instance().startIncallActivity();
return;
} else if (state == State.Error) {
// Convert Core message for internalization
if (call.getErrorInfo().getReason() == Reason.Declined) {
displayCustomToast(getString(R.string.error_call_declined), Toast.LENGTH_SHORT);
decline();
} else if (call.getErrorInfo().getReason() == Reason.NotFound) {
displayCustomToast(getString(R.string.error_user_not_found), Toast.LENGTH_SHORT);
decline();
} else if (call.getErrorInfo().getReason() == Reason.NotAcceptable) {
displayCustomToast(getString(R.string.error_incompatible_media), Toast.LENGTH_SHORT);
decline();
} else if (call.getErrorInfo().getReason() == Reason.Busy) {
displayCustomToast(getString(R.string.error_user_busy), Toast.LENGTH_SHORT);
decline();
} else if (message != null) {
displayCustomToast(getString(R.string.error_unknown) + " - " + message, Toast.LENGTH_SHORT);
decline();
}
} else if (state == State.End) {
// Convert Core message for internalization
if (call.getErrorInfo().getReason() == Reason.Declined) {
displayCustomToast(getString(R.string.error_call_declined), Toast.LENGTH_SHORT);
decline();
}
}
mListener =
new CoreListenerStub() {
@Override
public void onCallStateChanged(
Core lc, Call call, Call.State state, String message) {
if (call == mCall && State.Connected == state) {
if (!LinphoneActivity.isInstanciated()) {
return;
}
LinphoneActivity.instance().startIncallActivity();
return;
} else if (state == State.Error) {
// Convert Core message for internalization
if (call.getErrorInfo().getReason() == Reason.Declined) {
displayCustomToast(
getString(R.string.error_call_declined),
Toast.LENGTH_SHORT);
decline();
} else if (call.getErrorInfo().getReason() == Reason.NotFound) {
displayCustomToast(
getString(R.string.error_user_not_found),
Toast.LENGTH_SHORT);
decline();
} else if (call.getErrorInfo().getReason() == Reason.NotAcceptable) {
displayCustomToast(
getString(R.string.error_incompatible_media),
Toast.LENGTH_SHORT);
decline();
} else if (call.getErrorInfo().getReason() == Reason.Busy) {
displayCustomToast(
getString(R.string.error_user_busy), Toast.LENGTH_SHORT);
decline();
} else if (message != null) {
displayCustomToast(
getString(R.string.error_unknown) + " - " + message,
Toast.LENGTH_SHORT);
decline();
}
} else if (state == State.End) {
// Convert Core message for internalization
if (call.getErrorInfo().getReason() == Reason.Declined) {
displayCustomToast(
getString(R.string.error_call_declined),
Toast.LENGTH_SHORT);
decline();
}
}
if (LinphoneManager.getLc().getCallsNb() == 0) {
finish();
return;
}
}
};
if (LinphoneManager.getLc().getCallsNb() == 0) {
finish();
return;
}
}
};
instance = this;
}
@ -160,8 +174,10 @@ public class CallOutgoingActivity extends LinphoneGenericActivity implements OnC
if (LinphoneManager.getLcIfManagerNotDestroyedOrNull() != null) {
for (Call call : LinphoneManager.getLc().getCalls()) {
State cstate = call.getState();
if (State.OutgoingInit == cstate || State.OutgoingProgress == cstate
|| State.OutgoingRinging == cstate || State.OutgoingEarlyMedia == cstate) {
if (State.OutgoingInit == cstate
|| State.OutgoingProgress == cstate
|| State.OutgoingRinging == cstate
|| State.OutgoingEarlyMedia == cstate) {
mCall = call;
break;
}
@ -183,7 +199,8 @@ public class CallOutgoingActivity extends LinphoneGenericActivity implements OnC
Address address = mCall.getRemoteAddress();
LinphoneContact contact = ContactsManager.getInstance().findContactFromAddress(address);
if (contact != null) {
ImageUtils.setImagePictureFromUri(this, contactPicture, contact.getPhotoUri(), contact.getThumbnailUri());
ImageUtils.setImagePictureFromUri(
this, contactPicture, contact.getPhotoUri(), contact.getThumbnailUri());
name.setText(contact.getFullName());
} else {
name.setText(LinphoneUtils.getAddressDisplayName(address));
@ -241,7 +258,8 @@ public class CallOutgoingActivity extends LinphoneGenericActivity implements OnC
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (LinphoneManager.isInstanciated() && (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_HOME)) {
if (LinphoneManager.isInstanciated()
&& (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_HOME)) {
LinphoneManager.getLc().terminateCall(mCall);
finish();
}
@ -270,20 +288,36 @@ public class CallOutgoingActivity extends LinphoneGenericActivity implements OnC
private void checkAndRequestCallPermissions() {
ArrayList<String> permissionsList = new ArrayList<String>();
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 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"));
if (recordAudio != PackageManager.PERMISSION_GRANTED) {
if (LinphonePreferences.instance().firstTimeAskingForPermission(Manifest.permission.RECORD_AUDIO) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.RECORD_AUDIO)) {
if (LinphonePreferences.instance()
.firstTimeAskingForPermission(Manifest.permission.RECORD_AUDIO)
|| ActivityCompat.shouldShowRequestPermissionRationale(
this, Manifest.permission.RECORD_AUDIO)) {
Log.i("[Permission] Asking for record audio");
permissionsList.add(Manifest.permission.RECORD_AUDIO);
}
}
if (LinphonePreferences.instance().shouldInitiateVideoCall() || LinphonePreferences.instance().shouldAutomaticallyAcceptVideoRequests()) {
if (LinphonePreferences.instance().shouldInitiateVideoCall()
|| LinphonePreferences.instance().shouldAutomaticallyAcceptVideoRequests()) {
if (camera != PackageManager.PERMISSION_GRANTED) {
if (LinphonePreferences.instance().firstTimeAskingForPermission(Manifest.permission.CAMERA) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
if (LinphonePreferences.instance()
.firstTimeAskingForPermission(Manifest.permission.CAMERA)
|| ActivityCompat.shouldShowRequestPermissionRationale(
this, Manifest.permission.CAMERA)) {
Log.i("[Permission] Asking for camera");
permissionsList.add(Manifest.permission.CAMERA);
}
@ -298,9 +332,16 @@ public class CallOutgoingActivity extends LinphoneGenericActivity implements OnC
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
public void onRequestPermissionsResult(
int requestCode, String[] permissions, int[] grantResults) {
for (int i = 0; i < permissions.length; i++) {
Log.i("[Permission] " + permissions[i] + " is " + (grantResults[i] == PackageManager.PERMISSION_GRANTED ? "granted" : "denied"));
Log.i(
"[Permission] "
+ permissions[i]
+ " is "
+ (grantResults[i] == PackageManager.PERMISSION_GRANTED
? "granted"
: "denied"));
}
}
}

View file

@ -32,11 +32,8 @@ import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import org.linphone.LinphoneManager;
import org.linphone.settings.LinphonePreferences;
import org.linphone.LinphoneService;
import org.linphone.utils.LinphoneUtils;
import org.linphone.R;
import org.linphone.compatibility.CompatibilityScaleGestureDetector;
import org.linphone.compatibility.CompatibilityScaleGestureListener;
@ -44,8 +41,11 @@ import org.linphone.core.Call;
import org.linphone.core.Core;
import org.linphone.core.VideoDefinition;
import org.linphone.mediastream.Log;
import org.linphone.settings.LinphonePreferences;
import org.linphone.utils.LinphoneUtils;
public class CallVideoFragment extends Fragment implements OnGestureListener, OnDoubleTapListener, CompatibilityScaleGestureListener {
public class CallVideoFragment extends Fragment
implements OnGestureListener, OnDoubleTapListener, CompatibilityScaleGestureListener {
private TextureView mVideoView;
private TextureView mCaptureView;
private GestureDetector mGestureDetector;
@ -58,8 +58,8 @@ public class CallVideoFragment extends Fragment implements OnGestureListener, On
@SuppressWarnings("deprecation")
// Warning useless because value is ignored and automatically set by new APIs.
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view;
if (LinphoneManager.getLc().hasCrappyOpengl()) {
view = inflater.inflate(R.layout.video_no_opengl, container, false);
@ -69,48 +69,55 @@ public class CallVideoFragment extends Fragment implements OnGestureListener, On
mVideoView = view.findViewById(R.id.videoSurface);
mCaptureView = view.findViewById(R.id.videoCaptureSurface);
LinphoneManager.getLc().setNativeVideoWindowId(mVideoView);
LinphoneManager.getLc().setNativePreviewWindowId(mCaptureView);
mVideoView.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if (mScaleDetector != null) {
mScaleDetector.onTouchEvent(event);
}
mVideoView.setOnTouchListener(
new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if (mScaleDetector != null) {
mScaleDetector.onTouchEvent(event);
}
mGestureDetector.onTouchEvent(event);
if (inCallActivity != null) {
inCallActivity.displayVideoCallControlsIfHidden();
}
return true;
}
});
mGestureDetector.onTouchEvent(event);
if (inCallActivity != null) {
inCallActivity.displayVideoCallControlsIfHidden();
}
return true;
}
});
mCaptureView.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
previewX = (int) motionEvent.getX();
previewY = (int) motionEvent.getY();
break;
case MotionEvent.ACTION_MOVE:
int x = (int) motionEvent.getX();
int y = (int) motionEvent.getY();
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) mCaptureView.getLayoutParams();
lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, 0); // Clears the rule, as there is no removeRule until API 17.
lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, 0);
int left = lp.leftMargin + (x - previewX);
int top = lp.topMargin + (y - previewY);
lp.leftMargin = left;
lp.topMargin = top;
view.setLayoutParams(lp);
break;
}
return true;
}
});
mCaptureView.setOnTouchListener(
new OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
previewX = (int) motionEvent.getX();
previewY = (int) motionEvent.getY();
break;
case MotionEvent.ACTION_MOVE:
int x = (int) motionEvent.getX();
int y = (int) motionEvent.getY();
RelativeLayout.LayoutParams lp =
(RelativeLayout.LayoutParams)
mCaptureView.getLayoutParams();
lp.addRule(
RelativeLayout.ALIGN_PARENT_BOTTOM,
0); // Clears the rule, as there is no removeRule until API
// 17.
lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, 0);
int left = lp.leftMargin + (x - previewX);
int top = lp.topMargin + (y - previewY);
lp.leftMargin = left;
lp.topMargin = top;
view.setLayoutParams(lp);
break;
}
return true;
}
});
return view;
}
@ -135,9 +142,12 @@ public class CallVideoFragment extends Fragment implements OnGestureListener, On
DisplayMetrics metrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);
int screenHeight = metrics.heightPixels;
int maxHeight = screenHeight / 4; // Let's take at most 1/4 of the screen for the camera preview
int maxHeight =
screenHeight / 4; // Let's take at most 1/4 of the screen for the camera preview
VideoDefinition videoSize = call.getCurrentParams().getSentVideoDefinition(); // It already takes care of rotation
VideoDefinition videoSize =
call.getCurrentParams()
.getSentVideoDefinition(); // It already takes care of rotation
if (videoSize.getWidth() == 0 || videoSize.getHeight() == 0) {
Log.w("Couldn't get sent video definition, using default video definition");
videoSize = lc.getPreferredVideoDefinition();
@ -155,7 +165,9 @@ public class CallVideoFragment extends Fragment implements OnGestureListener, On
}
RelativeLayout.LayoutParams newLp = new RelativeLayout.LayoutParams(width, height);
newLp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, 1); // Clears the rule, as there is no removeRule until API 17.
newLp.addRule(
RelativeLayout.ALIGN_PARENT_BOTTOM,
1); // Clears the rule, as there is no removeRule until API 17.
newLp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, 1);
mCaptureView.setLayoutParams(newLp);
Log.d("Video preview size set to " + width + "x" + height);
@ -175,12 +187,9 @@ public class CallVideoFragment extends Fragment implements OnGestureListener, On
}
String newDevice;
if (index == 1)
newDevice = devices[0];
else if (devices.length > 1)
newDevice = devices[1];
else
newDevice = devices[index];
if (index == 1) newDevice = devices[0];
else if (devices.length > 1) newDevice = devices[1];
else newDevice = devices[index];
LinphoneManager.getLc().setVideoDevice(newDevice);
CallManager.getInstance().updateCall();
@ -217,10 +226,15 @@ public class CallVideoFragment extends Fragment implements OnGestureListener, On
mZoomFactor *= detector.getScaleFactor();
// Don't let the object get too small or too large.
// Zoom to make the video fill the screen vertically
float portraitZoomFactor = ((float) mVideoView.getHeight()) / (float) ((3 * mVideoView.getWidth()) / 4);
float portraitZoomFactor =
((float) mVideoView.getHeight()) / (float) ((3 * mVideoView.getWidth()) / 4);
// Zoom to make the video fill the screen horizontally
float landscapeZoomFactor = ((float) mVideoView.getWidth()) / (float) ((3 * mVideoView.getHeight()) / 4);
mZoomFactor = Math.max(0.1f, Math.min(mZoomFactor, Math.max(portraitZoomFactor, landscapeZoomFactor)));
float landscapeZoomFactor =
((float) mVideoView.getWidth()) / (float) ((3 * mVideoView.getHeight()) / 4);
mZoomFactor =
Math.max(
0.1f,
Math.min(mZoomFactor, Math.max(portraitZoomFactor, landscapeZoomFactor)));
Call currentCall = LinphoneManager.getLc().getCurrentCall();
if (currentCall != null) {
@ -246,16 +260,14 @@ public class CallVideoFragment extends Fragment implements OnGestureListener, On
mZoomCenterY -= 0.01;
}
if (mZoomCenterX > 1)
mZoomCenterX = 1;
if (mZoomCenterX < 0)
mZoomCenterX = 0;
if (mZoomCenterY > 1)
mZoomCenterY = 1;
if (mZoomCenterY < 0)
mZoomCenterY = 0;
if (mZoomCenterX > 1) mZoomCenterX = 1;
if (mZoomCenterX < 0) mZoomCenterX = 0;
if (mZoomCenterY > 1) mZoomCenterY = 1;
if (mZoomCenterY < 0) mZoomCenterY = 0;
LinphoneManager.getLc().getCurrentCall().zoom(mZoomFactor, mZoomCenterX, mZoomCenterY);
LinphoneManager.getLc()
.getCurrentCall()
.zoom(mZoomFactor, mZoomCenterX, mZoomCenterY);
return true;
}
}
@ -268,9 +280,13 @@ public class CallVideoFragment extends Fragment implements OnGestureListener, On
if (LinphoneUtils.isCallEstablished(LinphoneManager.getLc().getCurrentCall())) {
if (mZoomFactor == 1.f) {
// Zoom to make the video fill the screen vertically
float portraitZoomFactor = ((float) mVideoView.getHeight()) / (float) ((3 * mVideoView.getWidth()) / 4);
float portraitZoomFactor =
((float) mVideoView.getHeight())
/ (float) ((3 * mVideoView.getWidth()) / 4);
// Zoom to make the video fill the screen horizontally
float landscapeZoomFactor = ((float) mVideoView.getWidth()) / (float) ((3 * mVideoView.getHeight()) / 4);
float landscapeZoomFactor =
((float) mVideoView.getWidth())
/ (float) ((3 * mVideoView.getHeight()) / 4);
mZoomFactor = Math.max(portraitZoomFactor, landscapeZoomFactor);
} else {
@ -326,20 +342,15 @@ public class CallVideoFragment extends Fragment implements OnGestureListener, On
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
return false;
}
@Override
public void onLongPress(MotionEvent e) {
}
public void onLongPress(MotionEvent e) {}
@Override
public void onShowPress(MotionEvent e) {
}
public void onShowPress(MotionEvent e) {}
@Override
public boolean onSingleTapUp(MotionEvent e) {

View file

@ -20,8 +20,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import android.content.Context;
import androidx.recyclerview.widget.RecyclerView;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
@ -30,11 +28,12 @@ import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import org.linphone.R;
import org.linphone.core.ChatMessage;
public class ChatMessageOldViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public class ChatMessageOldViewHolder extends RecyclerView.ViewHolder
implements View.OnClickListener {
public String messageId;
public Context mContext;
public ChatMessage message;
@ -66,7 +65,8 @@ public class ChatMessageOldViewHolder extends RecyclerView.ViewHolder implements
public CheckBox delete;
private ChatMessageViewHolderClickListener mListener;
public ChatMessageOldViewHolder(Context context, View view, ChatMessageViewHolderClickListener listener) {
public ChatMessageOldViewHolder(
Context context, View view, ChatMessageViewHolderClickListener listener) {
this(view);
mContext = context;
mListener = listener;
@ -76,7 +76,7 @@ public class ChatMessageOldViewHolder extends RecyclerView.ViewHolder implements
public ChatMessageOldViewHolder(View view) {
super(view);
eventLayout = view.findViewById(R.id.event);
//eventTime = view.findViewById(R.id.event_date);
// eventTime = view.findViewById(R.id.event_date);
eventMessage = view.findViewById(R.id.event_text);
bubbleLayout = view.findViewById(R.id.bubble);
@ -110,4 +110,4 @@ public class ChatMessageOldViewHolder extends RecyclerView.ViewHolder implements
mListener.onItemClicked(getAdapterPosition());
}
}
}
}

View file

@ -19,12 +19,10 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import static android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION;
import android.Manifest;
import android.content.Context;
import androidx.core.content.FileProvider;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
@ -42,16 +40,18 @@ import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.core.content.FileProvider;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.flexbox.FlexboxLayout;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.linphone.LinphoneActivity;
import org.linphone.R;
import org.linphone.contacts.ContactsManager;
import org.linphone.contacts.LinphoneContact;
import org.linphone.core.Address;
import org.linphone.core.ChatMessage;
import org.linphone.core.ChatMessageListenerStub;
import org.linphone.core.Content;
import org.linphone.mediastream.Log;
import org.linphone.utils.FileUtils;
@ -60,12 +60,6 @@ import org.linphone.views.AsyncBitmap;
import org.linphone.views.BitmapWorkerTask;
import org.linphone.views.ContactAvatar;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import static android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION;
public class ChatMessageViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private Context mContext;
@ -93,7 +87,8 @@ public class ChatMessageViewHolder extends RecyclerView.ViewHolder implements Vi
public CheckBox deleteMessage;
private ChatMessageViewHolderClickListener mListener;
public ChatMessageViewHolder(Context context, View view, ChatMessageViewHolderClickListener listener) {
public ChatMessageViewHolder(
Context context, View view, ChatMessageViewHolderClickListener listener) {
this(view);
mContext = context;
mListener = listener;
@ -147,7 +142,9 @@ public class ChatMessageViewHolder extends RecyclerView.ViewHolder implements Vi
ChatMessage.State status = message.getState();
Address remoteSender = message.getFromAddress();
String displayName;
String time = LinphoneUtils.timestampToHumanDate(mContext, message.getTime(), R.string.messages_date_format);
String time =
LinphoneUtils.timestampToHumanDate(
mContext, message.getTime(), R.string.messages_date_format);
if (message.isOutgoing()) {
outgoingImdn.setVisibility(View.INVISIBLE); // For anchoring purposes
@ -215,14 +212,24 @@ public class ChatMessageViewHolder extends RecyclerView.ViewHolder implements Vi
if (fileContents.size() > 0) {
pictures.setVisibility(View.VISIBLE);
for (Content c : fileContents) {
View content = LayoutInflater.from(mContext).inflate(R.layout.chat_bubble_content, null, false);
View content =
LayoutInflater.from(mContext)
.inflate(R.layout.chat_bubble_content, null, false);
if (c.isFile() || (c.isFileTransfer() && message.isOutgoing())) { // If message is outgoing, even if content is file transfer we have the file available
if (c.isFile()
|| (c.isFileTransfer()
&& message
.isOutgoing())) { // If message is outgoing, even if content
// is file transfer we have the file
// available
String filePath = c.getFilePath();
View v;
if (FileUtils.isExtensionImage(filePath)) {
if (fileContents.size() == 1 && mContext.getResources().getBoolean(R.bool.use_big_pictures_to_preview_images_file_transfers)) {
if (fileContents.size() == 1
&& mContext.getResources()
.getBoolean(
R.bool.use_big_pictures_to_preview_images_file_transfers)) {
v = content.findViewById(R.id.bigImage);
loadBitmap(c.getFilePath(), ((ImageView) v));
} else {
@ -231,42 +238,56 @@ public class ChatMessageViewHolder extends RecyclerView.ViewHolder implements Vi
}
} else {
v = content.findViewById(R.id.file);
((TextView)v).setText(FileUtils.getNameFromFilePath(filePath));
((TextView) v).setText(FileUtils.getNameFromFilePath(filePath));
}
v.setVisibility(View.VISIBLE);
v.setTag(c.getFilePath());
v.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
openFile((String) v.getTag());
}
});
v.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
openFile((String) v.getTag());
}
});
} else {
Button download = content.findViewById(R.id.download);
download.setVisibility(View.VISIBLE);
if (mContext.getPackageManager().checkPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, mContext.getPackageName()) == PackageManager.PERMISSION_GRANTED) {
if (mContext.getPackageManager()
.checkPermission(
Manifest.permission.WRITE_EXTERNAL_STORAGE,
mContext.getPackageName())
== PackageManager.PERMISSION_GRANTED) {
String filename = c.getName();
File file = new File(FileUtils.getStorageDirectory(mContext), filename);
int prefix = 1;
while (file.exists()) {
file = new File(FileUtils.getStorageDirectory(mContext), prefix + "_" + filename);
Log.w("File with that name already exists, renamed to " + prefix + "_" + filename);
file =
new File(
FileUtils.getStorageDirectory(mContext),
prefix + "_" + filename);
Log.w(
"File with that name already exists, renamed to "
+ prefix
+ "_"
+ filename);
prefix += 1;
}
download.setTag(c);
c.setFilePath(file.getPath());
download.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Content c = (Content) v.getTag();
message.downloadContent(c);
}
});
download.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
Content c = (Content) v.getTag();
message.downloadContent(c);
}
});
} else {
Log.w("WRITE_EXTERNAL_STORAGE permission not granted, won't be able to store the downloaded file");
Log.w(
"WRITE_EXTERNAL_STORAGE permission not granted, won't be able to store the downloaded file");
LinphoneActivity.instance().checkAndRequestExternalStoragePermission();
}
}
@ -283,13 +304,21 @@ public class ChatMessageViewHolder extends RecyclerView.ViewHolder implements Vi
if (path.startsWith("file://")) {
path = path.substring("file://".length());
file = new File(path);
contentUri = FileProvider.getUriForFile(mContext, mContext.getResources().getString(R.string.file_provider), file);
contentUri =
FileProvider.getUriForFile(
mContext,
mContext.getResources().getString(R.string.file_provider),
file);
} else if (path.startsWith("content://")) {
contentUri = Uri.parse(path);
} else {
file = new File(path);
try {
contentUri = FileProvider.getUriForFile(mContext, mContext.getResources().getString(R.string.file_provider), file);
contentUri =
FileProvider.getUriForFile(
mContext,
mContext.getResources().getString(R.string.file_provider),
file);
} catch (Exception e) {
contentUri = Uri.parse(path);
}
@ -311,9 +340,11 @@ public class ChatMessageViewHolder extends RecyclerView.ViewHolder implements Vi
private void loadBitmap(String path, ImageView imageView) {
if (cancelPotentialWork(path, imageView)) {
Bitmap defaultBitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.chat_file);
Bitmap defaultBitmap =
BitmapFactory.decodeResource(mContext.getResources(), R.drawable.chat_file);
BitmapWorkerTask task = new BitmapWorkerTask(mContext, imageView, defaultBitmap);
final AsyncBitmap asyncBitmap = new AsyncBitmap(mContext.getResources(), defaultBitmap, task);
final AsyncBitmap asyncBitmap =
new AsyncBitmap(mContext.getResources(), defaultBitmap, task);
imageView.setImageDrawable(asyncBitmap);
task.execute(path);
}
@ -336,5 +367,4 @@ public class ChatMessageViewHolder extends RecyclerView.ViewHolder implements Vi
// No task associated with the ImageView, or an existing task was cancelled
return true;
}
}
}

View file

@ -20,13 +20,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import android.content.Context;
import androidx.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import org.linphone.mediastream.Log;
import org.linphone.utils.LinphoneUtils;
import androidx.annotation.NonNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.linphone.R;
import org.linphone.contacts.ContactsManager;
import org.linphone.contacts.LinphoneContact;
@ -34,15 +35,12 @@ import org.linphone.core.Address;
import org.linphone.core.ChatMessage;
import org.linphone.core.ChatMessageListenerStub;
import org.linphone.core.EventLog;
import org.linphone.utils.LinphoneUtils;
import org.linphone.utils.SelectableAdapter;
import org.linphone.utils.SelectableHelper;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class ChatMessagesAdapter extends SelectableAdapter<ChatMessageViewHolder> implements ChatMessagesGenericAdapter {
public class ChatMessagesAdapter extends SelectableAdapter<ChatMessageViewHolder>
implements ChatMessagesGenericAdapter {
public static int MAX_TIME_TO_GROUP_MESSAGES = 60;
private Context mContext;
@ -55,7 +53,13 @@ public class ChatMessagesAdapter extends SelectableAdapter<ChatMessageViewHolder
private ChatMessageViewHolderClickListener mClickListener;
public ChatMessagesAdapter(ChatMessagesFragment fragment, SelectableHelper helper, int itemResource, EventLog[] history, ArrayList<LinphoneContact> participants, ChatMessageViewHolderClickListener clickListener) {
public ChatMessagesAdapter(
ChatMessagesFragment fragment,
SelectableHelper helper,
int itemResource,
EventLog[] history,
ArrayList<LinphoneContact> participants,
ChatMessageViewHolderClickListener clickListener) {
super(helper);
mFragment = fragment;
mContext = mFragment.getActivity();
@ -69,11 +73,10 @@ public class ChatMessagesAdapter extends SelectableAdapter<ChatMessageViewHolder
@Override
public ChatMessageViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(mItemResource, parent, false);
View v = LayoutInflater.from(parent.getContext()).inflate(mItemResource, parent, false);
ChatMessageViewHolder VH = new ChatMessageViewHolder(mContext, v, mClickListener);
//Allows onLongClick ContextMenu on bubbles
// Allows onLongClick ContextMenu on bubbles
mFragment.registerForContextMenu(v);
v.setTag(VH);
return VH;
@ -100,26 +103,32 @@ public class ChatMessagesAdapter extends SelectableAdapter<ChatMessageViewHolder
holder.deleteMessage.setTag(position);
}
if ((message.isOutgoing() && message.getState() != ChatMessage.State.Displayed) || (!message.isOutgoing() && message.isFileTransfer())) {
if ((message.isOutgoing() && message.getState() != ChatMessage.State.Displayed)
|| (!message.isOutgoing() && message.isFileTransfer())) {
if (!mTransientMessages.contains(message)) {
mTransientMessages.add(message);
}
message.setUserData(holder); // This only works if JAVA object is kept, hence the transient list
message.setListener(new ChatMessageListenerStub() {
@Override
public void onMsgStateChanged(ChatMessage message, ChatMessage.State state) {
ChatMessageViewHolder holder = (ChatMessageViewHolder) message.getUserData();
if (holder != null) {
notifyItemChanged(holder.getAdapterPosition());
} else {
// Just in case, better to refresh the whole view than to miss an update
notifyDataSetChanged();
}
if (state == ChatMessage.State.Displayed) {
mTransientMessages.remove(message);
}
}
});
message.setUserData(
holder); // This only works if JAVA object is kept, hence the transient list
message.setListener(
new ChatMessageListenerStub() {
@Override
public void onMsgStateChanged(
ChatMessage message, ChatMessage.State state) {
ChatMessageViewHolder holder =
(ChatMessageViewHolder) message.getUserData();
if (holder != null) {
notifyItemChanged(holder.getAdapterPosition());
} else {
// Just in case, better to refresh the whole view than to miss
// an update
notifyDataSetChanged();
}
if (state == ChatMessage.State.Displayed) {
mTransientMessages.remove(message);
}
}
});
}
LinphoneContact contact = null;
@ -147,7 +156,8 @@ public class ChatMessagesAdapter extends SelectableAdapter<ChatMessageViewHolder
}
String displayName = "";
if (address != null) {
LinphoneContact contact = ContactsManager.getInstance().findContactFromAddress(address);
LinphoneContact contact =
ContactsManager.getInstance().findContactFromAddress(address);
if (contact != null) {
displayName = contact.getFullName();
} else {
@ -166,47 +176,65 @@ public class ChatMessagesAdapter extends SelectableAdapter<ChatMessageViewHolder
break;
case ConferenceParticipantAdded:
holder.eventLayout.setVisibility(View.VISIBLE);
holder.eventMessage.setText(mContext.getString(R.string.participant_added).replace("%s", displayName));
holder.eventMessage.setText(
mContext.getString(R.string.participant_added)
.replace("%s", displayName));
break;
case ConferenceParticipantRemoved:
holder.eventLayout.setVisibility(View.VISIBLE);
holder.eventMessage.setText(mContext.getString(R.string.participant_removed).replace("%s", displayName));
holder.eventMessage.setText(
mContext.getString(R.string.participant_removed)
.replace("%s", displayName));
break;
case ConferenceSubjectChanged:
holder.eventLayout.setVisibility(View.VISIBLE);
holder.eventMessage.setText(mContext.getString(R.string.subject_changed).replace("%s", event.getSubject()));
holder.eventMessage.setText(
mContext.getString(R.string.subject_changed)
.replace("%s", event.getSubject()));
break;
case ConferenceParticipantSetAdmin:
holder.eventLayout.setVisibility(View.VISIBLE);
holder.eventMessage.setText(mContext.getString(R.string.admin_set).replace("%s", displayName));
holder.eventMessage.setText(
mContext.getString(R.string.admin_set).replace("%s", displayName));
break;
case ConferenceParticipantUnsetAdmin:
holder.eventLayout.setVisibility(View.VISIBLE);
holder.eventMessage.setText(mContext.getString(R.string.admin_unset).replace("%s", displayName));
holder.eventMessage.setText(
mContext.getString(R.string.admin_unset).replace("%s", displayName));
break;
case ConferenceParticipantDeviceAdded:
holder.eventLayout.setVisibility(View.VISIBLE);
holder.eventMessage.setText(mContext.getString(R.string.device_added).replace("%s", displayName));
holder.eventMessage.setText(
mContext.getString(R.string.device_added).replace("%s", displayName));
break;
case ConferenceParticipantDeviceRemoved:
holder.eventLayout.setVisibility(View.VISIBLE);
holder.eventMessage.setText(mContext.getString(R.string.device_removed).replace("%s", displayName));
holder.eventMessage.setText(
mContext.getString(R.string.device_removed).replace("%s", displayName));
break;
case ConferenceSecurityEvent:
holder.securityEventLayout.setVisibility(View.VISIBLE);
switch (event.getSecurityEventType()) {
case EncryptionIdentityKeyChanged:
holder.securityEventMessage.setText(mContext.getString(R.string.lime_identity_key_changed).replace("%s", displayName));
holder.securityEventMessage.setText(
mContext.getString(R.string.lime_identity_key_changed)
.replace("%s", displayName));
break;
case ManInTheMiddleDetected:
holder.securityEventMessage.setText(mContext.getString(R.string.man_in_the_middle_detected).replace("%s", displayName));
holder.securityEventMessage.setText(
mContext.getString(R.string.man_in_the_middle_detected)
.replace("%s", displayName));
break;
case SecurityLevelDowngraded:
holder.securityEventMessage.setText(mContext.getString(R.string.security_level_downgraded).replace("%s", displayName));
holder.securityEventMessage.setText(
mContext.getString(R.string.security_level_downgraded)
.replace("%s", displayName));
break;
case ParticipantMaxDeviceCountExceeded:
holder.securityEventMessage.setText(mContext.getString(R.string.participant_max_count_exceeded).replace("%s", displayName));
holder.securityEventMessage.setText(
mContext.getString(R.string.participant_max_count_exceeded)
.replace("%s", displayName));
break;
case None:
default:
@ -216,7 +244,10 @@ public class ChatMessagesAdapter extends SelectableAdapter<ChatMessageViewHolder
case None:
default:
holder.eventLayout.setVisibility(View.VISIBLE);
holder.eventMessage.setText(mContext.getString(R.string.unexpected_event).replace("%s", displayName).replace("%i", String.valueOf(event.getType().toInt())));
holder.eventMessage.setText(
mContext.getString(R.string.unexpected_event)
.replace("%s", displayName)
.replace("%i", String.valueOf(event.getType().toInt())));
break;
}
}
@ -274,22 +305,29 @@ public class ChatMessagesAdapter extends SelectableAdapter<ChatMessageViewHolder
notifyItemRemoved(i);
}
private void changeBackgroundDependingOnPreviousAndNextEvents(ChatMessage message, ChatMessageViewHolder holder, int position) {
private void changeBackgroundDependingOnPreviousAndNextEvents(
ChatMessage message, ChatMessageViewHolder holder, int position) {
boolean hasPrevious = false, hasNext = false;
// Do not forget history is reversed, so previous in order is next in list display and chronology !
if (position > 0 && mContext.getResources().getBoolean(R.bool.lower_space_between_chat_bubbles_if_same_person)) {
// Do not forget history is reversed, so previous in order is next in list display and
// chronology !
if (position > 0
&& mContext.getResources()
.getBoolean(R.bool.lower_space_between_chat_bubbles_if_same_person)) {
EventLog previousEvent = (EventLog) getItem(position - 1);
if (previousEvent.getType() == EventLog.Type.ConferenceChatMessage) {
ChatMessage previousMessage = previousEvent.getChatMessage();
if (previousMessage.getFromAddress().weakEqual(message.getFromAddress())) {
if (previousMessage.getTime() - message.getTime() < MAX_TIME_TO_GROUP_MESSAGES) {
if (previousMessage.getTime() - message.getTime()
< MAX_TIME_TO_GROUP_MESSAGES) {
hasPrevious = true;
}
}
}
}
if (position < mHistory.size() - 1 && mContext.getResources().getBoolean(R.bool.lower_space_between_chat_bubbles_if_same_person)) {
if (position < mHistory.size() - 1
&& mContext.getResources()
.getBoolean(R.bool.lower_space_between_chat_bubbles_if_same_person)) {
EventLog nextEvent = (EventLog) getItem(position + 1);
if (nextEvent.getType() == EventLog.Type.ConferenceChatMessage) {
ChatMessage nextMessage = nextEvent.getChatMessage();

File diff suppressed because it is too large Load diff

View file

@ -1,28 +1,27 @@
package org.linphone.chat;
/*
ChatMessagesGenericAdapter.java
Copyright (C) 2018 Belledonne Communications, Grenoble, France
ChatMessagesGenericAdapter.java
Copyright (C) 2018 Belledonne Communications, Grenoble, France
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import org.linphone.contacts.LinphoneContact;
import org.linphone.core.EventLog;
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import java.util.ArrayList;
import org.linphone.contacts.LinphoneContact;
import org.linphone.core.EventLog;
public interface ChatMessagesGenericAdapter {
void addToHistory(EventLog log);

View file

@ -19,22 +19,15 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import static android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.AsyncTask;
import android.provider.MediaStore;
import androidx.annotation.NonNull;
import androidx.core.content.FileProvider;
import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.view.LayoutInflater;
@ -43,7 +36,13 @@ import android.view.ViewGroup;
import android.webkit.MimeTypeMap;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import androidx.annotation.NonNull;
import androidx.core.content.FileProvider;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.linphone.LinphoneActivity;
import org.linphone.LinphoneManager;
import org.linphone.R;
@ -65,18 +64,8 @@ import org.linphone.views.AsyncBitmap;
import org.linphone.views.BitmapWorkerTask;
import org.linphone.views.ContactAvatar;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION;
public class ChatMessagesOldAdapter extends SelectableAdapter<ChatMessageOldViewHolder> implements ChatMessagesGenericAdapter {
public class ChatMessagesOldAdapter extends SelectableAdapter<ChatMessageOldViewHolder>
implements ChatMessagesGenericAdapter {
private static int MARGIN_BETWEEN_MESSAGES = 10;
private static int SIDE_MARGIN = 100;
@ -90,7 +79,13 @@ public class ChatMessagesOldAdapter extends SelectableAdapter<ChatMessageOldView
private ChatMessageViewHolderClickListener mClickListener;
public ChatMessagesOldAdapter(ChatMessagesFragment fragment, SelectableHelper helper, int itemResource, EventLog[] history, ArrayList<LinphoneContact> participants, ChatMessageViewHolderClickListener clickListener) {
public ChatMessagesOldAdapter(
ChatMessagesFragment fragment,
SelectableHelper helper,
int itemResource,
EventLog[] history,
ArrayList<LinphoneContact> participants,
ChatMessageViewHolderClickListener clickListener) {
super(helper);
mFragment = fragment;
mContext = mFragment.getActivity();
@ -99,51 +94,55 @@ public class ChatMessagesOldAdapter extends SelectableAdapter<ChatMessageOldView
Collections.reverse(mHistory);
mParticipants = participants;
mClickListener = clickListener;
mListener = new ChatMessageListenerStub() {
@Override
public void onFileTransferProgressIndication(ChatMessage message, Content content, int offset, int total) {
ChatMessageOldViewHolder holder = (ChatMessageOldViewHolder) message.getUserData();
if (holder == null) return;
mListener =
new ChatMessageListenerStub() {
@Override
public void onFileTransferProgressIndication(
ChatMessage message, Content content, int offset, int total) {
ChatMessageOldViewHolder holder =
(ChatMessageOldViewHolder) message.getUserData();
if (holder == null) return;
if (offset == total) {
holder.fileTransferProgressBar.setVisibility(View.GONE);
holder.fileTransferAction.setVisibility(View.GONE);
holder.fileTransferLayout.setVisibility(View.GONE);
if (offset == total) {
holder.fileTransferProgressBar.setVisibility(View.GONE);
holder.fileTransferAction.setVisibility(View.GONE);
holder.fileTransferLayout.setVisibility(View.GONE);
displayAttachedFile(message, holder);
} else {
holder.fileTransferProgressBar.setVisibility(View.VISIBLE);
holder.fileTransferProgressBar.setProgress(offset * 100 / total);
}
}
@Override
public void onMsgStateChanged(ChatMessage message, ChatMessage.State state) {
if (state == ChatMessage.State.FileTransferDone) {
if (!message.isOutgoing()) {
message.setAppdata(message.getFileTransferFilepath());
displayAttachedFile(message, holder);
} else {
holder.fileTransferProgressBar.setVisibility(View.VISIBLE);
holder.fileTransferProgressBar.setProgress(offset * 100 / total);
}
}
message.setFileTransferFilepath(null); // Not needed anymore, will help differenciate between InProgress states for file transfer / message sending
}
for (int i = 0; i < mHistory.size(); i++) {
EventLog log = mHistory.get(i);
if (log.getType() == EventLog.Type.ConferenceChatMessage && log.getChatMessage() == message) {
notifyItemChanged(i);
break;
}
}
}
};
@Override
public void onMsgStateChanged(ChatMessage message, ChatMessage.State state) {
if (state == ChatMessage.State.FileTransferDone) {
if (!message.isOutgoing()) {
message.setAppdata(message.getFileTransferFilepath());
}
message.setFileTransferFilepath(
null); // Not needed anymore, will help differenciate between
// InProgress states for file transfer / message sending
}
for (int i = 0; i < mHistory.size(); i++) {
EventLog log = mHistory.get(i);
if (log.getType() == EventLog.Type.ConferenceChatMessage
&& log.getChatMessage() == message) {
notifyItemChanged(i);
break;
}
}
}
};
}
@Override
public ChatMessageOldViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(mItemResource, parent, false);
View v = LayoutInflater.from(parent.getContext()).inflate(mItemResource, parent, false);
ChatMessageOldViewHolder VH = new ChatMessageOldViewHolder(mContext, v, mClickListener);
//Allows onLongClick ContextMenu on bubbles
// Allows onLongClick ContextMenu on bubbles
mFragment.registerForContextMenu(v);
v.setTag(VH);
return VH;
@ -176,7 +175,9 @@ public class ChatMessagesOldAdapter extends SelectableAdapter<ChatMessageOldView
holder.bubbleLayout.setVisibility(View.VISIBLE);
final ChatMessage message = event.getChatMessage();
if (position > 0 && mContext.getResources().getBoolean(R.bool.lower_space_between_chat_bubbles_if_same_person)) {
if (position > 0
&& mContext.getResources()
.getBoolean(R.bool.lower_space_between_chat_bubbles_if_same_person)) {
EventLog previousEvent = (EventLog) getItem(position - 1);
if (previousEvent.getType() == EventLog.Type.ConferenceChatMessage) {
ChatMessage previousMessage = previousEvent.getChatMessage();
@ -192,7 +193,10 @@ public class ChatMessagesOldAdapter extends SelectableAdapter<ChatMessageOldView
holder.messageId = message.getMessageId();
message.setUserData(holder);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
RelativeLayout.LayoutParams layoutParams =
new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
ChatMessage.State status = message.getState();
Address remoteSender = message.getFromAddress();
@ -206,7 +210,9 @@ public class ChatMessagesOldAdapter extends SelectableAdapter<ChatMessageOldView
holder.messageSendingInProgress.setVisibility(View.VISIBLE);
}
if (!message.isSecured() && LinphoneManager.getLc().limeEnabled() == LimeState.Mandatory && status != ChatMessage.State.InProgress) {
if (!message.isSecured()
&& LinphoneManager.getLc().limeEnabled() == LimeState.Mandatory
&& status != ChatMessage.State.InProgress) {
holder.messageStatus.setVisibility(View.VISIBLE);
holder.messageStatus.setImageResource(R.drawable.chat_unsecure);
}
@ -233,20 +239,31 @@ public class ChatMessagesOldAdapter extends SelectableAdapter<ChatMessageOldView
holder.imdmLabel.setTextColor(mContext.getResources().getColor(R.color.colorI));
}
//layoutParams allow bubbles alignment during selection mode
// layoutParams allow bubbles alignment during selection mode
if (isEditionEnabled()) {
layoutParams.addRule(RelativeLayout.LEFT_OF, holder.delete.getId());
layoutParams.setMargins(SIDE_MARGIN, MARGIN_BETWEEN_MESSAGES / 2, 0, MARGIN_BETWEEN_MESSAGES / 2);
layoutParams.setMargins(
SIDE_MARGIN,
MARGIN_BETWEEN_MESSAGES / 2,
0,
MARGIN_BETWEEN_MESSAGES / 2);
} else {
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
layoutParams.setMargins(SIDE_MARGIN, MARGIN_BETWEEN_MESSAGES / 2, 0, MARGIN_BETWEEN_MESSAGES / 2);
layoutParams.setMargins(
SIDE_MARGIN,
MARGIN_BETWEEN_MESSAGES / 2,
0,
MARGIN_BETWEEN_MESSAGES / 2);
}
holder.background.setBackgroundResource(R.drawable.resizable_chat_bubble_outgoing);
Compatibility.setTextAppearance(holder.contactName, mContext, R.style.font3);
Compatibility.setTextAppearance(holder.fileTransferAction, mContext, R.style.font15);
holder.fileTransferAction.setBackgroundResource(R.drawable.resizable_confirm_delete_button);
ContactAvatar.setAvatarMask(holder.avatarLayout, R.drawable.avatar_chat_mask_outgoing);
Compatibility.setTextAppearance(
holder.fileTransferAction, mContext, R.style.font15);
holder.fileTransferAction.setBackgroundResource(
R.drawable.resizable_confirm_delete_button);
ContactAvatar.setAvatarMask(
holder.avatarLayout, R.drawable.avatar_chat_mask_outgoing);
} else {
for (LinphoneContact c : mParticipants) {
if (c != null && c.hasAddress(remoteSender.asStringUriOnly())) {
@ -257,16 +274,25 @@ public class ChatMessagesOldAdapter extends SelectableAdapter<ChatMessageOldView
if (isEditionEnabled()) {
layoutParams.addRule(RelativeLayout.LEFT_OF, holder.delete.getId());
layoutParams.setMargins(SIDE_MARGIN, MARGIN_BETWEEN_MESSAGES / 2, 0, MARGIN_BETWEEN_MESSAGES / 2);
layoutParams.setMargins(
SIDE_MARGIN,
MARGIN_BETWEEN_MESSAGES / 2,
0,
MARGIN_BETWEEN_MESSAGES / 2);
} else {
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
layoutParams.setMargins(0, MARGIN_BETWEEN_MESSAGES / 2, SIDE_MARGIN, MARGIN_BETWEEN_MESSAGES / 2);
layoutParams.setMargins(
0,
MARGIN_BETWEEN_MESSAGES / 2,
SIDE_MARGIN,
MARGIN_BETWEEN_MESSAGES / 2);
}
holder.background.setBackgroundResource(R.drawable.resizable_chat_bubble_incoming);
Compatibility.setTextAppearance(holder.contactName, mContext, R.style.font9);
Compatibility.setTextAppearance(holder.fileTransferAction, mContext, R.style.font8);
holder.fileTransferAction.setBackgroundResource(R.drawable.resizable_assistant_button);
holder.fileTransferAction.setBackgroundResource(
R.drawable.resizable_assistant_button);
ContactAvatar.setAvatarMask(holder.avatarLayout, R.drawable.avatar_chat_mask);
}
@ -284,7 +310,11 @@ public class ChatMessagesOldAdapter extends SelectableAdapter<ChatMessageOldView
displayName = LinphoneUtils.getAddressDisplayName(remoteSender);
ContactAvatar.displayAvatar(displayName, holder.avatarLayout);
}
holder.contactName.setText(LinphoneUtils.timestampToHumanDate(mContext, message.getTime(), R.string.messages_date_format) + " - " + displayName);
holder.contactName.setText(
LinphoneUtils.timestampToHumanDate(
mContext, message.getTime(), R.string.messages_date_format)
+ " - "
+ displayName);
if (message.hasTextContent()) {
String msg = message.getTextContent();
@ -320,42 +350,62 @@ public class ChatMessagesOldAdapter extends SelectableAdapter<ChatMessageOldView
holder.fileTransferAction.setVisibility(View.GONE);
} else {
holder.fileTransferAction.setText(mContext.getString(R.string.accept));
holder.fileTransferAction.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mContext.getPackageManager().checkPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, mContext.getPackageName()) == PackageManager.PERMISSION_GRANTED) {
v.setEnabled(false);
String filename = message.getFileTransferInformation().getName();
File file = new File(FileUtils.getStorageDirectory(mContext), filename);
int prefix = 1;
while (file.exists()) {
file = new File(FileUtils.getStorageDirectory(mContext), prefix + "_" + filename);
Log.w("File with that name already exists, renamed to " + prefix + "_" + filename);
prefix += 1;
}
message.setListener(mListener);
message.setFileTransferFilepath(file.getPath());
message.downloadFile();
holder.fileTransferAction.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mContext.getPackageManager()
.checkPermission(
Manifest.permission
.WRITE_EXTERNAL_STORAGE,
mContext.getPackageName())
== PackageManager.PERMISSION_GRANTED) {
v.setEnabled(false);
String filename =
message.getFileTransferInformation().getName();
File file =
new File(
FileUtils.getStorageDirectory(mContext),
filename);
int prefix = 1;
while (file.exists()) {
file =
new File(
FileUtils.getStorageDirectory(mContext),
prefix + "_" + filename);
Log.w(
"File with that name already exists, renamed to "
+ prefix
+ "_"
+ filename);
prefix += 1;
}
message.setListener(mListener);
message.setFileTransferFilepath(file.getPath());
message.downloadFile();
} else {
Log.w("WRITE_EXTERNAL_STORAGE permission not granted, won't be able to store the downloaded file");
LinphoneActivity.instance().checkAndRequestExternalStoragePermission();
}
}
});
} else {
Log.w(
"WRITE_EXTERNAL_STORAGE permission not granted, won't be able to store the downloaded file");
LinphoneActivity.instance()
.checkAndRequestExternalStoragePermission();
}
}
});
}
} else if (message.isFileTransferInProgress()) { // Outgoing file transfer in progress
message.setListener(mListener); // add the listener for file upload progress display
holder.messageSendingInProgress.setVisibility(View.GONE);
holder.fileTransferLayout.setVisibility(View.VISIBLE);
holder.fileTransferAction.setText(mContext.getString(R.string.cancel));
holder.fileTransferAction.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
message.cancelFileTransfer();
notifyItemChanged(holder.getAdapterPosition());
}
});
holder.fileTransferAction.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
message.cancelFileTransfer();
notifyItemChanged(holder.getAdapterPosition());
}
});
}
holder.bubbleLayout.setLayoutParams(layoutParams);
@ -371,7 +421,8 @@ public class ChatMessagesOldAdapter extends SelectableAdapter<ChatMessageOldView
}
String displayName = "";
if (address != null) {
LinphoneContact contact = ContactsManager.getInstance().findContactFromAddress(address);
LinphoneContact contact =
ContactsManager.getInstance().findContactFromAddress(address);
if (contact != null) {
displayName = contact.getFullName();
} else {
@ -387,43 +438,62 @@ public class ChatMessagesOldAdapter extends SelectableAdapter<ChatMessageOldView
holder.eventMessage.setText(mContext.getString(R.string.conference_destroyed));
break;
case ConferenceParticipantAdded:
holder.eventMessage.setText(mContext.getString(R.string.participant_added).replace("%s", displayName));
holder.eventMessage.setText(
mContext.getString(R.string.participant_added)
.replace("%s", displayName));
break;
case ConferenceParticipantRemoved:
holder.eventMessage.setText(mContext.getString(R.string.participant_removed).replace("%s", displayName));
holder.eventMessage.setText(
mContext.getString(R.string.participant_removed)
.replace("%s", displayName));
break;
case ConferenceSubjectChanged:
holder.eventMessage.setText(mContext.getString(R.string.subject_changed).replace("%s", event.getSubject()));
holder.eventMessage.setText(
mContext.getString(R.string.subject_changed)
.replace("%s", event.getSubject()));
break;
case ConferenceParticipantSetAdmin:
holder.eventMessage.setText(mContext.getString(R.string.admin_set).replace("%s", displayName));
holder.eventMessage.setText(
mContext.getString(R.string.admin_set).replace("%s", displayName));
break;
case ConferenceParticipantUnsetAdmin:
holder.eventMessage.setText(mContext.getString(R.string.admin_unset).replace("%s", displayName));
holder.eventMessage.setText(
mContext.getString(R.string.admin_unset).replace("%s", displayName));
break;
case ConferenceParticipantDeviceAdded:
holder.eventMessage.setText(mContext.getString(R.string.device_added).replace("%s", displayName));
holder.eventMessage.setText(
mContext.getString(R.string.device_added).replace("%s", displayName));
break;
case ConferenceParticipantDeviceRemoved:
holder.eventMessage.setText(mContext.getString(R.string.device_removed).replace("%s", displayName));
holder.eventMessage.setText(
mContext.getString(R.string.device_removed).replace("%s", displayName));
break;
case ConferenceSecurityEvent:
holder.eventMessage.setTextColor(mContext.getResources().getColor(R.color.colorI));
holder.eventMessage.setTextColor(
mContext.getResources().getColor(R.color.colorI));
holder.eventLayout.setBackgroundResource(R.drawable.event_decoration_red);
holder.eventLayout.setBackgroundResource(R.drawable.event_decoration_red);
switch (event.getSecurityEventType()) {
case EncryptionIdentityKeyChanged:
holder.eventMessage.setText(mContext.getString(R.string.lime_identity_key_changed).replace("%s", displayName));
holder.eventMessage.setText(
mContext.getString(R.string.lime_identity_key_changed)
.replace("%s", displayName));
break;
case ManInTheMiddleDetected:
holder.eventMessage.setText(mContext.getString(R.string.man_in_the_middle_detected).replace("%s", displayName));
holder.eventMessage.setText(
mContext.getString(R.string.man_in_the_middle_detected)
.replace("%s", displayName));
break;
case SecurityLevelDowngraded:
holder.eventMessage.setText(mContext.getString(R.string.security_level_downgraded).replace("%s", displayName));
holder.eventMessage.setText(
mContext.getString(R.string.security_level_downgraded)
.replace("%s", displayName));
break;
case ParticipantMaxDeviceCountExceeded:
holder.eventMessage.setText(mContext.getString(R.string.participant_max_count_exceeded).replace("%s", displayName));
holder.eventMessage.setText(
mContext.getString(R.string.participant_max_count_exceeded)
.replace("%s", displayName));
break;
case None:
default:
@ -432,7 +502,10 @@ public class ChatMessagesOldAdapter extends SelectableAdapter<ChatMessageOldView
break;
case None:
default:
holder.eventMessage.setText(mContext.getString(R.string.unexpected_event).replace("%s", displayName).replace("%i", String.valueOf(event.getType().toInt())));
holder.eventMessage.setText(
mContext.getString(R.string.unexpected_event)
.replace("%s", displayName)
.replace("%i", String.valueOf(event.getType().toInt())));
break;
}
}
@ -490,9 +563,11 @@ public class ChatMessagesOldAdapter extends SelectableAdapter<ChatMessageOldView
private void loadBitmap(String path, ImageView imageView) {
if (cancelPotentialWork(path, imageView)) {
mDefaultBitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.chat_file);
mDefaultBitmap =
BitmapFactory.decodeResource(mContext.getResources(), R.drawable.chat_file);
BitmapWorkerTask task = new BitmapWorkerTask(mContext, imageView, mDefaultBitmap);
final AsyncBitmap asyncBitmap = new AsyncBitmap(mContext.getResources(), mDefaultBitmap, task);
final AsyncBitmap asyncBitmap =
new AsyncBitmap(mContext.getResources(), mDefaultBitmap, task);
imageView.setImageDrawable(asyncBitmap);
task.execute(path);
}
@ -505,13 +580,21 @@ public class ChatMessagesOldAdapter extends SelectableAdapter<ChatMessageOldView
if (path.startsWith("file://")) {
path = path.substring("file://".length());
file = new File(path);
contentUri = FileProvider.getUriForFile(mContext, mContext.getResources().getString(R.string.file_provider), file);
contentUri =
FileProvider.getUriForFile(
mContext,
mContext.getResources().getString(R.string.file_provider),
file);
} else if (path.startsWith("content://")) {
contentUri = Uri.parse(path);
} else {
file = new File(path);
try {
contentUri = FileProvider.getUriForFile(mContext, mContext.getResources().getString(R.string.file_provider), file);
contentUri =
FileProvider.getUriForFile(
mContext,
mContext.getResources().getString(R.string.file_provider),
file);
} catch (Exception e) {
contentUri = Uri.parse(path);
}
@ -552,12 +635,13 @@ public class ChatMessagesOldAdapter extends SelectableAdapter<ChatMessageOldView
} else {
holder.openFileButton.setVisibility(View.VISIBLE);
holder.openFileButton.setTag(appData);
holder.openFileButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
openFile((String) v.getTag());
}
});
holder.openFileButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
openFile((String) v.getTag());
}
});
}
}
}

View file

@ -19,11 +19,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
package org.linphone.chat;
import static android.content.Context.INPUT_METHOD_SERVICE;
import android.app.Fragment;
import android.os.Bundle;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -36,11 +35,14 @@ import android.widget.RelativeLayout;
import android.widget.SearchView;
import android.widget.Switch;
import android.widget.TextView;
import org.linphone.LinphoneManager;
import org.linphone.settings.LinphonePreferences;
import org.linphone.R;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
import org.linphone.LinphoneActivity;
import org.linphone.LinphoneManager;
import org.linphone.R;
import org.linphone.contacts.ContactAddress;
import org.linphone.contacts.ContactsManager;
import org.linphone.contacts.ContactsUpdatedListener;
@ -52,14 +54,13 @@ import org.linphone.core.Core;
import org.linphone.core.ProxyConfig;
import org.linphone.fragments.FragmentsAvailable;
import org.linphone.mediastream.Log;
import org.linphone.settings.LinphonePreferences;
import org.linphone.views.ContactSelectView;
import java.util.ArrayList;
import java.util.List;
import static android.content.Context.INPUT_METHOD_SERVICE;
public class ChatRoomCreationFragment extends Fragment implements View.OnClickListener, SearchContactsListAdapter.ViewHolder.ClickListener, ContactsUpdatedListener {
public class ChatRoomCreationFragment extends Fragment
implements View.OnClickListener,
SearchContactsListAdapter.ViewHolder.ClickListener,
ContactsUpdatedListener {
private RecyclerView mContactsList;
private LinearLayout mContactsSelectedLayout;
private HorizontalScrollView mContactsSelectLayout;
@ -81,7 +82,8 @@ public class ChatRoomCreationFragment extends Fragment implements View.OnClickLi
private boolean mChatRoomEncrypted;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View view = inflater.inflate(R.layout.chat_create, container, false);
@ -92,7 +94,9 @@ public class ChatRoomCreationFragment extends Fragment implements View.OnClickLi
if (getArguments() != null) {
if (getArguments().getSerializable("selectedContacts") != null) {
mContactsSelected = (ArrayList<ContactAddress>) getArguments().getSerializable("selectedContacts");
mContactsSelected =
(ArrayList<ContactAddress>)
getArguments().getSerializable("selectedContacts");
}
mChatRoomSubject = getArguments().getString("subject");
mChatRoomAddress = getArguments().getString("groupChatRoomAddress");
@ -127,21 +131,24 @@ public class ChatRoomCreationFragment extends Fragment implements View.OnClickLi
mContactsFetchInProgress = view.findViewById(R.id.contactsFetchInProgress);
mContactsFetchInProgress.setVisibility(View.VISIBLE);
mSearchAdapter = new SearchContactsListAdapter(null, mContactsFetchInProgress, this, mCreateGroupChatRoom == false);
mSearchAdapter =
new SearchContactsListAdapter(
null, mContactsFetchInProgress, this, mCreateGroupChatRoom == false);
mSearchField = view.findViewById(R.id.searchField);
mSearchField.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return true;
}
mSearchField.setOnQueryTextListener(
new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return true;
}
@Override
public boolean onQueryTextChange(String newText) {
mSearchAdapter.searchContacts(newText, mContactsList);
return true;
}
});
@Override
public boolean onQueryTextChange(String newText) {
mSearchAdapter.searchContacts(newText, mContactsList);
return true;
}
});
mLinphoneContactsToggle = view.findViewById(R.id.layout_linphone_contacts);
mAllContactsToggle = view.findViewById(R.id.layout_all_contacts);
@ -149,39 +156,49 @@ public class ChatRoomCreationFragment extends Fragment implements View.OnClickLi
mSecurityToggle = view.findViewById(R.id.security_toogle);
mSecurityToggleOn = view.findViewById(R.id.security_toogle_on);
mSecurityToggleOff = view.findViewById(R.id.security_toogle_off);
mSecurityToggleOn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mSecurityToggle.setChecked(true);
}
});
mSecurityToggleOff.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mSecurityToggle.setChecked(false);
}
});
mSecurityToggleOn.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
mSecurityToggle.setChecked(true);
}
});
mSecurityToggleOff.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
mSecurityToggle.setChecked(false);
}
});
mSecurityToggle.setChecked(mChatRoomEncrypted);
ProxyConfig lpc = LinphoneManager.getLc().getDefaultProxyConfig();
if ((mChatRoomSubject != null && mChatRoomAddress != null) || (lpc == null || lpc.getConferenceFactoryUri() == null)) {
if ((mChatRoomSubject != null && mChatRoomAddress != null)
|| (lpc == null || lpc.getConferenceFactoryUri() == null)) {
mSecurityToggle.setVisibility(View.GONE);
mSecurityToggleOn.setVisibility(View.GONE);
mSecurityToggleOff.setVisibility(View.GONE);
}
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity().getApplicationContext());
LinearLayoutManager layoutManager =
new LinearLayoutManager(getActivity().getApplicationContext());
mContactsList.setAdapter(mSearchAdapter);
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mContactsList.getContext(),
layoutManager.getOrientation());
dividerItemDecoration.setDrawable(getActivity().getApplicationContext().getResources().getDrawable(R.drawable.divider));
DividerItemDecoration dividerItemDecoration =
new DividerItemDecoration(
mContactsList.getContext(), layoutManager.getOrientation());
dividerItemDecoration.setDrawable(
getActivity()
.getApplicationContext()
.getResources()
.getDrawable(R.drawable.divider));
mContactsList.addItemDecoration(dividerItemDecoration);
mContactsList.setLayoutManager(layoutManager);
if (savedInstanceState != null && savedInstanceState.getStringArrayList("mContactsSelected") != null) {
if (savedInstanceState != null
&& savedInstanceState.getStringArrayList("mContactsSelected") != null) {
mContactsSelectedLayout.removeAllViews();
// We need to get all contacts not only sip
for (String uri : savedInstanceState.getStringArrayList("mContactsSelected")) {
@ -197,7 +214,8 @@ public class ChatRoomCreationFragment extends Fragment implements View.OnClickLi
updateListSelected();
}
mOnlyDisplayLinphoneContacts = ContactsManager.getInstance().getSIPContacts().size() > 0 ? true : false;
mOnlyDisplayLinphoneContacts =
ContactsManager.getInstance().getSIPContacts().size() > 0 ? true : false;
if (savedInstanceState != null) {
mOnlyDisplayLinphoneContacts = savedInstanceState.getBoolean("onlySipContact", true);
}
@ -206,34 +224,37 @@ public class ChatRoomCreationFragment extends Fragment implements View.OnClickLi
displayChatCreation();
mChatRoomCreationListener = new ChatRoomListenerStub() {
@Override
public void onStateChanged(ChatRoom cr, ChatRoom.State newState) {
if (newState == ChatRoom.State.Created) {
mWaitLayout.setVisibility(View.GONE);
LinphoneActivity.instance().goToChat(cr.getPeerAddress().asStringUriOnly(), mShareInfos);
} else if (newState == ChatRoom.State.CreationFailed) {
mWaitLayout.setVisibility(View.GONE);
LinphoneActivity.instance().displayChatRoomError();
Log.e("Group chat room for address " + cr.getPeerAddress() + " has failed !");
}
}
};
mChatRoomCreationListener =
new ChatRoomListenerStub() {
@Override
public void onStateChanged(ChatRoom cr, ChatRoom.State newState) {
if (newState == ChatRoom.State.Created) {
mWaitLayout.setVisibility(View.GONE);
LinphoneActivity.instance()
.goToChat(cr.getPeerAddress().asStringUriOnly(), mShareInfos);
} else if (newState == ChatRoom.State.CreationFailed) {
mWaitLayout.setVisibility(View.GONE);
LinphoneActivity.instance().displayChatRoomError();
Log.e(
"Group chat room for address "
+ cr.getPeerAddress()
+ " has failed !");
}
}
};
if (getArguments() != null) {
String fileSharedUri = getArguments().getString("fileSharedUri");
String messageDraft = getArguments().getString("messageDraft");
if (fileSharedUri != null || messageDraft != null)
mShareInfos = new Bundle();
if (fileSharedUri != null || messageDraft != null) mShareInfos = new Bundle();
if (fileSharedUri != null) {
LinphoneActivity.instance().checkAndRequestPermissionsToSendImage();
mShareInfos.putString("fileSharedUri", fileSharedUri);
}
if (messageDraft != null)
mShareInfos.putString("messageDraft", messageDraft);
if (messageDraft != null) mShareInfos.putString("messageDraft", messageDraft);
}
return view;
@ -248,9 +269,11 @@ public class ChatRoomCreationFragment extends Fragment implements View.OnClickLi
LinphoneActivity.instance().selectMenu(FragmentsAvailable.CREATE_CHAT);
}
InputMethodManager inputMethodManager = (InputMethodManager) getActivity().getSystemService(INPUT_METHOD_SERVICE);
InputMethodManager inputMethodManager =
(InputMethodManager) getActivity().getSystemService(INPUT_METHOD_SERVICE);
if (getActivity().getCurrentFocus() != null) {
inputMethodManager.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), 0);
inputMethodManager.hideSoftInputFromWindow(
getActivity().getCurrentFocus().getWindowToken(), 0);
}
}
@ -337,11 +360,12 @@ public class ChatRoomCreationFragment extends Fragment implements View.OnClickLi
private int getIndexOfCa(ContactAddress ca, List<ContactAddress> caList) {
for (int i = 0; i < caList.size(); i++) {
if (ca.getAddress() != null && ca.getAddress().getUsername() != null) {
if (caList.get(i).getAddressAsDisplayableString().compareTo(ca.getAddressAsDisplayableString()) == 0)
return i;
if (caList.get(i)
.getAddressAsDisplayableString()
.compareTo(ca.getAddressAsDisplayableString())
== 0) return i;
} else if (ca.getPhoneNumber() != null && caList.get(i).getPhoneNumber() != null) {
if (ca.getPhoneNumber().compareTo(caList.get(i).getPhoneNumber()) == 0)
return i;
if (ca.getPhoneNumber().compareTo(caList.get(i).getPhoneNumber()) == 0) return i;
}
}
return -1;
@ -353,15 +377,21 @@ public class ChatRoomCreationFragment extends Fragment implements View.OnClickLi
}
private void addSelectedContactAddress(ContactAddress ca) {
View viewContact = LayoutInflater.from(LinphoneActivity.instance()).inflate(R.layout.contact_selected, null);
View viewContact =
LayoutInflater.from(LinphoneActivity.instance())
.inflate(R.layout.contact_selected, null);
if (ca.getContact() != null) {
String name = (ca.getContact().getFullName() != null && !ca.getContact().getFullName().isEmpty()) ?
ca.getContact().getFullName() : (ca.getDisplayName() != null) ?
ca.getDisplayName() : (ca.getUsername() != null) ?
ca.getUsername() : "";
String name =
(ca.getContact().getFullName() != null
&& !ca.getContact().getFullName().isEmpty())
? ca.getContact().getFullName()
: (ca.getDisplayName() != null)
? ca.getDisplayName()
: (ca.getUsername() != null) ? ca.getUsername() : "";
((TextView) viewContact.findViewById(R.id.sipUri)).setText(name);
} else {
((TextView) viewContact.findViewById(R.id.sipUri)).setText(ca.getAddressAsDisplayableString());
((TextView) viewContact.findViewById(R.id.sipUri))
.setText(ca.getAddressAsDisplayableString());
}
View removeContact = viewContact.findViewById(R.id.contactChatDelete);
removeContact.setTag(ca);
@ -390,7 +420,6 @@ public class ChatRoomCreationFragment extends Fragment implements View.OnClickLi
}
mSearchAdapter.setContactsSelectedList(mContactsSelected);
mContactsSelectedLayout.invalidate();
}
private void addOrRemoveContactFromSelection(ContactAddress ca) {
@ -443,9 +472,25 @@ public class ChatRoomCreationFragment extends Fragment implements View.OnClickLi
} else if (id == R.id.next) {
if (mChatRoomAddress == null && mChatRoomSubject == null) {
mContactsSelectedLayout.removeAllViews();
LinphoneActivity.instance().goToChatGroupInfos(null, mContactsSelected, null, true, false, mShareInfos, mSecurityToggle.isChecked());
LinphoneActivity.instance()
.goToChatGroupInfos(
null,
mContactsSelected,
null,
true,
false,
mShareInfos,
mSecurityToggle.isChecked());
} else {
LinphoneActivity.instance().goToChatGroupInfos(mChatRoomAddress, mContactsSelected, mChatRoomSubject, true, true, mShareInfos, mSecurityToggle.isChecked());
LinphoneActivity.instance()
.goToChatGroupInfos(
mChatRoomAddress,
mContactsSelected,
mChatRoomSubject,
true,
true,
mShareInfos,
mSecurityToggle.isChecked());
}
} else if (id == R.id.clearSearchField) {
mSearchField.setQuery("", false);
@ -464,32 +509,47 @@ public class ChatRoomCreationFragment extends Fragment implements View.OnClickLi
boolean createEncryptedChatRoom = mSecurityToggle.isChecked();
if (lpc == null || lpc.getConferenceFactoryUri() == null || mCreateGroupChatRoom == false) {
if (createEncryptedChatRoom && lpc != null && lpc.getConferenceFactoryUri() != null) {
mChatRoom = lc.findOneToOneChatRoom(lpc.getIdentityAddress(), ca.getAddress(), true);
mChatRoom =
lc.findOneToOneChatRoom(lpc.getIdentityAddress(), ca.getAddress(), true);
if (mChatRoom != null) {
LinphoneActivity.instance().goToChat(mChatRoom.getPeerAddress().asStringUriOnly(), mShareInfos);
LinphoneActivity.instance()
.goToChat(mChatRoom.getPeerAddress().asStringUriOnly(), mShareInfos);
} else {
mChatRoom = lc.createClientGroupChatRoom(getString(R.string.dummy_group_chat_subject), !createEncryptedChatRoom, createEncryptedChatRoom);
mChatRoom =
lc.createClientGroupChatRoom(
getString(R.string.dummy_group_chat_subject),
!createEncryptedChatRoom,
createEncryptedChatRoom);
mChatRoom.addListener(mChatRoomCreationListener);
Address participants[] = new Address[1];
participants[0] = ca.getAddress();
mChatRoom.addParticipants(participants);
}
} else {
if (lpc != null && lpc.getConferenceFactoryUri() != null && !LinphonePreferences.instance().useBasicChatRoomFor1To1()) {
mChatRoom = lc.findOneToOneChatRoom(lpc.getIdentityAddress(), ca.getAddress(), false);
if (lpc != null
&& lpc.getConferenceFactoryUri() != null
&& !LinphonePreferences.instance().useBasicChatRoomFor1To1()) {
mChatRoom =
lc.findOneToOneChatRoom(
lpc.getIdentityAddress(), ca.getAddress(), false);
if (mChatRoom == null) {
mWaitLayout.setVisibility(View.VISIBLE);
mChatRoom = lc.createClientGroupChatRoom(getString(R.string.dummy_group_chat_subject), true);
mChatRoom =
lc.createClientGroupChatRoom(
getString(R.string.dummy_group_chat_subject), true);
mChatRoom.addListener(mChatRoomCreationListener);
Address participants[] = new Address[1];
participants[0] = ca.getAddress();
mChatRoom.addParticipants(participants);
} else {
LinphoneActivity.instance().goToChat(mChatRoom.getPeerAddress().asStringUriOnly(), mShareInfos);
LinphoneActivity.instance()
.goToChat(
mChatRoom.getPeerAddress().asStringUriOnly(), mShareInfos);
}
} else {
ChatRoom chatRoom = lc.getChatRoom(ca.getAddress());
LinphoneActivity.instance().goToChat(chatRoom.getPeerAddress().asStringUriOnly(), mShareInfos);
LinphoneActivity.instance()
.goToChat(chatRoom.getPeerAddress().asStringUriOnly(), mShareInfos);
}
}
} else {

View file

@ -20,16 +20,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
package org.linphone.chat;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import androidx.recyclerview.widget.RecyclerView;
import android.view.View;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import org.linphone.utils.LinphoneUtils;
import androidx.recyclerview.widget.RecyclerView;
import org.linphone.R;
import org.linphone.contacts.ContactsManager;
import org.linphone.contacts.LinphoneContact;
@ -39,9 +34,11 @@ import org.linphone.core.ChatRoom;
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 {
public class ChatRoomViewHolder extends RecyclerView.ViewHolder
implements View.OnClickListener, View.OnLongClickListener {
public TextView lastMessageView;
public TextView date;
public TextView displayName;
@ -82,7 +79,11 @@ public class ChatRoomViewHolder extends RecyclerView.ViewHolder implements View.
}
}
lastMessageView.setText(getSender(mRoom) + messageContent);
date.setText(LinphoneUtils.timestampToHumanDate(mContext, mRoom.getLastUpdateTime(), R.string.messages_list_date_format));
date.setText(
LinphoneUtils.timestampToHumanDate(
mContext,
mRoom.getLastUpdateTime(),
R.string.messages_list_date_format));
} else {
date.setText("");
lastMessageView.setText("");
@ -108,18 +109,24 @@ public class ChatRoomViewHolder extends RecyclerView.ViewHolder implements View.
public String getSender(ChatRoom mRoom) {
if (mRoom.getLastMessageInHistory() != null) {
LinphoneContact contact = ContactsManager.getInstance().findContactFromAddress(mRoom.getLastMessageInHistory().getFromAddress());
LinphoneContact contact =
ContactsManager.getInstance()
.findContactFromAddress(
mRoom.getLastMessageInHistory().getFromAddress());
if (contact != null) {
return (contact.getFullName() + mContext.getString(R.string.separator));
}
return (LinphoneUtils.getAddressDisplayName(mRoom.getLastMessageInHistory().getFromAddress()) + mContext.getString(R.string.separator));
return (LinphoneUtils.getAddressDisplayName(
mRoom.getLastMessageInHistory().getFromAddress())
+ mContext.getString(R.string.separator));
}
return null;
}
public String getContact(ChatRoom mRoom) {
Address contactAddress = mRoom.getPeerAddress();
if (mRoom.hasCapability(ChatRoomCapabilities.OneToOne.toInt()) && mRoom.getParticipants().length > 0) {
if (mRoom.hasCapability(ChatRoomCapabilities.OneToOne.toInt())
&& mRoom.getParticipants().length > 0) {
contactAddress = mRoom.getParticipants()[0].getAddress();
}
@ -138,11 +145,15 @@ public class ChatRoomViewHolder extends RecyclerView.ViewHolder implements View.
if (mRoom.hasCapability(ChatRoomCapabilities.OneToOne.toInt())) {
LinphoneContact contact = null;
if (mRoom.hasCapability(ChatRoomCapabilities.Basic.toInt())) {
contact = ContactsManager.getInstance().findContactFromAddress(mRoom.getPeerAddress());
contact =
ContactsManager.getInstance()
.findContactFromAddress(mRoom.getPeerAddress());
} else {
Participant[] participants = mRoom.getParticipants();
if (participants != null && participants.length > 0) {
contact = ContactsManager.getInstance().findContactFromAddress(participants[0].getAddress());
contact =
ContactsManager.getInstance()
.findContactFromAddress(participants[0].getAddress());
}
}
if (contact != null) {
@ -156,9 +167,9 @@ public class ChatRoomViewHolder extends RecyclerView.ViewHolder implements View.
if (mRoom.hasCapability(ChatRoomCapabilities.Encrypted.toInt())) {
Participant[] participants = mRoom.getParticipants();
if (participants.length > 0) {
remoteAddr = participants[0].getAddress();
} else {
//TODO: error
remoteAddr = participants[0].getAddress();
} else {
// TODO: error
}
} else {
remoteAddr = mRoom.getPeerAddress();
@ -185,4 +196,4 @@ public class ChatRoomViewHolder extends RecyclerView.ViewHolder implements View.
boolean onItemLongClicked(int position);
}
}
}

View file

@ -23,17 +23,15 @@ import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import org.linphone.LinphoneManager;
import org.linphone.core.ChatRoom;
import org.linphone.utils.SelectableAdapter;
import org.linphone.utils.SelectableHelper;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.linphone.LinphoneManager;
import org.linphone.core.ChatRoom;
import org.linphone.utils.SelectableAdapter;
import org.linphone.utils.SelectableHelper;
public class ChatRoomsAdapter extends SelectableAdapter<ChatRoomViewHolder> {
private Context mContext;
@ -41,7 +39,12 @@ public class ChatRoomsAdapter extends SelectableAdapter<ChatRoomViewHolder> {
private int mItemResource;
private ChatRoomViewHolder.ClickListener mClickListener;
public ChatRoomsAdapter(Context context, int itemResource, List<ChatRoom> rooms, ChatRoomViewHolder.ClickListener clickListener, SelectableHelper helper) {
public ChatRoomsAdapter(
Context context,
int itemResource,
List<ChatRoom> rooms,
ChatRoomViewHolder.ClickListener clickListener,
SelectableHelper helper) {
super(helper);
mClickListener = clickListener;
mRooms = rooms;
@ -51,8 +54,7 @@ public class ChatRoomsAdapter extends SelectableAdapter<ChatRoomViewHolder> {
@Override
public ChatRoomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(mItemResource, parent, false);
View view = LayoutInflater.from(parent.getContext()).inflate(mItemResource, parent, false);
return new ChatRoomViewHolder(mContext, view, mClickListener);
}
@ -60,21 +62,26 @@ public class ChatRoomsAdapter extends SelectableAdapter<ChatRoomViewHolder> {
public void onBindViewHolder(ChatRoomViewHolder holder, int position) {
ChatRoom room = mRooms.get(position);
holder.delete.setVisibility(isEditionEnabled() ? View.VISIBLE : View.INVISIBLE);
holder.unreadMessages.setVisibility(isEditionEnabled() ? View.INVISIBLE : (room.getUnreadMessagesCount() > 0 ? View.VISIBLE : View.INVISIBLE));
holder.unreadMessages.setVisibility(
isEditionEnabled()
? View.INVISIBLE
: (room.getUnreadMessagesCount() > 0 ? View.VISIBLE : View.INVISIBLE));
holder.delete.setChecked(isSelected(position));
holder.bindChatRoom(room);
}
public void refresh() {
mRooms = new ArrayList<>(Arrays.asList(LinphoneManager.getLc().getChatRooms()));
Collections.sort(mRooms, new Comparator<ChatRoom>() {
public int compare(ChatRoom cr1, ChatRoom cr2) {
long timeDiff = cr1.getLastUpdateTime() - cr2.getLastUpdateTime();
if (timeDiff > 0) return -1;
else if (timeDiff == 0) return 0;
return 1;
}
});
Collections.sort(
mRooms,
new Comparator<ChatRoom>() {
public int compare(ChatRoom cr1, ChatRoom cr2) {
long timeDiff = cr1.getLastUpdateTime() - cr2.getLastUpdateTime();
if (timeDiff > 0) return -1;
else if (timeDiff == 0) return 0;
return 1;
}
});
notifyDataSetChanged();
}
@ -83,10 +90,7 @@ public class ChatRoomsAdapter extends SelectableAdapter<ChatRoomViewHolder> {
notifyDataSetChanged();
}
/**
* Adapter's methods
*/
/** Adapter's methods */
@Override
public int getItemCount() {
return mRooms.size();

View file

@ -19,22 +19,27 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
package org.linphone.chat;
import static org.linphone.fragments.FragmentsAvailable.CHAT_LIST;
import android.app.Fragment;
import android.content.Context;
import android.os.Bundle;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.linphone.LinphoneActivity;
import org.linphone.LinphoneManager;
import org.linphone.R;
import org.linphone.LinphoneActivity;
import org.linphone.contacts.ContactsManager;
import org.linphone.contacts.ContactsUpdatedListener;
import org.linphone.core.ChatMessage;
@ -47,14 +52,10 @@ import org.linphone.core.ProxyConfig;
import org.linphone.fragments.FragmentsAvailable;
import org.linphone.utils.SelectableHelper;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static org.linphone.fragments.FragmentsAvailable.CHAT_LIST;
public class ChatRoomsFragment extends Fragment implements ContactsUpdatedListener, ChatRoomViewHolder.ClickListener, SelectableHelper.DeleteListener {
public class ChatRoomsFragment extends Fragment
implements ContactsUpdatedListener,
ChatRoomViewHolder.ClickListener,
SelectableHelper.DeleteListener {
private RecyclerView mChatRoomsList;
private ImageView mNewDiscussionButton, mNewGroupDiscussionButton, mBackToCallButton;
@ -69,7 +70,8 @@ public class ChatRoomsFragment extends Fragment implements ContactsUpdatedListen
private TextView mNoChatHistory;
@Override
public View onCreateView(final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
public View onCreateView(
final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mRooms = new ArrayList<>(Arrays.asList(LinphoneManager.getLc().getChatRooms()));
@ -85,7 +87,9 @@ public class ChatRoomsFragment extends Fragment implements ContactsUpdatedListen
mNoChatHistory = view.findViewById(R.id.noChatHistory);
mSelectionHelper = new SelectableHelper(view, this);
mChatRoomsAdapter = new ChatRoomsAdapter(mContext, R.layout.chatlist_cell, mRooms, this, mSelectionHelper);
mChatRoomsAdapter =
new ChatRoomsAdapter(
mContext, R.layout.chatlist_cell, mRooms, this, mSelectionHelper);
mChatRoomsList.setAdapter(mChatRoomsAdapter);
mSelectionHelper.setAdapter(mChatRoomsAdapter);
@ -94,66 +98,81 @@ public class ChatRoomsFragment extends Fragment implements ContactsUpdatedListen
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(mContext);
mChatRoomsList.setLayoutManager(layoutManager);
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mChatRoomsList.getContext(),
((LinearLayoutManager) layoutManager).getOrientation());
dividerItemDecoration.setDrawable(getActivity().getApplicationContext().getResources().getDrawable(R.drawable.divider));
DividerItemDecoration dividerItemDecoration =
new DividerItemDecoration(
mChatRoomsList.getContext(),
((LinearLayoutManager) layoutManager).getOrientation());
dividerItemDecoration.setDrawable(
getActivity()
.getApplicationContext()
.getResources()
.getDrawable(R.drawable.divider));
mChatRoomsList.addItemDecoration(dividerItemDecoration);
mWaitLayout.setVisibility(View.GONE);
mNewDiscussionButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
LinphoneActivity.instance().goToChatCreator(null, null, null, false, null, false, false);
}
});
mNewGroupDiscussionButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
LinphoneActivity.instance().goToChatCreator(null, null, null, false, null, true, false);
}
});
mBackToCallButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
LinphoneActivity.instance().resetClassicMenuLayoutAndGoBackToCallIfStillRunning();
}
});
mListener = new CoreListenerStub() {
@Override
public void onMessageReceived(Core lc, ChatRoom cr, ChatMessage message) {
refreshChatRoomsList();
}
@Override
public void onChatRoomStateChanged(Core lc, ChatRoom cr, ChatRoom.State state) {
if (state == ChatRoom.State.Created) {
refreshChatRoomsList();
}
}
};
mChatRoomListener = new ChatRoomListenerStub() {
@Override
public void onStateChanged(ChatRoom room, ChatRoom.State state) {
super.onStateChanged(room, state);
if (state == ChatRoom.State.Deleted || state == ChatRoom.State.TerminationFailed) {
mChatRoomDeletionPendingCount -= 1;
if (state == ChatRoom.State.TerminationFailed) {
//TODO error message
mNewDiscussionButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
LinphoneActivity.instance()
.goToChatCreator(null, null, null, false, null, false, false);
}
});
if (mChatRoomDeletionPendingCount == 0) {
mWaitLayout.setVisibility(View.GONE);
mNewGroupDiscussionButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
LinphoneActivity.instance()
.goToChatCreator(null, null, null, false, null, true, false);
}
});
mBackToCallButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
LinphoneActivity.instance()
.resetClassicMenuLayoutAndGoBackToCallIfStillRunning();
}
});
mListener =
new CoreListenerStub() {
@Override
public void onMessageReceived(Core lc, ChatRoom cr, ChatMessage message) {
refreshChatRoomsList();
}
}
}
};
@Override
public void onChatRoomStateChanged(Core lc, ChatRoom cr, ChatRoom.State state) {
if (state == ChatRoom.State.Created) {
refreshChatRoomsList();
}
}
};
mChatRoomListener =
new ChatRoomListenerStub() {
@Override
public void onStateChanged(ChatRoom room, ChatRoom.State state) {
super.onStateChanged(room, state);
if (state == ChatRoom.State.Deleted
|| state == ChatRoom.State.TerminationFailed) {
mChatRoomDeletionPendingCount -= 1;
if (state == ChatRoom.State.TerminationFailed) {
// TODO error message
}
if (mChatRoomDeletionPendingCount == 0) {
mWaitLayout.setVisibility(View.GONE);
refreshChatRoomsList();
}
}
}
};
return view;
}
@ -178,7 +197,8 @@ public class ChatRoomsFragment extends Fragment implements ContactsUpdatedListen
private void refreshChatRoomsList() {
mChatRoomsAdapter.refresh();
mNoChatHistory.setVisibility(mChatRoomsAdapter.getItemCount() == 0 ? View.VISIBLE : View.GONE);
mNoChatHistory.setVisibility(
mChatRoomsAdapter.getItemCount() == 0 ? View.VISIBLE : View.GONE);
}
public void displayFirstChat() {
@ -220,7 +240,8 @@ public class ChatRoomsFragment extends Fragment implements ContactsUpdatedListen
refreshChatRoomsList();
ProxyConfig lpc = lc.getDefaultProxyConfig();
mNewGroupDiscussionButton.setVisibility((lpc != null && lpc.getConferenceFactoryUri() != null) ? View.VISIBLE : View.GONE);
mNewGroupDiscussionButton.setVisibility(
(lpc != null && lpc.getConferenceFactoryUri() != null) ? View.VISIBLE : View.GONE);
}
@Override
@ -247,7 +268,8 @@ public class ChatRoomsFragment extends Fragment implements ContactsUpdatedListen
if (message.getAppdata() != null && !message.isOutgoing()) {
File file = new File(message.getAppdata());
if (file.exists()) {
file.delete(); // Delete downloaded file from incoming message that will be deleted
file.delete(); // Delete downloaded file from incoming message that
// will be deleted
}
}
}
@ -259,17 +281,18 @@ public class ChatRoomsFragment extends Fragment implements ContactsUpdatedListen
if (mChatRoomDeletionPendingCount > 0) {
mWaitLayout.setVisibility(View.VISIBLE);
}
LinphoneActivity.instance().displayMissedChats(LinphoneManager.getInstance().getUnreadMessageCount());
LinphoneActivity.instance()
.displayMissedChats(LinphoneManager.getInstance().getUnreadMessageCount());
}
@Override
public void onContactsUpdated() {
if (!LinphoneActivity.isInstanciated() || LinphoneActivity.instance().getCurrentFragment() != CHAT_LIST)
return;
if (!LinphoneActivity.isInstanciated()
|| LinphoneActivity.instance().getCurrentFragment() != CHAT_LIST) return;
ChatRoomsAdapter adapter = (ChatRoomsAdapter) mChatRoomsList.getAdapter();
if (adapter != null) {
adapter.notifyDataSetChanged();
}
}
}
}

View file

@ -46,8 +46,7 @@ public abstract class ChatScrollListener extends RecyclerView.OnScrollListener {
for (int i = 0; i < lastVisibleItemPositions.length; i++) {
if (i == 0) {
maxSize = lastVisibleItemPositions[i];
}
else if (lastVisibleItemPositions[i] > maxSize) {
} else if (lastVisibleItemPositions[i] > maxSize) {
maxSize = lastVisibleItemPositions[i];
}
}

View file

@ -22,7 +22,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import org.linphone.R;
public class DeviceChildViewHolder {

View file

@ -23,7 +23,6 @@ import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import org.linphone.R;
public class DeviceGroupViewHolder {

View file

@ -24,8 +24,8 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import org.linphone.utils.LinphoneUtils;
import java.util.ArrayList;
import java.util.List;
import org.linphone.R;
import org.linphone.contacts.ContactsManager;
import org.linphone.contacts.LinphoneContact;
@ -33,11 +33,9 @@ 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;
import java.util.ArrayList;
import java.util.List;
public class DevicesAdapter extends BaseExpandableListAdapter {
private Context mContext;
private List<Participant> mParticipants;
@ -56,7 +54,8 @@ public class DevicesAdapter extends BaseExpandableListAdapter {
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View view, ViewGroup viewGroup) {
public View getGroupView(
int groupPosition, boolean isExpanded, View view, ViewGroup viewGroup) {
if (mOnlyDisplayChildsAsGroups) {
ParticipantDevice device = (ParticipantDevice) getGroup(groupPosition);
@ -76,7 +75,7 @@ public class DevicesAdapter extends BaseExpandableListAdapter {
}
Address deviceAddress = device.getAddress();
holder.deviceName.setText(deviceAddress.getUriParam("gr")); //TODO
holder.deviceName.setText(deviceAddress.getUriParam("gr")); // TODO
ChatRoomSecurityLevel level = device.getSecurityLevel();
switch (level) {
@ -111,24 +110,29 @@ public class DevicesAdapter extends BaseExpandableListAdapter {
}
Address participantAddress = participant.getAddress();
LinphoneContact contact = ContactsManager.getInstance().findContactFromAddress(participantAddress);
LinphoneContact contact =
ContactsManager.getInstance().findContactFromAddress(participantAddress);
if (contact != null) {
ContactAvatar.displayAvatar(contact, participant.getSecurityLevel(), holder.avatarLayout);
ContactAvatar.displayAvatar(
contact, participant.getSecurityLevel(), holder.avatarLayout);
holder.participantName.setText(contact.getFullName());
} else {
String displayName = LinphoneUtils.getAddressDisplayName(participantAddress);
ContactAvatar.displayAvatar(displayName, participant.getSecurityLevel(), holder.avatarLayout);
ContactAvatar.displayAvatar(
displayName, participant.getSecurityLevel(), holder.avatarLayout);
holder.participantName.setText(displayName);
}
holder.groupExpander.setImageResource(isExpanded ? R.drawable.chevron_list_open : R.drawable.chevron_list_close);
holder.groupExpander.setImageResource(
isExpanded ? R.drawable.chevron_list_open : R.drawable.chevron_list_close);
}
return view;
}
@Override
public View getChildView(int groupPosition, int childPosition, boolean b, View view, ViewGroup viewGroup) {
public View getChildView(
int groupPosition, int childPosition, boolean b, View view, ViewGroup viewGroup) {
ParticipantDevice device = (ParticipantDevice) getChild(groupPosition, childPosition);
DeviceChildViewHolder holder = null;
@ -147,7 +151,7 @@ public class DevicesAdapter extends BaseExpandableListAdapter {
}
Address deviceAddress = device.getAddress();
holder.deviceName.setText(deviceAddress.getUriParam("gr")); //TODO
holder.deviceName.setText(deviceAddress.getUriParam("gr")); // TODO
ChatRoomSecurityLevel level = device.getSecurityLevel();
switch (level) {
@ -170,19 +174,25 @@ public class DevicesAdapter extends BaseExpandableListAdapter {
@Override
public int getGroupCount() {
if (mParticipants.size() == 0) return 0;
return mOnlyDisplayChildsAsGroups ? mParticipants.get(0).getDevices().length : mParticipants.size();
return mOnlyDisplayChildsAsGroups
? mParticipants.get(0).getDevices().length
: mParticipants.size();
}
@Override
public int getChildrenCount(int groupPosition) {
if (mParticipants.size() == 0) return 0;
return mOnlyDisplayChildsAsGroups ? 0 : mParticipants.get(groupPosition).getDevices().length;
return mOnlyDisplayChildsAsGroups
? 0
: mParticipants.get(groupPosition).getDevices().length;
}
@Override
public Object getGroup(int groupPosition) {
if (mParticipants.size() == 0) return null;
return mOnlyDisplayChildsAsGroups ? mParticipants.get(0).getDevices()[groupPosition] : mParticipants.get(groupPosition);
return mOnlyDisplayChildsAsGroups
? mParticipants.get(0).getDevices()[groupPosition]
: mParticipants.get(groupPosition);
}
@Override

View file

@ -21,18 +21,17 @@ package org.linphone.chat;
import android.app.Fragment;
import android.os.Bundle;
import androidx.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ExpandableListView;
import android.widget.ImageView;
import android.widget.TextView;
import org.linphone.LinphoneManager;
import org.linphone.utils.LinphoneUtils;
import org.linphone.R;
import androidx.annotation.Nullable;
import java.util.Arrays;
import org.linphone.LinphoneActivity;
import org.linphone.LinphoneManager;
import org.linphone.R;
import org.linphone.contacts.ContactsManager;
import org.linphone.contacts.LinphoneContact;
import org.linphone.core.Address;
@ -41,8 +40,7 @@ import org.linphone.core.ChatRoomCapabilities;
import org.linphone.core.Core;
import org.linphone.core.ParticipantDevice;
import org.linphone.fragments.FragmentsAvailable;
import java.util.Arrays;
import org.linphone.utils.LinphoneUtils;
public class DevicesFragment extends Fragment {
private LayoutInflater mInflater;
@ -58,7 +56,8 @@ public class DevicesFragment extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
public View onCreateView(
LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
@ -72,26 +71,39 @@ public class DevicesFragment extends Fragment {
mOnlyDisplayChilds = false;
mExpandableList = view.findViewById(R.id.devices_list);
mExpandableList.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView expandableListView, View view, int groupPosition, int childPosition, long l) {
ParticipantDevice device = (ParticipantDevice) mAdapter.getChild(groupPosition, childPosition);
LinphoneManager.getLc().inviteAddress(device.getAddress());
return false;
}
});
mExpandableList.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
@Override
public boolean onGroupClick(ExpandableListView expandableListView, View view, int groupPosition, long l) {
if (mOnlyDisplayChilds) {
// in this case groups are childs, so call on click
ParticipantDevice device = (ParticipantDevice) mAdapter.getGroup(groupPosition);
LinphoneManager.getLc().inviteAddress(device.getAddress());
return true;
}
return false;
}
});
mExpandableList.setOnChildClickListener(
new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(
ExpandableListView expandableListView,
View view,
int groupPosition,
int childPosition,
long l) {
ParticipantDevice device =
(ParticipantDevice) mAdapter.getChild(groupPosition, childPosition);
LinphoneManager.getLc().inviteAddress(device.getAddress());
return false;
}
});
mExpandableList.setOnGroupClickListener(
new ExpandableListView.OnGroupClickListener() {
@Override
public boolean onGroupClick(
ExpandableListView expandableListView,
View view,
int groupPosition,
long l) {
if (mOnlyDisplayChilds) {
// in this case groups are childs, so call on click
ParticipantDevice device =
(ParticipantDevice) mAdapter.getGroup(groupPosition);
LinphoneManager.getLc().inviteAddress(device.getAddress());
return true;
}
return false;
}
});
initChatRoom();
@ -99,16 +111,17 @@ public class DevicesFragment extends Fragment {
initHeader();
mBackButton = view.findViewById(R.id.back);
mBackButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (LinphoneActivity.instance().isTablet()) {
LinphoneActivity.instance().goToChat(mRoomUri, null);
} else {
LinphoneActivity.instance().onBackPressed();
}
}
});
mBackButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View view) {
if (LinphoneActivity.instance().isTablet()) {
LinphoneActivity.instance().goToChat(mRoomUri, null);
} else {
LinphoneActivity.instance().onBackPressed();
}
}
});
return view;
}
@ -135,7 +148,8 @@ public class DevicesFragment extends Fragment {
if (mRoom.getParticipants().length > 0) {
remoteParticipantAddr = mRoom.getParticipants()[0].getAddress();
}
LinphoneContact c = ContactsManager.getInstance().findContactFromAddress(remoteParticipantAddr);
LinphoneContact c =
ContactsManager.getInstance().findContactFromAddress(remoteParticipantAddr);
String displayName;
if (c != null) {
displayName = c.getFullName();

View file

@ -19,8 +19,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
package org.linphone.chat;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -28,7 +26,10 @@ import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
import org.linphone.R;
import org.linphone.contacts.ContactAddress;
import org.linphone.contacts.LinphoneContact;
@ -36,9 +37,6 @@ import org.linphone.core.ChatRoom;
import org.linphone.core.Participant;
import org.linphone.views.ContactAvatar;
import java.util.ArrayList;
import java.util.List;
public class GroupInfoAdapter extends RecyclerView.Adapter<GroupInfoAdapter.ViewHolder> {
public static class ViewHolder extends RecyclerView.ViewHolder {
@ -63,7 +61,8 @@ public class GroupInfoAdapter extends RecyclerView.Adapter<GroupInfoAdapter.View
private boolean mHideAdminFeatures;
private ChatRoom mChatRoom;
public GroupInfoAdapter(List<ContactAddress> items, boolean hideAdminFeatures, boolean isCreation) {
public GroupInfoAdapter(
List<ContactAddress> items, boolean hideAdminFeatures, boolean isCreation) {
mItems = items;
mHideAdminFeatures = hideAdminFeatures || isCreation;
}
@ -71,7 +70,9 @@ public class GroupInfoAdapter extends RecyclerView.Adapter<GroupInfoAdapter.View
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.chat_infos_cell, parent, false);
View v =
LayoutInflater.from(parent.getContext())
.inflate(R.layout.chat_infos_cell, parent, false);
return new ViewHolder(v);
}
@ -80,8 +81,10 @@ public class GroupInfoAdapter extends RecyclerView.Adapter<GroupInfoAdapter.View
final ContactAddress ca = (ContactAddress) getItem(position);
LinphoneContact c = ca.getContact();
holder.name.setText((c.getFullName() != null) ? c.getFullName() :
(ca.getDisplayName() != null) ? ca.getDisplayName() : ca.getUsername());
holder.name.setText(
(c.getFullName() != null)
? c.getFullName()
: (ca.getDisplayName() != null) ? ca.getDisplayName() : ca.getUsername());
if (c != null) {
ContactAvatar.displayAvatar(c, holder.avatarLayout);
@ -89,42 +92,47 @@ public class GroupInfoAdapter extends RecyclerView.Adapter<GroupInfoAdapter.View
ContactAvatar.displayAvatar(holder.name.getText().toString(), holder.avatarLayout);
}
holder.delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mDeleteListener != null) {
mDeleteListener.onClick(view);
}
}
});
holder.delete.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mDeleteListener != null) {
mDeleteListener.onClick(view);
}
}
});
holder.delete.setTag(ca);
holder.isAdmin.setVisibility(ca.isAdmin() ? View.VISIBLE : View.GONE);
holder.isNotAdmin.setVisibility(ca.isAdmin() ? View.GONE : View.VISIBLE);
holder.isAdmin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
holder.isNotAdmin.setVisibility(View.VISIBLE);
holder.isAdmin.setVisibility(View.GONE);
ca.setAdmin(false);
}
});
holder.isAdmin.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View view) {
holder.isNotAdmin.setVisibility(View.VISIBLE);
holder.isAdmin.setVisibility(View.GONE);
ca.setAdmin(false);
}
});
holder.isNotAdmin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
holder.isNotAdmin.setVisibility(View.GONE);
holder.isAdmin.setVisibility(View.VISIBLE);
ca.setAdmin(true);
}
});
holder.isNotAdmin.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View view) {
holder.isNotAdmin.setVisibility(View.GONE);
holder.isAdmin.setVisibility(View.VISIBLE);
ca.setAdmin(true);
}
});
holder.delete.setVisibility(View.VISIBLE);
if (mHideAdminFeatures) {
holder.delete.setVisibility(View.INVISIBLE);
holder.isAdmin.setOnClickListener(null); // Do not allow not admin to remove it's rights but display admins
holder.isNotAdmin.setVisibility(View.GONE); // Hide not admin button for not admin participants
holder.isAdmin.setOnClickListener(
null); // Do not allow not admin to remove it's rights but display admins
holder.isNotAdmin.setVisibility(
View.GONE); // Hide not admin button for not admin participants
} else if (mChatRoom != null) {
boolean found = false;
for (Participant p : mChatRoom.getParticipants()) {
@ -134,7 +142,9 @@ public class GroupInfoAdapter extends RecyclerView.Adapter<GroupInfoAdapter.View
}
}
if (!found) {
holder.isNotAdmin.setVisibility(View.GONE); // Hide not admin button for participant not yet added so even if user click it it won't have any effect
holder.isNotAdmin.setVisibility(
View.GONE); // Hide not admin button for participant not yet added so
// even if user click it it won't have any effect
}
}
}

View file

@ -19,13 +19,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
package org.linphone.chat;
import static android.content.Context.INPUT_METHOD_SERVICE;
import android.app.Dialog;
import android.app.Fragment;
import android.content.Context;
import android.os.Bundle;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
@ -37,11 +36,13 @@ import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import org.linphone.LinphoneManager;
import org.linphone.utils.LinphoneUtils;
import org.linphone.R;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import org.linphone.LinphoneActivity;
import org.linphone.LinphoneManager;
import org.linphone.R;
import org.linphone.contacts.ContactAddress;
import org.linphone.contacts.ContactsManager;
import org.linphone.contacts.LinphoneContact;
@ -54,10 +55,7 @@ import org.linphone.core.EventLog;
import org.linphone.core.Participant;
import org.linphone.fragments.FragmentsAvailable;
import org.linphone.mediastream.Log;
import java.util.ArrayList;
import static android.content.Context.INPUT_METHOD_SERVICE;
import org.linphone.utils.LinphoneUtils;
public class GroupInfoFragment extends Fragment implements ChatRoomListener {
private ImageView mBackButton, mConfirmButton, mAddParticipantsButton;
@ -84,7 +82,8 @@ public class GroupInfoFragment extends Fragment implements ChatRoomListener {
private boolean mIsEncryptionEnabled;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mInflater = inflater;
View view = inflater.inflate(R.layout.chat_infos, container, false);
@ -93,7 +92,8 @@ public class GroupInfoFragment extends Fragment implements ChatRoomListener {
}
mContext = getActivity().getApplicationContext();
mParticipants = (ArrayList<ContactAddress>) getArguments().getSerializable("ContactAddress");
mParticipants =
(ArrayList<ContactAddress>) getArguments().getSerializable("ContactAddress");
mGroupChatRoomAddress = null;
mChatRoom = null;
@ -119,213 +119,271 @@ public class GroupInfoFragment extends Fragment implements ChatRoomListener {
mParticipantsList = view.findViewById(R.id.chat_room_participants);
mAdapter = new GroupInfoAdapter(mParticipants, !mIsEditionEnabled, !mIsAlreadyCreatedGroup);
mAdapter.setOnDeleteClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
ContactAddress ca = (ContactAddress) view.getTag();
mParticipants.remove(ca);
mAdapter.updateDataSet(mParticipants);
mParticipantsList.setAdapter(mAdapter);
mConfirmButton.setEnabled(mSubjectField.getText().length() > 0 && mParticipants.size() > 0);
}
});
mAdapter.setOnDeleteClickListener(
new View.OnClickListener() {
@Override
public void onClick(View view) {
ContactAddress ca = (ContactAddress) view.getTag();
mParticipants.remove(ca);
mAdapter.updateDataSet(mParticipants);
mParticipantsList.setAdapter(mAdapter);
mConfirmButton.setEnabled(
mSubjectField.getText().length() > 0 && mParticipants.size() > 0);
}
});
mParticipantsList.setAdapter(mAdapter);
mAdapter.setChatRoom(mChatRoom);
layoutManager = new LinearLayoutManager(mContext);
mParticipantsList.setLayoutManager(layoutManager);
//Divider between items
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mParticipantsList.getContext(),
layoutManager.getOrientation());
// Divider between items
DividerItemDecoration dividerItemDecoration =
new DividerItemDecoration(
mParticipantsList.getContext(), layoutManager.getOrientation());
dividerItemDecoration.setDrawable(mContext.getResources().getDrawable(R.drawable.divider));
mParticipantsList.addItemDecoration(dividerItemDecoration);
String fileSharedUri = getArguments().getString("fileSharedUri");
String messageDraft = getArguments().getString("messageDraft");
if (fileSharedUri != null || messageDraft != null)
mShareInfos = new Bundle();
if (fileSharedUri != null || messageDraft != null) mShareInfos = new Bundle();
if (fileSharedUri != null)
mShareInfos.putString("fileSharedUri", fileSharedUri);
if (fileSharedUri != null) mShareInfos.putString("fileSharedUri", fileSharedUri);
if (messageDraft != null)
mShareInfos.putString("messageDraft", messageDraft);
if (messageDraft != null) mShareInfos.putString("messageDraft", messageDraft);
mBackButton = view.findViewById(R.id.back);
mBackButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mIsAlreadyCreatedGroup) {
if (LinphoneActivity.instance().isTablet()) {
LinphoneActivity.instance().goToChat(mGroupChatRoomAddress.asStringUriOnly(), mShareInfos);
} else {
getFragmentManager().popBackStack();
mBackButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mIsAlreadyCreatedGroup) {
if (LinphoneActivity.instance().isTablet()) {
LinphoneActivity.instance()
.goToChat(
mGroupChatRoomAddress.asStringUriOnly(),
mShareInfos);
} else {
getFragmentManager().popBackStack();
}
} else {
LinphoneActivity.instance()
.goToChatCreator(
null,
mParticipants,
null,
true,
mShareInfos,
true,
mIsEncryptionEnabled);
}
}
} else {
LinphoneActivity.instance().goToChatCreator(null, mParticipants, null, true, mShareInfos, true, mIsEncryptionEnabled);
}
}
});
});
mConfirmButton = view.findViewById(R.id.confirm);
mLeaveGroupButton = view.findViewById(R.id.leaveGroupLayout);
mLeaveGroupButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
final Dialog dialog = LinphoneActivity.instance().displayDialog(getString(R.string.chat_room_leave_dialog));
Button delete = dialog.findViewById(R.id.dialog_delete_button);
delete.setText(getString(R.string.chat_room_leave_button));
Button cancel = dialog.findViewById(R.id.dialog_cancel_button);
delete.setOnClickListener(new View.OnClickListener() {
mLeaveGroupButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mChatRoom != null) {
mChatRoom.leave();
LinphoneActivity.instance().goToChat(mGroupChatRoomAddress.asString(), null);
} else {
Log.e("Can't leave, chatRoom for address " + mGroupChatRoomAddress.asString() + " is null...");
}
dialog.dismiss();
}
});
final Dialog dialog =
LinphoneActivity.instance()
.displayDialog(getString(R.string.chat_room_leave_dialog));
Button delete = dialog.findViewById(R.id.dialog_delete_button);
delete.setText(getString(R.string.chat_room_leave_button));
Button cancel = dialog.findViewById(R.id.dialog_cancel_button);
cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dialog.dismiss();
delete.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mChatRoom != null) {
mChatRoom.leave();
LinphoneActivity.instance()
.goToChat(
mGroupChatRoomAddress.asString(), null);
} else {
Log.e(
"Can't leave, chatRoom for address "
+ mGroupChatRoomAddress.asString()
+ " is null...");
}
dialog.dismiss();
}
});
cancel.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View view) {
dialog.dismiss();
}
});
dialog.show();
}
});
dialog.show();
}
});
mLeaveGroupButton.setVisibility(mIsAlreadyCreatedGroup && mChatRoom.hasBeenLeft() ? View.GONE : mIsAlreadyCreatedGroup ? View.VISIBLE : View.GONE);
mLeaveGroupButton.setVisibility(
mIsAlreadyCreatedGroup && mChatRoom.hasBeenLeft()
? View.GONE
: mIsAlreadyCreatedGroup ? View.VISIBLE : View.GONE);
mAddParticipantsLayout = view.findViewById(R.id.addParticipantsLayout);
mAddParticipantsLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mIsEditionEnabled && mIsAlreadyCreatedGroup) {
LinphoneActivity.instance().goToChatCreator(mGroupChatRoomAddress != null ? mGroupChatRoomAddress.asString() : null, mParticipants, mSubject, !mIsAlreadyCreatedGroup, null, true, mIsEncryptionEnabled);
}
}
});
mAddParticipantsLayout.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mIsEditionEnabled && mIsAlreadyCreatedGroup) {
LinphoneActivity.instance()
.goToChatCreator(
mGroupChatRoomAddress != null
? mGroupChatRoomAddress.asString()
: null,
mParticipants,
mSubject,
!mIsAlreadyCreatedGroup,
null,
true,
mIsEncryptionEnabled);
}
}
});
mAddParticipantsButton = view.findViewById(R.id.addParticipants);
mAddParticipantsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mIsEditionEnabled && mIsAlreadyCreatedGroup) {
LinphoneActivity.instance().goToChatCreator(mGroupChatRoomAddress != null ? mGroupChatRoomAddress.asString() : null, mParticipants, mSubject, !mIsAlreadyCreatedGroup, null, true, mIsEncryptionEnabled);
}
}
});
mAddParticipantsButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mIsEditionEnabled && mIsAlreadyCreatedGroup) {
LinphoneActivity.instance()
.goToChatCreator(
mGroupChatRoomAddress != null
? mGroupChatRoomAddress.asString()
: null,
mParticipants,
mSubject,
!mIsAlreadyCreatedGroup,
null,
true,
mIsEncryptionEnabled);
}
}
});
mAddParticipantsButton.setVisibility(mIsAlreadyCreatedGroup ? View.VISIBLE : View.GONE);
mSubjectField = view.findViewById(R.id.subjectField);
mSubjectField.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
mSubjectField.addTextChangedListener(
new TextWatcher() {
@Override
public void beforeTextChanged(
CharSequence charSequence, int i, int i1, int i2) {}
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable editable) {
mConfirmButton.setEnabled(mSubjectField.getText().length() > 0 && mParticipants.size() > 0);
}
});
@Override
public void afterTextChanged(Editable editable) {
mConfirmButton.setEnabled(
mSubjectField.getText().length() > 0 && mParticipants.size() > 0);
}
});
mSubjectField.setText(mSubject);
mChatRoomCreationListener = new ChatRoomListenerStub() {
@Override
public void onStateChanged(ChatRoom cr, ChatRoom.State newState) {
if (newState == ChatRoom.State.Created) {
mWaitLayout.setVisibility(View.GONE);
// This will remove both the creation fragment and the group info fragment from the back stack
getFragmentManager().popBackStack();
getFragmentManager().popBackStack();
LinphoneActivity.instance().goToChat(cr.getPeerAddress().asStringUriOnly(), mShareInfos);
} else if (newState == ChatRoom.State.CreationFailed) {
mWaitLayout.setVisibility(View.GONE);
LinphoneActivity.instance().displayChatRoomError();
Log.e("Group chat room for address " + cr.getPeerAddress() + " has failed !");
}
}
};
mConfirmButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (!mIsAlreadyCreatedGroup) {
mWaitLayout.setVisibility(View.VISIBLE);
mTempChatRoom = LinphoneManager.getLc().createClientGroupChatRoom(mSubjectField.getText().toString(), false, mIsEncryptionEnabled);
mTempChatRoom.addListener(mChatRoomCreationListener);
for (ContactAddress ca : mParticipants) {
mTempChatRoom.addParticipant(ca.getAddress());
}
} else {
// Subject
String newSubject = mSubjectField.getText().toString();
if (!newSubject.equals(mSubject)) {
mChatRoom.setSubject(newSubject);
mChatRoomCreationListener =
new ChatRoomListenerStub() {
@Override
public void onStateChanged(ChatRoom cr, ChatRoom.State newState) {
if (newState == ChatRoom.State.Created) {
mWaitLayout.setVisibility(View.GONE);
// This will remove both the creation fragment and the group info
// fragment from the back stack
getFragmentManager().popBackStack();
getFragmentManager().popBackStack();
LinphoneActivity.instance()
.goToChat(cr.getPeerAddress().asStringUriOnly(), mShareInfos);
} else if (newState == ChatRoom.State.CreationFailed) {
mWaitLayout.setVisibility(View.GONE);
LinphoneActivity.instance().displayChatRoomError();
Log.e(
"Group chat room for address "
+ cr.getPeerAddress()
+ " has failed !");
}
}
};
// Participants removed
ArrayList<Participant> toRemove = new ArrayList<>();
for (Participant p : mChatRoom.getParticipants()) {
boolean found = false;
for (ContactAddress c : mParticipants) {
if (c.getAddress().weakEqual(p.getAddress())) {
found = true;
break;
mConfirmButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View view) {
if (!mIsAlreadyCreatedGroup) {
mWaitLayout.setVisibility(View.VISIBLE);
mTempChatRoom =
LinphoneManager.getLc()
.createClientGroupChatRoom(
mSubjectField.getText().toString(),
false,
mIsEncryptionEnabled);
mTempChatRoom.addListener(mChatRoomCreationListener);
for (ContactAddress ca : mParticipants) {
mTempChatRoom.addParticipant(ca.getAddress());
}
} else {
// Subject
String newSubject = mSubjectField.getText().toString();
if (!newSubject.equals(mSubject)) {
mChatRoom.setSubject(newSubject);
}
}
if (!found) {
toRemove.add(p);
}
}
Participant[] participantsToRemove = new Participant[toRemove.size()];
toRemove.toArray(participantsToRemove);
mChatRoom.removeParticipants(participantsToRemove);
// Participants added
ArrayList<Address> toAdd = new ArrayList<>();
for (ContactAddress c : mParticipants) {
boolean found = false;
for (Participant p : mChatRoom.getParticipants()) {
if (p.getAddress().weakEqual(c.getAddress())) {
// Admin rights
if (c.isAdmin() != p.isAdmin()) {
mChatRoom.setParticipantAdminStatus(p, c.isAdmin());
// Participants removed
ArrayList<Participant> toRemove = new ArrayList<>();
for (Participant p : mChatRoom.getParticipants()) {
boolean found = false;
for (ContactAddress c : mParticipants) {
if (c.getAddress().weakEqual(p.getAddress())) {
found = true;
break;
}
}
if (!found) {
toRemove.add(p);
}
found = true;
break;
}
}
if (!found) {
Address addr = c.getAddress();
if (addr != null) {
toAdd.add(addr);
} else {
//TODO error
Participant[] participantsToRemove = new Participant[toRemove.size()];
toRemove.toArray(participantsToRemove);
mChatRoom.removeParticipants(participantsToRemove);
// Participants added
ArrayList<Address> toAdd = new ArrayList<>();
for (ContactAddress c : mParticipants) {
boolean found = false;
for (Participant p : mChatRoom.getParticipants()) {
if (p.getAddress().weakEqual(c.getAddress())) {
// Admin rights
if (c.isAdmin() != p.isAdmin()) {
mChatRoom.setParticipantAdminStatus(p, c.isAdmin());
}
found = true;
break;
}
}
if (!found) {
Address addr = c.getAddress();
if (addr != null) {
toAdd.add(addr);
} else {
// TODO error
}
}
}
Address[] participantsToAdd = new Address[toAdd.size()];
toAdd.toArray(participantsToAdd);
mChatRoom.addParticipants(participantsToAdd);
LinphoneActivity.instance()
.goToChat(mGroupChatRoomAddress.asString(), null);
}
}
Address[] participantsToAdd = new Address[toAdd.size()];
toAdd.toArray(participantsToAdd);
mChatRoom.addParticipants(participantsToAdd);
LinphoneActivity.instance().goToChat(mGroupChatRoomAddress.asString(), null);
}
}
});
});
mConfirmButton.setEnabled(mSubjectField.getText().length() > 0 && mParticipants.size() > 0);
if (!mIsEditionEnabled) {
@ -352,9 +410,11 @@ public class GroupInfoFragment extends Fragment implements ChatRoomListener {
LinphoneActivity.instance().selectMenu(FragmentsAvailable.INFO_GROUP_CHAT);
}
InputMethodManager inputMethodManager = (InputMethodManager) getActivity().getSystemService(INPUT_METHOD_SERVICE);
InputMethodManager inputMethodManager =
(InputMethodManager) getActivity().getSystemService(INPUT_METHOD_SERVICE);
if (getActivity().getCurrentFocus() != null) {
inputMethodManager.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), 0);
inputMethodManager.hideSoftInputFromWindow(
getActivity().getCurrentFocus().getWindowToken(), 0);
}
}
@ -404,16 +464,23 @@ public class GroupInfoFragment extends Fragment implements ChatRoomListener {
private void displayMeAdminStatusUpdated() {
if (mAdminStateChangedDialog != null) mAdminStateChangedDialog.dismiss();
mAdminStateChangedDialog = LinphoneActivity.instance().displayDialog(getString(mIsEditionEnabled ? R.string.chat_room_you_are_now_admin : R.string.chat_room_you_are_no_longer_admin));
mAdminStateChangedDialog =
LinphoneActivity.instance()
.displayDialog(
getString(
mIsEditionEnabled
? R.string.chat_room_you_are_now_admin
: R.string.chat_room_you_are_no_longer_admin));
Button cancel = mAdminStateChangedDialog.findViewById(R.id.dialog_cancel_button);
mAdminStateChangedDialog.findViewById(R.id.dialog_delete_button).setVisibility(View.GONE);
cancel.setText(getString(R.string.ok));
cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mAdminStateChangedDialog.dismiss();
}
});
cancel.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View view) {
mAdminStateChangedDialog.dismiss();
}
});
mAdminStateChangedDialog.show();
}
@ -435,12 +502,10 @@ public class GroupInfoFragment extends Fragment implements ChatRoomListener {
}
@Override
public void onConferenceJoined(ChatRoom cr, EventLog event_log) {
}
public void onConferenceJoined(ChatRoom cr, EventLog event_log) {}
@Override
public void onConferenceLeft(ChatRoom cr, EventLog event_log) {
}
public void onConferenceLeft(ChatRoom cr, EventLog event_log) {}
@Override
public void onParticipantAdded(ChatRoom cr, EventLog event_log) {
@ -453,49 +518,32 @@ public class GroupInfoFragment extends Fragment implements ChatRoomListener {
}
@Override
public void onChatMessageShouldBeStored(ChatRoom cr, ChatMessage msg) {
}
public void onChatMessageShouldBeStored(ChatRoom cr, ChatMessage msg) {}
@Override
public void onParticipantsCapabilitiesChecked(ChatRoom cr, Address deviceAddr, Address[] participantsAddr) {
}
public void onParticipantsCapabilitiesChecked(
ChatRoom cr, Address deviceAddr, Address[] participantsAddr) {}
@Override
public void onIsComposingReceived(ChatRoom cr, Address remoteAddr, boolean isComposing) {
}
public void onIsComposingReceived(ChatRoom cr, Address remoteAddr, boolean isComposing) {}
@Override
public void onChatMessageSent(ChatRoom cr, EventLog event_log) {
}
public void onChatMessageSent(ChatRoom cr, EventLog event_log) {}
@Override
public void onConferenceAddressGeneration(ChatRoom cr) {
}
public void onConferenceAddressGeneration(ChatRoom cr) {}
@Override
public void onChatMessageReceived(ChatRoom cr, EventLog event_log) {
}
public void onChatMessageReceived(ChatRoom cr, EventLog event_log) {}
@Override
public void onMessageReceived(ChatRoom cr, ChatMessage msg) {
}
public void onMessageReceived(ChatRoom cr, ChatMessage msg) {}
@Override
public void onParticipantDeviceRemoved(ChatRoom cr, EventLog event_log) {
}
public void onParticipantDeviceRemoved(ChatRoom cr, EventLog event_log) {}
@Override
public void onParticipantDeviceAdded(ChatRoom cr, EventLog event_log) {
}
public void onParticipantDeviceAdded(ChatRoom cr, EventLog event_log) {}
@Override
public void onSecurityEvent(ChatRoom cr, EventLog eventLog) {
@ -503,25 +551,19 @@ public class GroupInfoFragment extends Fragment implements ChatRoomListener {
}
@Override
public void onUndecryptableMessageReceived(ChatRoom cr, ChatMessage msg) {
}
public void onUndecryptableMessageReceived(ChatRoom cr, ChatMessage msg) {}
@Override
public void onStateChanged(ChatRoom cr, ChatRoom.State newState) {
}
public void onStateChanged(ChatRoom cr, ChatRoom.State newState) {}
@Override
public void onParticipantDeviceFetchRequested(ChatRoom cr, Address addr) {
}
public void onParticipantDeviceFetchRequested(ChatRoom cr, Address addr) {}
@Override
public void onParticipantRegistrationSubscriptionRequested(ChatRoom cr, Address participantAddr) {
}
public void onParticipantRegistrationSubscriptionRequested(
ChatRoom cr, Address participantAddr) {}
@Override
public void onParticipantRegistrationUnsubscriptionRequested(ChatRoom cr, Address participantAddr) {
}
public void onParticipantRegistrationUnsubscriptionRequested(
ChatRoom cr, Address participantAddr) {}
}

View file

@ -27,7 +27,7 @@ import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.Nullable;
import org.linphone.LinphoneActivity;
import org.linphone.LinphoneManager;
import org.linphone.R;
@ -43,11 +43,16 @@ import org.linphone.fragments.FragmentsAvailable;
import org.linphone.utils.LinphoneUtils;
import org.linphone.views.ContactAvatar;
import androidx.annotation.Nullable;
public class ImdnFragment extends Fragment {
private LayoutInflater mInflater;
private LinearLayout mRead, mReadHeader, mDelivered, mDeliveredHeader, mSent, mSentHeader, mUndelivered, mUndeliveredHeader;
private LinearLayout mRead,
mReadHeader,
mDelivered,
mDeliveredHeader,
mSent,
mSentHeader,
mUndelivered,
mUndeliveredHeader;
private ImageView mBackButton;
private ChatMessageViewHolder mBubble;
private ViewGroup mContainer;
@ -60,7 +65,8 @@ public class ImdnFragment extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
public View onCreateView(
LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
@ -77,16 +83,17 @@ public class ImdnFragment extends Fragment {
View view = mInflater.inflate(R.layout.chat_imdn, container, false);
mBackButton = view.findViewById(R.id.back);
mBackButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (LinphoneActivity.instance().isTablet()) {
LinphoneActivity.instance().goToChat(mRoomUri, null);
} else {
LinphoneActivity.instance().onBackPressed();
}
}
});
mBackButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View view) {
if (LinphoneActivity.instance().isTablet()) {
LinphoneActivity.instance().goToChat(mRoomUri, null);
} else {
LinphoneActivity.instance().onBackPressed();
}
}
});
mRead = view.findViewById(R.id.read_layout);
mDelivered = view.findViewById(R.id.delivered_layout);
@ -100,12 +107,14 @@ public class ImdnFragment extends Fragment {
mBubble = new ChatMessageViewHolder(getActivity(), view.findViewById(R.id.bubble), null);
mMessage = mRoom.findMessage(mMessageId);
mListener = new ChatMessageListenerStub() {
@Override
public void onParticipantImdnStateChanged(ChatMessage msg, ParticipantImdnState state) {
refreshInfo();
}
};
mListener =
new ChatMessageListenerStub() {
@Override
public void onParticipantImdnStateChanged(
ChatMessage msg, ParticipantImdnState state) {
refreshInfo();
}
};
if (mMessage == null) return null;
mMessage.setListener(mListener);
@ -121,12 +130,14 @@ public class ImdnFragment extends Fragment {
}
refreshInfo();
mMessage.setListener(new ChatMessageListenerStub() {
@Override
public void onParticipantImdnStateChanged(ChatMessage msg, ParticipantImdnState state) {
refreshInfo();
}
});
mMessage.setListener(
new ChatMessageListenerStub() {
@Override
public void onParticipantImdnStateChanged(
ChatMessage msg, ParticipantImdnState state) {
refreshInfo();
}
});
}
@Override
@ -137,11 +148,12 @@ public class ImdnFragment extends Fragment {
private void refreshInfo() {
if (mMessage == null) {
//TODO: error
// TODO: error
return;
}
Address remoteSender = mMessage.getFromAddress();
LinphoneContact contact = ContactsManager.getInstance().findContactFromAddress(remoteSender);
LinphoneContact contact =
ContactsManager.getInstance().findContactFromAddress(remoteSender);
mBubble.deleteMessage.setVisibility(View.GONE);
mBubble.deleteEvent.setVisibility(View.GONE);
@ -156,23 +168,34 @@ public class ImdnFragment extends Fragment {
mSent.removeAllViews();
mUndelivered.removeAllViews();
ParticipantImdnState[] participants = mMessage.getParticipantsByImdnState(ChatMessage.State.Displayed);
ParticipantImdnState[] participants =
mMessage.getParticipantsByImdnState(ChatMessage.State.Displayed);
mReadHeader.setVisibility(participants.length == 0 ? View.GONE : View.VISIBLE);
boolean first = true;
for (ParticipantImdnState participant : participants) {
Address address = participant.getParticipant().getAddress();
LinphoneContact participantContact = ContactsManager.getInstance().findContactFromAddress(address);
String participantDisplayName = participantContact != null ? participantContact.getFullName() : LinphoneUtils.getAddressDisplayName(address);
LinphoneContact participantContact =
ContactsManager.getInstance().findContactFromAddress(address);
String participantDisplayName =
participantContact != null
? participantContact.getFullName()
: LinphoneUtils.getAddressDisplayName(address);
View v = mInflater.inflate(R.layout.chat_imdn_cell, mContainer, false);
v.findViewById(R.id.separator).setVisibility(first ? View.GONE : View.VISIBLE);
((TextView) v.findViewById(R.id.time)).setText(LinphoneUtils.timestampToHumanDate(getActivity(), participant.getStateChangeTime(), R.string.messages_date_format));
((TextView) v.findViewById(R.id.time))
.setText(
LinphoneUtils.timestampToHumanDate(
getActivity(),
participant.getStateChangeTime(),
R.string.messages_date_format));
((TextView) v.findViewById(R.id.name)).setText(participantDisplayName);
if (participantContact != null) {
ContactAvatar.displayAvatar(participantContact, v.findViewById(R.id.avatar_layout));
} else {
ContactAvatar.displayAvatar(participantDisplayName, v.findViewById(R.id.avatar_layout));
ContactAvatar.displayAvatar(
participantDisplayName, v.findViewById(R.id.avatar_layout));
}
mRead.addView(v);
@ -185,17 +208,27 @@ public class ImdnFragment extends Fragment {
for (ParticipantImdnState participant : participants) {
Address address = participant.getParticipant().getAddress();
LinphoneContact participantContact = ContactsManager.getInstance().findContactFromAddress(address);
String participantDisplayName = participantContact != null ? participantContact.getFullName() : LinphoneUtils.getAddressDisplayName(address);
LinphoneContact participantContact =
ContactsManager.getInstance().findContactFromAddress(address);
String participantDisplayName =
participantContact != null
? participantContact.getFullName()
: LinphoneUtils.getAddressDisplayName(address);
View v = mInflater.inflate(R.layout.chat_imdn_cell, mContainer, false);
v.findViewById(R.id.separator).setVisibility(first ? View.GONE : View.VISIBLE);
((TextView) v.findViewById(R.id.time)).setText(LinphoneUtils.timestampToHumanDate(getActivity(), participant.getStateChangeTime(), R.string.messages_date_format));
((TextView) v.findViewById(R.id.time))
.setText(
LinphoneUtils.timestampToHumanDate(
getActivity(),
participant.getStateChangeTime(),
R.string.messages_date_format));
((TextView) v.findViewById(R.id.name)).setText(participantDisplayName);
if (participantContact != null) {
ContactAvatar.displayAvatar(participantContact, v.findViewById(R.id.avatar_layout));
} else {
ContactAvatar.displayAvatar(participantDisplayName, v.findViewById(R.id.avatar_layout));
ContactAvatar.displayAvatar(
participantDisplayName, v.findViewById(R.id.avatar_layout));
}
mDelivered.addView(v);
@ -208,17 +241,27 @@ public class ImdnFragment extends Fragment {
for (ParticipantImdnState participant : participants) {
Address address = participant.getParticipant().getAddress();
LinphoneContact participantContact = ContactsManager.getInstance().findContactFromAddress(address);
String participantDisplayName = participantContact != null ? participantContact.getFullName() : LinphoneUtils.getAddressDisplayName(address);
LinphoneContact participantContact =
ContactsManager.getInstance().findContactFromAddress(address);
String participantDisplayName =
participantContact != null
? participantContact.getFullName()
: LinphoneUtils.getAddressDisplayName(address);
View v = mInflater.inflate(R.layout.chat_imdn_cell, mContainer, false);
v.findViewById(R.id.separator).setVisibility(first ? View.GONE : View.VISIBLE);
((TextView) v.findViewById(R.id.time)).setText(LinphoneUtils.timestampToHumanDate(getActivity(), participant.getStateChangeTime(), R.string.messages_date_format));
((TextView) v.findViewById(R.id.time))
.setText(
LinphoneUtils.timestampToHumanDate(
getActivity(),
participant.getStateChangeTime(),
R.string.messages_date_format));
((TextView) v.findViewById(R.id.name)).setText(participantDisplayName);
if (participantContact != null) {
ContactAvatar.displayAvatar(participantContact, v.findViewById(R.id.avatar_layout));
} else {
ContactAvatar.displayAvatar(participantDisplayName, v.findViewById(R.id.avatar_layout));
ContactAvatar.displayAvatar(
participantDisplayName, v.findViewById(R.id.avatar_layout));
}
mSent.addView(v);
@ -231,8 +274,12 @@ public class ImdnFragment extends Fragment {
for (ParticipantImdnState participant : participants) {
Address address = participant.getParticipant().getAddress();
LinphoneContact participantContact = ContactsManager.getInstance().findContactFromAddress(address);
String participantDisplayName = participantContact != null ? participantContact.getFullName() : LinphoneUtils.getAddressDisplayName(address);
LinphoneContact participantContact =
ContactsManager.getInstance().findContactFromAddress(address);
String participantDisplayName =
participantContact != null
? participantContact.getFullName()
: LinphoneUtils.getAddressDisplayName(address);
View v = mInflater.inflate(R.layout.chat_imdn_cell, mContainer, false);
v.findViewById(R.id.separator).setVisibility(first ? View.GONE : View.VISIBLE);
@ -240,7 +287,8 @@ public class ImdnFragment extends Fragment {
if (participantContact != null) {
ContactAvatar.displayAvatar(participantContact, v.findViewById(R.id.avatar_layout));
} else {
ContactAvatar.displayAvatar(participantDisplayName, v.findViewById(R.id.avatar_layout));
ContactAvatar.displayAvatar(
participantDisplayName, v.findViewById(R.id.avatar_layout));
}
mUndelivered.addView(v);

View file

@ -21,7 +21,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
import android.app.Fragment;
import android.os.Bundle;
import androidx.annotation.Nullable;
import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.view.LayoutInflater;
@ -31,12 +30,10 @@ import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import org.linphone.LinphoneManager;
import org.linphone.utils.FileUtils;
import org.linphone.utils.LinphoneUtils;
import org.linphone.R;
import androidx.annotation.Nullable;
import org.linphone.LinphoneActivity;
import org.linphone.LinphoneManager;
import org.linphone.R;
import org.linphone.compatibility.Compatibility;
import org.linphone.contacts.ContactsManager;
import org.linphone.contacts.LinphoneContact;
@ -47,11 +44,20 @@ import org.linphone.core.ChatRoom;
import org.linphone.core.Core;
import org.linphone.core.ParticipantImdnState;
import org.linphone.fragments.FragmentsAvailable;
import org.linphone.utils.FileUtils;
import org.linphone.utils.LinphoneUtils;
import org.linphone.views.ContactAvatar;
public class ImdnOldFragment extends Fragment {
private LayoutInflater mInflater;
private LinearLayout mRead, mReadHeader, mDelivered, mDeliveredHeader, mSent, mSentHeader, mUndelivered, mUndeliveredHeader;
private LinearLayout mRead,
mReadHeader,
mDelivered,
mDeliveredHeader,
mSent,
mSentHeader,
mUndelivered,
mUndeliveredHeader;
private ImageView mBackButton;
private ChatMessageOldViewHolder mBubble;
private ViewGroup mContainer;
@ -64,7 +70,8 @@ public class ImdnOldFragment extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
public View onCreateView(
LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
@ -81,16 +88,17 @@ public class ImdnOldFragment extends Fragment {
View view = mInflater.inflate(R.layout.chat_imdn_old, container, false);
mBackButton = view.findViewById(R.id.back);
mBackButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (LinphoneActivity.instance().isTablet()) {
LinphoneActivity.instance().goToChat(mRoomUri, null);
} else {
LinphoneActivity.instance().onBackPressed();
}
}
});
mBackButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View view) {
if (LinphoneActivity.instance().isTablet()) {
LinphoneActivity.instance().goToChat(mRoomUri, null);
} else {
LinphoneActivity.instance().onBackPressed();
}
}
});
mRead = view.findViewById(R.id.read_layout);
mDelivered = view.findViewById(R.id.delivered_layout);
@ -115,28 +123,36 @@ public class ImdnOldFragment extends Fragment {
mBubble.imdmLayout.setVisibility(View.INVISIBLE);
mMessage = mRoom.findMessage(mMessageId);
mListener = new ChatMessageListenerStub() {
@Override
public void onParticipantImdnStateChanged(ChatMessage msg, ParticipantImdnState state) {
refreshInfo();
}
};
mListener =
new ChatMessageListenerStub() {
@Override
public void onParticipantImdnStateChanged(
ChatMessage msg, ParticipantImdnState state) {
refreshInfo();
}
};
if (mMessage == null) return null;
mMessage.setListener(mListener);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
RelativeLayout.LayoutParams layoutParams =
new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
layoutParams.setMargins(100, 10, 10, 10);
if (mMessage.isOutgoing()) {
mBubble.background.setBackgroundResource(R.drawable.resizable_chat_bubble_outgoing);
Compatibility.setTextAppearance(mBubble.contactName, getActivity(), R.style.font3);
Compatibility.setTextAppearance(mBubble.fileTransferAction, getActivity(), R.style.font15);
mBubble.fileTransferAction.setBackgroundResource(R.drawable.resizable_confirm_delete_button);
Compatibility.setTextAppearance(
mBubble.fileTransferAction, getActivity(), R.style.font15);
mBubble.fileTransferAction.setBackgroundResource(
R.drawable.resizable_confirm_delete_button);
ContactAvatar.setAvatarMask(mBubble.avatarLayout, R.drawable.avatar_chat_mask_outgoing);
} else {
mBubble.background.setBackgroundResource(R.drawable.resizable_chat_bubble_incoming);
Compatibility.setTextAppearance(mBubble.contactName, getActivity(), R.style.font9);
Compatibility.setTextAppearance(mBubble.fileTransferAction, getActivity(), R.style.font8);
Compatibility.setTextAppearance(
mBubble.fileTransferAction, getActivity(), R.style.font8);
mBubble.fileTransferAction.setBackgroundResource(R.drawable.resizable_assistant_button);
ContactAvatar.setAvatarMask(mBubble.avatarLayout, R.drawable.avatar_chat_mask);
}
@ -157,7 +173,8 @@ public class ImdnOldFragment extends Fragment {
private void refreshInfo() {
Address remoteSender = mMessage.getFromAddress();
LinphoneContact contact = ContactsManager.getInstance().findContactFromAddress(remoteSender);
LinphoneContact contact =
ContactsManager.getInstance().findContactFromAddress(remoteSender);
String displayName;
if (contact != null) {
@ -172,7 +189,11 @@ public class ImdnOldFragment extends Fragment {
displayName = LinphoneUtils.getAddressDisplayName(remoteSender);
ContactAvatar.displayAvatar(displayName, mBubble.avatarLayout);
}
mBubble.contactName.setText(LinphoneUtils.timestampToHumanDate(getActivity(), mMessage.getTime(), R.string.messages_date_format) + " - " + displayName);
mBubble.contactName.setText(
LinphoneUtils.timestampToHumanDate(
getActivity(), mMessage.getTime(), R.string.messages_date_format)
+ " - "
+ displayName);
if (mMessage.hasTextContent()) {
String msg = mMessage.getTextContent();
@ -194,23 +215,34 @@ public class ImdnOldFragment extends Fragment {
mSent.removeAllViews();
mUndelivered.removeAllViews();
ParticipantImdnState[] participants = mMessage.getParticipantsByImdnState(ChatMessage.State.Displayed);
ParticipantImdnState[] participants =
mMessage.getParticipantsByImdnState(ChatMessage.State.Displayed);
mReadHeader.setVisibility(participants.length == 0 ? View.GONE : View.VISIBLE);
boolean first = true;
for (ParticipantImdnState participant : participants) {
Address address = participant.getParticipant().getAddress();
LinphoneContact participantContact = ContactsManager.getInstance().findContactFromAddress(address);
String participantDisplayName = participantContact != null ? participantContact.getFullName() : LinphoneUtils.getAddressDisplayName(address);
LinphoneContact participantContact =
ContactsManager.getInstance().findContactFromAddress(address);
String participantDisplayName =
participantContact != null
? participantContact.getFullName()
: LinphoneUtils.getAddressDisplayName(address);
View v = mInflater.inflate(R.layout.chat_imdn_cell, mContainer, false);
v.findViewById(R.id.separator).setVisibility(first ? View.GONE : View.VISIBLE);
((TextView) v.findViewById(R.id.time)).setText(LinphoneUtils.timestampToHumanDate(getActivity(), participant.getStateChangeTime(), R.string.messages_date_format));
((TextView) v.findViewById(R.id.time))
.setText(
LinphoneUtils.timestampToHumanDate(
getActivity(),
participant.getStateChangeTime(),
R.string.messages_date_format));
((TextView) v.findViewById(R.id.name)).setText(participantDisplayName);
if (participantContact != null) {
ContactAvatar.displayAvatar(participantContact, v.findViewById(R.id.avatar_layout));
} else {
ContactAvatar.displayAvatar(participantDisplayName, v.findViewById(R.id.avatar_layout));
ContactAvatar.displayAvatar(
participantDisplayName, v.findViewById(R.id.avatar_layout));
}
mRead.addView(v);
@ -223,17 +255,27 @@ public class ImdnOldFragment extends Fragment {
for (ParticipantImdnState participant : participants) {
Address address = participant.getParticipant().getAddress();
LinphoneContact participantContact = ContactsManager.getInstance().findContactFromAddress(address);
String participantDisplayName = participantContact != null ? participantContact.getFullName() : LinphoneUtils.getAddressDisplayName(address);
LinphoneContact participantContact =
ContactsManager.getInstance().findContactFromAddress(address);
String participantDisplayName =
participantContact != null
? participantContact.getFullName()
: LinphoneUtils.getAddressDisplayName(address);
View v = mInflater.inflate(R.layout.chat_imdn_cell, mContainer, false);
v.findViewById(R.id.separator).setVisibility(first ? View.GONE : View.VISIBLE);
((TextView) v.findViewById(R.id.time)).setText(LinphoneUtils.timestampToHumanDate(getActivity(), participant.getStateChangeTime(), R.string.messages_date_format));
((TextView) v.findViewById(R.id.time))
.setText(
LinphoneUtils.timestampToHumanDate(
getActivity(),
participant.getStateChangeTime(),
R.string.messages_date_format));
((TextView) v.findViewById(R.id.name)).setText(participantDisplayName);
if (participantContact != null) {
ContactAvatar.displayAvatar(participantContact, v.findViewById(R.id.avatar_layout));
} else {
ContactAvatar.displayAvatar(participantDisplayName, v.findViewById(R.id.avatar_layout));
ContactAvatar.displayAvatar(
participantDisplayName, v.findViewById(R.id.avatar_layout));
}
mDelivered.addView(v);
@ -246,17 +288,27 @@ public class ImdnOldFragment extends Fragment {
for (ParticipantImdnState participant : participants) {
Address address = participant.getParticipant().getAddress();
LinphoneContact participantContact = ContactsManager.getInstance().findContactFromAddress(address);
String participantDisplayName = participantContact != null ? participantContact.getFullName() : LinphoneUtils.getAddressDisplayName(address);
LinphoneContact participantContact =
ContactsManager.getInstance().findContactFromAddress(address);
String participantDisplayName =
participantContact != null
? participantContact.getFullName()
: LinphoneUtils.getAddressDisplayName(address);
View v = mInflater.inflate(R.layout.chat_imdn_cell, mContainer, false);
v.findViewById(R.id.separator).setVisibility(first ? View.GONE : View.VISIBLE);
((TextView) v.findViewById(R.id.time)).setText(LinphoneUtils.timestampToHumanDate(getActivity(), participant.getStateChangeTime(), R.string.messages_date_format));
((TextView) v.findViewById(R.id.time))
.setText(
LinphoneUtils.timestampToHumanDate(
getActivity(),
participant.getStateChangeTime(),
R.string.messages_date_format));
((TextView) v.findViewById(R.id.name)).setText(participantDisplayName);
if (participantContact != null) {
ContactAvatar.displayAvatar(participantContact, v.findViewById(R.id.avatar_layout));
} else {
ContactAvatar.displayAvatar(participantDisplayName, v.findViewById(R.id.avatar_layout));
ContactAvatar.displayAvatar(
participantDisplayName, v.findViewById(R.id.avatar_layout));
}
mSent.addView(v);
@ -269,8 +321,12 @@ public class ImdnOldFragment extends Fragment {
for (ParticipantImdnState participant : participants) {
Address address = participant.getParticipant().getAddress();
LinphoneContact participantContact = ContactsManager.getInstance().findContactFromAddress(address);
String participantDisplayName = participantContact != null ? participantContact.getFullName() : LinphoneUtils.getAddressDisplayName(address);
LinphoneContact participantContact =
ContactsManager.getInstance().findContactFromAddress(address);
String participantDisplayName =
participantContact != null
? participantContact.getFullName()
: LinphoneUtils.getAddressDisplayName(address);
View v = mInflater.inflate(R.layout.chat_imdn_cell, mContainer, false);
v.findViewById(R.id.separator).setVisibility(first ? View.GONE : View.VISIBLE);
@ -278,7 +334,8 @@ public class ImdnOldFragment extends Fragment {
if (participantContact != null) {
ContactAvatar.displayAvatar(participantContact, v.findViewById(R.id.avatar_layout));
} else {
ContactAvatar.displayAvatar(participantDisplayName, v.findViewById(R.id.avatar_layout));
ContactAvatar.displayAvatar(
participantDisplayName, v.findViewById(R.id.avatar_layout));
}
mUndelivered.addView(v);

View file

@ -19,6 +19,12 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import static org.linphone.compatibility.Compatibility.CHAT_NOTIFICATIONS_GROUP;
import static org.linphone.compatibility.Compatibility.INTENT_LOCAL_IDENTITY;
import static org.linphone.compatibility.Compatibility.INTENT_NOTIF_ID;
import static org.linphone.compatibility.Compatibility.INTENT_REPLY_NOTIF_ACTION;
import static org.linphone.compatibility.Compatibility.KEY_TEXT_REPLY;
import android.annotation.TargetApi;
import android.app.Notification;
import android.app.PendingIntent;
@ -28,48 +34,51 @@ import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.Icon;
import android.net.Uri;
import org.linphone.R;
import org.linphone.mediastream.Log;
import org.linphone.notifications.Notifiable;
import org.linphone.notifications.NotifiableMessage;
import org.linphone.notifications.NotificationBroadcastReceiver;
import org.linphone.utils.FileUtils;
import static org.linphone.compatibility.Compatibility.CHAT_NOTIFICATIONS_GROUP;
import static org.linphone.compatibility.Compatibility.INTENT_LOCAL_IDENTITY;
import static org.linphone.compatibility.Compatibility.INTENT_NOTIF_ID;
import static org.linphone.compatibility.Compatibility.INTENT_REPLY_NOTIF_ACTION;
import static org.linphone.compatibility.Compatibility.KEY_TEXT_REPLY;
@TargetApi(28)
public class ApiTwentyEightPlus {
public static Notification createMessageNotification(Context context, Notifiable notif, Bitmap contactIcon, PendingIntent intent) {
public static Notification createMessageNotification(
Context context, Notifiable notif, Bitmap contactIcon, PendingIntent intent) {
String replyLabel = context.getResources().getString(R.string.notification_reply_label);
RemoteInput remoteInput = new RemoteInput.Builder(KEY_TEXT_REPLY).setLabel(replyLabel).build();
RemoteInput remoteInput =
new RemoteInput.Builder(KEY_TEXT_REPLY).setLabel(replyLabel).build();
Intent replyIntent = new Intent(context, NotificationBroadcastReceiver.class);
replyIntent.setAction(INTENT_REPLY_NOTIF_ACTION);
replyIntent.putExtra(INTENT_NOTIF_ID, notif.getNotificationId());
replyIntent.putExtra(INTENT_LOCAL_IDENTITY, notif.getLocalIdentity());
PendingIntent replyPendingIntent = PendingIntent.getBroadcast(context,
notif.getNotificationId(), replyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent replyPendingIntent =
PendingIntent.getBroadcast(
context,
notif.getNotificationId(),
replyIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
Notification.Action action = new Notification.Action.Builder(R.drawable.chat_send_over,
context.getString(R.string.notification_reply_label), replyPendingIntent)
.addRemoteInput(remoteInput)
.setAllowGeneratedReplies(true)
.build();
Notification.Action action =
new Notification.Action.Builder(
R.drawable.chat_send_over,
context.getString(R.string.notification_reply_label),
replyPendingIntent)
.addRemoteInput(remoteInput)
.setAllowGeneratedReplies(true)
.build();
Person me = new Person.Builder().setName(notif.getMyself()).build();
Notification.MessagingStyle style = new Notification.MessagingStyle(me);
for (NotifiableMessage message : notif.getMessages()) {
Icon userIcon = Icon.createWithBitmap(message.getSenderBitmap());
Person user = new Person.Builder().setName(message.getSender()).setIcon(userIcon).build();
Notification.MessagingStyle.Message msg = new Notification.MessagingStyle.Message(message.getMessage(), message.getTime(), user);
if (message.getFilePath() != null) msg.setData(message.getFileMime(), message.getFilePath());
Person user =
new Person.Builder().setName(message.getSender()).setIcon(userIcon).build();
Notification.MessagingStyle.Message msg =
new Notification.MessagingStyle.Message(
message.getMessage(), message.getTime(), user);
if (message.getFilePath() != null)
msg.setData(message.getFileMime(), message.getFilePath());
style.addMessage(msg);
}
if (notif.isGroup()) {
@ -77,22 +86,26 @@ public class ApiTwentyEightPlus {
}
style.setGroupConversation(notif.isGroup());
return new Notification.Builder(context, context.getString(R.string.notification_channel_id))
.setSmallIcon(R.drawable.topbar_chat_notification)
.setAutoCancel(true)
.setContentIntent(intent)
.setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE | Notification.DEFAULT_LIGHTS)
.setLargeIcon(contactIcon)
.setCategory(Notification.CATEGORY_MESSAGE)
.setGroup(CHAT_NOTIFICATIONS_GROUP)
.setVisibility(Notification.VISIBILITY_PRIVATE)
.setPriority(Notification.PRIORITY_HIGH)
.setNumber(notif.getMessages().size())
.setWhen(System.currentTimeMillis())
.setShowWhen(true)
.setColor(context.getColor(R.color.notification_color_led))
.setStyle(style)
.addAction(action)
.build();
return new Notification.Builder(
context, context.getString(R.string.notification_channel_id))
.setSmallIcon(R.drawable.topbar_chat_notification)
.setAutoCancel(true)
.setContentIntent(intent)
.setDefaults(
Notification.DEFAULT_SOUND
| Notification.DEFAULT_VIBRATE
| Notification.DEFAULT_LIGHTS)
.setLargeIcon(contactIcon)
.setCategory(Notification.CATEGORY_MESSAGE)
.setGroup(CHAT_NOTIFICATIONS_GROUP)
.setVisibility(Notification.VISIBILITY_PRIVATE)
.setPriority(Notification.PRIORITY_HIGH)
.setNumber(notif.getMessages().size())
.setWhen(System.currentTimeMillis())
.setShowWhen(true)
.setColor(context.getColor(R.color.notification_color_led))
.setStyle(style)
.addAction(action)
.build();
}
}

View file

@ -19,22 +19,6 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import android.annotation.TargetApi;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.RemoteInput;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import org.linphone.R;
import org.linphone.mediastream.Log;
import org.linphone.notifications.Notifiable;
import org.linphone.notifications.NotifiableMessage;
import org.linphone.notifications.NotificationBroadcastReceiver;
import org.linphone.utils.FileUtils;
import static org.linphone.compatibility.Compatibility.CHAT_NOTIFICATIONS_GROUP;
import static org.linphone.compatibility.Compatibility.INTENT_ANSWER_CALL_NOTIF_ACTION;
import static org.linphone.compatibility.Compatibility.INTENT_HANGUP_CALL_NOTIF_ACTION;
@ -43,97 +27,141 @@ import static org.linphone.compatibility.Compatibility.INTENT_NOTIF_ID;
import static org.linphone.compatibility.Compatibility.INTENT_REPLY_NOTIF_ACTION;
import static org.linphone.compatibility.Compatibility.KEY_TEXT_REPLY;
import android.annotation.TargetApi;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.RemoteInput;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import org.linphone.R;
import org.linphone.notifications.Notifiable;
import org.linphone.notifications.NotifiableMessage;
import org.linphone.notifications.NotificationBroadcastReceiver;
@TargetApi(24)
public class ApiTwentyFourPlus {
public static Notification createRepliedNotification(Context context, String reply) {
return new Notification.Builder(context)
.setSmallIcon(R.drawable.topbar_chat_notification)
.setContentText(context.getString(R.string.notification_replied_label).replace("%s", reply))
.build();
}
public static Notification createRepliedNotification(Context context, String reply) {
return new Notification.Builder(context)
.setSmallIcon(R.drawable.topbar_chat_notification)
.setContentText(
context.getString(R.string.notification_replied_label).replace("%s", reply))
.build();
}
public static Notification createMessageNotification(Context context, Notifiable notif, Bitmap contactIcon, PendingIntent intent) {
String replyLabel = context.getResources().getString(R.string.notification_reply_label);
RemoteInput remoteInput = new RemoteInput.Builder(KEY_TEXT_REPLY).setLabel(replyLabel).build();
public static Notification createMessageNotification(
Context context, Notifiable notif, Bitmap contactIcon, PendingIntent intent) {
String replyLabel = context.getResources().getString(R.string.notification_reply_label);
RemoteInput remoteInput =
new RemoteInput.Builder(KEY_TEXT_REPLY).setLabel(replyLabel).build();
Intent replyIntent = new Intent(context, NotificationBroadcastReceiver.class);
replyIntent.setAction(INTENT_REPLY_NOTIF_ACTION);
replyIntent.putExtra(INTENT_NOTIF_ID, notif.getNotificationId());
replyIntent.putExtra(INTENT_LOCAL_IDENTITY, notif.getLocalIdentity());
Intent replyIntent = new Intent(context, NotificationBroadcastReceiver.class);
replyIntent.setAction(INTENT_REPLY_NOTIF_ACTION);
replyIntent.putExtra(INTENT_NOTIF_ID, notif.getNotificationId());
replyIntent.putExtra(INTENT_LOCAL_IDENTITY, notif.getLocalIdentity());
PendingIntent replyPendingIntent = PendingIntent.getBroadcast(context,
notif.getNotificationId(), replyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent replyPendingIntent =
PendingIntent.getBroadcast(
context,
notif.getNotificationId(),
replyIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
Notification.Action action = new Notification.Action.Builder(R.drawable.chat_send_over,
context.getString(R.string.notification_reply_label), replyPendingIntent)
.addRemoteInput(remoteInput)
.setAllowGeneratedReplies(true)
.build();
Notification.Action action =
new Notification.Action.Builder(
R.drawable.chat_send_over,
context.getString(R.string.notification_reply_label),
replyPendingIntent)
.addRemoteInput(remoteInput)
.setAllowGeneratedReplies(true)
.build();
Notification.MessagingStyle style = new Notification.MessagingStyle(notif.getMyself());
for (NotifiableMessage message : notif.getMessages()) {
Notification.MessagingStyle.Message msg = new Notification.MessagingStyle.Message(message.getMessage(), message.getTime(), message.getSender());
if (message.getFilePath() != null) msg.setData(message.getFileMime(), message.getFilePath());
Notification.MessagingStyle style = new Notification.MessagingStyle(notif.getMyself());
for (NotifiableMessage message : notif.getMessages()) {
Notification.MessagingStyle.Message msg =
new Notification.MessagingStyle.Message(
message.getMessage(), message.getTime(), message.getSender());
if (message.getFilePath() != null)
msg.setData(message.getFileMime(), message.getFilePath());
style.addMessage(msg);
}
if (notif.isGroup()) {
style.setConversationTitle(notif.getGroupTitle());
}
}
if (notif.isGroup()) {
style.setConversationTitle(notif.getGroupTitle());
}
return new Notification.Builder(context)
.setSmallIcon(R.drawable.topbar_chat_notification)
.setAutoCancel(true)
.setContentIntent(intent)
.setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE | Notification.DEFAULT_LIGHTS)
.setLargeIcon(contactIcon)
.setCategory(Notification.CATEGORY_MESSAGE)
.setGroup(CHAT_NOTIFICATIONS_GROUP)
.setVisibility(Notification.VISIBILITY_PRIVATE)
.setPriority(Notification.PRIORITY_HIGH)
.setNumber(notif.getMessages().size())
.setWhen(System.currentTimeMillis())
.setShowWhen(true)
.setColor(context.getColor(R.color.notification_color_led))
.setStyle(style)
.addAction(action)
.build();
}
return new Notification.Builder(context)
.setSmallIcon(R.drawable.topbar_chat_notification)
.setAutoCancel(true)
.setContentIntent(intent)
.setDefaults(
Notification.DEFAULT_SOUND
| Notification.DEFAULT_VIBRATE
| Notification.DEFAULT_LIGHTS)
.setLargeIcon(contactIcon)
.setCategory(Notification.CATEGORY_MESSAGE)
.setGroup(CHAT_NOTIFICATIONS_GROUP)
.setVisibility(Notification.VISIBILITY_PRIVATE)
.setPriority(Notification.PRIORITY_HIGH)
.setNumber(notif.getMessages().size())
.setWhen(System.currentTimeMillis())
.setShowWhen(true)
.setColor(context.getColor(R.color.notification_color_led))
.setStyle(style)
.addAction(action)
.build();
}
public static Notification createInCallNotification(Context context,
int callId, boolean showAnswerAction, String msg, int iconID, Bitmap contactIcon, String contactName, PendingIntent intent) {
public static Notification createInCallNotification(
Context context,
int callId,
boolean showAnswerAction,
String msg,
int iconID,
Bitmap contactIcon,
String contactName,
PendingIntent intent) {
Intent hangupIntent = new Intent(context, NotificationBroadcastReceiver.class);
hangupIntent.setAction(INTENT_HANGUP_CALL_NOTIF_ACTION);
hangupIntent.putExtra(INTENT_NOTIF_ID, callId);
Intent hangupIntent = new Intent(context, NotificationBroadcastReceiver.class);
hangupIntent.setAction(INTENT_HANGUP_CALL_NOTIF_ACTION);
hangupIntent.putExtra(INTENT_NOTIF_ID, callId);
PendingIntent hangupPendingIntent = PendingIntent.getBroadcast(context,
callId, hangupIntent, PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent hangupPendingIntent =
PendingIntent.getBroadcast(
context, callId, hangupIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Notification.Builder builder = new Notification.Builder(context)
.setContentTitle(contactName)
.setContentText(msg)
.setSmallIcon(iconID)
.setAutoCancel(false)
.setContentIntent(intent)
.setLargeIcon(contactIcon)
.setCategory(Notification.CATEGORY_CALL)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setPriority(Notification.PRIORITY_HIGH)
.setWhen(System.currentTimeMillis())
.setShowWhen(true)
.setColor(context.getColor(R.color.notification_color_led))
.addAction(R.drawable.call_hangup, context.getString(R.string.notification_call_hangup_label), hangupPendingIntent);
Notification.Builder builder =
new Notification.Builder(context)
.setContentTitle(contactName)
.setContentText(msg)
.setSmallIcon(iconID)
.setAutoCancel(false)
.setContentIntent(intent)
.setLargeIcon(contactIcon)
.setCategory(Notification.CATEGORY_CALL)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setPriority(Notification.PRIORITY_HIGH)
.setWhen(System.currentTimeMillis())
.setShowWhen(true)
.setColor(context.getColor(R.color.notification_color_led))
.addAction(
R.drawable.call_hangup,
context.getString(R.string.notification_call_hangup_label),
hangupPendingIntent);
if (showAnswerAction) {
Intent answerIntent = new Intent(context, NotificationBroadcastReceiver.class);
answerIntent.setAction(INTENT_ANSWER_CALL_NOTIF_ACTION);
answerIntent.putExtra(INTENT_NOTIF_ID, callId);
PendingIntent answerPendingIntent = PendingIntent.getBroadcast(context,
callId, answerIntent, PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent answerPendingIntent =
PendingIntent.getBroadcast(
context, callId, answerIntent, PendingIntent.FLAG_UPDATE_CURRENT);
builder.addAction(R.drawable.call_audio_start, context.getString(R.string.notification_call_answer_label), answerPendingIntent);
builder.addAction(
R.drawable.call_audio_start,
context.getString(R.string.notification_call_answer_label),
answerPendingIntent);
}
return builder.build();

View file

@ -25,148 +25,183 @@ import android.app.PendingIntent;
import android.content.Context;
import android.graphics.Bitmap;
import androidx.core.content.ContextCompat;
import org.linphone.R;
@TargetApi(21)
public class ApiTwentyOnePlus {
@SuppressWarnings("deprecation")
public static Notification createMessageNotification(Context context,
int msgCount, String msgSender, String msg, Bitmap contactIcon,
PendingIntent intent) {
public static Notification createMessageNotification(
Context context,
int msgCount,
String msgSender,
String msg,
Bitmap contactIcon,
PendingIntent intent) {
String title;
if (msgCount == 1) {
title = msgSender;
} else {
title = context.getString(R.string.unread_messages).replace("%i", String.valueOf(msgCount));
title =
context.getString(R.string.unread_messages)
.replace("%i", String.valueOf(msgCount));
}
Notification notif = new Notification.Builder(context)
.setContentTitle(title)
.setContentText(msg)
.setSmallIcon(R.drawable.topbar_chat_notification)
.setAutoCancel(true)
.setContentIntent(intent)
.setDefaults(Notification.DEFAULT_SOUND
| Notification.DEFAULT_VIBRATE
| Notification.DEFAULT_LIGHTS)
.setLargeIcon(contactIcon)
.setLights(ContextCompat.getColor(context, R.color.notification_color_led),
context.getResources().getInteger(R.integer.notification_ms_on),
context.getResources().getInteger(R.integer.notification_ms_off))
.setCategory(Notification.CATEGORY_MESSAGE)
.setVisibility(Notification.VISIBILITY_PRIVATE)
.setPriority(Notification.PRIORITY_HIGH)
.setNumber(msgCount)
.setWhen(System.currentTimeMillis())
.setShowWhen(true)
.build();
Notification notif =
new Notification.Builder(context)
.setContentTitle(title)
.setContentText(msg)
.setSmallIcon(R.drawable.topbar_chat_notification)
.setAutoCancel(true)
.setContentIntent(intent)
.setDefaults(
Notification.DEFAULT_SOUND
| Notification.DEFAULT_VIBRATE
| Notification.DEFAULT_LIGHTS)
.setLargeIcon(contactIcon)
.setLights(
ContextCompat.getColor(context, R.color.notification_color_led),
context.getResources().getInteger(R.integer.notification_ms_on),
context.getResources().getInteger(R.integer.notification_ms_off))
.setCategory(Notification.CATEGORY_MESSAGE)
.setVisibility(Notification.VISIBILITY_PRIVATE)
.setPriority(Notification.PRIORITY_HIGH)
.setNumber(msgCount)
.setWhen(System.currentTimeMillis())
.setShowWhen(true)
.build();
return notif;
}
public static Notification createInCallNotification(Context context,
String title, String msg, int iconID, Bitmap contactIcon,
String contactName, PendingIntent intent) {
public static Notification createInCallNotification(
Context context,
String title,
String msg,
int iconID,
Bitmap contactIcon,
String contactName,
PendingIntent intent) {
Notification notif = new Notification.Builder(context).setContentTitle(contactName)
.setContentText(msg)
.setSmallIcon(iconID)
.setAutoCancel(false)
.setContentIntent(intent)
.setLargeIcon(contactIcon)
.setCategory(Notification.CATEGORY_CALL)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setPriority(Notification.PRIORITY_HIGH)
.setLights(ContextCompat.getColor(context, R.color.notification_color_led),
context.getResources().getInteger(R.integer.notification_ms_on),
context.getResources().getInteger(R.integer.notification_ms_off))
.setShowWhen(true)
.build();
Notification notif =
new Notification.Builder(context)
.setContentTitle(contactName)
.setContentText(msg)
.setSmallIcon(iconID)
.setAutoCancel(false)
.setContentIntent(intent)
.setLargeIcon(contactIcon)
.setCategory(Notification.CATEGORY_CALL)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setPriority(Notification.PRIORITY_HIGH)
.setLights(
ContextCompat.getColor(context, R.color.notification_color_led),
context.getResources().getInteger(R.integer.notification_ms_on),
context.getResources().getInteger(R.integer.notification_ms_off))
.setShowWhen(true)
.build();
return notif;
}
public static Notification createNotification(Context context, String title, String message, int icon, int level, Bitmap largeIcon, PendingIntent intent, boolean isOngoingEvent, int priority) {
public static Notification createNotification(
Context context,
String title,
String message,
int icon,
int level,
Bitmap largeIcon,
PendingIntent intent,
boolean isOngoingEvent,
int priority) {
Notification notif;
if (largeIcon != null) {
notif = new Notification.Builder(context)
.setContentTitle(title)
.setContentText(message)
.setSmallIcon(icon, level)
.setLargeIcon(largeIcon)
.setContentIntent(intent)
.setCategory(Notification.CATEGORY_SERVICE)
.setVisibility(Notification.VISIBILITY_SECRET)
.setLights(ContextCompat.getColor(context, R.color.notification_color_led),
context.getResources().getInteger(R.integer.notification_ms_on),
context.getResources().getInteger(R.integer.notification_ms_off))
.setWhen(System.currentTimeMillis())
.setPriority(priority)
.setShowWhen(true)
.build();
notif =
new Notification.Builder(context)
.setContentTitle(title)
.setContentText(message)
.setSmallIcon(icon, level)
.setLargeIcon(largeIcon)
.setContentIntent(intent)
.setCategory(Notification.CATEGORY_SERVICE)
.setVisibility(Notification.VISIBILITY_SECRET)
.setLights(
ContextCompat.getColor(context, R.color.notification_color_led),
context.getResources().getInteger(R.integer.notification_ms_on),
context.getResources()
.getInteger(R.integer.notification_ms_off))
.setWhen(System.currentTimeMillis())
.setPriority(priority)
.setShowWhen(true)
.build();
} else {
notif = new Notification.Builder(context)
.setContentTitle(title)
.setContentText(message)
.setSmallIcon(icon, level)
.setContentIntent(intent)
.setCategory(Notification.CATEGORY_SERVICE)
.setVisibility(Notification.VISIBILITY_SECRET)
.setLights(ContextCompat.getColor(context, R.color.notification_color_led),
context.getResources().getInteger(R.integer.notification_ms_on),
context.getResources().getInteger(R.integer.notification_ms_off))
.setPriority(priority)
.setWhen(System.currentTimeMillis())
.setShowWhen(true)
.build();
notif =
new Notification.Builder(context)
.setContentTitle(title)
.setContentText(message)
.setSmallIcon(icon, level)
.setContentIntent(intent)
.setCategory(Notification.CATEGORY_SERVICE)
.setVisibility(Notification.VISIBILITY_SECRET)
.setLights(
ContextCompat.getColor(context, R.color.notification_color_led),
context.getResources().getInteger(R.integer.notification_ms_on),
context.getResources()
.getInteger(R.integer.notification_ms_off))
.setPriority(priority)
.setWhen(System.currentTimeMillis())
.setShowWhen(true)
.build();
}
return notif;
}
public static Notification createMissedCallNotification(Context context, String title, String text, PendingIntent intent) {
Notification notif = new Notification.Builder(context)
.setContentTitle(title)
.setContentText(text)
.setSmallIcon(R.drawable.call_status_missed)
.setAutoCancel(true)
.setContentIntent(intent)
.setDefaults(Notification.DEFAULT_SOUND
| Notification.DEFAULT_VIBRATE)
.setCategory(Notification.CATEGORY_EVENT)
.setVisibility(Notification.VISIBILITY_PRIVATE)
.setLights(ContextCompat.getColor(context, R.color.notification_color_led),
context.getResources().getInteger(R.integer.notification_ms_on),
context.getResources().getInteger(R.integer.notification_ms_off))
.setPriority(Notification.PRIORITY_HIGH)
.setWhen(System.currentTimeMillis())
.setShowWhen(true)
.build();
public static Notification createMissedCallNotification(
Context context, String title, String text, PendingIntent intent) {
Notification notif =
new Notification.Builder(context)
.setContentTitle(title)
.setContentText(text)
.setSmallIcon(R.drawable.call_status_missed)
.setAutoCancel(true)
.setContentIntent(intent)
.setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE)
.setCategory(Notification.CATEGORY_EVENT)
.setVisibility(Notification.VISIBILITY_PRIVATE)
.setLights(
ContextCompat.getColor(context, R.color.notification_color_led),
context.getResources().getInteger(R.integer.notification_ms_on),
context.getResources().getInteger(R.integer.notification_ms_off))
.setPriority(Notification.PRIORITY_HIGH)
.setWhen(System.currentTimeMillis())
.setShowWhen(true)
.build();
return notif;
}
public static Notification createSimpleNotification(Context context, String title, String text, PendingIntent intent) {
Notification notif = new Notification.Builder(context)
.setContentTitle(title)
.setContentText(text)
.setSmallIcon(R.drawable.linphone_logo)
.setAutoCancel(true)
.setContentIntent(intent)
.setDefaults(Notification.DEFAULT_SOUND
| Notification.DEFAULT_VIBRATE)
.setCategory(Notification.CATEGORY_MESSAGE)
.setVisibility(Notification.VISIBILITY_PRIVATE)
.setLights(ContextCompat.getColor(context, R.color.notification_color_led),
context.getResources().getInteger(R.integer.notification_ms_on),
context.getResources().getInteger(R.integer.notification_ms_off))
.setWhen(System.currentTimeMillis())
.setPriority(Notification.PRIORITY_HIGH)
.setShowWhen(true)
.build();
public static Notification createSimpleNotification(
Context context, String title, String text, PendingIntent intent) {
Notification notif =
new Notification.Builder(context)
.setContentTitle(title)
.setContentText(text)
.setSmallIcon(R.drawable.linphone_logo)
.setAutoCancel(true)
.setContentIntent(intent)
.setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE)
.setCategory(Notification.CATEGORY_MESSAGE)
.setVisibility(Notification.VISIBILITY_PRIVATE)
.setLights(
ContextCompat.getColor(context, R.color.notification_color_led),
context.getResources().getInteger(R.integer.notification_ms_on),
context.getResources().getInteger(R.integer.notification_ms_off))
.setWhen(System.currentTimeMillis())
.setPriority(Notification.PRIORITY_HIGH)
.setShowWhen(true)
.build();
return notif;
}

View file

@ -19,6 +19,14 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import static org.linphone.compatibility.Compatibility.CHAT_NOTIFICATIONS_GROUP;
import static org.linphone.compatibility.Compatibility.INTENT_ANSWER_CALL_NOTIF_ACTION;
import static org.linphone.compatibility.Compatibility.INTENT_HANGUP_CALL_NOTIF_ACTION;
import static org.linphone.compatibility.Compatibility.INTENT_LOCAL_IDENTITY;
import static org.linphone.compatibility.Compatibility.INTENT_NOTIF_ID;
import static org.linphone.compatibility.Compatibility.INTENT_REPLY_NOTIF_ACTION;
import static org.linphone.compatibility.Compatibility.KEY_TEXT_REPLY;
import android.annotation.TargetApi;
import android.app.FragmentTransaction;
import android.app.Notification;
@ -29,45 +37,37 @@ import android.app.RemoteInput;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import org.linphone.R;
import org.linphone.notifications.Notifiable;
import org.linphone.notifications.NotifiableMessage;
import org.linphone.notifications.NotificationBroadcastReceiver;
import org.linphone.utils.FileUtils;
import static org.linphone.compatibility.Compatibility.CHAT_NOTIFICATIONS_GROUP;
import static org.linphone.compatibility.Compatibility.INTENT_ANSWER_CALL_NOTIF_ACTION;
import static org.linphone.compatibility.Compatibility.INTENT_HANGUP_CALL_NOTIF_ACTION;
import static org.linphone.compatibility.Compatibility.INTENT_LOCAL_IDENTITY;
import static org.linphone.compatibility.Compatibility.INTENT_NOTIF_ID;
import static org.linphone.compatibility.Compatibility.INTENT_REPLY_NOTIF_ACTION;
import static org.linphone.compatibility.Compatibility.KEY_TEXT_REPLY;
@TargetApi(26)
public class ApiTwentySixPlus {
public static Notification createRepliedNotification(Context context, String reply) {
return new Notification.Builder(context, context.getString(R.string.notification_channel_id))
.setSmallIcon(R.drawable.topbar_chat_notification)
.setContentText(context.getString(R.string.notification_replied_label).replace("%s", reply))
.build();
}
public static Notification createRepliedNotification(Context context, String reply) {
return new Notification.Builder(
context, context.getString(R.string.notification_channel_id))
.setSmallIcon(R.drawable.topbar_chat_notification)
.setContentText(
context.getString(R.string.notification_replied_label).replace("%s", reply))
.build();
}
public static void createServiceChannel(Context context) {
NotificationManager notificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
// Create service/call notification channel
String id = context.getString(R.string.notification_service_channel_id);
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);
channel.setDescription(description);
channel.enableVibration(false);
channel.enableLights(false);
public static void createServiceChannel(Context context) {
NotificationManager notificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
// Create service/call notification channel
String id = context.getString(R.string.notification_service_channel_id);
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);
channel.setDescription(description);
channel.enableVibration(false);
channel.enableLights(false);
channel.setShowBadge(false);
notificationManager.createNotificationChannel(channel);
}
notificationManager.createNotificationChannel(channel);
}
public static void createMessageChannel(Context context) {
NotificationManager notificationManager =
@ -76,7 +76,8 @@ public class ApiTwentySixPlus {
String id = context.getString(R.string.notification_channel_id);
String name = context.getString(R.string.content_title_notification);
String description = context.getString(R.string.content_title_notification);
NotificationChannel channel = new NotificationChannel(id, name, NotificationManager.IMPORTANCE_HIGH);
NotificationChannel channel =
new NotificationChannel(id, name, NotificationManager.IMPORTANCE_HIGH);
channel.setDescription(description);
channel.setLightColor(context.getColor(R.color.notification_color_led));
channel.enableLights(true);
@ -85,166 +86,213 @@ public class ApiTwentySixPlus {
notificationManager.createNotificationChannel(channel);
}
public static Notification createMessageNotification(Context context, Notifiable notif, Bitmap contactIcon, PendingIntent intent) {
String replyLabel = context.getResources().getString(R.string.notification_reply_label);
RemoteInput remoteInput = new RemoteInput.Builder(KEY_TEXT_REPLY).setLabel(replyLabel).build();
public static Notification createMessageNotification(
Context context, Notifiable notif, Bitmap contactIcon, PendingIntent intent) {
String replyLabel = context.getResources().getString(R.string.notification_reply_label);
RemoteInput remoteInput =
new RemoteInput.Builder(KEY_TEXT_REPLY).setLabel(replyLabel).build();
Intent replyIntent = new Intent(context, NotificationBroadcastReceiver.class);
replyIntent.setAction(INTENT_REPLY_NOTIF_ACTION);
replyIntent.putExtra(INTENT_NOTIF_ID, notif.getNotificationId());
replyIntent.putExtra(INTENT_LOCAL_IDENTITY, notif.getLocalIdentity());
Intent replyIntent = new Intent(context, NotificationBroadcastReceiver.class);
replyIntent.setAction(INTENT_REPLY_NOTIF_ACTION);
replyIntent.putExtra(INTENT_NOTIF_ID, notif.getNotificationId());
replyIntent.putExtra(INTENT_LOCAL_IDENTITY, notif.getLocalIdentity());
PendingIntent replyPendingIntent = PendingIntent.getBroadcast(context,
notif.getNotificationId(), replyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent replyPendingIntent =
PendingIntent.getBroadcast(
context,
notif.getNotificationId(),
replyIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
Notification.Action action = new Notification.Action.Builder(R.drawable.chat_send_over,
context.getString(R.string.notification_reply_label), replyPendingIntent)
.addRemoteInput(remoteInput)
.setAllowGeneratedReplies(true)
.build();
Notification.Action action =
new Notification.Action.Builder(
R.drawable.chat_send_over,
context.getString(R.string.notification_reply_label),
replyPendingIntent)
.addRemoteInput(remoteInput)
.setAllowGeneratedReplies(true)
.build();
Notification.MessagingStyle style = new Notification.MessagingStyle(notif.getMyself());
for (NotifiableMessage message : notif.getMessages()) {
Notification.MessagingStyle.Message msg = new Notification.MessagingStyle.Message(message.getMessage(), message.getTime(), message.getSender());
if (message.getFilePath() != null) msg.setData(message.getFileMime(), message.getFilePath());
Notification.MessagingStyle style = new Notification.MessagingStyle(notif.getMyself());
for (NotifiableMessage message : notif.getMessages()) {
Notification.MessagingStyle.Message msg =
new Notification.MessagingStyle.Message(
message.getMessage(), message.getTime(), message.getSender());
if (message.getFilePath() != null)
msg.setData(message.getFileMime(), message.getFilePath());
style.addMessage(msg);
}
if (notif.isGroup()) {
style.setConversationTitle(notif.getGroupTitle());
}
}
if (notif.isGroup()) {
style.setConversationTitle(notif.getGroupTitle());
}
return new Notification.Builder(context, context.getString(R.string.notification_channel_id))
.setSmallIcon(R.drawable.topbar_chat_notification)
.setAutoCancel(true)
.setContentIntent(intent)
.setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE | Notification.DEFAULT_LIGHTS)
.setLargeIcon(contactIcon)
.setCategory(Notification.CATEGORY_MESSAGE)
.setGroup(CHAT_NOTIFICATIONS_GROUP)
.setVisibility(Notification.VISIBILITY_PRIVATE)
.setPriority(Notification.PRIORITY_HIGH)
.setNumber(notif.getMessages().size())
.setWhen(System.currentTimeMillis())
.setShowWhen(true)
.setColor(context.getColor(R.color.notification_color_led))
.setStyle(style)
.addAction(action)
.build();
}
return new Notification.Builder(
context, context.getString(R.string.notification_channel_id))
.setSmallIcon(R.drawable.topbar_chat_notification)
.setAutoCancel(true)
.setContentIntent(intent)
.setDefaults(
Notification.DEFAULT_SOUND
| Notification.DEFAULT_VIBRATE
| Notification.DEFAULT_LIGHTS)
.setLargeIcon(contactIcon)
.setCategory(Notification.CATEGORY_MESSAGE)
.setGroup(CHAT_NOTIFICATIONS_GROUP)
.setVisibility(Notification.VISIBILITY_PRIVATE)
.setPriority(Notification.PRIORITY_HIGH)
.setNumber(notif.getMessages().size())
.setWhen(System.currentTimeMillis())
.setShowWhen(true)
.setColor(context.getColor(R.color.notification_color_led))
.setStyle(style)
.addAction(action)
.build();
}
public static Notification createInCallNotification(Context context,
int callId, boolean showAnswerAction, String msg, int iconID, Bitmap contactIcon, String contactName, PendingIntent intent) {
public static Notification createInCallNotification(
Context context,
int callId,
boolean showAnswerAction,
String msg,
int iconID,
Bitmap contactIcon,
String contactName,
PendingIntent intent) {
Intent hangupIntent = new Intent(context, NotificationBroadcastReceiver.class);
hangupIntent.setAction(INTENT_HANGUP_CALL_NOTIF_ACTION);
hangupIntent.putExtra(INTENT_NOTIF_ID, callId);
PendingIntent hangupPendingIntent = PendingIntent.getBroadcast(context,
callId, hangupIntent, PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent hangupPendingIntent =
PendingIntent.getBroadcast(
context, callId, hangupIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Notification.Builder builder = new Notification.Builder(context, context.getString(R.string.notification_service_channel_id))
.setContentTitle(contactName)
.setContentText(msg)
.setSmallIcon(iconID)
.setAutoCancel(false)
.setContentIntent(intent)
.setLargeIcon(contactIcon)
.setCategory(Notification.CATEGORY_CALL)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setPriority(Notification.PRIORITY_HIGH)
.setWhen(System.currentTimeMillis())
.setShowWhen(true)
.setColor(context.getColor(R.color.notification_color_led))
.addAction(R.drawable.call_hangup, context.getString(R.string.notification_call_hangup_label), hangupPendingIntent);
Notification.Builder builder =
new Notification.Builder(
context,
context.getString(R.string.notification_service_channel_id))
.setContentTitle(contactName)
.setContentText(msg)
.setSmallIcon(iconID)
.setAutoCancel(false)
.setContentIntent(intent)
.setLargeIcon(contactIcon)
.setCategory(Notification.CATEGORY_CALL)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setPriority(Notification.PRIORITY_HIGH)
.setWhen(System.currentTimeMillis())
.setShowWhen(true)
.setColor(context.getColor(R.color.notification_color_led))
.addAction(
R.drawable.call_hangup,
context.getString(R.string.notification_call_hangup_label),
hangupPendingIntent);
if (showAnswerAction) {
Intent answerIntent = new Intent(context, NotificationBroadcastReceiver.class);
answerIntent.setAction(INTENT_ANSWER_CALL_NOTIF_ACTION);
answerIntent.putExtra(INTENT_NOTIF_ID, callId);
PendingIntent answerPendingIntent = PendingIntent.getBroadcast(context,
callId, answerIntent, PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent answerPendingIntent =
PendingIntent.getBroadcast(
context, callId, answerIntent, PendingIntent.FLAG_UPDATE_CURRENT);
builder.addAction(R.drawable.call_audio_start, context.getString(R.string.notification_call_answer_label), answerPendingIntent);
builder.addAction(
R.drawable.call_audio_start,
context.getString(R.string.notification_call_answer_label),
answerPendingIntent);
}
return builder.build();
}
}
public static Notification createNotification(Context context, String title, String message, int icon, int level,
Bitmap largeIcon, PendingIntent intent, boolean isOngoingEvent,int priority) {
public static Notification createNotification(
Context context,
String title,
String message,
int icon,
int level,
Bitmap largeIcon,
PendingIntent intent,
boolean isOngoingEvent,
int priority) {
if (largeIcon != null) {
return new Notification.Builder(context, context.getString(R.string.notification_service_channel_id))
.setContentTitle(title)
.setContentText(message)
.setSmallIcon(icon, level)
.setLargeIcon(largeIcon)
.setContentIntent(intent)
.setCategory(Notification.CATEGORY_SERVICE)
.setVisibility(Notification.VISIBILITY_SECRET)
.setPriority(priority)
.setWhen(System.currentTimeMillis())
.setShowWhen(true)
.setColor(context.getColor(R.color.notification_color_led))
.build();
} else {
return new Notification.Builder(context, context.getString(R.string.notification_service_channel_id))
.setContentTitle(title)
.setContentText(message)
.setSmallIcon(icon, level)
.setContentIntent(intent)
.setCategory(Notification.CATEGORY_SERVICE)
.setVisibility(Notification.VISIBILITY_SECRET)
.setPriority(priority)
.setWhen(System.currentTimeMillis())
.setShowWhen(true)
.setColor(context.getColor(R.color.notification_color_led))
.build();
}
}
if (largeIcon != null) {
return new Notification.Builder(
context, context.getString(R.string.notification_service_channel_id))
.setContentTitle(title)
.setContentText(message)
.setSmallIcon(icon, level)
.setLargeIcon(largeIcon)
.setContentIntent(intent)
.setCategory(Notification.CATEGORY_SERVICE)
.setVisibility(Notification.VISIBILITY_SECRET)
.setPriority(priority)
.setWhen(System.currentTimeMillis())
.setShowWhen(true)
.setColor(context.getColor(R.color.notification_color_led))
.build();
} else {
return new Notification.Builder(
context, context.getString(R.string.notification_service_channel_id))
.setContentTitle(title)
.setContentText(message)
.setSmallIcon(icon, level)
.setContentIntent(intent)
.setCategory(Notification.CATEGORY_SERVICE)
.setVisibility(Notification.VISIBILITY_SECRET)
.setPriority(priority)
.setWhen(System.currentTimeMillis())
.setShowWhen(true)
.setColor(context.getColor(R.color.notification_color_led))
.build();
}
}
public static Notification createMissedCallNotification(Context context, String title, String text, PendingIntent intent) {
return new Notification.Builder(context, context.getString(R.string.notification_channel_id))
.setContentTitle(title)
.setContentText(text)
.setSmallIcon(R.drawable.call_status_missed)
.setAutoCancel(true)
.setContentIntent(intent)
.setDefaults(Notification.DEFAULT_SOUND
| Notification.DEFAULT_VIBRATE)
.setCategory(Notification.CATEGORY_EVENT)
.setVisibility(Notification.VISIBILITY_PRIVATE)
.setPriority(Notification.PRIORITY_HIGH)
.setWhen(System.currentTimeMillis())
.setShowWhen(true)
.setColor(context.getColor(R.color.notification_color_led))
.build();
}
public static Notification createMissedCallNotification(
Context context, String title, String text, PendingIntent intent) {
return new Notification.Builder(
context, context.getString(R.string.notification_channel_id))
.setContentTitle(title)
.setContentText(text)
.setSmallIcon(R.drawable.call_status_missed)
.setAutoCancel(true)
.setContentIntent(intent)
.setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE)
.setCategory(Notification.CATEGORY_EVENT)
.setVisibility(Notification.VISIBILITY_PRIVATE)
.setPriority(Notification.PRIORITY_HIGH)
.setWhen(System.currentTimeMillis())
.setShowWhen(true)
.setColor(context.getColor(R.color.notification_color_led))
.build();
}
public static Notification createSimpleNotification(Context context, String title, String text, PendingIntent intent) {
return new Notification.Builder(context, context.getString(R.string.notification_channel_id))
.setContentTitle(title)
.setContentText(text)
.setSmallIcon(R.drawable.linphone_logo)
.setAutoCancel(true)
.setContentIntent(intent)
.setDefaults(Notification.DEFAULT_SOUND
| Notification.DEFAULT_VIBRATE)
.setCategory(Notification.CATEGORY_MESSAGE)
.setVisibility(Notification.VISIBILITY_PRIVATE)
.setPriority(Notification.PRIORITY_HIGH)
.setWhen(System.currentTimeMillis())
.setShowWhen(true)
.setColorized(true)
.setColor(context.getColor(R.color.notification_color_led))
.build();
}
public static Notification createSimpleNotification(
Context context, String title, String text, PendingIntent intent) {
return new Notification.Builder(
context, context.getString(R.string.notification_channel_id))
.setContentTitle(title)
.setContentText(text)
.setSmallIcon(R.drawable.linphone_logo)
.setAutoCancel(true)
.setContentIntent(intent)
.setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE)
.setCategory(Notification.CATEGORY_MESSAGE)
.setVisibility(Notification.VISIBILITY_PRIVATE)
.setPriority(Notification.PRIORITY_HIGH)
.setWhen(System.currentTimeMillis())
.setShowWhen(true)
.setColorized(true)
.setColor(context.getColor(R.color.notification_color_led))
.build();
}
public static void startService(Context context, Intent intent) {
context.startForegroundService(intent);
}
public static void startService(Context context, Intent intent) {
context.startForegroundService(intent);
}
public static void setFragmentTransactionReorderingAllowed(FragmentTransaction transaction, boolean allowed) {
transaction.setReorderingAllowed(allowed);
}
public static void setFragmentTransactionReorderingAllowed(
FragmentTransaction transaction, boolean allowed) {
transaction.setReorderingAllowed(allowed);
}
}

View file

@ -27,7 +27,6 @@ import android.graphics.Bitmap;
import android.os.Build;
import android.provider.Settings;
import android.widget.TextView;
import org.linphone.mediastream.Version;
import org.linphone.notifications.Notifiable;
@ -47,29 +46,39 @@ public class Compatibility {
}
}
public static Notification createSimpleNotification(Context context, String title, String text, PendingIntent intent) {
public static Notification createSimpleNotification(
Context context, String title, String text, PendingIntent intent) {
if (Version.sdkAboveOrEqual(Version.API26_O_80)) {
return ApiTwentySixPlus.createSimpleNotification(context, title, text, intent);
}
return ApiTwentyOnePlus.createSimpleNotification(context, title, text, intent);
}
public static Notification createMissedCallNotification(Context context, String title, String text, PendingIntent intent) {
public static Notification createMissedCallNotification(
Context context, String title, String text, PendingIntent intent) {
if (Version.sdkAboveOrEqual(Version.API26_O_80)) {
return ApiTwentySixPlus.createMissedCallNotification(context, title, text, intent);
}
return ApiTwentyOnePlus.createMissedCallNotification(context, title, text, intent);
}
public static Notification createMessageNotification(Context context, Notifiable notif, String msgSender, String msg, Bitmap contactIcon, PendingIntent intent) {
public static Notification createMessageNotification(
Context context,
Notifiable notif,
String msgSender,
String msg,
Bitmap contactIcon,
PendingIntent intent) {
if (Version.sdkAboveOrEqual(28)) {
return ApiTwentyEightPlus.createMessageNotification(context, notif, contactIcon, intent);
return ApiTwentyEightPlus.createMessageNotification(
context, notif, contactIcon, intent);
} else if (Version.sdkAboveOrEqual(Version.API26_O_80)) {
return ApiTwentySixPlus.createMessageNotification(context, notif, contactIcon, intent);
} else if (Version.sdkAboveOrEqual(Version.API24_NOUGAT_70)) {
return ApiTwentyFourPlus.createMessageNotification(context, notif, contactIcon, intent);
}
return ApiTwentyOnePlus.createMessageNotification(context, notif.getMessages().size(), msgSender, msg, contactIcon, intent);
return ApiTwentyOnePlus.createMessageNotification(
context, notif.getMessages().size(), msgSender, msg, contactIcon, intent);
}
public static Notification createRepliedNotification(Context context, String reply) {
@ -81,20 +90,73 @@ public class Compatibility {
return null;
}
public static Notification createInCallNotification(Context context, int callId, boolean showAnswerAction, String title, String msg, int iconID, Bitmap contactIcon, String contactName, PendingIntent intent) {
public static Notification createInCallNotification(
Context context,
int callId,
boolean showAnswerAction,
String title,
String msg,
int iconID,
Bitmap contactIcon,
String contactName,
PendingIntent intent) {
if (Version.sdkAboveOrEqual(Version.API26_O_80)) {
return ApiTwentySixPlus.createInCallNotification(context, callId, showAnswerAction, msg, iconID, contactIcon, contactName, intent);
return ApiTwentySixPlus.createInCallNotification(
context,
callId,
showAnswerAction,
msg,
iconID,
contactIcon,
contactName,
intent);
} else if (Version.sdkAboveOrEqual(Version.API24_NOUGAT_70)) {
return ApiTwentyFourPlus.createInCallNotification(context, callId, showAnswerAction, msg, iconID, contactIcon, contactName, intent);
return ApiTwentyFourPlus.createInCallNotification(
context,
callId,
showAnswerAction,
msg,
iconID,
contactIcon,
contactName,
intent);
}
return ApiTwentyOnePlus.createInCallNotification(context, title, msg, iconID, contactIcon, contactName, intent);
return ApiTwentyOnePlus.createInCallNotification(
context, title, msg, iconID, contactIcon, contactName, intent);
}
public static Notification createNotification(Context context, String title, String message, int icon, int iconLevel, Bitmap largeIcon, PendingIntent intent, boolean isOngoingEvent, int priority) {
public static Notification createNotification(
Context context,
String title,
String message,
int icon,
int iconLevel,
Bitmap largeIcon,
PendingIntent intent,
boolean isOngoingEvent,
int priority) {
if (Version.sdkAboveOrEqual(Version.API26_O_80)) {
return ApiTwentySixPlus.createNotification(context, title, message, icon, iconLevel, largeIcon, intent, isOngoingEvent, priority);
return ApiTwentySixPlus.createNotification(
context,
title,
message,
icon,
iconLevel,
largeIcon,
intent,
isOngoingEvent,
priority);
}
return ApiTwentyOnePlus.createNotification(context, title, message, icon, iconLevel, largeIcon, intent, isOngoingEvent, priority);
return ApiTwentyOnePlus.createNotification(
context,
title,
message,
icon,
iconLevel,
largeIcon,
intent,
isOngoingEvent,
priority);
}
public static boolean canDrawOverlays(Context context) {
@ -120,7 +182,8 @@ public class Compatibility {
}
}
public static void setFragmentTransactionReorderingAllowed(FragmentTransaction transaction, boolean allowed) {
public static void setFragmentTransactionReorderingAllowed(
FragmentTransaction transaction, boolean allowed) {
if (Version.sdkAboveOrEqual(Version.API26_O_80)) {
ApiTwentySixPlus.setFragmentTransactionReorderingAllowed(transaction, allowed);
}

View file

@ -25,7 +25,8 @@ import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
@TargetApi(8)
public class CompatibilityScaleGestureDetector extends ScaleGestureDetector.SimpleOnScaleGestureListener {
public class CompatibilityScaleGestureDetector
extends ScaleGestureDetector.SimpleOnScaleGestureListener {
private ScaleGestureDetector detector;
private CompatibilityScaleGestureListener listener;
@ -58,4 +59,4 @@ public class CompatibilityScaleGestureDetector extends ScaleGestureDetector.Simp
listener = null;
detector = null;
}
}
}

View file

@ -21,4 +21,4 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
public interface CompatibilityScaleGestureListener {
public boolean onScale(CompatibilityScaleGestureDetector detector);
}
}

View file

@ -20,13 +20,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import android.view.View;
import java.io.Serializable;
import org.linphone.core.Address;
import org.linphone.core.Factory;
import org.linphone.core.SearchResult;
import java.io.Serializable;
public class ContactAddress implements Serializable {
private LinphoneContact contact;
private SearchResult result;
@ -37,6 +35,15 @@ public class ContactAddress implements Serializable {
private boolean isAdmin = false;
private transient View view;
public ContactAddress(LinphoneContact c, String a, String pn, boolean isLC) {
init(c, a, pn, isLC);
}
public ContactAddress(LinphoneContact c, String a, String pn, boolean isLC, boolean isAdmin) {
init(c, a, pn, isLC);
this.isAdmin = isAdmin;
}
public boolean isAdmin() {
return isAdmin;
}
@ -49,14 +56,18 @@ public class ContactAddress implements Serializable {
return isSelect;
}
public void setView(View v) {
view = v;
public void setSelect(boolean select) {
isSelect = select;
}
public View getView() {
return view;
}
public void setView(View v) {
view = v;
}
public LinphoneContact getContact() {
return contact;
}
@ -76,7 +87,9 @@ public class ContactAddress implements Serializable {
}
public Address getAddress() {
String presence = contact.getPresenceModelForUriOrTel((phoneNumber != null && !phoneNumber.isEmpty()) ? phoneNumber : address);
String presence =
contact.getPresenceModelForUriOrTel(
(phoneNumber != null && !phoneNumber.isEmpty()) ? phoneNumber : address);
Address addr = Factory.instance().createAddress(presence != null ? presence : address);
// Remove the user=phone URI param if existing, it will break everything otherwise
if (addr.hasUriParam("user")) {
@ -109,10 +122,6 @@ public class ContactAddress implements Serializable {
return phoneNumber;
}
public void setSelect(boolean select) {
isSelect = select;
}
public boolean isLinphoneContact() {
return isLinphoneContact;
}
@ -124,22 +133,13 @@ public class ContactAddress implements Serializable {
isLinphoneContact = isLC;
}
public ContactAddress(LinphoneContact c, String a, String pn, boolean isLC) {
init(c, a, pn, isLC);
}
public ContactAddress(LinphoneContact c, String a, String pn, boolean isLC, boolean isAdmin) {
init(c, a, pn, isLC);
this.isAdmin = isAdmin;
}
@Override
public boolean equals(Object other) {
if (other == null) return false;
if (other == this) return true;
if (!(other instanceof ContactAddress)) return false;
if (((ContactAddress) other).getAddressAsDisplayableString() == this.getAddressAsDisplayableString())
return true;
if (((ContactAddress) other).getAddressAsDisplayableString()
== this.getAddressAsDisplayableString()) return true;
return false;
}
}

View file

@ -25,7 +25,6 @@ import android.app.Fragment;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
@ -35,13 +34,9 @@ import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TableLayout;
import android.widget.TextView;
import org.linphone.LinphoneManager;
import org.linphone.settings.LinphonePreferences;
import org.linphone.utils.ImageUtils;
import org.linphone.utils.LinphoneUtils;
import org.linphone.R;
import org.linphone.LinphoneActivity;
import org.linphone.LinphoneManager;
import org.linphone.R;
import org.linphone.core.Address;
import org.linphone.core.ChatRoom;
import org.linphone.core.ChatRoomListenerStub;
@ -52,6 +47,9 @@ import org.linphone.core.PresenceModel;
import org.linphone.core.ProxyConfig;
import org.linphone.fragments.FragmentsAvailable;
import org.linphone.mediastream.Log;
import org.linphone.settings.LinphonePreferences;
import org.linphone.utils.ImageUtils;
import org.linphone.utils.LinphoneUtils;
public class ContactDetailsFragment extends Fragment implements OnClickListener {
private LinphoneContact contact;
@ -64,49 +62,68 @@ public class ContactDetailsFragment extends Fragment implements OnClickListener
private ChatRoom mChatRoom;
private ChatRoomListenerStub mChatRoomCreationListener;
private OnClickListener dialListener = new OnClickListener() {
@Override
public void onClick(View v) {
if (LinphoneActivity.isInstanciated()) {
String tag = (String) v.getTag();
LinphoneActivity.instance().setAddresGoToDialerAndCall(tag, contact.getFullName(), contact.getPhotoUri());
}
}
};
private OnClickListener dialListener =
new OnClickListener() {
@Override
public void onClick(View v) {
if (LinphoneActivity.isInstanciated()) {
String tag = (String) v.getTag();
LinphoneActivity.instance()
.setAddresGoToDialerAndCall(
tag, contact.getFullName(), contact.getPhotoUri());
}
}
};
private OnClickListener chatListener = new OnClickListener() {
@Override
public void onClick(View v) {
if (LinphoneActivity.isInstanciated()) {
String tag = (String) v.getTag();
Core lc = LinphoneManager.getLc();
Address participant = Factory.instance().createAddress(tag);
ProxyConfig defaultProxyConfig = lc.getDefaultProxyConfig();
boolean isSecured = v.getId() == R.id.contact_chat_secured;
private OnClickListener chatListener =
new OnClickListener() {
@Override
public void onClick(View v) {
if (LinphoneActivity.isInstanciated()) {
String tag = (String) v.getTag();
Core lc = LinphoneManager.getLc();
Address participant = Factory.instance().createAddress(tag);
ProxyConfig defaultProxyConfig = lc.getDefaultProxyConfig();
boolean isSecured = v.getId() == R.id.contact_chat_secured;
if (defaultProxyConfig != null) {
ChatRoom room = lc.findOneToOneChatRoom(defaultProxyConfig.getContact(), participant, isSecured);
if (room != null) {
LinphoneActivity.instance().goToChat(room.getPeerAddress().asStringUriOnly(), null);
} else {
if (defaultProxyConfig.getConferenceFactoryUri() != null && (isSecured || !LinphonePreferences.instance().useBasicChatRoomFor1To1())) {
mWaitLayout.setVisibility(View.VISIBLE);
mChatRoom = lc.createClientGroupChatRoom(getString(R.string.dummy_group_chat_subject), !isSecured, isSecured);
mChatRoom.addListener(mChatRoomCreationListener);
Address participants[] = new Address[1];
participants[0] = participant;
mChatRoom.addParticipants(participants);
} else {
room = lc.getChatRoom(participant);
LinphoneActivity.instance().goToChat(room.getPeerAddress().asStringUriOnly(), null);
if (defaultProxyConfig != null) {
ChatRoom room =
lc.findOneToOneChatRoom(
defaultProxyConfig.getContact(),
participant,
isSecured);
if (room != null) {
LinphoneActivity.instance()
.goToChat(room.getPeerAddress().asStringUriOnly(), null);
} else {
if (defaultProxyConfig.getConferenceFactoryUri() != null
&& (isSecured
|| !LinphonePreferences.instance()
.useBasicChatRoomFor1To1())) {
mWaitLayout.setVisibility(View.VISIBLE);
mChatRoom =
lc.createClientGroupChatRoom(
getString(R.string.dummy_group_chat_subject),
!isSecured,
isSecured);
mChatRoom.addListener(mChatRoomCreationListener);
Address participants[] = new Address[1];
participants[0] = participant;
mChatRoom.addParticipants(participants);
} else {
room = lc.getChatRoom(participant);
LinphoneActivity.instance()
.goToChat(
room.getPeerAddress().asStringUriOnly(), null);
}
}
}
}
}
}
}
};
};
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
contact = (LinphoneContact) getArguments().getSerializable("Contact");
this.inflater = inflater;
@ -141,19 +158,24 @@ public class ContactDetailsFragment extends Fragment implements OnClickListener
back.setOnClickListener(this);
}
mChatRoomCreationListener = new ChatRoomListenerStub() {
@Override
public void onStateChanged(ChatRoom cr, ChatRoom.State newState) {
if (newState == ChatRoom.State.Created) {
mWaitLayout.setVisibility(View.GONE);
LinphoneActivity.instance().goToChat(cr.getPeerAddress().asStringUriOnly(), null);
} else if (newState == ChatRoom.State.CreationFailed) {
mWaitLayout.setVisibility(View.GONE);
LinphoneActivity.instance().displayChatRoomError();
Log.e("Group chat room for address " + cr.getPeerAddress() + " has failed !");
}
}
};
mChatRoomCreationListener =
new ChatRoomListenerStub() {
@Override
public void onStateChanged(ChatRoom cr, ChatRoom.State newState) {
if (newState == ChatRoom.State.Created) {
mWaitLayout.setVisibility(View.GONE);
LinphoneActivity.instance()
.goToChat(cr.getPeerAddress().asStringUriOnly(), null);
} else if (newState == ChatRoom.State.CreationFailed) {
mWaitLayout.setVisibility(View.GONE);
LinphoneActivity.instance().displayChatRoomError();
Log.e(
"Group chat room for address "
+ cr.getPeerAddress()
+ " has failed !");
}
}
};
return view;
}
@ -175,7 +197,11 @@ public class ContactDetailsFragment extends Fragment implements OnClickListener
private void displayContact(LayoutInflater inflater, View view) {
ImageView contactPicture = view.findViewById(R.id.contact_picture);
if (contact.hasPhoto()) {
ImageUtils.setImagePictureFromUri(getActivity(), contactPicture, contact.getPhotoUri(), contact.getThumbnailUri());
ImageUtils.setImagePictureFromUri(
getActivity(),
contactPicture,
contact.getPhotoUri(),
contact.getThumbnailUri());
} else {
contactPicture.setImageBitmap(ContactsManager.getInstance().getDefaultAvatarBitmap());
}
@ -191,7 +217,8 @@ public class ContactDetailsFragment extends Fragment implements OnClickListener
View v = inflater.inflate(R.layout.contact_control_row, null);
String value = noa.getValue();
String displayednumberOrAddress = LinphoneUtils.getDisplayableUsernameFromAddress(value);
String displayednumberOrAddress =
LinphoneUtils.getDisplayableUsernameFromAddress(value);
TextView label = v.findViewById(R.id.address_label);
if (noa.isSIPAddress()) {
@ -206,7 +233,6 @@ public class ContactDetailsFragment extends Fragment implements OnClickListener
tv.setText(displayednumberOrAddress);
tv.setSelected(true);
ProxyConfig lpc = LinphoneManager.getLc().getDefaultProxyConfig();
if (lpc != null) {
String username = lpc.normalizePhoneNumber(displayednumberOrAddress);
@ -221,27 +247,32 @@ public class ContactDetailsFragment extends Fragment implements OnClickListener
if (pm != null && pm.getBasicStatus().equals(PresenceBasicStatus.Open)) {
v.findViewById(R.id.friendLinphone).setVisibility(View.VISIBLE);
} else {
if (getResources().getBoolean(R.bool.hide_numbers_and_addresses_without_presence)) {
if (getResources()
.getBoolean(R.bool.hide_numbers_and_addresses_without_presence)) {
skip = true;
}
}
}
v.findViewById(R.id.inviteFriend).setVisibility(View.GONE);
if (!noa.isSIPAddress() && v.findViewById(R.id.friendLinphone).getVisibility() == View.GONE) {
if (!noa.isSIPAddress()
&& v.findViewById(R.id.friendLinphone).getVisibility() == View.GONE) {
v.findViewById(R.id.inviteFriend).setVisibility(View.VISIBLE);
v.findViewById(R.id.inviteFriend).setTag(noa.getNormalizedPhone());
v.findViewById(R.id.inviteFriend).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
String number = (String)v.getTag();
Intent smsIntent = new Intent(Intent.ACTION_SENDTO);
smsIntent.putExtra("address", number);
smsIntent.setData(Uri.parse("smsto:" + number));
smsIntent.putExtra("sms_body", getString(R.string.invite_friend_text));
startActivity(smsIntent);
}
});
v.findViewById(R.id.inviteFriend)
.setOnClickListener(
new OnClickListener() {
@Override
public void onClick(View v) {
String number = (String) v.getTag();
Intent smsIntent = new Intent(Intent.ACTION_SENDTO);
smsIntent.putExtra("address", number);
smsIntent.setData(Uri.parse("smsto:" + number));
smsIntent.putExtra(
"sms_body", getString(R.string.invite_friend_text));
startActivity(smsIntent);
}
});
}
String contactAddress = contact.getPresenceModelForUriOrTel(noa.getValue());
@ -266,8 +297,8 @@ public class ContactDetailsFragment extends Fragment implements OnClickListener
v.findViewById(R.id.contact_chat_secured).setTag(value);
}
if (v.findViewById(R.id.friendLinphone).getVisibility() == View.VISIBLE /* TODO Does contact have LIME capability ?*/
if (v.findViewById(R.id.friendLinphone).getVisibility()
== View.VISIBLE /* TODO Does contact have LIME capability ?*/
&& lpc.getConferenceFactoryUri() != null) {
v.findViewById(R.id.contact_chat_secured).setVisibility(View.VISIBLE);
} else {
@ -303,26 +334,28 @@ public class ContactDetailsFragment extends Fragment implements OnClickListener
if (id == R.id.editContact) {
ContactsManager.getInstance().editContact(getActivity(), contact, null);
} else if (id == R.id.deleteContact) {
final Dialog dialog = LinphoneActivity.instance().displayDialog(getString(R.string.delete_text));
final Dialog dialog =
LinphoneActivity.instance().displayDialog(getString(R.string.delete_text));
Button delete = dialog.findViewById(R.id.dialog_delete_button);
Button cancel = dialog.findViewById(R.id.dialog_cancel_button);
delete.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
contact.delete();
LinphoneActivity.instance().displayContacts(false);
dialog.dismiss();
}
});
delete.setOnClickListener(
new OnClickListener() {
@Override
public void onClick(View view) {
contact.delete();
LinphoneActivity.instance().displayContacts(false);
dialog.dismiss();
}
});
cancel.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
dialog.dismiss();
}
});
cancel.setOnClickListener(
new OnClickListener() {
@Override
public void onClick(View view) {
dialog.dismiss();
}
});
dialog.show();
} else if (id == R.id.back) {
getFragmentManager().popBackStackImmediate();

View file

@ -1,23 +1,23 @@
package org.linphone.contacts;
/*
ContactEditorFragment.java
Copyright (C) 2017 Belledonne Communications, Grenoble, France
ContactEditorFragment.java
Copyright (C) 2017 Belledonne Communications, Grenoble, France
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import android.annotation.SuppressLint;
import android.app.Activity;
@ -46,34 +46,30 @@ import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import org.linphone.LinphoneManager;
import org.linphone.utils.FileUtils;
import org.linphone.utils.ImageUtils;
import org.linphone.utils.LinphoneUtils;
import org.linphone.R;
import org.linphone.LinphoneActivity;
import org.linphone.mediastream.Log;
import org.linphone.mediastream.Version;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import org.linphone.LinphoneActivity;
import org.linphone.LinphoneManager;
import org.linphone.R;
import org.linphone.mediastream.Log;
import org.linphone.mediastream.Version;
import org.linphone.utils.FileUtils;
import org.linphone.utils.ImageUtils;
import org.linphone.utils.LinphoneUtils;
public class ContactEditorFragment extends Fragment {
private static final int ADD_PHOTO = 1337;
private static final int PHOTO_SIZE = 128;
private View view;
private ImageView cancel, deleteContact, ok;
private ImageView addNumber, addSipAddress, contactPicture;
private LinearLayout phoneNumbersSection, sipAddressesSection;
private EditText firstName, lastName, organization;
private LayoutInflater inflater;
private static final int ADD_PHOTO = 1337;
private static final int PHOTO_SIZE = 128;
private boolean isNewContact;
private LinphoneContact contact;
private List<LinphoneNumberOrAddress> numbersAndAddresses;
@ -83,7 +79,8 @@ public class ContactEditorFragment extends Fragment {
private Uri pickedPhotoForContactUri;
private byte[] photoToAdd;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
this.inflater = inflater;
contact = null;
@ -111,8 +108,9 @@ public class ContactEditorFragment extends Fragment {
view = inflater.inflate(R.layout.contact_edit, container, false);
phoneNumbersSection = view.findViewById(R.id.phone_numbers);
if (getResources().getBoolean(R.bool.hide_phone_numbers_in_editor) || !ContactsManager.getInstance().hasContactsAccess()) {
//Currently linphone friends don't support phone numbers, so hide them
if (getResources().getBoolean(R.bool.hide_phone_numbers_in_editor)
|| !ContactsManager.getInstance().hasContactsAccess()) {
// Currently linphone friends don't support phone numbers, so hide them
phoneNumbersSection.setVisibility(View.GONE);
}
@ -124,97 +122,106 @@ public class ContactEditorFragment extends Fragment {
deleteContact = view.findViewById(R.id.delete_contact);
cancel = view.findViewById(R.id.cancel);
cancel.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
getFragmentManager().popBackStackImmediate();
}
});
cancel.setOnClickListener(
new OnClickListener() {
@Override
public void onClick(View v) {
getFragmentManager().popBackStackImmediate();
}
});
ok = view.findViewById(R.id.ok);
ok.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (isNewContact) {
boolean areAllFielsEmpty = true;
for (LinphoneNumberOrAddress nounoa : numbersAndAddresses) {
if (nounoa.getValue() != null && !nounoa.getValue().equals("")) {
areAllFielsEmpty = false;
break;
ok.setOnClickListener(
new OnClickListener() {
@Override
public void onClick(View v) {
if (isNewContact) {
boolean areAllFielsEmpty = true;
for (LinphoneNumberOrAddress nounoa : numbersAndAddresses) {
if (nounoa.getValue() != null && !nounoa.getValue().equals("")) {
areAllFielsEmpty = false;
break;
}
}
if (areAllFielsEmpty) {
getFragmentManager().popBackStackImmediate();
return;
}
contact = LinphoneContact.createContact();
}
}
if (areAllFielsEmpty) {
contact.setFirstNameAndLastName(
firstName.getText().toString(),
lastName.getText().toString(),
true);
if (photoToAdd != null) {
contact.setPhoto(photoToAdd);
}
for (LinphoneNumberOrAddress noa : numbersAndAddresses) {
if (noa.isSIPAddress() && noa.getValue() != null) {
noa.setValue(
LinphoneUtils.getFullAddressFromUsername(noa.getValue()));
}
contact.addOrUpdateNumberOrAddress(noa);
}
contact.setOrganization(organization.getText().toString(), true);
contact.save();
getFragmentManager().popBackStackImmediate();
return;
}
contact = LinphoneContact.createContact();
}
contact.setFirstNameAndLastName(firstName.getText().toString(), lastName.getText().toString(), true);
if (photoToAdd != null) {
contact.setPhoto(photoToAdd);
}
for (LinphoneNumberOrAddress noa : numbersAndAddresses) {
if (noa.isSIPAddress() && noa.getValue() != null) {
noa.setValue(LinphoneUtils.getFullAddressFromUsername(noa.getValue()));
}
contact.addOrUpdateNumberOrAddress(noa);
}
contact.setOrganization(organization.getText().toString(), true);
contact.save();
getFragmentManager().popBackStackImmediate();
}
});
});
lastName = view.findViewById(R.id.contactLastName);
// Hack to display keyboard when touching focused edittext on Nexus One
if (Version.sdkStrictlyBelow(Version.API11_HONEYCOMB_30)) {
lastName.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
InputMethodManager imm = (InputMethodManager) LinphoneActivity.instance().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
}
});
lastName.setOnClickListener(
new OnClickListener() {
@Override
public void onClick(View v) {
InputMethodManager imm =
(InputMethodManager)
LinphoneActivity.instance()
.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
}
});
}
lastName.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (lastName.getText().length() > 0 || firstName.getText().length() > 0) {
ok.setEnabled(true);
} else {
ok.setEnabled(false);
}
}
lastName.addTextChangedListener(
new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (lastName.getText().length() > 0 || firstName.getText().length() > 0) {
ok.setEnabled(true);
} else {
ok.setEnabled(false);
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void beforeTextChanged(
CharSequence s, int start, int count, int after) {}
@Override
public void afterTextChanged(Editable s) {
}
});
@Override
public void afterTextChanged(Editable s) {}
});
firstName = view.findViewById(R.id.contactFirstName);
firstName.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (firstName.getText().length() > 0 || lastName.getText().length() > 0) {
ok.setEnabled(true);
} else {
ok.setEnabled(false);
}
}
firstName.addTextChangedListener(
new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (firstName.getText().length() > 0 || lastName.getText().length() > 0) {
ok.setEnabled(true);
} else {
ok.setEnabled(false);
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
});
@Override
public void beforeTextChanged(
CharSequence s, int start, int count, int after) {}
@Override
public void afterTextChanged(Editable s) {}
});
organization = view.findViewById(R.id.contactOrganization);
boolean isOrgVisible = getResources().getBoolean(R.bool.display_contact_organization);
@ -238,50 +245,59 @@ public class ContactEditorFragment extends Fragment {
firstName.setText("");
}
deleteContact.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
final Dialog dialog = LinphoneActivity.instance().displayDialog(getString(R.string.delete_text));
Button delete = dialog.findViewById(R.id.dialog_delete_button);
Button cancel = dialog.findViewById(R.id.dialog_cancel_button);
delete.setOnClickListener(new OnClickListener() {
deleteContact.setOnClickListener(
new OnClickListener() {
@Override
public void onClick(View view) {
contact.delete();
LinphoneActivity.instance().displayContacts(false);
dialog.dismiss();
public void onClick(View v) {
final Dialog dialog =
LinphoneActivity.instance()
.displayDialog(getString(R.string.delete_text));
Button delete = dialog.findViewById(R.id.dialog_delete_button);
Button cancel = dialog.findViewById(R.id.dialog_cancel_button);
delete.setOnClickListener(
new OnClickListener() {
@Override
public void onClick(View view) {
contact.delete();
LinphoneActivity.instance().displayContacts(false);
dialog.dismiss();
}
});
cancel.setOnClickListener(
new OnClickListener() {
@Override
public void onClick(View view) {
dialog.dismiss();
}
});
dialog.show();
}
});
cancel.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
dialog.dismiss();
}
});
dialog.show();
}
});
} else {
deleteContact.setVisibility(View.INVISIBLE);
}
contactPicture = view.findViewById(R.id.contact_picture);
if (contact != null) {
ImageUtils.setImagePictureFromUri(getActivity(), contactPicture, contact.getPhotoUri(), contact.getThumbnailUri());
ImageUtils.setImagePictureFromUri(
getActivity(),
contactPicture,
contact.getPhotoUri(),
contact.getThumbnailUri());
} else {
contactPicture.setImageBitmap(ContactsManager.getInstance().getDefaultAvatarBitmap());
}
contactPicture.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
pickImage();
LinphoneActivity.instance().checkAndRequestCameraPermission();
}
});
contactPicture.setOnClickListener(
new OnClickListener() {
@Override
public void onClick(View view) {
pickImage();
LinphoneActivity.instance().checkAndRequestCameraPermission();
}
});
numbersAndAddresses = new ArrayList<>();
sipAddresses = initSipAddressFields(contact);
@ -291,23 +307,25 @@ public class ContactEditorFragment extends Fragment {
if (getResources().getBoolean(R.bool.allow_only_one_sip_address)) {
addSipAddress.setVisibility(View.GONE);
}
addSipAddress.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
addEmptyRowToAllowNewNumberOrAddress(sipAddresses, true);
}
});
addSipAddress.setOnClickListener(
new OnClickListener() {
@Override
public void onClick(View view) {
addEmptyRowToAllowNewNumberOrAddress(sipAddresses, true);
}
});
addNumber = view.findViewById(R.id.add_number_field);
if (getResources().getBoolean(R.bool.allow_only_one_phone_number)) {
addNumber.setVisibility(View.GONE);
}
addNumber.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
addEmptyRowToAllowNewNumberOrAddress(numbers, false);
}
});
addNumber.setOnClickListener(
new OnClickListener() {
@Override
public void onClick(View view) {
addEmptyRowToAllowNewNumberOrAddress(numbers, false);
}
});
lastName.requestFocus();
@ -318,17 +336,21 @@ public class ContactEditorFragment extends Fragment {
public void onResume() {
super.onResume();
if (LinphoneActivity.isInstanciated()) {
}
if (LinphoneActivity.isInstanciated()) {}
// Force hide keyboard
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
getActivity()
.getWindow()
.setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN
| WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
}
@Override
public void onPause() {
// Force hide keyboard
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
InputMethodManager imm =
(InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
View view = getActivity().getCurrentFocus();
if (imm != null && view != null) {
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
@ -341,7 +363,10 @@ public class ContactEditorFragment extends Fragment {
pickedPhotoForContactUri = null;
final List<Intent> cameraIntents = new ArrayList<>();
final Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File file = new File(FileUtils.getStorageDirectory(LinphoneActivity.instance()), getString(R.string.temp_photo_name));
File file =
new File(
FileUtils.getStorageDirectory(LinphoneActivity.instance()),
getString(R.string.temp_photo_name));
pickedPhotoForContactUri = Uri.fromFile(file);
captureIntent.putExtra("outputX", PHOTO_SIZE);
captureIntent.putExtra("outputY", PHOTO_SIZE);
@ -356,8 +381,10 @@ public class ContactEditorFragment extends Fragment {
galleryIntent.setType("image/*");
galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
final Intent chooserIntent = Intent.createChooser(galleryIntent, getString(R.string.image_picker_title));
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[]{}));
final Intent chooserIntent =
Intent.createChooser(galleryIntent, getString(R.string.image_picker_title));
chooserIntent.putExtra(
Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[] {}));
startActivityForResult(chooserIntent, ADD_PHOTO);
}
@ -371,8 +398,12 @@ public class ContactEditorFragment extends Fragment {
} else if (data != null && data.getData() != null) {
Uri selectedImageUri = data.getData();
try {
Bitmap selectedImage = MediaStore.Images.Media.getBitmap(LinphoneManager.getInstance().getContext().getContentResolver(), selectedImageUri);
selectedImage = Bitmap.createScaledBitmap(selectedImage, PHOTO_SIZE, PHOTO_SIZE, false);
Bitmap selectedImage =
MediaStore.Images.Media.getBitmap(
LinphoneManager.getInstance().getContext().getContentResolver(),
selectedImageUri);
selectedImage =
Bitmap.createScaledBitmap(selectedImage, PHOTO_SIZE, PHOTO_SIZE, false);
editContactPicture(null, selectedImage);
} catch (IOException e) {
Log.e(e);
@ -381,7 +412,10 @@ public class ContactEditorFragment extends Fragment {
String filePath = pickedPhotoForContactUri.getPath();
editContactPicture(filePath, null);
} else {
File file = new File(FileUtils.getStorageDirectory(LinphoneActivity.instance()), getString(R.string.temp_photo_name));
File file =
new File(
FileUtils.getStorageDirectory(LinphoneActivity.instance()),
getString(R.string.temp_photo_name));
if (file.exists()) {
pickedPhotoForContactUri = Uri.fromFile(file);
String filePath = pickedPhotoForContactUri.getPath();
@ -415,7 +449,15 @@ public class ContactEditorFragment extends Fragment {
private int getThumbnailSize() {
int value = -1;
Cursor c = LinphoneActivity.instance().getContentResolver().query(DisplayPhoto.CONTENT_MAX_DIMENSIONS_URI, new String[]{DisplayPhoto.THUMBNAIL_MAX_DIM}, null, null, null);
Cursor c =
LinphoneActivity.instance()
.getContentResolver()
.query(
DisplayPhoto.CONTENT_MAX_DIMENSIONS_URI,
new String[] {DisplayPhoto.THUMBNAIL_MAX_DIM},
null,
null,
null);
try {
c.moveToFirst();
value = c.getInt(0);
@ -433,25 +475,24 @@ public class ContactEditorFragment extends Fragment {
for (LinphoneNumberOrAddress numberOrAddress : contact.getNumbersOrAddresses()) {
if (!numberOrAddress.isSIPAddress()) {
View view = displayNumberOrAddress(controls, numberOrAddress.getValue(), false);
if (view != null)
controls.addView(view);
if (view != null) controls.addView(view);
}
}
}
if (newSipOrNumberToAdd != null) {
boolean isSip = LinphoneUtils.isStrictSipAddress(newSipOrNumberToAdd) || !LinphoneUtils.isNumberAddress(newSipOrNumberToAdd);
boolean isSip =
LinphoneUtils.isStrictSipAddress(newSipOrNumberToAdd)
|| !LinphoneUtils.isNumberAddress(newSipOrNumberToAdd);
if (!isSip) {
View view = displayNumberOrAddress(controls, newSipOrNumberToAdd, false);
if (view != null)
controls.addView(view);
if (view != null) controls.addView(view);
}
}
if (newDisplayName != null) {
EditText lastNameEditText = view.findViewById(R.id.contactLastName);
if (view != null)
lastNameEditText.setText(newDisplayName);
if (view != null) lastNameEditText.setText(newDisplayName);
}
if (controls.getChildCount() == 0) {
@ -469,18 +510,18 @@ public class ContactEditorFragment extends Fragment {
for (LinphoneNumberOrAddress numberOrAddress : contact.getNumbersOrAddresses()) {
if (numberOrAddress.isSIPAddress()) {
View view = displayNumberOrAddress(controls, numberOrAddress.getValue(), true);
if (view != null)
controls.addView(view);
if (view != null) controls.addView(view);
}
}
}
if (newSipOrNumberToAdd != null) {
boolean isSip = LinphoneUtils.isStrictSipAddress(newSipOrNumberToAdd) || !LinphoneUtils.isNumberAddress(newSipOrNumberToAdd);
boolean isSip =
LinphoneUtils.isStrictSipAddress(newSipOrNumberToAdd)
|| !LinphoneUtils.isNumberAddress(newSipOrNumberToAdd);
if (isSip) {
View view = displayNumberOrAddress(controls, newSipOrNumberToAdd, true);
if (view != null)
controls.addView(view);
if (view != null) controls.addView(view);
}
}
@ -491,24 +532,31 @@ public class ContactEditorFragment extends Fragment {
return controls;
}
private View displayNumberOrAddress(final LinearLayout controls, String numberOrAddress, boolean isSIP) {
private View displayNumberOrAddress(
final LinearLayout controls, String numberOrAddress, boolean isSIP) {
return displayNumberOrAddress(controls, numberOrAddress, isSIP, false);
}
@SuppressLint("InflateParams")
private View displayNumberOrAddress(final LinearLayout controls, String numberOrAddress, boolean isSIP, boolean forceAddNumber) {
private View displayNumberOrAddress(
final LinearLayout controls,
String numberOrAddress,
boolean isSIP,
boolean forceAddNumber) {
String displayNumberOrAddress = numberOrAddress;
if (isSIP) {
if (firstSipAddressIndex == -1) {
firstSipAddressIndex = controls.getChildCount();
}
displayNumberOrAddress = LinphoneUtils.getDisplayableUsernameFromAddress(numberOrAddress);
displayNumberOrAddress =
LinphoneUtils.getDisplayableUsernameFromAddress(numberOrAddress);
}
if ((getResources().getBoolean(R.bool.hide_phone_numbers_in_editor) && !isSIP) || (getResources().getBoolean(R.bool.hide_sip_addresses_in_editor) && isSIP)) {
if ((getResources().getBoolean(R.bool.hide_phone_numbers_in_editor) && !isSIP)
|| (getResources().getBoolean(R.bool.hide_sip_addresses_in_editor) && isSIP)) {
if (forceAddNumber)
isSIP = !isSIP; // If number can't be displayed because we hide a sort of number, change that category
else
return null;
isSIP = !isSIP; // If number can't be displayed because we hide a sort of number,
// change that category
else return null;
}
LinphoneNumberOrAddress tempNounoa;
@ -531,44 +579,46 @@ public class ContactEditorFragment extends Fragment {
noa.setInputType(InputType.TYPE_CLASS_PHONE);
}
noa.setText(displayNumberOrAddress);
noa.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
nounoa.setValue(noa.getText().toString());
}
noa.addTextChangedListener(
new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
nounoa.setValue(noa.getText().toString());
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void beforeTextChanged(
CharSequence s, int start, int count, int after) {}
@Override
public void afterTextChanged(Editable s) {
}
});
@Override
public void afterTextChanged(Editable s) {}
});
if (forceAddNumber) {
nounoa.setValue(noa.getText().toString());
}
ImageView delete = view.findViewById(R.id.delete_field);
if ((getResources().getBoolean(R.bool.allow_only_one_phone_number) && !isSIP) || (getResources().getBoolean(R.bool.allow_only_one_sip_address) && isSIP)) {
if ((getResources().getBoolean(R.bool.allow_only_one_phone_number) && !isSIP)
|| (getResources().getBoolean(R.bool.allow_only_one_sip_address) && isSIP)) {
delete.setVisibility(View.GONE);
}
delete.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (contact != null) {
contact.removeNumberOrAddress(nounoa);
}
numbersAndAddresses.remove(nounoa);
view.setVisibility(View.GONE);
}
});
delete.setOnClickListener(
new OnClickListener() {
@Override
public void onClick(View v) {
if (contact != null) {
contact.removeNumberOrAddress(nounoa);
}
numbersAndAddresses.remove(nounoa);
view.setVisibility(View.GONE);
}
});
return view;
}
@SuppressLint("InflateParams")
private void addEmptyRowToAllowNewNumberOrAddress(final LinearLayout controls, final boolean isSip) {
private void addEmptyRowToAllowNewNumberOrAddress(
final LinearLayout controls, final boolean isSip) {
final View view = inflater.inflate(R.layout.contact_edit_row, null);
final LinphoneNumberOrAddress nounoa = new LinphoneNumberOrAddress(null, isSip);
@ -579,33 +629,35 @@ public class ContactEditorFragment extends Fragment {
noa.setInputType(InputType.TYPE_CLASS_PHONE);
}
noa.requestFocus();
noa.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
nounoa.setValue(noa.getText().toString());
}
noa.addTextChangedListener(
new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
nounoa.setValue(noa.getText().toString());
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void beforeTextChanged(
CharSequence s, int start, int count, int after) {}
@Override
public void afterTextChanged(Editable s) {
}
});
@Override
public void afterTextChanged(Editable s) {}
});
final ImageView delete = view.findViewById(R.id.delete_field);
if ((getResources().getBoolean(R.bool.allow_only_one_phone_number) && !isSip) || (getResources().getBoolean(R.bool.allow_only_one_sip_address) && isSip)) {
if ((getResources().getBoolean(R.bool.allow_only_one_phone_number) && !isSip)
|| (getResources().getBoolean(R.bool.allow_only_one_sip_address) && isSip)) {
delete.setVisibility(View.GONE);
}
delete.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
numbersAndAddresses.remove(nounoa);
view.setVisibility(View.GONE);
}
});
delete.setOnClickListener(
new OnClickListener() {
@Override
public void onClick(View v) {
numbersAndAddresses.remove(nounoa);
view.setVisibility(View.GONE);
}
});
controls.addView(view);
}
}
}

View file

@ -1,21 +1,21 @@
/*
ContactPicked.java
Copyright (C) 2017 Belledonne Communications, Grenoble, France
ContactPicked.java
Copyright (C) 2017 Belledonne Communications, Grenoble, France
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.linphone.contacts;
@ -23,4 +23,4 @@ import android.net.Uri;
public interface ContactPicked {
void setAddresGoToDialerAndCall(String number, String name, Uri photo);
}
}

View file

@ -1,27 +1,25 @@
package org.linphone.contacts;
/*
ContactsListAdapter.java
Copyright (C) 2018 Belledonne Communications, Grenoble, France
ContactsListAdapter.java
Copyright (C) 2018 Belledonne Communications, Grenoble, France
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -31,67 +29,20 @@ import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.SectionIndexer;
import android.widget.TextView;
import org.linphone.R;
import org.linphone.views.ContactAvatar;
import org.linphone.utils.SelectableAdapter;
import org.linphone.utils.SelectableHelper;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.linphone.R;
import org.linphone.utils.SelectableAdapter;
import org.linphone.utils.SelectableHelper;
import org.linphone.views.ContactAvatar;
public class ContactsListAdapter extends SelectableAdapter<ContactsListAdapter.ViewHolder> implements SectionIndexer {
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
public CheckBox delete;
public ImageView linphoneFriend;
public TextView name;
public LinearLayout separator;
public TextView separatorText;
public RelativeLayout avatarLayout;
public TextView organization;
//public ImageView friendStatus;
private ClickListener mListener;
private ViewHolder(View view, ClickListener listener) {
super(view);
delete = view.findViewById(R.id.delete);
linphoneFriend = view.findViewById(R.id.friendLinphone);
name = view.findViewById(R.id.name);
separator = view.findViewById(R.id.separator);
separatorText = view.findViewById(R.id.separator_text);
avatarLayout = view.findViewById(R.id.avatar_layout);
organization = view.findViewById(R.id.contactOrganization);
//friendStatus = view.findViewById(R.id.friendStatus);
mListener = listener;
view.setOnClickListener(this);
view.setOnLongClickListener(this);
}
@Override
public void onClick(View view) {
if (mListener != null) {
mListener.onItemClicked(getAdapterPosition());
}
}
public boolean onLongClick(View v) {
if (mListener != null) {
return mListener.onItemLongClicked(getAdapterPosition());
}
return false;
}
public interface ClickListener {
void onItemClicked(int position);
boolean onItemLongClicked(int position);
}
}
public class ContactsListAdapter extends SelectableAdapter<ContactsListAdapter.ViewHolder>
implements SectionIndexer {
private List<LinphoneContact> mContacts;
private String[] mSections;
private ArrayList<String> mSectionsList;
@ -100,7 +51,11 @@ public class ContactsListAdapter extends SelectableAdapter<ContactsListAdapter.V
private Context mContext;
private boolean mIsSearchMode;
ContactsListAdapter(Context context, List<LinphoneContact> contactsList, ViewHolder.ClickListener clickListener, SelectableHelper helper) {
ContactsListAdapter(
Context context,
List<LinphoneContact> contactsList,
ViewHolder.ClickListener clickListener,
SelectableHelper helper) {
super(helper);
mContext = context;
updateDataSet(contactsList);
@ -110,7 +65,9 @@ public class ContactsListAdapter extends SelectableAdapter<ContactsListAdapter.V
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.contact_cell, parent, false);
View v =
LayoutInflater.from(parent.getContext())
.inflate(R.layout.contact_cell, parent, false);
return new ViewHolder(v, mClickListener);
}
@ -126,12 +83,19 @@ public class ContactsListAdapter extends SelectableAdapter<ContactsListAdapter.V
holder.separatorText.setText(String.valueOf(fullName.charAt(0)));
}
}
holder.separator.setVisibility(mIsSearchMode || (!mIsSearchMode && getPositionForSection(getSectionForPosition(position)) != position) ? View.GONE : View.VISIBLE);
holder.separator.setVisibility(
mIsSearchMode
|| (!mIsSearchMode
&& getPositionForSection(getSectionForPosition(position))
!= position)
? View.GONE
: View.VISIBLE);
holder.linphoneFriend.setVisibility(contact.isInFriendList() ? View.VISIBLE : View.GONE);
ContactAvatar.displayAvatar(contact, holder.avatarLayout);
boolean isOrgVisible = mContext.getResources().getBoolean(R.bool.display_contact_organization);
boolean isOrgVisible =
mContext.getResources().getBoolean(R.bool.display_contact_organization);
String org = contact.getOrganization();
if (org != null && !org.isEmpty() && isOrgVisible) {
holder.organization.setText(org);
@ -212,4 +176,53 @@ public class ContactsListAdapter extends SelectableAdapter<ContactsListAdapter.V
String letter = fullName.substring(0, 1).toUpperCase(Locale.getDefault());
return mSectionsList.indexOf(letter);
}
}
public static class ViewHolder extends RecyclerView.ViewHolder
implements View.OnClickListener, View.OnLongClickListener {
public CheckBox delete;
public ImageView linphoneFriend;
public TextView name;
public LinearLayout separator;
public TextView separatorText;
public RelativeLayout avatarLayout;
public TextView organization;
// public ImageView friendStatus;
private ClickListener mListener;
private ViewHolder(View view, ClickListener listener) {
super(view);
delete = view.findViewById(R.id.delete);
linphoneFriend = view.findViewById(R.id.friendLinphone);
name = view.findViewById(R.id.name);
separator = view.findViewById(R.id.separator);
separatorText = view.findViewById(R.id.separator_text);
avatarLayout = view.findViewById(R.id.avatar_layout);
organization = view.findViewById(R.id.contactOrganization);
// friendStatus = view.findViewById(R.id.friendStatus);
mListener = listener;
view.setOnClickListener(this);
view.setOnLongClickListener(this);
}
@Override
public void onClick(View view) {
if (mListener != null) {
mListener.onItemClicked(getAdapterPosition());
}
}
public boolean onLongClick(View v) {
if (mListener != null) {
return mListener.onItemLongClicked(getAdapterPosition());
}
return false;
}
public interface ClickListener {
void onItemClicked(int position);
boolean onItemLongClicked(int position);
}
}
}

View file

@ -19,17 +19,9 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import android.app.Fragment;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.provider.ContactsContract;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -39,17 +31,22 @@ import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.SearchView;
import android.widget.TextView;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
import org.linphone.LinphoneActivity;
import org.linphone.LinphoneManager;
import org.linphone.R;
import org.linphone.LinphoneActivity;
import org.linphone.fragments.FragmentsAvailable;
import org.linphone.utils.SelectableHelper;
import java.util.ArrayList;
import java.util.List;
public class ContactsListFragment extends Fragment implements OnItemClickListener, ContactsUpdatedListener, ContactsListAdapter.ViewHolder.ClickListener, SelectableHelper.DeleteListener {
public class ContactsListFragment extends Fragment
implements OnItemClickListener,
ContactsUpdatedListener,
ContactsListAdapter.ViewHolder.ClickListener,
SelectableHelper.DeleteListener {
private RecyclerView contactsList;
private TextView noSipContact, noContact;
private ImageView allContacts, linphoneContacts, newContact;
@ -66,7 +63,8 @@ public class ContactsListFragment extends Fragment implements OnItemClickListene
private ContactsListAdapter mContactAdapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.contacts_list, container, false);
mContext = getActivity().getApplicationContext();
mSelectionHelper = new SelectableHelper(view, this);
@ -91,37 +89,41 @@ public class ContactsListFragment extends Fragment implements OnItemClickListene
contactsFetchInProgress = view.findViewById(R.id.contactsFetchInProgress);
newContact = view.findViewById(R.id.newContact);
allContacts.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onlyDisplayLinphoneContacts = false;
allContactsSelected.setVisibility(View.VISIBLE);
allContacts.setEnabled(false);
linphoneContacts.setEnabled(true);
linphoneContactsSelected.setVisibility(View.INVISIBLE);
changeContactsAdapter();
}
});
allContacts.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
onlyDisplayLinphoneContacts = false;
allContactsSelected.setVisibility(View.VISIBLE);
allContacts.setEnabled(false);
linphoneContacts.setEnabled(true);
linphoneContactsSelected.setVisibility(View.INVISIBLE);
changeContactsAdapter();
}
});
linphoneContacts.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
allContactsSelected.setVisibility(View.INVISIBLE);
linphoneContactsSelected.setVisibility(View.VISIBLE);
linphoneContacts.setEnabled(false);
allContacts.setEnabled(true);
onlyDisplayLinphoneContacts = true;
changeContactsAdapter();
}
});
linphoneContacts.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
allContactsSelected.setVisibility(View.INVISIBLE);
linphoneContactsSelected.setVisibility(View.VISIBLE);
linphoneContacts.setEnabled(false);
allContacts.setEnabled(true);
onlyDisplayLinphoneContacts = true;
changeContactsAdapter();
}
});
newContact.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
editConsumed = true;
ContactsManager.getInstance().createContact(getActivity(), displayName, sipAddressToAdd);
}
});
newContact.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
editConsumed = true;
ContactsManager.getInstance()
.createContact(getActivity(), displayName, sipAddressToAdd);
}
});
if (getResources().getBoolean(R.bool.hide_non_linphone_contacts)) {
allContacts.setEnabled(false);
@ -140,40 +142,47 @@ public class ContactsListFragment extends Fragment implements OnItemClickListene
if (!ContactsManager.getInstance().contactsFetchedOnce()) {
contactsFetchInProgress.setVisibility(View.VISIBLE);
} else {
if (!onlyDisplayLinphoneContacts && ContactsManager.getInstance().getContacts().size() == 0) {
if (!onlyDisplayLinphoneContacts
&& ContactsManager.getInstance().getContacts().size() == 0) {
noContact.setVisibility(View.VISIBLE);
} else if (onlyDisplayLinphoneContacts && ContactsManager.getInstance().getSIPContacts().size() == 0) {
} else if (onlyDisplayLinphoneContacts
&& ContactsManager.getInstance().getSIPContacts().size() == 0) {
noSipContact.setVisibility(View.VISIBLE);
}
}
mSearchView = view.findViewById(R.id.searchField);
mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return true;
}
mSearchView.setOnQueryTextListener(
new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return true;
}
@Override
public boolean onQueryTextChange(String newText) {
searchContacts(newText);
return true;
}
});
@Override
public boolean onQueryTextChange(String newText) {
searchContacts(newText);
return true;
}
});
layoutManager = new LinearLayoutManager(mContext);
contactsList.setLayoutManager(layoutManager);
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(contactsList.getContext(),
layoutManager.getOrientation());
dividerItemDecoration.setDrawable(getActivity().getResources().getDrawable(R.drawable.divider));
DividerItemDecoration dividerItemDecoration =
new DividerItemDecoration(
contactsList.getContext(), layoutManager.getOrientation());
dividerItemDecoration.setDrawable(
getActivity().getResources().getDrawable(R.drawable.divider));
contactsList.addItemDecoration(dividerItemDecoration);
return view;
}
public void displayFirstContact() {
if (contactsList != null && contactsList.getAdapter() != null && contactsList.getAdapter().getItemCount() > 0) {
if (contactsList != null
&& contactsList.getAdapter() != null
&& contactsList.getAdapter().getItemCount() > 0) {
ContactsListAdapter mAdapt = (ContactsListAdapter) contactsList.getAdapter();
LinphoneActivity.instance().displayContact((LinphoneContact) mAdapt.getItem(0), false);
} else {
@ -203,7 +212,7 @@ public class ContactsListFragment extends Fragment implements OnItemClickListene
mContactAdapter = new ContactsListAdapter(mContext, listContact, this, mSelectionHelper);
// contactsList.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE);
// contactsList.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE);
mSelectionHelper.setAdapter(mContactAdapter);
if (isEditionEnabled) {
mSelectionHelper.enterEditionMode();
@ -211,7 +220,6 @@ public class ContactsListFragment extends Fragment implements OnItemClickListene
contactsList.setAdapter(mContactAdapter);
}
private void changeContactsAdapter() {
changeContactsToggle();
List<LinphoneContact> listContact;
@ -228,9 +236,13 @@ public class ContactsListFragment extends Fragment implements OnItemClickListene
}
} else {
if (onlyDisplayLinphoneContacts) {
listContact = ContactsManager.getInstance().getSIPContacts(mSearchView.getQuery().toString());
listContact =
ContactsManager.getInstance()
.getSIPContacts(mSearchView.getQuery().toString());
} else {
listContact = ContactsManager.getInstance().getContacts(mSearchView.getQuery().toString());
listContact =
ContactsManager.getInstance()
.getContacts(mSearchView.getQuery().toString());
}
}
@ -257,7 +269,8 @@ public class ContactsListFragment extends Fragment implements OnItemClickListene
}
private void changeContactsToggle() {
if (onlyDisplayLinphoneContacts && !getResources().getBoolean(R.bool.hide_non_linphone_contacts)) {
if (onlyDisplayLinphoneContacts
&& !getResources().getBoolean(R.bool.hide_non_linphone_contacts)) {
allContacts.setEnabled(true);
allContactsSelected.setVisibility(View.INVISIBLE);
linphoneContacts.setEnabled(false);
@ -319,7 +332,9 @@ public class ContactsListFragment extends Fragment implements OnItemClickListene
if (LinphoneActivity.isInstanciated()) {
LinphoneActivity.instance().selectMenu(FragmentsAvailable.CONTACTS_LIST);
onlyDisplayLinphoneContacts = ContactsManager.getInstance().isLinphoneContactsPrefered() || getResources().getBoolean(R.bool.hide_non_linphone_contacts);
onlyDisplayLinphoneContacts =
ContactsManager.getInstance().isLinphoneContactsPrefered()
|| getResources().getBoolean(R.bool.hide_non_linphone_contacts);
}
changeContactsToggle();
invalidate();
@ -333,10 +348,14 @@ public class ContactsListFragment extends Fragment implements OnItemClickListene
@Override
public void onContactsUpdated() {
if (!LinphoneActivity.isInstanciated() || LinphoneActivity.instance().getCurrentFragment() != FragmentsAvailable.CONTACTS_LIST)
return;
if (!LinphoneActivity.isInstanciated()
|| LinphoneActivity.instance().getCurrentFragment()
!= FragmentsAvailable.CONTACTS_LIST) return;
if (mContactAdapter != null) {
mContactAdapter.updateDataSet(onlyDisplayLinphoneContacts ? ContactsManager.getInstance().getSIPContacts() : ContactsManager.getInstance().getContacts());
mContactAdapter.updateDataSet(
onlyDisplayLinphoneContacts
? ContactsManager.getInstance().getSIPContacts()
: ContactsManager.getInstance().getContacts());
mContactAdapter.notifyDataSetChanged();
if (mContactAdapter.getItemCount() > 0) {
@ -345,7 +364,6 @@ public class ContactsListFragment extends Fragment implements OnItemClickListene
}
}
contactsFetchInProgress.setVisibility(View.GONE);
}
public void invalidate() {

View file

@ -19,13 +19,14 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import static android.os.AsyncTask.THREAD_POOL_EXECUTOR;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.ContentProviderOperation;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
@ -37,12 +38,14 @@ import android.net.Uri;
import android.os.AsyncTask;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Data;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import org.linphone.LinphoneActivity;
import org.linphone.LinphoneManager;
import org.linphone.settings.LinphonePreferences;
import org.linphone.LinphoneService;
import org.linphone.utils.LinphoneUtils;
import org.linphone.R;
import org.linphone.core.Address;
import org.linphone.core.Core;
@ -54,18 +57,24 @@ import org.linphone.core.PresenceBasicStatus;
import org.linphone.core.PresenceModel;
import org.linphone.core.ProxyConfig;
import org.linphone.mediastream.Log;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import static android.os.AsyncTask.THREAD_POOL_EXECUTOR;
import org.linphone.settings.LinphonePreferences;
import org.linphone.utils.LinphoneUtils;
public class ContactsManager extends ContentObserver implements FriendListListener {
private static ContactsManager instance;
@SuppressLint("InlinedApi")
private static final String[] PROJECTION = {
Data.CONTACT_ID,
ContactsContract.Contacts.LOOKUP_KEY,
ContactsContract.Contacts.DISPLAY_NAME_PRIMARY,
Data.MIMETYPE,
"data1", // Company, Phone or SIP Address
"data2", // ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME
"data3", // ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME
"data4", // Normalized phone number
};
private static ContactsManager instance;
private static ArrayList<ContactsUpdatedListener> contactsUpdatedListeners;
private List<LinphoneContact> mContacts, mSipContacts;
private MagicSearch magicSearch;
private Bitmap defaultAvatar;
@ -73,7 +82,18 @@ public class ContactsManager extends ContentObserver implements FriendListListen
private Context mContext;
private AsyncContactsLoader mLoadContactTask;
private static ArrayList<ContactsUpdatedListener> contactsUpdatedListeners;
private ContactsManager() {
super(LinphoneService.instance().mHandler);
defaultAvatar =
BitmapFactory.decodeResource(
LinphoneService.instance().getResources(), R.drawable.avatar);
contactsUpdatedListeners = new ArrayList<>();
mContacts = new ArrayList<>();
mSipContacts = new ArrayList<>();
if (LinphoneManager.getLcIfManagerNotDestroyedOrNull() != null) {
magicSearch = LinphoneManager.getLcIfManagerNotDestroyedOrNull().createMagicSearch();
}
}
public static void addContactsListener(ContactsUpdatedListener listener) {
contactsUpdatedListeners.add(listener);
@ -83,15 +103,39 @@ public class ContactsManager extends ContentObserver implements FriendListListen
contactsUpdatedListeners.remove(listener);
}
private ContactsManager() {
super(LinphoneService.instance().mHandler);
defaultAvatar = BitmapFactory.decodeResource(LinphoneService.instance().getResources(), R.drawable.avatar);
contactsUpdatedListeners = new ArrayList<>();
mContacts = new ArrayList<>();
mSipContacts = new ArrayList<>();
if (LinphoneManager.getLcIfManagerNotDestroyedOrNull() != null) {
magicSearch = LinphoneManager.getLcIfManagerNotDestroyedOrNull().createMagicSearch();
public static final ContactsManager getInstance() {
if (instance == null) instance = new ContactsManager();
return instance;
}
public static String getAddressOrNumberForAndroidContact(
ContentResolver resolver, Uri contactUri) {
// Phone Numbers
String[] projection = new String[] {ContactsContract.CommonDataKinds.Phone.NUMBER};
Cursor c = resolver.query(contactUri, projection, null, null, null);
if (c != null) {
while (c.moveToNext()) {
int numberIndex = c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
String number = c.getString(numberIndex);
c.close();
return number;
}
}
// SIP addresses
projection = new String[] {ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS};
c = resolver.query(contactUri, projection, null, null, null);
if (c != null) {
while (c.moveToNext()) {
int numberIndex =
c.getColumnIndex(ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS);
String address = c.getString(numberIndex);
c.close();
return address;
}
c.close();
}
return null;
}
public void destroy() {
@ -122,17 +166,11 @@ public class ContactsManager extends ContentObserver implements FriendListListen
onChange(selfChange, null);
}
@Override
public void onChange(boolean selfChange, Uri uri) {
fetchContactsAsync();
}
public static final ContactsManager getInstance() {
if (instance == null) instance = new ContactsManager();
return instance;
}
public synchronized boolean hasContacts() {
return mContacts.size() > 0;
}
@ -143,6 +181,12 @@ public class ContactsManager extends ContentObserver implements FriendListListen
}
}
public void setContacts(List<LinphoneContact> c) {
synchronized (mContacts) {
mContacts = c;
}
}
public List<LinphoneContact> getSIPContacts() {
synchronized (mSipContacts) {
return mSipContacts;
@ -157,7 +201,9 @@ public class ContactsManager extends ContentObserver implements FriendListListen
if (contact.getFullName() != null) {
if (contact.getFullName().toLowerCase(Locale.getDefault()).startsWith(search)) {
searchContactsBegin.add(contact);
} else if (contact.getFullName().toLowerCase(Locale.getDefault()).contains(search)) {
} else if (contact.getFullName()
.toLowerCase(Locale.getDefault())
.contains(search)) {
searchContactsContain.add(contact);
}
}
@ -174,7 +220,9 @@ public class ContactsManager extends ContentObserver implements FriendListListen
if (contact.getFullName() != null) {
if (contact.getFullName().toLowerCase(Locale.getDefault()).startsWith(search)) {
searchContactsBegin.add(contact);
} else if (contact.getFullName().toLowerCase(Locale.getDefault()).contains(search)) {
} else if (contact.getFullName()
.toLowerCase(Locale.getDefault())
.contains(search)) {
searchContactsContain.add(contact);
}
}
@ -198,14 +246,21 @@ public class ContactsManager extends ContentObserver implements FriendListListen
if (mContext == null) {
return false;
}
boolean contactsR = (PackageManager.PERMISSION_GRANTED ==
mContext.getPackageManager().checkPermission(android.Manifest.permission.READ_CONTACTS, mContext.getPackageName()));
return contactsR && !mContext.getResources().getBoolean(R.bool.force_use_of_linphone_friends);
boolean contactsR =
(PackageManager.PERMISSION_GRANTED
== mContext.getPackageManager()
.checkPermission(
android.Manifest.permission.READ_CONTACTS,
mContext.getPackageName()));
return contactsR
&& !mContext.getResources().getBoolean(R.bool.force_use_of_linphone_friends);
}
public boolean isLinphoneContactsPrefered() {
ProxyConfig lpc = LinphoneManager.getLc().getDefaultProxyConfig();
if (lpc != null && lpc.getIdentityAddress().getDomain().equals(getString(R.string.default_domain))) return true;
if (lpc != null
&& lpc.getIdentityAddress().getDomain().equals(getString(R.string.default_domain)))
return true;
return false;
}
@ -219,12 +274,14 @@ public class ContactsManager extends ContentObserver implements FriendListListen
public void initializeSyncAccount(Activity activity) {
initializeContactManager(activity);
AccountManager accountManager = (AccountManager) activity.getSystemService(Context.ACCOUNT_SERVICE);
AccountManager accountManager =
(AccountManager) activity.getSystemService(Context.ACCOUNT_SERVICE);
Account[] accounts = accountManager.getAccountsByType(activity.getPackageName());
if (accounts != null && accounts.length == 0) {
Account newAccount = new Account(getString(R.string.sync_account_name), activity.getPackageName());
Account newAccount =
new Account(getString(R.string.sync_account_name), activity.getPackageName());
try {
accountManager.addAccountExplicitly(newAccount, null, null);
} catch (Exception e) {
@ -259,7 +316,9 @@ public class ContactsManager extends ContentObserver implements FriendListListen
return null;
}
addr.setUriParam("user", "phone");
Friend lf = lc.findFriend(addr); // Without this, the hashmap inside liblinphone won't find it...
Friend lf =
lc.findFriend(
addr); // Without this, the hashmap inside liblinphone won't find it...
if (lf != null) {
LinphoneContact contact = (LinphoneContact) lf.getUserData();
return contact;
@ -276,34 +335,6 @@ public class ContactsManager extends ContentObserver implements FriendListListen
return false;
}
public static String getAddressOrNumberForAndroidContact(ContentResolver resolver, Uri contactUri) {
// Phone Numbers
String[] projection = new String[]{ContactsContract.CommonDataKinds.Phone.NUMBER};
Cursor c = resolver.query(contactUri, projection, null, null, null);
if (c != null) {
while (c.moveToNext()) {
int numberIndex = c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
String number = c.getString(numberIndex);
c.close();
return number;
}
}
// SIP addresses
projection = new String[]{ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS};
c = resolver.query(contactUri, projection, null, null, null);
if (c != null) {
while (c.moveToNext()) {
int numberIndex = c.getColumnIndex(ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS);
String address = c.getString(numberIndex);
c.close();
return address;
}
c.close();
}
return null;
}
public void delete(String id) {
ArrayList<String> ids = new ArrayList<>();
ids.add(id);
@ -315,8 +346,11 @@ public class ContactsManager extends ContentObserver implements FriendListListen
ArrayList<ContentProviderOperation> ops = new ArrayList<>();
for (String id : ids) {
String[] args = new String[]{id};
ops.add(ContentProviderOperation.newDelete(ContactsContract.RawContacts.CONTENT_URI).withSelection(select, args).build());
String[] args = new String[] {id};
ops.add(
ContentProviderOperation.newDelete(ContactsContract.RawContacts.CONTENT_URI)
.withSelection(select, args)
.build());
}
try {
@ -332,24 +366,16 @@ public class ContactsManager extends ContentObserver implements FriendListListen
}
@Override
public void onContactCreated(FriendList list, Friend lf) {
}
public void onContactCreated(FriendList list, Friend lf) {}
@Override
public void onContactDeleted(FriendList list, Friend lf) {
}
public void onContactDeleted(FriendList list, Friend lf) {}
@Override
public void onContactUpdated(FriendList list, Friend newFriend, Friend oldFriend) {
}
public void onContactUpdated(FriendList list, Friend newFriend, Friend oldFriend) {}
@Override
public void onSyncStatusChanged(FriendList list, FriendList.SyncStatus status, String msg) {
}
public void onSyncStatusChanged(FriendList list, FriendList.SyncStatus status, String msg) {}
@Override
public void onPresenceReceived(FriendList list, Friend[] friends) {
@ -371,18 +397,47 @@ public class ContactsManager extends ContentObserver implements FriendListListen
mLoadContactTask.executeOnExecutor(THREAD_POOL_EXECUTOR);
}
@SuppressLint("InlinedApi")
private static final String[] PROJECTION =
{
Data.CONTACT_ID,
ContactsContract.Contacts.LOOKUP_KEY,
ContactsContract.Contacts.DISPLAY_NAME_PRIMARY,
Data.MIMETYPE,
"data1", //Company, Phone or SIP Address
"data2", //ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME
"data3", //ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME
"data4", //Normalized phone number
};
public synchronized void setSipContacts(List<LinphoneContact> c) {
synchronized (mSipContacts) {
mSipContacts = c;
}
}
public void editContact(Context context, LinphoneContact contact, String valueToAdd) {
if (context.getResources().getBoolean(R.bool.use_native_contact_editor)) {
Intent intent = new Intent(Intent.ACTION_EDIT);
Uri contactUri =
ContactsContract.Contacts.getLookupUri(
Long.parseLong(contact.getAndroidId()), contact.getAndroidLookupKey());
intent.setDataAndType(contactUri, ContactsContract.Contacts.CONTENT_ITEM_TYPE);
intent.putExtra(
"finishActivityOnSaveCompleted", true); // So after save will go back here
if (valueToAdd != null) {
intent.putExtra(ContactsContract.Intents.Insert.IM_HANDLE, valueToAdd);
}
context.startActivity(intent);
} else {
LinphoneActivity.instance().editContact(contact);
}
}
public void createContact(Context context, String name, String valueToAdd) {
if (context.getResources().getBoolean(R.bool.use_native_contact_editor)) {
Intent intent = new Intent(ContactsContract.Intents.Insert.ACTION);
intent.setType(ContactsContract.RawContacts.CONTENT_TYPE);
intent.putExtra(
"finishActivityOnSaveCompleted", true); // So after save will go back here
if (name != null) {
intent.putExtra(ContactsContract.Intents.Insert.NAME, name);
}
if (valueToAdd != null) {
intent.putExtra(ContactsContract.Intents.Insert.IM_HANDLE, valueToAdd);
}
context.startActivity(intent);
} else {
LinphoneActivity.instance().addContact(name, valueToAdd);
}
}
class AsyncContactsData {
List<LinphoneContact> contacts;
@ -402,10 +457,13 @@ public class ContactsManager extends ContentObserver implements FriendListListen
mAndroidContactsCache = new HashMap<>();
mContactsFetchedOnce = true;
if (LinphonePreferences.instance() != null && LinphonePreferences.instance().isFriendlistsubscriptionEnabled()) {
if (LinphonePreferences.instance() != null
&& LinphonePreferences.instance().isFriendlistsubscriptionEnabled()) {
String rls = getString(R.string.rls_uri);
for (FriendList list : LinphoneManager.getLc().getFriendsLists()) {
if (rls != null && (list.getRlsAddress() == null || !list.getRlsAddress().asStringUriOnly().equals(rls))) {
if (rls != null
&& (list.getRlsAddress() == null
|| !list.getRlsAddress().asStringUriOnly().equals(rls))) {
list.setRlsUri(rls);
}
list.setListener(ContactsManager.this);
@ -415,7 +473,14 @@ public class ContactsManager extends ContentObserver implements FriendListListen
@Override
protected AsyncContactsData doInBackground(Void... params) {
Cursor c = mContext.getContentResolver().query(ContactsContract.Data.CONTENT_URI, PROJECTION, Data.IN_VISIBLE_GROUP + " == 1", null, null);
Cursor c =
mContext.getContentResolver()
.query(
ContactsContract.Data.CONTENT_URI,
PROJECTION,
Data.IN_VISIBLE_GROUP + " == 1",
null,
null);
AsyncContactsData data = new AsyncContactsData();
Core lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
@ -432,7 +497,9 @@ public class ContactsManager extends ContentObserver implements FriendListListen
}
} else {
if (friend.getRefKey() != null) {
// Friend has a refkey and but no LinphoneContact => represents a native contact stored in db from a previous version of Linphone, remove it
// Friend has a refkey and but no LinphoneContact => represents a
// native contact stored in db from a previous version of Linphone,
// remove it
list.removeFriend(friend);
} else {
// No refkey so it's a standalone contact
@ -458,7 +525,8 @@ public class ContactsManager extends ContentObserver implements FriendListListen
String data2 = c.getString(c.getColumnIndex("data2"));
String data3 = c.getString(c.getColumnIndex("data3"));
String data4 = c.getString(c.getColumnIndex("data4"));
String lookupKey = c.getString(c.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
String lookupKey =
c.getString(c.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
LinphoneContact contact = mAndroidContactsCache.get(id);
if (contact == null) {
@ -475,11 +543,15 @@ public class ContactsManager extends ContentObserver implements FriendListListen
if (ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE.equals(mime)) {
contact.addNumberOrAddress(new LinphoneNumberOrAddress(data1, data4));
} else if (ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE.equals(mime) || getInstance().getString(R.string.sync_mimetype).equals(mime)) {
} else if (ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE.equals(
mime)
|| getInstance().getString(R.string.sync_mimetype).equals(mime)) {
contact.addNumberOrAddress(new LinphoneNumberOrAddress(data1, true));
} else if (ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE.equals(mime)) {
} else if (ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE
.equals(mime)) {
contact.setOrganization(data1, false);
} else if (ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE.equals(mime)) {
} else if (ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE
.equals(mime)) {
contact.setFirstNameAndLastName(data2, data3, false);
}
}
@ -504,13 +576,19 @@ public class ContactsManager extends ContentObserver implements FriendListListen
for (LinphoneContact contact : mAndroidContactsCache.values()) {
if (isCancelled()) return data;
boolean hideContactsWithoutPresence = mContext.getResources().getBoolean(R.bool.hide_sip_contacts_without_presence);
boolean hideContactsWithoutPresence =
mContext.getResources()
.getBoolean(R.bool.hide_sip_contacts_without_presence);
if (contact.hasAddress()) {
if (contact.getFullName() == null) {
for (LinphoneNumberOrAddress noa : contact.getNumbersOrAddresses()) {
if (noa.isSIPAddress()) {
contact.setFullName(LinphoneUtils.getAddressDisplayName(noa.getValue()));
Log.w("[Contacts Manager] Couldn't find a display name for contact " + contact.getFullName() + ", used SIP address display name / username instead...");
contact.setFullName(
LinphoneUtils.getAddressDisplayName(noa.getValue()));
Log.w(
"[Contacts Manager] Couldn't find a display name for contact "
+ contact.getFullName()
+ ", used SIP address display name / username instead...");
break;
}
}
@ -518,8 +596,11 @@ public class ContactsManager extends ContentObserver implements FriendListListen
if (hideContactsWithoutPresence) {
if (contact.getFriend() != null) {
for (LinphoneNumberOrAddress noa : contact.getNumbersOrAddresses()) {
PresenceModel pm = contact.getFriend().getPresenceModelForUriOrTel(noa.getValue());
if (pm != null && pm.getBasicStatus().equals(PresenceBasicStatus.Open)) {
PresenceModel pm =
contact.getFriend()
.getPresenceModelForUriOrTel(noa.getValue());
if (pm != null
&& pm.getBasicStatus().equals(PresenceBasicStatus.Open)) {
data.sipContacts.add(contact);
break;
}
@ -552,48 +633,4 @@ public class ContactsManager extends ContentObserver implements FriendListListen
setSipContacts(data.sipContacts);
}
}
public void setContacts(List<LinphoneContact> c) {
synchronized (mContacts) {
mContacts = c;
}
}
public synchronized void setSipContacts(List<LinphoneContact> c) {
synchronized (mSipContacts) {
mSipContacts = c;
}
}
public void editContact(Context context, LinphoneContact contact, String valueToAdd) {
if (context.getResources().getBoolean(R.bool.use_native_contact_editor)) {
Intent intent = new Intent(Intent.ACTION_EDIT);
Uri contactUri = ContactsContract.Contacts.getLookupUri(Long.parseLong(contact.getAndroidId()), contact.getAndroidLookupKey());
intent.setDataAndType(contactUri, ContactsContract.Contacts.CONTENT_ITEM_TYPE);
intent.putExtra("finishActivityOnSaveCompleted", true); // So after save will go back here
if (valueToAdd != null) {
intent.putExtra(ContactsContract.Intents.Insert.IM_HANDLE, valueToAdd);
}
context.startActivity(intent);
} else {
LinphoneActivity.instance().editContact(contact);
}
}
public void createContact(Context context, String name, String valueToAdd) {
if (context.getResources().getBoolean(R.bool.use_native_contact_editor)) {
Intent intent = new Intent(ContactsContract.Intents.Insert.ACTION);
intent.setType(ContactsContract.RawContacts.CONTENT_TYPE);
intent.putExtra("finishActivityOnSaveCompleted", true); // So after save will go back here
if (name != null) {
intent.putExtra(ContactsContract.Intents.Insert.NAME, name);
}
if (valueToAdd != null) {
intent.putExtra(ContactsContract.Intents.Insert.IM_HANDLE, valueToAdd);
}
context.startActivity(intent);
} else {
LinphoneActivity.instance().addContact(name, valueToAdd);
}
}
}

View file

@ -21,4 +21,4 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
public interface ContactsUpdatedListener {
void onContactsUpdated();
}
}

File diff suppressed because it is too large Load diff

View file

@ -86,5 +86,7 @@ public class LinphoneNumberOrAddress implements Serializable, Comparable<Linphon
value = v;
}
public String getNormalizedPhone() { return normalizedPhone != null ? normalizedPhone : value; }
public String getNormalizedPhone() {
return normalizedPhone != null ? normalizedPhone : value;
}
}

View file

@ -19,8 +19,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
package org.linphone.contacts;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -28,10 +26,13 @@ import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
import org.linphone.LinphoneActivity;
import org.linphone.LinphoneManager;
import org.linphone.R;
import org.linphone.LinphoneActivity;
import org.linphone.core.Address;
import org.linphone.core.Factory;
import org.linphone.core.PresenceBasicStatus;
@ -40,46 +41,11 @@ import org.linphone.core.ProxyConfig;
import org.linphone.core.SearchResult;
import org.linphone.views.ContactAvatar;
import java.util.ArrayList;
import java.util.List;
public class SearchContactsListAdapter extends RecyclerView.Adapter<SearchContactsListAdapter.ViewHolder> {
public class SearchContactsListAdapter
extends RecyclerView.Adapter<SearchContactsListAdapter.ViewHolder> {
@SuppressWarnings("unused")
private static final String TAG = SearchContactsListAdapter.class.getSimpleName();
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView name;
public TextView address;
public ImageView linphoneContact;
public ImageView isSelect;
public RelativeLayout avatarLayout;
private ClickListener mListener;
public ViewHolder(View view, ClickListener listener) {
super(view);
name = view.findViewById(R.id.contact_name);
address = view.findViewById(R.id.contact_address);
linphoneContact = view.findViewById(R.id.contact_linphone);
isSelect = view.findViewById(R.id.contact_is_select);
avatarLayout = view.findViewById(R.id.avatar_layout);
mListener = listener;
view.setOnClickListener(this);
}
@Override
public void onClick(View view) {
if (mListener != null) {
mListener.onItemClicked(getAdapterPosition());
}
}
public interface ClickListener {
void onItemClicked(int position);
}
}
private List<ContactAddress> contacts;
private List<ContactAddress> contactsSelected;
private ProgressBar progressBar;
@ -88,6 +54,19 @@ public class SearchContactsListAdapter extends RecyclerView.Adapter<SearchContac
private boolean mHideSelectionMark;
private String mPreviousSearch;
public SearchContactsListAdapter(
List<ContactAddress> contactsList,
ProgressBar pB,
ViewHolder.ClickListener clickListener,
boolean hideSelectionMark) {
mHideSelectionMark = hideSelectionMark;
mListener = clickListener;
progressBar = pB;
setContactsSelectedList(null);
setContactsList(contactsList);
mPreviousSearch = null;
}
public List<ContactAddress> getContacts() {
return contacts;
}
@ -100,32 +79,27 @@ public class SearchContactsListAdapter extends RecyclerView.Adapter<SearchContac
mListener = listener;
}
public SearchContactsListAdapter(List<ContactAddress> contactsList, ProgressBar pB, ViewHolder.ClickListener clickListener, boolean hideSelectionMark) {
mHideSelectionMark = hideSelectionMark;
mListener = clickListener;
progressBar = pB;
setContactsSelectedList(null);
setContactsList(contactsList);
mPreviousSearch = null;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.search_contact_cell, parent, false);
View v =
LayoutInflater.from(parent.getContext())
.inflate(R.layout.search_contact_cell, parent, false);
return new ViewHolder(v, mListener);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
ContactAddress contact = getItem(position);
final String a = (contact.getAddressAsDisplayableString().isEmpty()) ? contact.getPhoneNumber() : contact.getAddressAsDisplayableString();
final String a =
(contact.getAddressAsDisplayableString().isEmpty())
? contact.getPhoneNumber()
: contact.getAddressAsDisplayableString();
LinphoneContact c = contact.getContact();
String address = contact.getAddressAsDisplayableString();
if (c != null && c.getFullName() != null) {
if (address == null)
address = c.getPresenceModelForUriOrTel(a);
if (address == null) address = c.getPresenceModelForUriOrTel(a);
holder.name.setVisibility(View.VISIBLE);
holder.name.setText(c.getFullName());
} else if (contact.getAddress() != null) {
@ -139,7 +113,10 @@ public class SearchContactsListAdapter extends RecyclerView.Adapter<SearchContac
} else if (address != null) {
Address tmpAddr = Factory.instance().createAddress(address);
holder.name.setVisibility(View.VISIBLE);
holder.name.setText((tmpAddr.getDisplayName() != null) ? tmpAddr.getDisplayName() : tmpAddr.getUsername());
holder.name.setText(
(tmpAddr.getDisplayName() != null)
? tmpAddr.getDisplayName()
: tmpAddr.getUsername());
} else {
holder.name.setVisibility(View.GONE);
}
@ -149,7 +126,7 @@ public class SearchContactsListAdapter extends RecyclerView.Adapter<SearchContac
c.setFullName(holder.name.getText().toString());
}
ContactAvatar.displayAvatar(c, holder.avatarLayout);
//TODO get if contact has security capabilities
// TODO get if contact has security capabilities
} else {
ContactAvatar.displayAvatar(holder.name.getText().toString(), holder.avatarLayout);
}
@ -193,14 +170,8 @@ public class SearchContactsListAdapter extends RecyclerView.Adapter<SearchContac
return false;
}
public void setContactsList(List<ContactAddress> contactsList) {
if (contactsList == null) {
contacts = getContactsList();
if (progressBar != null)
progressBar.setVisibility(View.GONE);
} else {
contacts = contactsList;
}
public List<ContactAddress> getContactsSelectedList() {
return contactsSelected;
}
public void setContactsSelectedList(List<ContactAddress> contactsList) {
@ -211,26 +182,37 @@ public class SearchContactsListAdapter extends RecyclerView.Adapter<SearchContac
}
}
public List<ContactAddress> getContactsSelectedList() {
return contactsSelected;
}
public List<ContactAddress> getContactsList() {
List<ContactAddress> list = new ArrayList<>();
if (ContactsManager.getInstance().hasContacts()) {
List<LinphoneContact> contacts = mOnlySipContact ? ContactsManager.getInstance().getSIPContacts() : ContactsManager.getInstance().getContacts();
List<LinphoneContact> contacts =
mOnlySipContact
? ContactsManager.getInstance().getSIPContacts()
: ContactsManager.getInstance().getContacts();
for (LinphoneContact contact : contacts) {
for (LinphoneNumberOrAddress noa : contact.getNumbersOrAddresses()) {
if (!mOnlySipContact || (mOnlySipContact && (noa.isSIPAddress() || contact.getPresenceModelForUriOrTel(noa.getValue()) != null))) {
if (!mOnlySipContact
|| (mOnlySipContact
&& (noa.isSIPAddress()
|| contact.getPresenceModelForUriOrTel(noa.getValue())
!= null))) {
ContactAddress ca = null;
if (noa.isSIPAddress()) {
Address address = LinphoneManager.getLc().interpretUrl(noa.getValue());
if (address != null) {
ca = new ContactAddress(contact, address.asString(), "", contact.isFriend());
ca =
new ContactAddress(
contact,
address.asString(),
"",
contact.isFriend());
}
} else {
ProxyConfig prx = LinphoneManager.getLc().getDefaultProxyConfig();
String number = (prx != null) ? prx.normalizePhoneNumber(noa.getValue()) : noa.getValue();
String number =
(prx != null)
? prx.normalizePhoneNumber(noa.getValue())
: noa.getValue();
ca = new ContactAddress(contact, "", number, contact.isFriend());
}
if (ca != null) list.add(ca);
@ -247,6 +229,15 @@ public class SearchContactsListAdapter extends RecyclerView.Adapter<SearchContac
return list;
}
public void setContactsList(List<ContactAddress> contactsList) {
if (contactsList == null) {
contacts = getContactsList();
if (progressBar != null) progressBar.setVisibility(View.GONE);
} else {
contacts = contactsList;
}
}
public int getCount() {
return contacts.size();
}
@ -255,7 +246,6 @@ public class SearchContactsListAdapter extends RecyclerView.Adapter<SearchContac
return contacts.get(position);
}
@Override
public int getItemCount() {
return contacts.size();
@ -274,10 +264,14 @@ public class SearchContactsListAdapter extends RecyclerView.Adapter<SearchContac
String domain = "";
ProxyConfig prx = LinphoneManager.getLc().getDefaultProxyConfig();
if (prx != null) domain = prx.getDomain();
SearchResult[] results = ContactsManager.getInstance().getMagicSearch().getContactListFromFilter(search, mOnlySipContact ? domain : "");
SearchResult[] results =
ContactsManager.getInstance()
.getMagicSearch()
.getContactListFromFilter(search, mOnlySipContact ? domain : "");
for (SearchResult sr : results) {
boolean found = false;
LinphoneContact contact = ContactsManager.getInstance().findContactFromAddress(sr.getAddress());
LinphoneContact contact =
ContactsManager.getInstance().findContactFromAddress(sr.getAddress());
if (contact == null) {
contact = new LinphoneContact();
if (sr.getFriend() != null) {
@ -287,35 +281,54 @@ public class SearchContactsListAdapter extends RecyclerView.Adapter<SearchContac
}
if (sr.getAddress() != null || sr.getPhoneNumber() != null) {
for (ContactAddress ca : result) {
String normalizedPhoneNumber = (ca != null && ca.getPhoneNumber() != null && prx != null) ? prx.normalizePhoneNumber(ca.getPhoneNumber()) : null;
if ((sr.getAddress() != null && ca.getAddress() != null
&& ca.getAddress().asStringUriOnly().equals(sr.getAddress().asStringUriOnly()))
|| (sr.getPhoneNumber() != null && normalizedPhoneNumber != null
&& sr.getPhoneNumber().equals(normalizedPhoneNumber))) {
String normalizedPhoneNumber =
(ca != null && ca.getPhoneNumber() != null && prx != null)
? prx.normalizePhoneNumber(ca.getPhoneNumber())
: null;
if ((sr.getAddress() != null
&& ca.getAddress() != null
&& ca.getAddress()
.asStringUriOnly()
.equals(sr.getAddress().asStringUriOnly()))
|| (sr.getPhoneNumber() != null
&& normalizedPhoneNumber != null
&& sr.getPhoneNumber().equals(normalizedPhoneNumber))) {
found = true;
break;
}
}
}
if (!found) {
if (LinphoneActivity.instance().getResources().getBoolean(R.bool.hide_sip_contacts_without_presence)) {
if (LinphoneActivity.instance()
.getResources()
.getBoolean(R.bool.hide_sip_contacts_without_presence)) {
if (contact.getFriend() != null) {
for (LinphoneNumberOrAddress noa : contact.getNumbersOrAddresses()) {
PresenceModel pm = contact.getFriend().getPresenceModelForUriOrTel(noa.getValue());
if (pm != null && pm.getBasicStatus().equals(PresenceBasicStatus.Open)) {
result.add(new ContactAddress(contact,
(sr.getAddress() != null) ? sr.getAddress().asStringUriOnly() : "",
sr.getPhoneNumber(),
contact.isFriend()));
PresenceModel pm =
contact.getFriend().getPresenceModelForUriOrTel(noa.getValue());
if (pm != null
&& pm.getBasicStatus().equals(PresenceBasicStatus.Open)) {
result.add(
new ContactAddress(
contact,
(sr.getAddress() != null)
? sr.getAddress().asStringUriOnly()
: "",
sr.getPhoneNumber(),
contact.isFriend()));
break;
}
}
}
} else {
result.add(new ContactAddress(contact,
(sr.getAddress() != null) ? sr.getAddress().asStringUriOnly() : "",
sr.getPhoneNumber(),
contact.isFriend()));
result.add(
new ContactAddress(
contact,
(sr.getAddress() != null)
? sr.getAddress().asStringUriOnly()
: "",
sr.getPhoneNumber(),
contact.isFriend()));
}
}
}
@ -324,5 +337,36 @@ public class SearchContactsListAdapter extends RecyclerView.Adapter<SearchContac
resultContactsSearch.setAdapter(this);
notifyDataSetChanged();
}
}
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView name;
public TextView address;
public ImageView linphoneContact;
public ImageView isSelect;
public RelativeLayout avatarLayout;
private ClickListener mListener;
public ViewHolder(View view, ClickListener listener) {
super(view);
name = view.findViewById(R.id.contact_name);
address = view.findViewById(R.id.contact_address);
linphoneContact = view.findViewById(R.id.contact_linphone);
isSelect = view.findViewById(R.id.contact_is_select);
avatarLayout = view.findViewById(R.id.avatar_layout);
mListener = listener;
view.setOnClickListener(this);
}
@Override
public void onClick(View view) {
if (mListener != null) {
mListener.onItemClicked(getAdapterPosition());
}
}
public interface ClickListener {
void onItemClicked(int position);
}
}
}

View file

@ -21,7 +21,6 @@ package org.linphone.firebase;
import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.iid.FirebaseInstanceIdService;
import org.linphone.settings.LinphonePreferences;
import org.linphone.utils.LinphoneUtils;
@ -30,13 +29,16 @@ public class FirebaseIdService extends FirebaseInstanceIdService {
public void onTokenRefresh() {
// Get updated InstanceID token.
final String refreshedToken = FirebaseInstanceId.getInstance().getToken();
android.util.Log.i("FirebaseIdService", "[Push Notification] Refreshed token: " + refreshedToken);
android.util.Log.i(
"FirebaseIdService", "[Push Notification] Refreshed token: " + refreshedToken);
LinphoneUtils.dispatchOnUIThread(new Runnable() {
@Override
public void run() {
LinphonePreferences.instance().setPushNotificationRegistrationID(refreshedToken);
}
});
LinphoneUtils.dispatchOnUIThread(
new Runnable() {
@Override
public void run() {
LinphonePreferences.instance()
.setPushNotificationRegistrationID(refreshedToken);
}
});
}
}

View file

@ -19,21 +19,18 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import android.content.Intent;
import static android.content.Intent.ACTION_MAIN;
import android.content.Intent;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
import org.linphone.LinphoneManager;
import org.linphone.LinphoneService;
import org.linphone.mediastream.Log;
import org.linphone.utils.LinphoneUtils;
import static android.content.Intent.ACTION_MAIN;
public class FirebaseMessaging extends FirebaseMessagingService {
public FirebaseMessaging() {
}
public FirebaseMessaging() {}
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
@ -46,16 +43,19 @@ public class FirebaseMessaging extends FirebaseMessagingService {
intent.putExtra("PushNotification", true);
startService(intent);
} else if (LinphoneManager.isInstanciated() && LinphoneManager.getLc().getCallsNb() == 0) {
LinphoneUtils.dispatchOnUIThread(new Runnable() {
@Override
public void run() {
Log.i("[Push Notification] Push notification received with LinphoneManager still alive");
if (LinphoneManager.isInstanciated() && LinphoneManager.getLc().getCallsNb() == 0) {
LinphoneManager.getLc().setNetworkReachable(false);
LinphoneManager.getLc().setNetworkReachable(true);
}
}
});
LinphoneUtils.dispatchOnUIThread(
new Runnable() {
@Override
public void run() {
Log.i(
"[Push Notification] Push notification received with LinphoneManager still alive");
if (LinphoneManager.isInstanciated()
&& LinphoneManager.getLc().getCallsNb() == 0) {
LinphoneManager.getLc().setNetworkReachable(false);
LinphoneManager.getLc().setNetworkReachable(true);
}
}
});
}
}
}

View file

@ -25,25 +25,23 @@ import android.content.Intent;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import androidx.core.content.ContextCompat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.core.content.ContextCompat;
import org.linphone.BuildConfig;
import org.linphone.LinphoneActivity;
import org.linphone.LinphoneManager;
import org.linphone.settings.LinphonePreferences;
import org.linphone.LinphoneService;
import org.linphone.R;
import org.linphone.LinphoneActivity;
import org.linphone.core.Core;
import org.linphone.core.Core.LogCollectionUploadState;
import org.linphone.core.CoreListenerStub;
import org.linphone.mediastream.Log;
import org.linphone.settings.LinphonePreferences;
public class AboutFragment extends Fragment implements OnClickListener {
View sendLogButton = null;
@ -53,40 +51,52 @@ public class AboutFragment extends Fragment implements OnClickListener {
private boolean uploadInProgress;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.about, container, false);
TextView aboutVersion = view.findViewById(R.id.about_android_version);
TextView aboutLiblinphoneVersion = view.findViewById(R.id.about_liblinphone_version);
aboutLiblinphoneVersion.setText(String.format(getString(R.string.about_liblinphone_version), LinphoneManager.getLc().getVersion()));
aboutVersion.setText(String.format(getString(R.string.about_version), BuildConfig.VERSION_NAME + " (" + BuildConfig.VERSION_CODE + ")"));
aboutLiblinphoneVersion.setText(
String.format(
getString(R.string.about_liblinphone_version),
LinphoneManager.getLc().getVersion()));
aboutVersion.setText(
String.format(
getString(R.string.about_version),
BuildConfig.VERSION_NAME + " (" + BuildConfig.VERSION_CODE + ")"));
sendLogButton = view.findViewById(R.id.send_log);
sendLogButton.setOnClickListener(this);
sendLogButton.setVisibility(LinphonePreferences.instance().isDebugEnabled() ? View.VISIBLE : View.GONE);
sendLogButton.setVisibility(
LinphonePreferences.instance().isDebugEnabled() ? View.VISIBLE : View.GONE);
resetLogButton = view.findViewById(R.id.reset_log);
resetLogButton.setOnClickListener(this);
resetLogButton.setVisibility(LinphonePreferences.instance().isDebugEnabled() ? View.VISIBLE : View.GONE);
resetLogButton.setVisibility(
LinphonePreferences.instance().isDebugEnabled() ? View.VISIBLE : View.GONE);
mListener = new CoreListenerStub() {
@Override
public void onLogCollectionUploadProgressIndication(Core lc, int offset, int total) {
}
mListener =
new CoreListenerStub() {
@Override
public void onLogCollectionUploadProgressIndication(
Core lc, int offset, int total) {}
@Override
public void onLogCollectionUploadStateChanged(Core lc, LogCollectionUploadState state, String info) {
if (state == LogCollectionUploadState.InProgress) {
displayUploadLogsInProgress();
} else if (state == LogCollectionUploadState.Delivered || state == LogCollectionUploadState.NotDelivered) {
uploadInProgress = false;
if (progress != null) progress.dismiss();
if (state == LogCollectionUploadState.Delivered) {
sendLogs(LinphoneService.instance().getApplicationContext(), info);
@Override
public void onLogCollectionUploadStateChanged(
Core lc, LogCollectionUploadState state, String info) {
if (state == LogCollectionUploadState.InProgress) {
displayUploadLogsInProgress();
} else if (state == LogCollectionUploadState.Delivered
|| state == LogCollectionUploadState.NotDelivered) {
uploadInProgress = false;
if (progress != null) progress.dismiss();
if (state == LogCollectionUploadState.Delivered) {
sendLogs(LinphoneService.instance().getApplicationContext(), info);
}
}
}
}
}
};
};
return view;
}
@ -100,7 +110,10 @@ public class AboutFragment extends Fragment implements OnClickListener {
progress = ProgressDialog.show(LinphoneActivity.instance(), null, null);
Drawable d = new ColorDrawable(ContextCompat.getColor(getActivity(), R.color.colorE));
d.setAlpha(200);
progress.getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
progress.getWindow()
.setLayout(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT);
progress.getWindow().setBackgroundDrawable(d);
progress.setContentView(R.layout.progress_dialog);
progress.show();
@ -110,7 +123,9 @@ public class AboutFragment extends Fragment implements OnClickListener {
final String appName = context.getString(R.string.app_name);
Intent i = new Intent(Intent.ACTION_SEND);
i.putExtra(Intent.EXTRA_EMAIL, new String[]{context.getString(R.string.about_bugreport_email)});
i.putExtra(
Intent.EXTRA_EMAIL,
new String[] {context.getString(R.string.about_bugreport_email)});
i.putExtra(Intent.EXTRA_SUBJECT, appName + " Logs");
i.putExtra(Intent.EXTRA_TEXT, info);
i.setType("application/zip");

View file

@ -30,11 +30,10 @@ import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import org.linphone.LinphoneActivity;
import org.linphone.LinphoneManager;
import org.linphone.LinphoneService;
import org.linphone.R;
import org.linphone.LinphoneActivity;
import org.linphone.contacts.ContactsManager;
import org.linphone.core.Core;
import org.linphone.mediastream.Log;
@ -53,9 +52,14 @@ public class DialerFragment extends Fragment {
private ImageView mAddContact;
private OnClickListener addContactListener, cancelListener, transferListener;
/** @return null if not ready yet */
public static DialerFragment instance() {
return instance;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dialer, container, false);
mAddress = view.findViewById(R.id.address);
@ -66,14 +70,19 @@ public class DialerFragment extends Fragment {
mCall = view.findViewById(R.id.call);
mCall.setAddressWidget(mAddress);
if (LinphoneActivity.isInstanciated() && LinphoneManager.getLcIfManagerNotDestroyedOrNull() != null && LinphoneManager.getLcIfManagerNotDestroyedOrNull().getCallsNb() > 0) {
if (LinphoneActivity.isInstanciated()
&& LinphoneManager.getLcIfManagerNotDestroyedOrNull() != null
&& LinphoneManager.getLcIfManagerNotDestroyedOrNull().getCallsNb() > 0) {
if (isCallTransferOngoing) {
mCall.setImageResource(R.drawable.call_transfer);
} else {
mCall.setImageResource(R.drawable.call_add);
}
} else {
if (LinphoneManager.getLcIfManagerNotDestroyedOrNull() != null && LinphoneManager.getLcIfManagerNotDestroyedOrNull().getVideoActivationPolicy().getAutomaticallyInitiate()) {
if (LinphoneManager.getLcIfManagerNotDestroyedOrNull() != null
&& LinphoneManager.getLcIfManagerNotDestroyedOrNull()
.getVideoActivationPolicy()
.getAutomaticallyInitiate()) {
mCall.setImageResource(R.drawable.call_video_start);
} else {
mCall.setImageResource(R.drawable.call_audio_start);
@ -86,32 +95,41 @@ public class DialerFragment extends Fragment {
}
mAddContact = view.findViewById(R.id.add_contact);
mAddContact.setEnabled(!(LinphoneActivity.isInstanciated() && LinphoneManager.getLcIfManagerNotDestroyedOrNull() != null && LinphoneManager.getLc().getCallsNb() > 0));
mAddContact.setEnabled(
!(LinphoneActivity.isInstanciated()
&& LinphoneManager.getLcIfManagerNotDestroyedOrNull() != null
&& LinphoneManager.getLc().getCallsNb() > 0));
addContactListener = new OnClickListener() {
@Override
public void onClick(View v) {
LinphoneActivity.instance().displayContactsForEdition(mAddress.getText().toString());
}
};
cancelListener = new OnClickListener() {
@Override
public void onClick(View v) {
LinphoneActivity.instance().resetClassicMenuLayoutAndGoBackToCallIfStillRunning();
}
};
transferListener = new OnClickListener() {
@Override
public void onClick(View v) {
Core lc = LinphoneManager.getLc();
if (lc.getCurrentCall() == null) {
return;
}
lc.transferCall(lc.getCurrentCall(), mAddress.getText().toString());
isCallTransferOngoing = false;
LinphoneActivity.instance().resetClassicMenuLayoutAndGoBackToCallIfStillRunning();
}
};
addContactListener =
new OnClickListener() {
@Override
public void onClick(View v) {
LinphoneActivity.instance()
.displayContactsForEdition(mAddress.getText().toString());
}
};
cancelListener =
new OnClickListener() {
@Override
public void onClick(View v) {
LinphoneActivity.instance()
.resetClassicMenuLayoutAndGoBackToCallIfStillRunning();
}
};
transferListener =
new OnClickListener() {
@Override
public void onClick(View v) {
Core lc = LinphoneManager.getLc();
if (lc.getCurrentCall() == null) {
return;
}
lc.transferCall(lc.getCurrentCall(), mAddress.getText().toString());
isCallTransferOngoing = false;
LinphoneActivity.instance()
.resetClassicMenuLayoutAndGoBackToCallIfStillRunning();
}
};
resetLayout();
@ -129,13 +147,6 @@ public class DialerFragment extends Fragment {
return view;
}
/**
* @return null if not ready yet
*/
public static DialerFragment instance() {
return instance;
}
@Override
public void onPause() {
instance = null;
@ -153,7 +164,9 @@ public class DialerFragment extends Fragment {
LinphoneActivity.instance().showStatusBar();
}
boolean isOrientationLandscape = getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
boolean isOrientationLandscape =
getResources().getConfiguration().orientation
== Configuration.ORIENTATION_LANDSCAPE;
if (isOrientationLandscape && !getResources().getBoolean(R.bool.isTablet)) {
((LinearLayout) numpad).setVisibility(View.GONE);
} else {
@ -165,7 +178,8 @@ public class DialerFragment extends Fragment {
String addressWaitingToBeCalled = LinphoneActivity.instance().mAddressWaitingToBeCalled;
if (addressWaitingToBeCalled != null) {
mAddress.setText(addressWaitingToBeCalled);
if (getResources().getBoolean(R.bool.automatically_start_intercepted_outgoing_gsm_call)) {
if (getResources()
.getBoolean(R.bool.automatically_start_intercepted_outgoing_gsm_call)) {
newOutgoingCall(addressWaitingToBeCalled);
}
LinphoneActivity.instance().mAddressWaitingToBeCalled = null;
@ -207,7 +221,10 @@ public class DialerFragment extends Fragment {
}
public void enableDisableAddContact() {
mAddContact.setEnabled(LinphoneManager.getLcIfManagerNotDestroyedOrNull() != null && LinphoneManager.getLc().getCallsNb() > 0 || !mAddress.getText().toString().equals(""));
mAddContact.setEnabled(
LinphoneManager.getLcIfManagerNotDestroyedOrNull() != null
&& LinphoneManager.getLc().getCallsNb() > 0
|| !mAddress.getText().toString().equals(""));
}
public void displayTextInAddressBar(String numberOrSipAddress) {
@ -228,7 +245,9 @@ public class DialerFragment extends Fragment {
mAddress.setText(intent.getData().getSchemeSpecificPart());
} else {
Uri contactUri = intent.getData();
String address = ContactsManager.getAddressOrNumberForAndroidContact(LinphoneService.instance().getContentResolver(), contactUri);
String address =
ContactsManager.getAddressOrNumberForAndroidContact(
LinphoneService.instance().getContentResolver(), contactUri);
if (address != null) {
mAddress.setText(address);
} else {

View file

@ -24,17 +24,15 @@ import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import org.linphone.R;
public class EmptyFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.empty_fragment, container, false);
return view;
}
}

View file

@ -46,16 +46,23 @@ public enum FragmentsAvailable {
return fragment == HISTORY_LIST || fragment == HISTORY_DETAIL;
case CONTACT_DETAIL:
return fragment == CONTACTS_LIST || fragment == CONTACT_EDITOR || fragment == CONTACT_DETAIL;
return fragment == CONTACTS_LIST
|| fragment == CONTACT_EDITOR
|| fragment == CONTACT_DETAIL;
case CONTACT_EDITOR:
return fragment == CONTACTS_LIST || fragment == CONTACT_DETAIL || fragment == CONTACT_EDITOR;
return fragment == CONTACTS_LIST
|| fragment == CONTACT_DETAIL
|| fragment == CONTACT_EDITOR;
case CHAT:
return fragment == CHAT_LIST || fragment == CHAT;
case GROUP_CHAT:
return fragment == CHAT_LIST || fragment == GROUP_CHAT || fragment == INFO_GROUP_CHAT || fragment == CREATE_CHAT;
return fragment == CHAT_LIST
|| fragment == GROUP_CHAT
|| fragment == INFO_GROUP_CHAT
|| fragment == CREATE_CHAT;
case MESSAGE_IMDN:
return fragment == GROUP_CHAT || fragment == MESSAGE_IMDN;

View file

@ -26,7 +26,6 @@ import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import androidx.core.content.ContextCompat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
@ -36,12 +35,11 @@ import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.core.content.ContextCompat;
import org.linphone.LinphoneActivity;
import org.linphone.LinphoneManager;
import org.linphone.settings.LinphonePreferences;
import org.linphone.LinphoneService;
import org.linphone.R;
import org.linphone.LinphoneActivity;
import org.linphone.assistant.AssistantActivity;
import org.linphone.call.CallActivity;
import org.linphone.core.Call;
@ -53,6 +51,7 @@ import org.linphone.core.MediaEncryption;
import org.linphone.core.ProxyConfig;
import org.linphone.core.RegistrationState;
import org.linphone.mediastream.Log;
import org.linphone.settings.LinphonePreferences;
public class StatusFragment extends Fragment {
private Handler refreshHandler = new Handler();
@ -65,8 +64,8 @@ public class StatusFragment extends Fragment {
private int mDisplayedQuality = -1;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.status, container, false);
statusText = view.findViewById(R.id.status_text);
@ -80,64 +79,71 @@ public class StatusFragment extends Fragment {
// We create it once to not delay the first display
populateSliderContent();
mListener = new CoreListenerStub() {
@Override
public void onRegistrationStateChanged(final Core lc, final ProxyConfig proxy, final RegistrationState state, String smessage) {
if (!isAttached || !LinphoneService.isReady()) {
return;
}
if (lc.getProxyConfigList() == null) {
statusLed.setImageResource(R.drawable.led_disconnected);
statusText.setText(getString(R.string.no_account));
} else {
statusLed.setVisibility(View.VISIBLE);
}
if (lc.getDefaultProxyConfig() != null && lc.getDefaultProxyConfig().equals(proxy)) {
statusLed.setImageResource(getStatusIconResource(state, true));
statusText.setText(getStatusIconText(state));
} else if (lc.getDefaultProxyConfig() == null) {
statusLed.setImageResource(getStatusIconResource(state, true));
statusText.setText(getStatusIconText(state));
}
try {
statusText.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
lc.refreshRegisters();
mListener =
new CoreListenerStub() {
@Override
public void onRegistrationStateChanged(
final Core lc,
final ProxyConfig proxy,
final RegistrationState state,
String smessage) {
if (!isAttached || !LinphoneService.isReady()) {
return;
}
});
} catch (IllegalStateException ise) {
}
}
@Override
public void onNotifyReceived(Core lc, Event ev, String eventName, Content content) {
if (lc.getProxyConfigList() == null) {
statusLed.setImageResource(R.drawable.led_disconnected);
statusText.setText(getString(R.string.no_account));
} else {
statusLed.setVisibility(View.VISIBLE);
}
if (!content.getType().equals("application")) return;
if (!content.getSubtype().equals("simple-message-summary")) return;
if (lc.getDefaultProxyConfig() != null
&& lc.getDefaultProxyConfig().equals(proxy)) {
statusLed.setImageResource(getStatusIconResource(state, true));
statusText.setText(getStatusIconText(state));
} else if (lc.getDefaultProxyConfig() == null) {
statusLed.setImageResource(getStatusIconResource(state, true));
statusText.setText(getStatusIconText(state));
}
if (content.getSize() == 0) return;
try {
statusText.setOnClickListener(
new OnClickListener() {
@Override
public void onClick(View v) {
lc.refreshRegisters();
}
});
} catch (IllegalStateException ise) {
}
}
int unreadCount = -1;
String data = content.getStringBuffer();
String[] voiceMail = data.split("voice-message: ");
final String[] intToParse = voiceMail[1].split("/", 0);
@Override
public void onNotifyReceived(
Core lc, Event ev, String eventName, Content content) {
unreadCount = Integer.parseInt(intToParse[0]);
if (unreadCount > 0) {
voicemailCount.setText(unreadCount);
voicemail.setVisibility(View.VISIBLE);
voicemailCount.setVisibility(View.VISIBLE);
} else {
voicemail.setVisibility(View.GONE);
voicemailCount.setVisibility(View.GONE);
}
}
if (!content.getType().equals("application")) return;
if (!content.getSubtype().equals("simple-message-summary")) return;
};
if (content.getSize() == 0) return;
int unreadCount = -1;
String data = content.getStringBuffer();
String[] voiceMail = data.split("voice-message: ");
final String[] intToParse = voiceMail[1].split("/", 0);
unreadCount = Integer.parseInt(intToParse[0]);
if (unreadCount > 0) {
voicemailCount.setText(unreadCount);
voicemail.setVisibility(View.VISIBLE);
voicemailCount.setVisibility(View.VISIBLE);
} else {
voicemail.setVisibility(View.GONE);
voicemailCount.setVisibility(View.GONE);
}
}
};
isAttached = true;
Activity activity = getActivity();
@ -174,15 +180,15 @@ public class StatusFragment extends Fragment {
isAttached = false;
}
//NORMAL STATUS BAR
// NORMAL STATUS BAR
private void populateSliderContent() {
if (LinphoneManager.isInstanciated() && LinphoneManager.getLc() != null) {
voicemailCount.setVisibility(View.GONE);
if (isInCall && isAttached) {
//Call call = LinphoneManager.getLc().getCurrentCall();
//initCallStatsRefresher(call, callStats);
// Call call = LinphoneManager.getLc().getCurrentCall();
// initCallStatsRefresher(call, callStats);
} else if (!isInCall) {
voicemailCount.setVisibility(View.VISIBLE);
}
@ -208,7 +214,13 @@ public class StatusFragment extends Fragment {
private int getStatusIconResource(RegistrationState state, boolean isDefaultAccount) {
try {
Core lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
boolean defaultAccountConnected = (isDefaultAccount && lc != null && lc.getDefaultProxyConfig() != null && lc.getDefaultProxyConfig().getState() == RegistrationState.Ok) || !isDefaultAccount;
boolean defaultAccountConnected =
(isDefaultAccount
&& lc != null
&& lc.getDefaultProxyConfig() != null
&& lc.getDefaultProxyConfig().getState()
== RegistrationState.Ok)
|| !isDefaultAccount;
if (state == RegistrationState.Ok && defaultAccountConnected) {
return R.drawable.led_connected;
} else if (state == RegistrationState.Progress) {
@ -227,13 +239,15 @@ public class StatusFragment extends Fragment {
private String getStatusIconText(RegistrationState state) {
Context context = getActivity();
if (!isAttached && LinphoneActivity.isInstanciated())
context = LinphoneActivity.instance();
else if (!isAttached && LinphoneService.isReady())
context = LinphoneService.instance();
if (!isAttached && LinphoneActivity.isInstanciated()) context = LinphoneActivity.instance();
else if (!isAttached && LinphoneService.isReady()) context = LinphoneService.instance();
try {
if (state == RegistrationState.Ok && LinphoneManager.getLcIfManagerNotDestroyedOrNull().getDefaultProxyConfig().getState() == RegistrationState.Ok) {
if (state == RegistrationState.Ok
&& LinphoneManager.getLcIfManagerNotDestroyedOrNull()
.getDefaultProxyConfig()
.getState()
== RegistrationState.Ok) {
return context.getString(R.string.status_connected);
} else if (state == RegistrationState.Progress) {
return context.getString(R.string.status_in_progress);
@ -249,27 +263,28 @@ public class StatusFragment extends Fragment {
return context.getString(R.string.status_not_connected);
}
//INCALL STATUS BAR
// INCALL STATUS BAR
private void startCallQuality() {
callQuality.setVisibility(View.VISIBLE);
refreshHandler.postDelayed(mCallQualityUpdater = new Runnable() {
Call mCurrentCall = LinphoneManager.getLc()
.getCurrentCall();
refreshHandler.postDelayed(
mCallQualityUpdater =
new Runnable() {
Call mCurrentCall = LinphoneManager.getLc().getCurrentCall();
public void run() {
if (mCurrentCall == null) {
mCallQualityUpdater = null;
return;
}
float newQuality = mCurrentCall.getCurrentQuality();
updateQualityOfSignalIcon(newQuality);
public void run() {
if (mCurrentCall == null) {
mCallQualityUpdater = null;
return;
}
float newQuality = mCurrentCall.getCurrentQuality();
updateQualityOfSignalIcon(newQuality);
if (isInCall) {
refreshHandler.postDelayed(this, 1000);
} else
mCallQualityUpdater = null;
}
}, 1000);
if (isInCall) {
refreshHandler.postDelayed(this, 1000);
} else mCallQualityUpdater = null;
}
},
1000);
}
void updateQualityOfSignalIcon(float quality) {
@ -278,24 +293,19 @@ public class StatusFragment extends Fragment {
if (iQuality == mDisplayedQuality) return;
if (quality >= 4) // Good Quality
{
callQuality.setImageResource(
R.drawable.call_quality_indicator_4);
callQuality.setImageResource(R.drawable.call_quality_indicator_4);
} else if (quality >= 3) // Average quality
{
callQuality.setImageResource(
R.drawable.call_quality_indicator_3);
callQuality.setImageResource(R.drawable.call_quality_indicator_3);
} else if (quality >= 2) // Low quality
{
callQuality.setImageResource(
R.drawable.call_quality_indicator_2);
callQuality.setImageResource(R.drawable.call_quality_indicator_2);
} else if (quality >= 1) // Very low quality
{
callQuality.setImageResource(
R.drawable.call_quality_indicator_1);
callQuality.setImageResource(R.drawable.call_quality_indicator_1);
} else // Worst quality
{
callQuality.setImageResource(
R.drawable.call_quality_indicator_0);
callQuality.setImageResource(R.drawable.call_quality_indicator_0);
}
mDisplayedQuality = iQuality;
}
@ -326,7 +336,8 @@ public class StatusFragment extends Fragment {
statusLed.setImageResource(R.drawable.led_disconnected);
statusText.setText(getString(R.string.no_account));
} else {
statusLed.setImageResource(getStatusIconResource(lc.getDefaultProxyConfig().getState(), true));
statusLed.setImageResource(
getStatusIconResource(lc.getDefaultProxyConfig().getState(), true));
statusText.setText(getStatusIconText(lc.getDefaultProxyConfig().getState()));
}
}
@ -357,15 +368,19 @@ public class StatusFragment extends Fragment {
MediaEncryption mediaEncryption = call.getCurrentParams().getMediaEncryption();
if (isVideoEnabled) {
//background.setVisibility(View.GONE);
// background.setVisibility(View.GONE);
} else {
//background.setVisibility(View.VISIBLE);
// background.setVisibility(View.VISIBLE);
}
encryption.setVisibility(View.VISIBLE);
if (mediaEncryption == MediaEncryption.SRTP || (mediaEncryption == MediaEncryption.ZRTP && call.getAuthenticationTokenVerified()) || mediaEncryption == MediaEncryption.DTLS) {
if (mediaEncryption == MediaEncryption.SRTP
|| (mediaEncryption == MediaEncryption.ZRTP
&& call.getAuthenticationTokenVerified())
|| mediaEncryption == MediaEncryption.DTLS) {
encryption.setImageResource(R.drawable.security_ok);
} else if (mediaEncryption == MediaEncryption.ZRTP && !call.getAuthenticationTokenVerified()) {
} else if (mediaEncryption == MediaEncryption.ZRTP
&& !call.getAuthenticationTokenVerified()) {
encryption.setImageResource(R.drawable.security_pending);
} else {
encryption.setImageResource(R.drawable.security_ko);
@ -376,12 +391,13 @@ public class StatusFragment extends Fragment {
}
if (mediaEncryption == MediaEncryption.ZRTP) {
encryption.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
showZRTPDialog(call);
}
});
encryption.setOnClickListener(
new OnClickListener() {
@Override
public void onClick(View v) {
showZRTPDialog(call);
}
});
} else {
encryption.setOnClickListener(null);
}
@ -414,7 +430,10 @@ public class StatusFragment extends Fragment {
Drawable d = new ColorDrawable(ContextCompat.getColor(getActivity(), R.color.colorC));
d.setAlpha(200);
ZRTPdialog.setContentView(R.layout.dialog);
ZRTPdialog.getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
ZRTPdialog.getWindow()
.setLayout(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT);
ZRTPdialog.getWindow().setBackgroundDrawable(d);
String zrtpToRead, zrtpToListen;
@ -450,29 +469,31 @@ public class StatusFragment extends Fragment {
icon.setVisibility(View.VISIBLE);
icon.setImageResource(R.drawable.security_2_indicator);
delete.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
if (call != null) {
call.setAuthenticationTokenVerified(false);
if (encryption != null) {
encryption.setImageResource(R.drawable.security_ko);
delete.setOnClickListener(
new OnClickListener() {
@Override
public void onClick(View view) {
if (call != null) {
call.setAuthenticationTokenVerified(false);
if (encryption != null) {
encryption.setImageResource(R.drawable.security_ko);
}
}
ZRTPdialog.dismiss();
}
}
ZRTPdialog.dismiss();
}
});
});
accept.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
call.setAuthenticationTokenVerified(true);
if (encryption != null) {
encryption.setImageResource(R.drawable.security_ok);
}
ZRTPdialog.dismiss();
}
});
accept.setOnClickListener(
new OnClickListener() {
@Override
public void onClick(View view) {
call.setAuthenticationTokenVerified(true);
if (encryption != null) {
encryption.setImageResource(R.drawable.security_ok);
}
ZRTPdialog.dismiss();
}
});
ZRTPdialog.show();
}
}

View file

@ -1,53 +1,55 @@
package org.linphone.history;
/*
HistoryAdapter.java
Copyright (C) 2018 Belledonne Communications, Grenoble, France
HistoryAdapter.java
Copyright (C) 2018 Belledonne Communications, Grenoble, France
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import android.annotation.SuppressLint;
import android.content.Context;
import androidx.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import org.linphone.utils.LinphoneUtils;
import org.linphone.R;
import androidx.annotation.NonNull;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List;
import org.linphone.LinphoneActivity;
import org.linphone.R;
import org.linphone.contacts.ContactsManager;
import org.linphone.contacts.LinphoneContact;
import org.linphone.core.Address;
import org.linphone.core.Call;
import org.linphone.core.CallLog;
import org.linphone.views.ContactAvatar;
import org.linphone.utils.LinphoneUtils;
import org.linphone.utils.SelectableAdapter;
import org.linphone.utils.SelectableHelper;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List;
import org.linphone.views.ContactAvatar;
public class HistoryAdapter extends SelectableAdapter<HistoryViewHolder> {
private List<CallLog> mLogs;
private Context mContext;
private HistoryViewHolder.ClickListener clickListener;
public HistoryAdapter(Context aContext, List<CallLog> logs, HistoryViewHolder.ClickListener listener, SelectableHelper helper) {
public HistoryAdapter(
Context aContext,
List<CallLog> logs,
HistoryViewHolder.ClickListener listener,
SelectableHelper helper) {
super(helper);
this.mLogs = logs;
this.mContext = aContext;
@ -65,9 +67,10 @@ public class HistoryAdapter extends SelectableAdapter<HistoryViewHolder> {
@NonNull
@Override
public HistoryViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.history_cell, parent, false);
View v =
LayoutInflater.from(parent.getContext())
.inflate(R.layout.history_cell, parent, false);
return new HistoryViewHolder(v, clickListener);
}
@Override
@ -130,18 +133,17 @@ public class HistoryAdapter extends SelectableAdapter<HistoryViewHolder> {
}
holder.detail.setVisibility(isEditionEnabled() ? View.INVISIBLE : View.VISIBLE);
holder.detail.setOnClickListener(!isEditionEnabled() ?
new View.OnClickListener() {
@Override
public void onClick(View v) {
if (LinphoneActivity.isInstanciated()) {
LinphoneActivity.instance().displayHistoryDetail(sipUri, log);
holder.detail.setOnClickListener(
!isEditionEnabled()
? new View.OnClickListener() {
@Override
public void onClick(View v) {
if (LinphoneActivity.isInstanciated()) {
LinphoneActivity.instance().displayHistoryDetail(sipUri, log);
}
}
}
}
}
:
null
);
: null);
}
@Override
@ -157,7 +159,9 @@ public class HistoryAdapter extends SelectableAdapter<HistoryViewHolder> {
} else if (isYesterday(cal)) {
return mContext.getString(R.string.yesterday);
} else {
dateFormat = new SimpleDateFormat(mContext.getResources().getString(R.string.history_date_format));
dateFormat =
new SimpleDateFormat(
mContext.getResources().getString(R.string.history_date_format));
}
return dateFormat.format(cal.getTime());
@ -168,9 +172,9 @@ public class HistoryAdapter extends SelectableAdapter<HistoryViewHolder> {
return false;
}
return (cal1.get(Calendar.ERA) == cal2.get(Calendar.ERA) &&
cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) &&
cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR));
return (cal1.get(Calendar.ERA) == cal2.get(Calendar.ERA)
&& cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR)
&& cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR));
}
private boolean isToday(Calendar cal) {
@ -182,4 +186,4 @@ public class HistoryAdapter extends SelectableAdapter<HistoryViewHolder> {
yesterday.roll(Calendar.DAY_OF_MONTH, -1);
return isSameDay(cal, yesterday);
}
}
}

View file

@ -29,14 +29,9 @@ import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import org.linphone.LinphoneManager;
import org.linphone.fragments.FragmentsAvailable;
import org.linphone.settings.LinphonePreferences;
import org.linphone.utils.ImageUtils;
import org.linphone.utils.LinphoneUtils;
import org.linphone.R;
import org.linphone.LinphoneActivity;
import org.linphone.LinphoneManager;
import org.linphone.R;
import org.linphone.contacts.ContactsManager;
import org.linphone.contacts.LinphoneContact;
import org.linphone.core.Address;
@ -47,6 +42,9 @@ import org.linphone.core.Factory;
import org.linphone.core.ProxyConfig;
import org.linphone.fragments.FragmentsAvailable;
import org.linphone.mediastream.Log;
import org.linphone.settings.LinphonePreferences;
import org.linphone.utils.ImageUtils;
import org.linphone.utils.LinphoneUtils;
public class HistoryDetailFragment extends Fragment implements OnClickListener {
private ImageView dialBack, chat, addToContacts, goToContact, back;
@ -60,8 +58,8 @@ public class HistoryDetailFragment extends Fragment implements OnClickListener {
private ChatRoomListenerStub mChatRoomCreationListener;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
sipUri = getArguments().getString("SipUri");
displayName = getArguments().getString("DisplayName");
pictureUri = getArguments().getString("PictureUri");
@ -107,19 +105,24 @@ public class HistoryDetailFragment extends Fragment implements OnClickListener {
displayHistory(status, callTime, callDate);
mChatRoomCreationListener = new ChatRoomListenerStub() {
@Override
public void onStateChanged(ChatRoom cr, ChatRoom.State newState) {
if (newState == ChatRoom.State.Created) {
mWaitLayout.setVisibility(View.GONE);
LinphoneActivity.instance().goToChat(cr.getPeerAddress().asStringUriOnly(), null);
} else if (newState == ChatRoom.State.CreationFailed) {
mWaitLayout.setVisibility(View.GONE);
LinphoneActivity.instance().displayChatRoomError();
Log.e("Group chat room for address " + cr.getPeerAddress() + " has failed !");
}
}
};
mChatRoomCreationListener =
new ChatRoomListenerStub() {
@Override
public void onStateChanged(ChatRoom cr, ChatRoom.State newState) {
if (newState == ChatRoom.State.Created) {
mWaitLayout.setVisibility(View.GONE);
LinphoneActivity.instance()
.goToChat(cr.getPeerAddress().asStringUriOnly(), null);
} else if (newState == ChatRoom.State.CreationFailed) {
mWaitLayout.setVisibility(View.GONE);
LinphoneActivity.instance().displayChatRoomError();
Log.e(
"Group chat room for address "
+ cr.getPeerAddress()
+ " has failed !");
}
}
};
return view;
}
@ -143,7 +146,9 @@ public class HistoryDetailFragment extends Fragment implements OnClickListener {
time.setText(callTime == null ? "" : callTime);
Long longDate = Long.parseLong(callDate);
date.setText(LinphoneUtils.timestampToHumanDate(getActivity(), longDate, getString(R.string.history_detail_date_format)));
date.setText(
LinphoneUtils.timestampToHumanDate(
getActivity(), longDate, getString(R.string.history_detail_date_format)));
Address lAddress = Factory.instance().createAddress(sipUri);
@ -152,22 +157,39 @@ public class HistoryDetailFragment extends Fragment implements OnClickListener {
contact = ContactsManager.getInstance().findContactFromAddress(lAddress);
if (contact != null) {
contactName.setText(contact.getFullName());
ImageUtils.setImagePictureFromUri(view.getContext(), contactPicture, contact.getPhotoUri(), contact.getThumbnailUri());
ImageUtils.setImagePictureFromUri(
view.getContext(),
contactPicture,
contact.getPhotoUri(),
contact.getThumbnailUri());
addToContacts.setVisibility(View.GONE);
goToContact.setVisibility(View.VISIBLE);
} else {
contactName.setText(displayName == null ? LinphoneUtils.getAddressDisplayName(sipUri) : displayName);
contactPicture.setImageBitmap(ContactsManager.getInstance().getDefaultAvatarBitmap());
contactName.setText(
displayName == null
? LinphoneUtils.getAddressDisplayName(sipUri)
: displayName);
contactPicture.setImageBitmap(
ContactsManager.getInstance().getDefaultAvatarBitmap());
addToContacts.setVisibility(View.VISIBLE);
goToContact.setVisibility(View.GONE);
}
} else {
contactAddress.setText(sipUri);
contactName.setText(displayName == null ? LinphoneUtils.getAddressDisplayName(sipUri) : displayName);
contactName.setText(
displayName == null
? LinphoneUtils.getAddressDisplayName(sipUri)
: displayName);
}
}
public void changeDisplayedHistory(String sipUri, String displayName, String pictureUri, String status, String callTime, String callDate) {
public void changeDisplayedHistory(
String sipUri,
String displayName,
String pictureUri,
String status,
String callTime,
String callDate) {
if (displayName == null) {
displayName = LinphoneUtils.getUsernameFromAddress(sipUri);
}
@ -195,23 +217,32 @@ public class HistoryDetailFragment extends Fragment implements OnClickListener {
getFragmentManager().popBackStackImmediate();
}
if (id == R.id.call) {
LinphoneActivity.instance().setAddresGoToDialerAndCall(sipUri, displayName, pictureUri == null ? null : Uri.parse(pictureUri));
LinphoneActivity.instance()
.setAddresGoToDialerAndCall(
sipUri, displayName, pictureUri == null ? null : Uri.parse(pictureUri));
} else if (id == R.id.chat) {
Core lc = LinphoneManager.getLc();
Address participant = Factory.instance().createAddress(sipUri);
ChatRoom room = lc.findOneToOneChatRoom(lc.getDefaultProxyConfig().getContact(), participant, false);
ChatRoom room =
lc.findOneToOneChatRoom(
lc.getDefaultProxyConfig().getContact(), participant, false);
if (room != null) {
LinphoneActivity.instance().goToChat(room.getPeerAddress().asStringUriOnly(), null);
} else {
ProxyConfig lpc = lc.getDefaultProxyConfig();
if (lpc != null && lpc.getConferenceFactoryUri() != null && !LinphonePreferences.instance().useBasicChatRoomFor1To1()) {
if (lpc != null
&& lpc.getConferenceFactoryUri() != null
&& !LinphonePreferences.instance().useBasicChatRoomFor1To1()) {
mWaitLayout.setVisibility(View.VISIBLE);
mChatRoom = lc.createClientGroupChatRoom(getString(R.string.dummy_group_chat_subject), true);
mChatRoom =
lc.createClientGroupChatRoom(
getString(R.string.dummy_group_chat_subject), true);
mChatRoom.addListener(mChatRoomCreationListener);
mChatRoom.addParticipant(participant);
} else {
room = lc.getChatRoom(participant);
LinphoneActivity.instance().goToChat(room.getPeerAddress().asStringUriOnly(), null);
LinphoneActivity.instance()
.goToChat(room.getPeerAddress().asStringUriOnly(), null);
}
}
} else if (id == R.id.add_contact) {

View file

@ -22,9 +22,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
import android.app.Fragment;
import android.content.Context;
import android.os.Bundle;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
@ -33,24 +30,29 @@ import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.linphone.LinphoneActivity;
import org.linphone.LinphoneManager;
import org.linphone.R;
import org.linphone.LinphoneActivity;
import org.linphone.fragments.FragmentsAvailable;
import org.linphone.contacts.ContactsManager;
import org.linphone.contacts.ContactsUpdatedListener;
import org.linphone.core.Address;
import org.linphone.core.Call;
import org.linphone.core.CallLog;
import org.linphone.fragments.FragmentsAvailable;
import org.linphone.utils.SelectableHelper;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class HistoryListFragment extends Fragment implements OnClickListener, OnItemClickListener, HistoryViewHolder.ClickListener, ContactsUpdatedListener, SelectableHelper.DeleteListener {
public class HistoryListFragment extends Fragment
implements OnClickListener,
OnItemClickListener,
HistoryViewHolder.ClickListener,
ContactsUpdatedListener,
SelectableHelper.DeleteListener {
private RecyclerView historyList;
private TextView noCallHistory, noMissedCallHistory;
private ImageView missedCalls, allCalls;
@ -63,8 +65,8 @@ public class HistoryListFragment extends Fragment implements OnClickListener, On
private SelectableHelper mSelectionHelper;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.history, container, false);
mContext = getActivity().getApplicationContext();
mSelectionHelper = new SelectableHelper(view, this);
@ -76,9 +78,10 @@ public class HistoryListFragment extends Fragment implements OnClickListener, On
mLayoutManager = new LinearLayoutManager(mContext);
historyList.setLayoutManager(mLayoutManager);
//Divider between items
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(historyList.getContext(),
mLayoutManager.getOrientation());
// Divider between items
DividerItemDecoration dividerItemDecoration =
new DividerItemDecoration(
historyList.getContext(), mLayoutManager.getOrientation());
dividerItemDecoration.setDrawable(mContext.getResources().getDrawable(R.drawable.divider));
historyList.addItemDecoration(dividerItemDecoration);
@ -133,7 +136,7 @@ public class HistoryListFragment extends Fragment implements OnClickListener, On
removeNotMissedCallsFromLogs();
noCallHistory.setVisibility(View.GONE);
noMissedCallHistory.setVisibility(View.GONE);
if (mLogs.isEmpty()) {
if (mOnlyDisplayMissedCalls) {
noMissedCallHistory.setVisibility(View.VISIBLE);
@ -160,7 +163,9 @@ public class HistoryListFragment extends Fragment implements OnClickListener, On
mLogs = Arrays.asList(LinphoneManager.getLc().getCallLogs());
hideHistoryListAndDisplayMessageIfEmpty();
mHistoryAdapter = new HistoryAdapter(getActivity().getApplicationContext(), mLogs, this, mSelectionHelper);
mHistoryAdapter =
new HistoryAdapter(
getActivity().getApplicationContext(), mLogs, this, mSelectionHelper);
historyList.setAdapter(mHistoryAdapter);
mSelectionHelper.setAdapter(mHistoryAdapter);
mSelectionHelper.setDialogMessage(R.string.chat_room_delete_dialog);
@ -174,8 +179,9 @@ public class HistoryListFragment extends Fragment implements OnClickListener, On
@Override
public void onContactsUpdated() {
if (!LinphoneActivity.isInstanciated() || LinphoneActivity.instance().getCurrentFragment() != FragmentsAvailable.HISTORY_LIST)
return;
if (!LinphoneActivity.isInstanciated()
|| LinphoneActivity.instance().getCurrentFragment()
!= FragmentsAvailable.HISTORY_LIST) return;
HistoryAdapter adapter = (HistoryAdapter) historyList.getAdapter();
if (adapter != null) {
adapter.notifyDataSetChanged();
@ -240,7 +246,9 @@ public class HistoryListFragment extends Fragment implements OnClickListener, On
} else {
address = log.getToAddress();
}
LinphoneActivity.instance().setAddresGoToDialerAndCall(address.asStringUriOnly(), address.getDisplayName(), null);
LinphoneActivity.instance()
.setAddresGoToDialerAndCall(
address.asStringUriOnly(), address.getDisplayName(), null);
}
}
}
@ -253,4 +261,4 @@ public class HistoryListFragment extends Fragment implements OnClickListener, On
mHistoryAdapter.toggleSelection(position);
return true;
}
}
}

View file

@ -1,35 +1,35 @@
package org.linphone.history;
/*
HistoryViewHolder.java
Copyright (C) 2018 Belledonne Communications, Grenoble, France
HistoryViewHolder.java
Copyright (C) 2018 Belledonne Communications, Grenoble, France
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import androidx.recyclerview.widget.RecyclerView;
import android.view.View;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import org.linphone.R;
public class HistoryViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
public class HistoryViewHolder extends RecyclerView.ViewHolder
implements View.OnClickListener, View.OnLongClickListener {
public TextView contact;
public ImageView detail;
public CheckBox select;
@ -75,4 +75,4 @@ public class HistoryViewHolder extends RecyclerView.ViewHolder implements View.O
boolean onItemLongClicked(int position);
}
}
}

View file

@ -30,7 +30,8 @@ public class NotifiableMessage {
Uri mFilePath;
String mFileMime;
public NotifiableMessage(String message, String sender, long time, Uri filePath, String fileMime) {
public NotifiableMessage(
String message, String sender, long time, Uri filePath, String fileMime) {
mMessage = message;
mSender = sender;
mTime = time;

View file

@ -26,11 +26,10 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import org.linphone.LinphoneActivity;
import org.linphone.LinphoneManager;
import org.linphone.LinphoneService;
import org.linphone.R;
import org.linphone.LinphoneActivity;
import org.linphone.compatibility.Compatibility;
import org.linphone.core.Address;
import org.linphone.core.Call;
@ -38,7 +37,6 @@ import org.linphone.core.ChatMessage;
import org.linphone.core.ChatMessageListenerStub;
import org.linphone.core.ChatRoom;
import org.linphone.core.Core;
import org.linphone.core.ProxyConfig;
import org.linphone.mediastream.Log;
public class NotificationBroadcastReceiver extends BroadcastReceiver {
@ -54,17 +52,20 @@ public class NotificationBroadcastReceiver extends BroadcastReceiver {
onError(context, notifId);
return;
}
String remoteSipAddr = LinphoneService.instance().getNotificationManager().getSipUriForNotificationId(notifId);
String remoteSipAddr =
LinphoneService.instance()
.getNotificationManager()
.getSipUriForNotificationId(notifId);
Core core = LinphoneManager.getLc();
if (core == null) {
if (core == null) {
Log.e("Couldn't get Core instance");
onError(context, notifId);
return;
}
Address remoteAddr = core.interpretUrl(remoteSipAddr);
if (remoteAddr == null) {
if (remoteAddr == null) {
Log.e("Couldn't interpret remote address " + remoteSipAddr);
onError(context, notifId);
return;
@ -78,33 +79,46 @@ public class NotificationBroadcastReceiver extends BroadcastReceiver {
}
ChatRoom room = core.findChatRoom(remoteAddr, localAddr);
if (room == null) {
Log.e("Couldn't find chat room for remote address " + remoteSipAddr + " and local address " + localyIdentity);
if (room == null) {
Log.e(
"Couldn't find chat room for remote address "
+ remoteSipAddr
+ " and local address "
+ localyIdentity);
onError(context, notifId);
return;
}
room.markAsRead();
if (LinphoneActivity.isInstanciated()) {
LinphoneActivity.instance().displayMissedChats(LinphoneManager.getInstance().getUnreadMessageCount());
LinphoneActivity.instance()
.displayMissedChats(LinphoneManager.getInstance().getUnreadMessageCount());
}
ChatMessage msg = room.createMessage(reply);
msg.send();
msg.setListener(new ChatMessageListenerStub() {
@Override
public void onMsgStateChanged(ChatMessage msg, ChatMessage.State state) {
if (state == ChatMessage.State.Delivered) {
Notification replied = Compatibility.createRepliedNotification(context, reply);
LinphoneService.instance().getNotificationManager().sendNotification(notifId, replied);
} else if (state == ChatMessage.State.NotDelivered) {
Log.e("Couldn't send reply, message is not delivered");
onError(context, notifId);
}
}
});
} else if (intent.getAction() == Compatibility.INTENT_ANSWER_CALL_NOTIF_ACTION || intent.getAction() == Compatibility.INTENT_HANGUP_CALL_NOTIF_ACTION) {
String remoteAddr = LinphoneService.instance().getNotificationManager().getSipUriForCallNotificationId(notifId);
msg.setListener(
new ChatMessageListenerStub() {
@Override
public void onMsgStateChanged(ChatMessage msg, ChatMessage.State state) {
if (state == ChatMessage.State.Delivered) {
Notification replied =
Compatibility.createRepliedNotification(context, reply);
LinphoneService.instance()
.getNotificationManager()
.sendNotification(notifId, replied);
} else if (state == ChatMessage.State.NotDelivered) {
Log.e("Couldn't send reply, message is not delivered");
onError(context, notifId);
}
}
});
} else if (intent.getAction() == Compatibility.INTENT_ANSWER_CALL_NOTIF_ACTION
|| intent.getAction() == Compatibility.INTENT_HANGUP_CALL_NOTIF_ACTION) {
String remoteAddr =
LinphoneService.instance()
.getNotificationManager()
.getSipUriForCallNotificationId(notifId);
Core core = LinphoneManager.getLc();
if (core == null) {
@ -126,7 +140,8 @@ public class NotificationBroadcastReceiver extends BroadcastReceiver {
}
private void onError(Context context, int notifId) {
Notification replyError = Compatibility.createRepliedNotification(context, context.getString(R.string.error));
Notification replyError =
Compatibility.createRepliedNotification(context, context.getString(R.string.error));
LinphoneService.instance().getNotificationManager().sendNotification(notifId, replyError);
}

View file

@ -19,6 +19,8 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import static android.content.Context.NOTIFICATION_SERVICE;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
@ -27,24 +29,20 @@ import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import org.linphone.LinphoneManager;
import org.linphone.settings.LinphonePreferences;
import org.linphone.LinphoneService;
import org.linphone.utils.ImageUtils;
import org.linphone.utils.LinphoneUtils;
import org.linphone.R;
import java.util.HashMap;
import org.linphone.LinphoneActivity;
import org.linphone.LinphoneManager;
import org.linphone.LinphoneService;
import org.linphone.R;
import org.linphone.compatibility.Compatibility;
import org.linphone.contacts.ContactsManager;
import org.linphone.contacts.LinphoneContact;
import org.linphone.core.Address;
import org.linphone.core.Call;
import org.linphone.mediastream.Version;
import java.util.HashMap;
import static android.content.Context.NOTIFICATION_SERVICE;
import org.linphone.settings.LinphonePreferences;
import org.linphone.utils.ImageUtils;
import org.linphone.utils.LinphoneUtils;
public class NotificationsManager {
private static final int SERVICE_NOTIF_ID = 1;
@ -69,10 +67,11 @@ public class NotificationsManager {
Compatibility.createNotificationChannels(mContext);
Intent notifIntent = new Intent(mContext, LinphoneService.instance().getIncomingReceivedActivity());
Intent notifIntent =
new Intent(mContext, LinphoneService.instance().getIncomingReceivedActivity());
notifIntent.putExtra("Notification", true);
//Disable service notification for Android O
// Disable service notification for Android O
if (Version.sdkAboveOrEqual(Version.API26_O_80)) {
LinphonePreferences.instance().setServiceNotificationVisibility(false);
}
@ -83,10 +82,20 @@ public class NotificationsManager {
} catch (Exception e) {
}
PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, notifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
mServiceNotification = Compatibility.createNotification(mContext, mContext.getString(R.string.service_name), "",
R.drawable.linphone_notification_icon, R.mipmap.ic_launcher, bm, pendingIntent, true,
Notification.PRIORITY_MIN);
PendingIntent pendingIntent =
PendingIntent.getActivity(
mContext, 0, notifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
mServiceNotification =
Compatibility.createNotification(
mContext,
mContext.getString(R.string.service_name),
"",
R.drawable.linphone_notification_icon,
R.mipmap.ic_launcher,
bm,
pendingIntent,
true,
Notification.PRIORITY_MIN);
if (isServiceNotificationDisplayed()) {
startForeground();
@ -130,15 +139,27 @@ public class NotificationsManager {
return null;
}
public void displayGroupChatMessageNotification(String subject, String conferenceAddress, String fromName, Uri fromPictureUri, String message, Address localIdentity, long timestamp, Uri filePath, String fileMime) {
public void displayGroupChatMessageNotification(
String subject,
String conferenceAddress,
String fromName,
Uri fromPictureUri,
String message,
Address localIdentity,
long timestamp,
Uri filePath,
String fileMime) {
Intent notifIntent = new Intent(mContext, LinphoneActivity.class);
notifIntent.putExtra("GoToChat", true);
notifIntent.putExtra("ChatContactSipUri", conferenceAddress);
PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, notifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent pendingIntent =
PendingIntent.getActivity(
mContext, 0, notifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Bitmap bm = ImageUtils.getRoundBitmapFromUri(mContext, fromPictureUri);
Notifiable notif = mChatNotifMap.get(conferenceAddress);
NotifiableMessage notifMessage = new NotifiableMessage(message, fromName, timestamp, filePath, fileMime);
NotifiableMessage notifMessage =
new NotifiableMessage(message, fromName, timestamp, filePath, fileMime);
if (notif == null) {
notif = new Notifiable(mLastNotificationId);
mLastNotificationId += 1;
@ -152,16 +173,34 @@ public class NotificationsManager {
notif.setMyself(LinphoneUtils.getAddressDisplayName(localIdentity));
notif.setLocalIdentity(localIdentity.asString());
Notification notification = Compatibility.createMessageNotification(mContext, notif, subject,
mContext.getString(R.string.group_chat_notif).replace("%1", fromName).replace("%2", message), bm, pendingIntent);
Notification notification =
Compatibility.createMessageNotification(
mContext,
notif,
subject,
mContext.getString(R.string.group_chat_notif)
.replace("%1", fromName)
.replace("%2", message),
bm,
pendingIntent);
sendNotification(notif.getNotificationId(), notification);
}
public void displayMessageNotification(String fromSipUri, String fromName, Uri fromPictureUri, String message, Address localIdentity, long timestamp, Uri filePath, String fileMime) {
public void displayMessageNotification(
String fromSipUri,
String fromName,
Uri fromPictureUri,
String message,
Address localIdentity,
long timestamp,
Uri filePath,
String fileMime) {
Intent notifIntent = new Intent(mContext, LinphoneActivity.class);
notifIntent.putExtra("GoToChat", true);
notifIntent.putExtra("ChatContactSipUri", fromSipUri);
PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, notifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent pendingIntent =
PendingIntent.getActivity(
mContext, 0, notifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
if (fromName == null) {
fromName = fromSipUri;
@ -169,7 +208,8 @@ public class NotificationsManager {
Bitmap bm = ImageUtils.getRoundBitmapFromUri(mContext, fromPictureUri);
Notifiable notif = mChatNotifMap.get(fromSipUri);
NotifiableMessage notifMessage = new NotifiableMessage(message, fromName, timestamp, filePath, fileMime);
NotifiableMessage notifMessage =
new NotifiableMessage(message, fromName, timestamp, filePath, fileMime);
if (notif == null) {
notif = new Notifiable(mLastNotificationId);
mLastNotificationId += 1;
@ -182,19 +222,26 @@ public class NotificationsManager {
notif.setMyself(LinphoneUtils.getAddressDisplayName(localIdentity));
notif.setLocalIdentity(localIdentity.asString());
Notification notification = Compatibility.createMessageNotification(mContext, notif, fromName, message, bm, pendingIntent);
Notification notification =
Compatibility.createMessageNotification(
mContext, notif, fromName, message, bm, pendingIntent);
sendNotification(notif.getNotificationId(), notification);
}
public void displayMissedCallNotification(Call call) {
Intent missedCallNotifIntent = new Intent(mContext, LinphoneActivity.class);
missedCallNotifIntent.putExtra("GoToHistory", true);
PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, missedCallNotifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent pendingIntent =
PendingIntent.getActivity(
mContext, 0, missedCallNotifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
int missedCallCount = LinphoneManager.getLcIfManagerNotDestroyedOrNull().getMissedCallsCount();
int missedCallCount =
LinphoneManager.getLcIfManagerNotDestroyedOrNull().getMissedCallsCount();
String body;
if (missedCallCount > 1) {
body = mContext.getString(R.string.missed_calls_notif_body).replace("%i", String.valueOf(missedCallCount));
body =
mContext.getString(R.string.missed_calls_notif_body)
.replace("%i", String.valueOf(missedCallCount));
} else {
Address address = call.getRemoteAddress();
LinphoneContact c = ContactsManager.getInstance().findContactFromAddress(address);
@ -208,14 +255,22 @@ public class NotificationsManager {
}
}
Notification notif = Compatibility.createMissedCallNotification(mContext, mContext.getString(R.string.missed_calls_notif_title), body, pendingIntent);
Notification notif =
Compatibility.createMissedCallNotification(
mContext,
mContext.getString(R.string.missed_calls_notif_title),
body,
pendingIntent);
sendNotification(MISSED_CALLS_NOTIF_ID, notif);
}
public void displayCallNotification(Call call) {
if (call == null) return;
Intent callNotifIntent = new Intent(mContext, LinphoneService.instance().getIncomingReceivedActivity());
PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, callNotifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Intent callNotifIntent =
new Intent(mContext, LinphoneService.instance().getIncomingReceivedActivity());
PendingIntent pendingIntent =
PendingIntent.getActivity(
mContext, 0, callNotifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Address address = call.getRemoteAddress();
String addressAsString = address.asStringUriOnly();
@ -264,10 +319,20 @@ public class NotificationsManager {
Bitmap bm = ImageUtils.getRoundBitmapFromUri(mContext, pictureUri);
String name = LinphoneUtils.getAddressDisplayName(address);
boolean showAnswerAction = call.getState() == Call.State.IncomingReceived || call.getState() == Call.State.IncomingEarlyMedia;
Notification notification = Compatibility.createInCallNotification(mContext, notif.getNotificationId(),
showAnswerAction, mContext.getString(R.string.service_name),
mContext.getString(notificationTextId), iconId, bm, name, pendingIntent);
boolean showAnswerAction =
call.getState() == Call.State.IncomingReceived
|| call.getState() == Call.State.IncomingEarlyMedia;
Notification notification =
Compatibility.createInCallNotification(
mContext,
notif.getNotificationId(),
showAnswerAction,
mContext.getString(R.string.service_name),
mContext.getString(notificationTextId),
iconId,
bm,
name,
pendingIntent);
sendNotification(notif.getNotificationId(), notification);
}
@ -283,9 +348,16 @@ public class NotificationsManager {
public void displayInappNotification(String message) {
Intent notifIntent = new Intent(mContext, LinphoneActivity.class);
notifIntent.putExtra("GoToInapp", true);
PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, notifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent pendingIntent =
PendingIntent.getActivity(
mContext, 0, notifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Notification notif = Compatibility.createSimpleNotification(mContext, mContext.getString(R.string.inapp_notification_title), message, pendingIntent);
Notification notif =
Compatibility.createSimpleNotification(
mContext,
mContext.getString(R.string.inapp_notification_title),
message,
pendingIntent);
sendNotification(IN_APP_NOTIF_ID, notif);
}
}

View file

@ -29,17 +29,16 @@ import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.Toast;
import org.linphone.settings.LinphonePreferences;
import java.util.ArrayList;
import java.util.List;
import org.linphone.R;
import org.linphone.mediastream.Log;
import org.linphone.settings.LinphonePreferences;
import org.linphone.xmlrpc.XmlRpcHelper;
import org.linphone.xmlrpc.XmlRpcListenerBase;
import java.util.ArrayList;
import java.util.List;
public class InAppPurchaseActivity extends Activity implements InAppPurchaseListener, OnClickListener {
public class InAppPurchaseActivity extends Activity
implements InAppPurchaseListener, OnClickListener {
private static InAppPurchaseActivity instance;
private InAppPurchaseHelper inAppPurchaseHelper;
private ImageView cancel, back;
@ -49,6 +48,10 @@ public class InAppPurchaseActivity extends Activity implements InAppPurchaseList
private Fragment fragment;
private Handler mHandler = new Handler();
public static InAppPurchaseActivity instance() {
return instance;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -92,12 +95,10 @@ public class InAppPurchaseActivity extends Activity implements InAppPurchaseList
inAppPurchaseHelper.purchaseItemAsync(item.getId(), username);
}
public String getGmailAccount() {
return inAppPurchaseHelper.getGmailAccount();
}
@Override
protected void onDestroy() {
instance = null;
@ -122,22 +123,18 @@ public class InAppPurchaseActivity extends Activity implements InAppPurchaseList
return null;
}
public static InAppPurchaseActivity instance() {
return instance;
}
@Override
public void onServiceAvailableForQueries() {
//email.setText(inAppPurchaseHelper.getGmailAccount());
//email.setEnabled(false);
// email.setText(inAppPurchaseHelper.getGmailAccount());
// email.setEnabled(false);
//inAppPurchaseHelper.getPurchasedItemsAsync();
// inAppPurchaseHelper.getPurchasedItemsAsync();
inAppPurchaseHelper.getAvailableItemsForPurchaseAsync();
}
@Override
public void onAvailableItemsForPurchaseQueryFinished(ArrayList<Purchasable> items) {
//purchasableItemsLayout.removeAllViews();
// purchasableItemsLayout.removeAllViews();
inProgress.setVisibility(View.GONE);
purchasedItems = new ArrayList<>();
for (Purchasable item : items) {
@ -154,8 +151,10 @@ public class InAppPurchaseActivity extends Activity implements InAppPurchaseList
inAppPurchaseHelper.getAvailableItemsForPurchaseAsync();
} else {
for (Purchasable purchasedItem : purchasedItems) {
Log.d("[In-app purchase] Found already bought item, expires " + purchasedItem.getExpireDate());
//displayRecoverAccountButton(purchasedItem);
Log.d(
"[In-app purchase] Found already bought item, expires "
+ purchasedItem.getExpireDate());
// displayRecoverAccountButton(purchasedItem);
}
}
}
@ -167,12 +166,18 @@ public class InAppPurchaseActivity extends Activity implements InAppPurchaseList
Purchasable item = LinphonePreferences.instance().getInAppPurchasedItem();
xmlRpcHelper.updateAccountExpireAsync(new XmlRpcListenerBase() {
@Override
public void onAccountExpireUpdated(String result) {
//TODO
}
}, LinphonePreferences.instance().getAccountUsername(0), LinphonePreferences.instance().getAccountHa1(0), getString(R.string.default_domain), item.getPayload(), item.getPayloadSignature());
xmlRpcHelper.updateAccountExpireAsync(
new XmlRpcListenerBase() {
@Override
public void onAccountExpireUpdated(String result) {
// TODO
}
},
LinphonePreferences.instance().getAccountUsername(0),
LinphonePreferences.instance().getAccountHa1(0),
getString(R.string.default_domain),
item.getPayload(),
item.getPayloadSignature());
}
}
@ -193,19 +198,19 @@ public class InAppPurchaseActivity extends Activity implements InAppPurchaseList
}
@Override
public void onRecoverAccountSuccessful(boolean success) {
}
public void onRecoverAccountSuccessful(boolean success) {}
@Override
public void onError(final String error) {
Log.e(error);
mHandler.post(new Runnable() {
@Override
public void run() {
inProgress.setVisibility(View.GONE);
Toast.makeText(InAppPurchaseActivity.this, error, Toast.LENGTH_LONG).show();
}
});
mHandler.post(
new Runnable() {
@Override
public void run() {
inProgress.setVisibility(View.GONE);
Toast.makeText(InAppPurchaseActivity.this, error, Toast.LENGTH_LONG).show();
}
});
}
@Override

View file

@ -29,13 +29,11 @@ import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.Locale;
import org.linphone.LinphoneManager;
import org.linphone.settings.LinphonePreferences;
import org.linphone.R;
import org.linphone.core.ProxyConfig;
import java.util.Locale;
import org.linphone.settings.LinphonePreferences;
public class InAppPurchaseFragment extends Fragment implements View.OnClickListener {
private LinearLayout usernameLayout;
@ -47,8 +45,8 @@ public class InAppPurchaseFragment extends Fragment implements View.OnClickListe
private Button buyItemButton;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -61,13 +59,19 @@ public class InAppPurchaseFragment extends Fragment implements View.OnClickListe
displayBuySubscriptionButton(item);
defaultEmail = InAppPurchaseActivity.instance().getGmailAccount();
defaultUsername = LinphonePreferences.instance().getAccountUsername(LinphonePreferences.instance().getDefaultAccountIndex());
defaultUsername =
LinphonePreferences.instance()
.getAccountUsername(
LinphonePreferences.instance().getDefaultAccountIndex());
usernameLayout = view.findViewById(R.id.username_layout);
username = view.findViewById(R.id.username);
if (!getResources().getBoolean(R.bool.hide_username_in_inapp)) {
usernameLayout.setVisibility(View.VISIBLE);
username.setText(LinphonePreferences.instance().getAccountUsername(LinphonePreferences.instance().getDefaultAccountIndex()));
username.setText(
LinphonePreferences.instance()
.getAccountUsername(
LinphonePreferences.instance().getDefaultAccountIndex()));
addUsernameHandler(username, errorMessage);
} else {
@ -90,27 +94,25 @@ public class InAppPurchaseFragment extends Fragment implements View.OnClickListe
}
private void addUsernameHandler(final EditText field, final TextView errorMessage) {
field.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
field.addTextChangedListener(
new TextWatcher() {
public void afterTextChanged(Editable s) {}
}
public void beforeTextChanged(
CharSequence s, int start, int count, int after) {}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int count, int after) {
usernameOk = false;
String username = s.toString();
if (isUsernameCorrect(username)) {
usernameOk = true;
errorMessage.setText("");
} else {
errorMessage.setText(R.string.wizard_username_incorrect);
}
if (buyItemButton != null) buyItemButton.setEnabled(usernameOk);
}
});
public void onTextChanged(CharSequence s, int start, int count, int after) {
usernameOk = false;
String username = s.toString();
if (isUsernameCorrect(username)) {
usernameOk = true;
errorMessage.setText("");
} else {
errorMessage.setText(R.string.wizard_username_incorrect);
}
if (buyItemButton != null) buyItemButton.setEnabled(usernameOk);
}
});
}
private boolean isUsernameCorrect(String username) {
@ -137,4 +139,4 @@ public class InAppPurchaseFragment extends Fragment implements View.OnClickListe
username = lpc.normalizePhoneNumber(username);
return username.toLowerCase(Locale.getDefault());
}
}
}

View file

@ -32,18 +32,15 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Patterns;
import com.android.vending.billing.IInAppBillingService;
import org.json.JSONException;
import org.json.JSONObject;
import org.linphone.settings.LinphonePreferences;
import org.linphone.mediastream.Log;
import org.linphone.xmlrpc.XmlRpcHelper;
import org.linphone.xmlrpc.XmlRpcListenerBase;
import java.util.ArrayList;
import java.util.regex.Pattern;
import org.json.JSONException;
import org.json.JSONObject;
import org.linphone.mediastream.Log;
import org.linphone.settings.LinphonePreferences;
import org.linphone.xmlrpc.XmlRpcHelper;
import org.linphone.xmlrpc.XmlRpcListenerBase;
public class InAppPurchaseHelper {
public static final int API_VERSION = 3;
@ -86,9 +83,12 @@ public class InAppPurchaseHelper {
public static final String PURCHASE_DETAILS_PAYLOAD = "developerPayload";
public static final String PURCHASE_DETAILS_PURCHASE_TOKEN = "purchaseToken";
public static final String CLIENT_ERROR_SUBSCRIPTION_PURCHASE_NOT_AVAILABLE = "SUBSCRIPTION_PURCHASE_NOT_AVAILABLE";
public static final String CLIENT_ERROR_BIND_TO_BILLING_SERVICE_FAILED = "BIND_TO_BILLING_SERVICE_FAILED";
public static final String CLIENT_ERROR_BILLING_SERVICE_UNAVAILABLE = "BILLING_SERVICE_UNAVAILABLE";
public static final String CLIENT_ERROR_SUBSCRIPTION_PURCHASE_NOT_AVAILABLE =
"SUBSCRIPTION_PURCHASE_NOT_AVAILABLE";
public static final String CLIENT_ERROR_BIND_TO_BILLING_SERVICE_FAILED =
"BIND_TO_BILLING_SERVICE_FAILED";
public static final String CLIENT_ERROR_BILLING_SERVICE_UNAVAILABLE =
"BILLING_SERVICE_UNAVAILABLE";
private Context mContext;
private InAppPurchaseListener mListener;
@ -97,6 +97,59 @@ public class InAppPurchaseHelper {
private Handler mHandler = new Handler();
private String mGmailAccount;
public InAppPurchaseHelper(Activity context, InAppPurchaseListener listener) {
mContext = context;
mListener = listener;
mGmailAccount = getGmailAccount();
Log.d(
"[In-app purchase] creating InAppPurchaseHelper for context "
+ context.getLocalClassName());
mServiceConn =
new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
Log.d("[In-app purchase] onServiceDisconnected!");
mService = null;
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d("[In-app purchase] onServiceConnected!");
mService = IInAppBillingService.Stub.asInterface(service);
String packageName = mContext.getPackageName();
try {
int response =
mService.isBillingSupported(
API_VERSION, packageName, ITEM_TYPE_SUBS);
if (response != RESPONSE_RESULT_OK || mGmailAccount == null) {
Log.e("[In-app purchase] Error: Subscriptions aren't supported!");
mListener.onError(CLIENT_ERROR_SUBSCRIPTION_PURCHASE_NOT_AVAILABLE);
} else {
mListener.onServiceAvailableForQueries();
}
} catch (RemoteException e) {
Log.e(e);
}
}
};
Intent serviceIntent = new Intent("com.android.vending.billing.InAppBillingService.BIND");
serviceIntent.setPackage("com.android.vending");
if (!mContext.getPackageManager().queryIntentServices(serviceIntent, 0).isEmpty()) {
boolean ok =
mContext.bindService(serviceIntent, mServiceConn, Context.BIND_AUTO_CREATE);
if (!ok) {
Log.e("[In-app purchase] Error: Bind service failed");
mListener.onError(CLIENT_ERROR_BIND_TO_BILLING_SERVICE_FAILED);
}
} else {
Log.e("[In-app purchase] Error: Billing service unavailable on device.");
mListener.onError(CLIENT_ERROR_BILLING_SERVICE_UNAVAILABLE);
}
}
private String responseCodeToErrorMessage(int responseCode) {
switch (responseCode) {
case RESULT_USER_CANCELED:
@ -119,54 +172,6 @@ public class InAppPurchaseHelper {
return "UNKNOWN_RESPONSE_CODE";
}
public InAppPurchaseHelper(Activity context, InAppPurchaseListener listener) {
mContext = context;
mListener = listener;
mGmailAccount = getGmailAccount();
Log.d("[In-app purchase] creating InAppPurchaseHelper for context " + context.getLocalClassName());
mServiceConn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
Log.d("[In-app purchase] onServiceDisconnected!");
mService = null;
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d("[In-app purchase] onServiceConnected!");
mService = IInAppBillingService.Stub.asInterface(service);
String packageName = mContext.getPackageName();
try {
int response = mService.isBillingSupported(API_VERSION, packageName, ITEM_TYPE_SUBS);
if (response != RESPONSE_RESULT_OK || mGmailAccount == null) {
Log.e("[In-app purchase] Error: Subscriptions aren't supported!");
mListener.onError(CLIENT_ERROR_SUBSCRIPTION_PURCHASE_NOT_AVAILABLE);
} else {
mListener.onServiceAvailableForQueries();
}
} catch (RemoteException e) {
Log.e(e);
}
}
};
Intent serviceIntent = new Intent("com.android.vending.billing.InAppBillingService.BIND");
serviceIntent.setPackage("com.android.vending");
if (!mContext.getPackageManager().queryIntentServices(serviceIntent, 0).isEmpty()) {
boolean ok = mContext.bindService(serviceIntent, mServiceConn, Context.BIND_AUTO_CREATE);
if (!ok) {
Log.e("[In-app purchase] Error: Bind service failed");
mListener.onError(CLIENT_ERROR_BIND_TO_BILLING_SERVICE_FAILED);
}
} else {
Log.e("[In-app purchase] Error: Billing service unavailable on device.");
mListener.onError(CLIENT_ERROR_BILLING_SERVICE_UNAVAILABLE);
}
}
private ArrayList<Purchasable> getAvailableItemsForPurchase() {
ArrayList<Purchasable> products = new ArrayList<>();
ArrayList<String> skuList = LinphonePreferences.instance().getInAppPurchasables();
@ -175,7 +180,9 @@ public class InAppPurchaseHelper {
Bundle skuDetails = null;
try {
skuDetails = mService.getSkuDetails(API_VERSION, mContext.getPackageName(), ITEM_TYPE_SUBS, querySkus);
skuDetails =
mService.getSkuDetails(
API_VERSION, mContext.getPackageName(), ITEM_TYPE_SUBS, querySkus);
} catch (RemoteException e) {
Log.e(e);
}
@ -192,7 +199,11 @@ public class InAppPurchaseHelper {
String title = object.getString(SKU_DETAILS_TITLE);
String desc = object.getString(SKU_DETAILS_DESC);
Purchasable purchasable = new Purchasable(id).setTitle(title).setDescription(desc).setPrice(price);
Purchasable purchasable =
new Purchasable(id)
.setTitle(title)
.setDescription(desc)
.setPrice(price);
Log.w("Purchasable item " + purchasable.getDescription());
products.add(purchasable);
} catch (JSONException e) {
@ -200,7 +211,9 @@ public class InAppPurchaseHelper {
}
}
} else {
Log.e("[In-app purchase] Error: responde code is not ok: " + responseCodeToErrorMessage(response));
Log.e(
"[In-app purchase] Error: responde code is not ok: "
+ responseCodeToErrorMessage(response));
mListener.onError(responseCodeToErrorMessage(response));
}
}
@ -209,21 +222,27 @@ public class InAppPurchaseHelper {
}
public void getAvailableItemsForPurchaseAsync() {
new Thread(new Runnable() {
public void run() {
final ArrayList<Purchasable> items = getAvailableItemsForPurchase();
if (mHandler != null && mListener != null) {
mHandler.post(new Runnable() {
public void run() {
mListener.onAvailableItemsForPurchaseQueryFinished(items);
}
});
}
}
}).start();
new Thread(
new Runnable() {
public void run() {
final ArrayList<Purchasable> items = getAvailableItemsForPurchase();
if (mHandler != null && mListener != null) {
mHandler.post(
new Runnable() {
public void run() {
mListener
.onAvailableItemsForPurchaseQueryFinished(
items);
}
});
}
}
})
.start();
}
public void parseAndVerifyPurchaseItemResultAsync(int requestCode, int resultCode, Intent data) {
public void parseAndVerifyPurchaseItemResultAsync(
int requestCode, int resultCode, Intent data) {
if (requestCode == ACTIVITY_RESULT_CODE_PURCHASE_ITEM) {
int responseCode = data.getIntExtra(RESPONSE_CODE, 0);
@ -236,12 +255,15 @@ public class InAppPurchaseHelper {
LinphonePreferences.instance().setInAppPurchasedItem(item);
XmlRpcHelper xmlRpcHelper = new XmlRpcHelper();
xmlRpcHelper.verifySignatureAsync(new XmlRpcListenerBase() {
@Override
public void onSignatureVerified(boolean success) {
mListener.onPurchasedItemConfirmationQueryFinished(success);
}
}, payload, signature);
xmlRpcHelper.verifySignatureAsync(
new XmlRpcListenerBase() {
@Override
public void onSignatureVerified(boolean success) {
mListener.onPurchasedItemConfirmationQueryFinished(success);
}
},
payload,
signature);
}
}
}
@ -249,7 +271,13 @@ public class InAppPurchaseHelper {
private void purchaseItem(String productId, String sipIdentity) {
Bundle buyIntentBundle = null;
try {
buyIntentBundle = mService.getBuyIntent(API_VERSION, mContext.getPackageName(), productId, ITEM_TYPE_SUBS, sipIdentity);
buyIntentBundle =
mService.getBuyIntent(
API_VERSION,
mContext.getPackageName(),
productId,
ITEM_TYPE_SUBS,
sipIdentity);
} catch (RemoteException e) {
Log.e(e);
}
@ -258,7 +286,14 @@ public class InAppPurchaseHelper {
PendingIntent pendingIntent = buyIntentBundle.getParcelable(RESPONSE_BUY_INTENT);
if (pendingIntent != null) {
try {
((Activity) mContext).startIntentSenderForResult(pendingIntent.getIntentSender(), ACTIVITY_RESULT_CODE_PURCHASE_ITEM, new Intent(), 0, 0, 0);
((Activity) mContext)
.startIntentSenderForResult(
pendingIntent.getIntentSender(),
ACTIVITY_RESULT_CODE_PURCHASE_ITEM,
new Intent(),
0,
0,
0);
} catch (SendIntentException e) {
Log.e(e);
}
@ -267,11 +302,13 @@ public class InAppPurchaseHelper {
}
public void purchaseItemAsync(final String productId, final String sipIdentity) {
new Thread(new Runnable() {
public void run() {
purchaseItem(productId, sipIdentity);
}
}).start();
new Thread(
new Runnable() {
public void run() {
purchaseItem(productId, sipIdentity);
}
})
.start();
}
public void destroy() {
@ -298,18 +335,18 @@ public class InAppPurchaseHelper {
private Purchasable verifySignature(String payload, String signature) {
// TODO FIXME rework to be async
/*XmlRpcHelper helper = new XmlRpcHelper();
if (helper.verifySignature(payload, signature)) {
try {
JSONObject json = new JSONObject(payload);
String productId = json.getString(PURCHASE_DETAILS_PRODUCT_ID);
Purchasable item = new Purchasable(productId);
item.setPayloadAndSignature(payload, signature);
return item;
} catch (JSONException e) {
Log.e(e);
}
}*/
/*XmlRpcHelper helper = new XmlRpcHelper();
if (helper.verifySignature(payload, signature)) {
try {
JSONObject json = new JSONObject(payload);
String productId = json.getString(PURCHASE_DETAILS_PRODUCT_ID);
Purchasable item = new Purchasable(productId);
item.setPayloadAndSignature(payload, signature);
return item;
} catch (JSONException e) {
Log.e(e);
}
}*/
return null;
}

View file

@ -28,10 +28,8 @@ import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import org.linphone.R;
import java.util.List;
import org.linphone.R;
public class InAppPurchaseListFragment extends Fragment implements AdapterView.OnItemClickListener {
private ListView inappList;
@ -39,8 +37,8 @@ public class InAppPurchaseListFragment extends Fragment implements AdapterView.O
private List<Purchasable> mPurchasableItems;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mInflater = inflater;
View view = inflater.inflate(R.layout.in_app_list, container, false);
@ -54,9 +52,14 @@ public class InAppPurchaseListFragment extends Fragment implements AdapterView.O
return view;
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Purchasable item = (Purchasable) view.getTag();
InAppPurchaseActivity.instance().displayPurchase(item);
}
class InAppListAdapter extends BaseAdapter {
InAppListAdapter() {
}
InAppListAdapter() {}
public int getCount() {
return mPurchasableItems.size();
@ -92,11 +95,4 @@ public class InAppPurchaseListFragment extends Fragment implements AdapterView.O
return view;
}
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Purchasable item = (Purchasable) view.getTag();
InAppPurchaseActivity.instance().displayPurchase(item);
}
}

View file

@ -21,9 +21,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
import java.util.ArrayList;
public interface InAppPurchaseListener {
/**
* Callback called when the in-app purchase listener is connected and available for queries
*/
/** Callback called when the in-app purchase listener is connected and available for queries */
void onServiceAvailableForQueries();
/**

View file

@ -69,17 +69,17 @@ public class Purchasable {
return expire;
}
public Purchasable setExpire(long expire) {
this.expire = expire;
return this;
}
public String getExpireDate() {
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss", Locale.getDefault());
Date date = new Date(expire);
return dateFormat.format(date);
}
public Purchasable setExpire(long expire) {
this.expire = expire;
return this;
}
public Purchasable setPayloadAndSignature(String payload, String signature) {
this.purchasePayload = payload;
this.purchasePayloadSignature = signature;
@ -94,12 +94,12 @@ public class Purchasable {
return this.purchasePayloadSignature;
}
public String getUserData() {
return this.userData;
}
public Purchasable setUserData(String data) {
this.userData = data;
return this;
}
public String getUserData() {
return this.userData;
}
}

View file

@ -23,7 +23,6 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import org.linphone.settings.LinphonePreferences;
public class AccountEnableReceiver extends BroadcastReceiver {
@ -35,10 +34,14 @@ public class AccountEnableReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
int prefsAccountIndex = (int) (long) intent.getLongExtra(FIELD_ID, -1);
boolean enable = intent.getBooleanExtra(FIELD_ACTIVE, true);
Log.i(TAG, "Received broadcast for index=" + Integer.toString(prefsAccountIndex) + ",enable=" + Boolean.toString(enable));
if (prefsAccountIndex < 0 || prefsAccountIndex >= LinphonePreferences.instance().getAccountCount())
return;
Log.i(
TAG,
"Received broadcast for index="
+ Integer.toString(prefsAccountIndex)
+ ",enable="
+ Boolean.toString(enable));
if (prefsAccountIndex < 0
|| prefsAccountIndex >= LinphonePreferences.instance().getAccountCount()) return;
LinphonePreferences.instance().setAccountEnabled(prefsAccountIndex, enable);
}
}

View file

@ -28,13 +28,11 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
import java.util.List;
import org.linphone.LinphoneManager;
import org.linphone.LinphoneService;
import org.linphone.call.CallActivity;
import java.util.List;
public class BluetoothManager extends BroadcastReceiver {
private static BluetoothManager instance;
@ -47,6 +45,16 @@ public class BluetoothManager extends BroadcastReceiver {
private boolean isBluetoothConnected;
private boolean isScoConnected;
public BluetoothManager() {
isBluetoothConnected = false;
if (!ensureInit()) {
android.util.Log.w(
"BluetoothManager",
"[Bluetooth] Manager tried to init but LinphoneService not ready yet...");
}
instance = this;
}
public static BluetoothManager getInstance() {
if (instance == null) {
instance = new BluetoothManager();
@ -54,22 +62,19 @@ public class BluetoothManager extends BroadcastReceiver {
return instance;
}
public BluetoothManager() {
isBluetoothConnected = false;
if (!ensureInit()) {
android.util.Log.w("BluetoothManager", "[Bluetooth] Manager tried to init but LinphoneService not ready yet...");
}
instance = this;
}
public void initBluetooth() {
if (!ensureInit()) {
android.util.Log.w("BluetoothManager", "[Bluetooth] Manager tried to init bluetooth but LinphoneService not ready yet...");
android.util.Log.w(
"BluetoothManager",
"[Bluetooth] Manager tried to init bluetooth but LinphoneService not ready yet...");
return;
}
IntentFilter filter = new IntentFilter();
filter.addCategory(BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID_CATEGORY + "." + BluetoothAssignedNumbers.PLANTRONICS);
filter.addCategory(
BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID_CATEGORY
+ "."
+ BluetoothAssignedNumbers.PLANTRONICS);
filter.addAction(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED);
filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
filter.addAction(BluetoothHeadset.ACTION_VENDOR_SPECIFIC_HEADSET_EVENT);
@ -89,29 +94,36 @@ public class BluetoothManager extends BroadcastReceiver {
if (mBluetoothAdapter != null && mBluetoothAdapter.isEnabled()) {
if (mProfileListener != null) {
android.util.Log.w("BluetoothManager", "[Bluetooth] Headset profile was already opened, let's close it");
android.util.Log.w(
"BluetoothManager",
"[Bluetooth] Headset profile was already opened, let's close it");
mBluetoothAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mBluetoothHeadset);
}
mProfileListener = new BluetoothProfile.ServiceListener() {
public void onServiceConnected(int profile, BluetoothProfile proxy) {
if (profile == BluetoothProfile.HEADSET) {
android.util.Log.d("BluetoothManager", "[Bluetooth] Headset connected");
mBluetoothHeadset = (BluetoothHeadset) proxy;
isBluetoothConnected = true;
}
}
mProfileListener =
new BluetoothProfile.ServiceListener() {
public void onServiceConnected(int profile, BluetoothProfile proxy) {
if (profile == BluetoothProfile.HEADSET) {
android.util.Log.d(
"BluetoothManager", "[Bluetooth] Headset connected");
mBluetoothHeadset = (BluetoothHeadset) proxy;
isBluetoothConnected = true;
}
}
public void onServiceDisconnected(int profile) {
if (profile == BluetoothProfile.HEADSET) {
mBluetoothHeadset = null;
isBluetoothConnected = false;
android.util.Log.d("BluetoothManager", "[Bluetooth] Headset disconnected");
LinphoneManager.getInstance().routeAudioToReceiver();
}
}
};
boolean success = mBluetoothAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.HEADSET);
public void onServiceDisconnected(int profile) {
if (profile == BluetoothProfile.HEADSET) {
mBluetoothHeadset = null;
isBluetoothConnected = false;
android.util.Log.d(
"BluetoothManager", "[Bluetooth] Headset disconnected");
LinphoneManager.getInstance().routeAudioToReceiver();
}
}
};
boolean success =
mBluetoothAdapter.getProfileProxy(
mContext, mProfileListener, BluetoothProfile.HEADSET);
if (!success) {
android.util.Log.e("BluetoothManager", "[Bluetooth] getProfileProxy failed !");
}
@ -146,7 +158,10 @@ public class BluetoothManager extends BroadcastReceiver {
public boolean routeAudioToBluetooth() {
ensureInit();
if (mBluetoothAdapter != null && mBluetoothAdapter.isEnabled() && mAudioManager != null && mAudioManager.isBluetoothScoAvailableOffCall()) {
if (mBluetoothAdapter != null
&& mBluetoothAdapter.isEnabled()
&& mAudioManager != null
&& mAudioManager.isBluetoothScoAvailableOffCall()) {
if (isBluetoothHeadsetAvailable()) {
if (mAudioManager != null && !mAudioManager.isBluetoothScoOn()) {
android.util.Log.d("BluetoothManager", "[Bluetooth] SCO off, let's start it");
@ -177,7 +192,9 @@ public class BluetoothManager extends BroadcastReceiver {
}
if (ok) {
if (retries > 0) {
android.util.Log.d("BluetoothManager", "[Bluetooth] Audio route ok after " + retries + " retries");
android.util.Log.d(
"BluetoothManager",
"[Bluetooth] Audio route ok after " + retries + " retries");
} else {
android.util.Log.d("BluetoothManager", "[Bluetooth] Audio route ok");
}
@ -192,24 +209,34 @@ public class BluetoothManager extends BroadcastReceiver {
}
public boolean isUsingBluetoothAudioRoute() {
return mBluetoothHeadset != null && mBluetoothHeadset.isAudioConnected(mBluetoothDevice) && isScoConnected;
return mBluetoothHeadset != null
&& mBluetoothHeadset.isAudioConnected(mBluetoothDevice)
&& isScoConnected;
}
public boolean isBluetoothHeadsetAvailable() {
ensureInit();
if (mBluetoothAdapter != null && mBluetoothAdapter.isEnabled() && mAudioManager != null && mAudioManager.isBluetoothScoAvailableOffCall()) {
if (mBluetoothAdapter != null
&& mBluetoothAdapter.isEnabled()
&& mAudioManager != null
&& mAudioManager.isBluetoothScoAvailableOffCall()) {
boolean isHeadsetConnected = false;
if (mBluetoothHeadset != null) {
List<BluetoothDevice> devices = mBluetoothHeadset.getConnectedDevices();
mBluetoothDevice = null;
for (final BluetoothDevice dev : devices) {
if (mBluetoothHeadset.getConnectionState(dev) == BluetoothHeadset.STATE_CONNECTED) {
if (mBluetoothHeadset.getConnectionState(dev)
== BluetoothHeadset.STATE_CONNECTED) {
mBluetoothDevice = dev;
isHeadsetConnected = true;
break;
}
}
android.util.Log.d("BluetoothManager", isHeadsetConnected ? "[Bluetooth] Headset found, bluetooth audio route available" : "[Bluetooth] No headset found, bluetooth audio route unavailable");
android.util.Log.d(
"BluetoothManager",
isHeadsetConnected
? "[Bluetooth] Headset found, bluetooth audio route available"
: "[Bluetooth] No headset found, bluetooth audio route unavailable");
}
return isHeadsetConnected;
}
@ -275,30 +302,32 @@ public class BluetoothManager extends BroadcastReceiver {
}
public void onReceive(Context context, Intent intent) {
if (!LinphoneManager.isInstanciated())
return;
if (!LinphoneManager.isInstanciated()) return;
String action = intent.getAction();
if (AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED.equals(action)) {
int state = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, 0);
if (state == AudioManager.SCO_AUDIO_STATE_CONNECTED) {
android.util.Log.d("BluetoothManager", "[Bluetooth] SCO state: connected");
// LinphoneManager.getInstance().audioStateChanged(AudioState.BLUETOOTH);
// LinphoneManager.getInstance().audioStateChanged(AudioState.BLUETOOTH);
isScoConnected = true;
} else if (state == AudioManager.SCO_AUDIO_STATE_DISCONNECTED) {
android.util.Log.d("BluetoothManager", "[Bluetooth] SCO state: disconnected");
// LinphoneManager.getInstance().audioStateChanged(AudioState.SPEAKER);
// LinphoneManager.getInstance().audioStateChanged(AudioState.SPEAKER);
isScoConnected = false;
} else if (state == AudioManager.SCO_AUDIO_STATE_CONNECTING) {
android.util.Log.d("BluetoothManager", "[Bluetooth] SCO state: connecting");
// LinphoneManager.getInstance().audioStateChanged(AudioState.BLUETOOTH);
// LinphoneManager.getInstance().audioStateChanged(AudioState.BLUETOOTH);
isScoConnected = true;
} else {
android.util.Log.d("BluetoothManager", "[Bluetooth] SCO state: " + state);
}
refreshCallView();
} else if (BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
int state = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE, BluetoothAdapter.STATE_DISCONNECTED);
int state =
intent.getIntExtra(
BluetoothAdapter.EXTRA_CONNECTION_STATE,
BluetoothAdapter.STATE_DISCONNECTED);
if (state == 0) {
android.util.Log.d("BluetoothManager", "[Bluetooth] State: disconnected");
stopBluetooth();
@ -308,22 +337,41 @@ public class BluetoothManager extends BroadcastReceiver {
} else {
android.util.Log.d("BluetoothManager", "[Bluetooth] State: " + state);
}
} else if (intent.getAction().equals(BluetoothHeadset.ACTION_VENDOR_SPECIFIC_HEADSET_EVENT)) {
String command = intent.getExtras().getString(BluetoothHeadset.EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD);
//int type = intent.getExtras().getInt(BluetoothHeadset.EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE);
} else if (intent.getAction()
.equals(BluetoothHeadset.ACTION_VENDOR_SPECIFIC_HEADSET_EVENT)) {
String command =
intent.getExtras()
.getString(BluetoothHeadset.EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD);
// int type =
// intent.getExtras().getInt(BluetoothHeadset.EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE);
Object[] args = (Object[]) intent.getExtras().get(BluetoothHeadset.EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS);
Object[] args =
(Object[])
intent.getExtras()
.get(BluetoothHeadset.EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS);
if (args.length <= 0) {
android.util.Log.d("BluetoothManager", "[Bluetooth] Event: " + command + ", no args");
android.util.Log.d(
"BluetoothManager", "[Bluetooth] Event: " + command + ", no args");
return;
}
String eventName = (args[0]).toString();
if (eventName.equals("BUTTON") && args.length >= 3) {
String buttonID = args[1].toString();
String mode = args[2].toString();
android.util.Log.d("BluetoothManager", "[Bluetooth] Event: " + command + " : " + eventName + ", id = " + buttonID + " (" + mode + ")");
android.util.Log.d(
"BluetoothManager",
"[Bluetooth] Event: "
+ command
+ " : "
+ eventName
+ ", id = "
+ buttonID
+ " ("
+ mode
+ ")");
} else {
android.util.Log.d("BluetoothManager", "[Bluetooth] Event: " + command + " : " + eventName);
android.util.Log.d(
"BluetoothManager", "[Bluetooth] Event: " + command + " : " + eventName);
}
}
}

View file

@ -22,11 +22,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import org.linphone.LinphoneManager;
import org.linphone.settings.LinphonePreferences;
import org.linphone.LinphoneService;
import org.linphone.compatibility.Compatibility;
import org.linphone.settings.LinphonePreferences;
public class BootReceiver extends BroadcastReceiver {
@ -34,11 +33,14 @@ public class BootReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
LinphonePreferences.instance().setContext(context);
if (intent.getAction().equalsIgnoreCase(Intent.ACTION_SHUTDOWN)) {
android.util.Log.d("LinphoneBootReceiver", "Device is shutting down, destroying Core to unregister");
android.util.Log.d(
"LinphoneBootReceiver",
"Device is shutting down, destroying Core to unregister");
LinphoneManager.destroy();
} else {
boolean autostart = LinphonePreferences.instance().isAutoStartEnabled();
android.util.Log.i("LinphoneBootReceiver", "Device is starting, auto_start is " + autostart);
android.util.Log.i(
"LinphoneBootReceiver", "Device is starting, auto_start is " + autostart);
if (autostart && !LinphoneService.isReady()) {
Intent lLinphoneServiceIntent = new Intent(Intent.ACTION_MAIN);
lLinphoneServiceIntent.setClass(context, LinphoneService.class);

View file

@ -23,14 +23,13 @@ import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.PowerManager;
import org.linphone.LinphoneManager;
import org.linphone.settings.LinphonePreferences;
import org.linphone.LinphoneService;
import org.linphone.utils.LinphoneUtils;
import org.linphone.R;
import org.linphone.core.Core;
import org.linphone.mediastream.Log;
import org.linphone.settings.LinphonePreferences;
import org.linphone.utils.LinphoneUtils;
/*
* Purpose of this receiver is to disable keep alives when device is on idle

View file

@ -23,27 +23,24 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import org.linphone.LinphoneManager;
import org.linphone.mediastream.Log;
public class HookReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (isOrderedBroadcast())
abortBroadcast();
if (isOrderedBroadcast()) abortBroadcast();
Bundle extras = intent.getExtras();
boolean b = extras.getBoolean("hookoff");
if (b) {
//handset on
// handset on
Log.i(" ======>>>>>> HookReceiver - handset ON");
LinphoneManager.getInstance().enableSpeaker(false);
if (!LinphoneManager.getInstance().isHansetModeOn())
LinphoneManager.getInstance().setHandsetMode(true);
} else {
//handset off
// handset off
Log.i(" ======>>>>>> HookReceiver - handset OFF");
LinphoneManager.getInstance().enableSpeaker(true);
LinphoneManager.getInstance().setHandsetMode(false);

View file

@ -25,14 +25,13 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.SystemClock;
import org.linphone.LinphoneManager;
import org.linphone.settings.LinphonePreferences;
import org.linphone.LinphoneService;
import org.linphone.utils.LinphoneUtils;
import org.linphone.R;
import org.linphone.core.Core;
import org.linphone.mediastream.Log;
import org.linphone.settings.LinphonePreferences;
import org.linphone.utils.LinphoneUtils;
/*
* Purpose of this receiver is to disable keep alives when screen is off
@ -52,18 +51,25 @@ public class KeepAliveReceiver extends BroadcastReceiver {
if (action == null) {
Log.i("[KeepAlive] Refresh registers");
lc.refreshRegisters();
//make sure iterate will have enough time, device will not sleep until exit from this method
// make sure iterate will have enough time, device will not sleep until exit from
// this method
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
Log.e("Cannot sleep for 2s", e);
} finally {
//make sure the application will at least wakes up every 10 mn
// make sure the application will at least wakes up every 10 mn
Intent newIntent = new Intent(context, KeepAliveReceiver.class);
PendingIntent keepAlivePendingIntent = PendingIntent.getBroadcast(context, 0, newIntent, PendingIntent.FLAG_ONE_SHOT);
PendingIntent keepAlivePendingIntent =
PendingIntent.getBroadcast(
context, 0, newIntent, PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager = ((AlarmManager) context.getSystemService(Context.ALARM_SERVICE));
alarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 600000, keepAlivePendingIntent);
AlarmManager alarmManager =
((AlarmManager) context.getSystemService(Context.ALARM_SERVICE));
alarmManager.setExact(
AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + 600000,
keepAlivePendingIntent);
}
} else if (action.equalsIgnoreCase(Intent.ACTION_SCREEN_ON)) {
Log.i("[KeepAlive] Screen is on, enable");

View file

@ -23,21 +23,19 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import org.linphone.LinphoneManager;
/**
* Intercept network state changes and update linphone core through LinphoneManager.
*/
/** Intercept network state changes and update linphone core through LinphoneManager. */
public class NetworkManager extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
Boolean lNoConnectivity = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
ConnectivityManager cm =
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
Boolean lNoConnectivity =
intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
if (LinphoneManager.isInstanciated()) {
LinphoneManager.getInstance().connectivityChanged(cm, lNoConnectivity);
}
}
}

View file

@ -19,18 +19,16 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import org.linphone.settings.LinphonePreferences;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
public class OutgoingCallReceiver extends BroadcastReceiver {
private final static String TAG = "CallHandler";
private static final String TAG = "CallHandler";
private final String ACTION_CALL_LINPHONE = "org.linphone.intent.action.CallLaunched";
private LinphonePreferences mPrefs;
@ -53,4 +51,4 @@ public class OutgoingCallReceiver extends BroadcastReceiver {
}
}
}
}
}

View file

@ -23,22 +23,19 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.TelephonyManager;
import org.linphone.LinphoneManager;
import org.linphone.core.Core;
/**
* Pause current SIP calls when GSM phone rings or is active.
*/
/** Pause current SIP calls when GSM phone rings or is active. */
public class PhoneStateChangedReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
final String extraState = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
if (!LinphoneManager.isInstanciated())
return;
if (!LinphoneManager.isInstanciated()) return;
if (TelephonyManager.EXTRA_STATE_OFFHOOK.equals(extraState) || TelephonyManager.EXTRA_STATE_RINGING.equals(extraState)) {
if (TelephonyManager.EXTRA_STATE_OFFHOOK.equals(extraState)
|| TelephonyManager.EXTRA_STATE_RINGING.equals(extraState)) {
LinphoneManager.getInstance().setCallGsmON(true);
Core lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
lc.pauseAllCalls();

View file

@ -22,20 +22,20 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Handler;
import android.support.annotation.NonNull;
import org.linphone.LinphoneManager;
import org.linphone.core.Player;
import org.linphone.core.PlayerListener;
import org.linphone.mediastream.Log;
import androidx.annotation.NonNull;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.linphone.LinphoneManager;
import org.linphone.core.Player;
import org.linphone.core.PlayerListener;
import org.linphone.mediastream.Log;
public class Recording implements PlayerListener, Comparable<Recording> {
public static final Pattern RECORD_PATTERN =
Pattern.compile(".*/(.*)_(\\d{2}-\\d{2}-\\d{4}-\\d{2}-\\d{2}-\\d{2})\\..*");
private String recordPath, name;
private Date recordDate;
private Player player;
@ -43,8 +43,6 @@ public class Recording implements PlayerListener, Comparable<Recording> {
private Handler handler;
private Runnable updateCurrentPositionTimer;
public static final Pattern RECORD_PATTERN = Pattern.compile(".*/(.*)_(\\d{2}-\\d{2}-\\d{4}-\\d{2}-\\d{2}-\\d{2})\\..*");
@SuppressLint("SimpleDateFormat")
public Recording(Context context, String recordPath) {
this.recordPath = recordPath;
@ -61,13 +59,14 @@ public class Recording implements PlayerListener, Comparable<Recording> {
}
handler = new Handler(context.getMainLooper());
updateCurrentPositionTimer = new Runnable() {
@Override
public void run() {
if (listener != null) listener.currentPositionChanged(getCurrentPosition());
if (isPlaying()) handler.postDelayed(updateCurrentPositionTimer, 20);
}
};
updateCurrentPositionTimer =
new Runnable() {
@Override
public void run() {
if (listener != null) listener.currentPositionChanged(getCurrentPosition());
if (isPlaying()) handler.postDelayed(updateCurrentPositionTimer, 20);
}
};
player = LinphoneManager.getLc().createLocalPlayer(null, null, null);
player.setListener(this);

View file

@ -21,28 +21,30 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
import android.annotation.SuppressLint;
import android.content.Context;
import android.support.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.SeekBar;
import org.linphone.R;
import org.linphone.utils.SelectableAdapter;
import org.linphone.utils.SelectableHelper;
import androidx.annotation.NonNull;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.linphone.R;
import org.linphone.utils.SelectableAdapter;
import org.linphone.utils.SelectableHelper;
public class RecordingAdapter extends SelectableAdapter<RecordingViewHolder> {
private List<Recording> recordings;
private Context context;
private RecordingViewHolder.ClickListener clickListener;
public RecordingAdapter(Context context, List<Recording> recordings, RecordingViewHolder.ClickListener listener, SelectableHelper helper) {
public RecordingAdapter(
Context context,
List<Recording> recordings,
RecordingViewHolder.ClickListener listener,
SelectableHelper helper) {
super(helper);
this.recordings = recordings;
@ -58,7 +60,9 @@ public class RecordingAdapter extends SelectableAdapter<RecordingViewHolder> {
@NonNull
@Override
public RecordingViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.recording_cell, viewGroup, false);
View v =
LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.recording_cell, viewGroup, false);
return new RecordingViewHolder(v, clickListener);
}
@ -95,87 +99,101 @@ public class RecordingAdapter extends SelectableAdapter<RecordingViewHolder> {
} else {
viewHolder.playButton.setImageResource(R.drawable.record_play);
}
viewHolder.playButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (record.isPaused()) {
record.play();
viewHolder.playButton.setImageResource(R.drawable.record_pause);
} else {
record.pause();
viewHolder.playButton.setImageResource(R.drawable.record_play);
}
}
});
viewHolder.playButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
if (record.isPaused()) {
record.play();
viewHolder.playButton.setImageResource(R.drawable.record_pause);
} else {
record.pause();
viewHolder.playButton.setImageResource(R.drawable.record_play);
}
}
});
viewHolder.name.setText(record.getName());
viewHolder.date.setText(new SimpleDateFormat("HH:mm").format(record.getRecordDate()));
int position = record.getCurrentPosition();
viewHolder.currentPosition.setText(String.format("%02d:%02d",
TimeUnit.MILLISECONDS.toMinutes(position),
TimeUnit.MILLISECONDS.toSeconds(position) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(position))
));
viewHolder.currentPosition.setText(
String.format(
"%02d:%02d",
TimeUnit.MILLISECONDS.toMinutes(position),
TimeUnit.MILLISECONDS.toSeconds(position)
- TimeUnit.MINUTES.toSeconds(
TimeUnit.MILLISECONDS.toMinutes(position))));
int duration = record.getDuration();
viewHolder.duration.setText(String.format("%02d:%02d",
TimeUnit.MILLISECONDS.toMinutes(duration),
TimeUnit.MILLISECONDS.toSeconds(duration) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(duration))
));
viewHolder.duration.setText(
String.format(
"%02d:%02d",
TimeUnit.MILLISECONDS.toMinutes(duration),
TimeUnit.MILLISECONDS.toSeconds(duration)
- TimeUnit.MINUTES.toSeconds(
TimeUnit.MILLISECONDS.toMinutes(duration))));
viewHolder.progressionBar.setMax(record.getDuration());
viewHolder.progressionBar.setProgress(0);
viewHolder.progressionBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser) {
int progressToSet = progress > 0 && progress < seekBar.getMax() ? progress : 0;
viewHolder.progressionBar.setOnSeekBarChangeListener(
new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser) {
int progressToSet =
progress > 0 && progress < seekBar.getMax() ? progress : 0;
if (progress == seekBar.getMax()) {
if (record.isPlaying()) record.pause();
if (progress == seekBar.getMax()) {
if (record.isPlaying()) record.pause();
}
record.seek(progressToSet);
seekBar.setProgress(progressToSet);
int currentPosition = record.getCurrentPosition();
viewHolder.currentPosition.setText(
String.format(
"%02d:%02d",
TimeUnit.MILLISECONDS.toMinutes(currentPosition),
TimeUnit.MILLISECONDS.toSeconds(currentPosition)
- TimeUnit.MINUTES.toSeconds(
TimeUnit.MILLISECONDS.toMinutes(
currentPosition))));
}
}
record.seek(progressToSet);
seekBar.setProgress(progressToSet);
@Override
public void onStartTrackingTouch(SeekBar seekBar) {}
int currentPosition = record.getCurrentPosition();
viewHolder.currentPosition.setText(String.format("%02d:%02d",
TimeUnit.MILLISECONDS.toMinutes(currentPosition),
TimeUnit.MILLISECONDS.toSeconds(currentPosition) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(currentPosition))
));
}
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {}
});
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
record.setRecordingListener(
new RecordingListener() {
@Override
public void currentPositionChanged(int currentPosition) {
viewHolder.currentPosition.setText(
String.format(
"%02d:%02d",
TimeUnit.MILLISECONDS.toMinutes(currentPosition),
TimeUnit.MILLISECONDS.toSeconds(currentPosition)
- TimeUnit.MINUTES.toSeconds(
TimeUnit.MILLISECONDS.toMinutes(
currentPosition))));
viewHolder.progressionBar.setProgress(currentPosition);
}
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
record.setRecordingListener(new RecordingListener() {
@Override
public void currentPositionChanged(int currentPosition) {
viewHolder.currentPosition.setText(String.format("%02d:%02d",
TimeUnit.MILLISECONDS.toMinutes(currentPosition),
TimeUnit.MILLISECONDS.toSeconds(currentPosition) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(currentPosition))
));
viewHolder.progressionBar.setProgress(currentPosition);
}
@Override
public void endOfRecordReached() {
record.pause();
record.seek(0);
viewHolder.progressionBar.setProgress(0);
viewHolder.currentPosition.setText("00:00");
viewHolder.playButton.setImageResource(R.drawable.record_play);
}
});
@Override
public void endOfRecordReached() {
record.pause();
record.seek(0);
viewHolder.progressionBar.setProgress(0);
viewHolder.currentPosition.setText("00:00");
viewHolder.playButton.setImageResource(R.drawable.record_play);
}
});
}
@Override
@ -191,7 +209,9 @@ public class RecordingAdapter extends SelectableAdapter<RecordingViewHolder> {
} else if (isYesterday(cal)) {
return context.getString(R.string.yesterday);
} else {
dateFormat = new SimpleDateFormat(context.getResources().getString(R.string.history_date_format));
dateFormat =
new SimpleDateFormat(
context.getResources().getString(R.string.history_date_format));
}
return dateFormat.format(cal.getTime());
@ -202,9 +222,9 @@ public class RecordingAdapter extends SelectableAdapter<RecordingViewHolder> {
return false;
}
return (cal1.get(Calendar.ERA) == cal2.get(Calendar.ERA) &&
cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) &&
cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR));
return (cal1.get(Calendar.ERA) == cal2.get(Calendar.ERA)
&& cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR)
&& cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR));
}
private boolean isToday(Calendar cal) {

View file

@ -22,15 +22,18 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
import android.app.Fragment;
import android.content.Context;
import android.os.Bundle;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.TextView;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.linphone.LinphoneActivity;
import org.linphone.LinphoneManager;
import org.linphone.R;
@ -38,12 +41,10 @@ import org.linphone.fragments.FragmentsAvailable;
import org.linphone.utils.FileUtils;
import org.linphone.utils.SelectableHelper;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class RecordingListFragment extends Fragment implements AdapterView.OnItemClickListener, RecordingViewHolder.ClickListener, SelectableHelper.DeleteListener {
public class RecordingListFragment extends Fragment
implements AdapterView.OnItemClickListener,
RecordingViewHolder.ClickListener,
SelectableHelper.DeleteListener {
private RecyclerView recordingList;
private List<Recording> recordings;
private TextView noRecordings;
@ -53,8 +54,8 @@ public class RecordingListFragment extends Fragment implements AdapterView.OnIte
private SelectableHelper selectableHelper;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.recordings_list, container, false);
context = getActivity().getApplicationContext();
@ -66,9 +67,10 @@ public class RecordingListFragment extends Fragment implements AdapterView.OnIte
layoutManager = new LinearLayoutManager(context);
recordingList.setLayoutManager(layoutManager);
//Divider between items
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recordingList.getContext(),
layoutManager.getOrientation());
// Divider between items
DividerItemDecoration dividerItemDecoration =
new DividerItemDecoration(
recordingList.getContext(), layoutManager.getOrientation());
dividerItemDecoration.setDrawable(context.getResources().getDrawable(R.drawable.divider));
recordingList.addItemDecoration(dividerItemDecoration);
@ -94,9 +96,9 @@ public class RecordingListFragment extends Fragment implements AdapterView.OnIte
if (directory.exists() && directory.isDirectory()) {
File[] existingRecordings = directory.listFiles();
for(Recording r : recordings) {
for (Recording r : recordings) {
boolean exists = false;
for(File f : existingRecordings) {
for (File f : existingRecordings) {
if (f.getPath().equals(r.getRecordPath())) {
exists = true;
break;
@ -117,9 +119,9 @@ public class RecordingListFragment extends Fragment implements AdapterView.OnIte
if (directory.exists() && directory.isDirectory()) {
File[] existingRecordings = directory.listFiles();
for(File f : existingRecordings) {
for (File f : existingRecordings) {
boolean exists = false;
for(Recording r : recordings) {
for (Recording r : recordings) {
if (r.getRecordPath().equals(f.getPath())) {
exists = true;
break;
@ -141,7 +143,8 @@ public class RecordingListFragment extends Fragment implements AdapterView.OnIte
public void onResume() {
super.onResume();
// This is necessary, without it you won't be able to remove recordings as you won't be allowed to.
// This is necessary, without it you won't be able to remove recordings as you won't be
// allowed to.
LinphoneActivity.instance().checkAndRequestExternalStoragePermission();
LinphoneManager.getInstance().setAudioManagerModeNormal();
@ -155,7 +158,9 @@ public class RecordingListFragment extends Fragment implements AdapterView.OnIte
searchForRecordings();
hideRecordingListAndDisplayMessageIfEmpty();
recordingAdapter = new RecordingAdapter(getActivity().getApplicationContext(), recordings, this, selectableHelper);
recordingAdapter =
new RecordingAdapter(
getActivity().getApplicationContext(), recordings, this, selectableHelper);
recordingList.setAdapter(recordingAdapter);
selectableHelper.setAdapter(recordingAdapter);
selectableHelper.setDialogMessage(R.string.recordings_delete_dialog);

View file

@ -1,36 +1,35 @@
package org.linphone.recording;
/*
RecordingViewHolder.java
Copyright (C) 2018 Belledonne Communications, Grenoble, France
RecordingViewHolder.java
Copyright (C) 2018 Belledonne Communications, Grenoble, France
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import org.linphone.R;
public class RecordingViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
public class RecordingViewHolder extends RecyclerView.ViewHolder
implements View.OnClickListener, View.OnLongClickListener {
public ImageView playButton;
public TextView name, date, currentPosition, duration;
public SeekBar progressionBar;

View file

@ -30,12 +30,11 @@ import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceCategory;
import android.preference.PreferenceScreen;
import android.view.WindowManager;
import org.linphone.LinphoneManager;
import org.linphone.settings.LinphonePreferences.AccountBuilder;
import org.linphone.utils.LinphoneUtils;
import org.linphone.R;
import java.util.ArrayList;
import java.util.List;
import org.linphone.LinphoneActivity;
import org.linphone.LinphoneManager;
import org.linphone.R;
import org.linphone.assistant.AssistantActivity;
import org.linphone.core.AccountCreator;
import org.linphone.core.AccountCreatorListener;
@ -44,17 +43,276 @@ import org.linphone.core.NatPolicy;
import org.linphone.core.ProxyConfig;
import org.linphone.fragments.FragmentsAvailable;
import org.linphone.mediastream.Log;
import org.linphone.settings.LinphonePreferences.AccountBuilder;
import org.linphone.utils.LinphoneUtils;
import java.util.ArrayList;
import java.util.List;
public class AccountPreferencesFragment extends PreferencesListFragment implements AccountCreatorListener {
public class AccountPreferencesFragment extends PreferencesListFragment
implements AccountCreatorListener {
private int n;
OnPreferenceClickListener linkAccountListener =
new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
Intent assistant = new Intent();
assistant.setClass(LinphoneActivity.instance(), AssistantActivity.class);
assistant.putExtra("LinkPhoneNumber", true);
assistant.putExtra("FromPref", true);
assistant.putExtra("AccountNumber", n);
startActivity(assistant);
return true;
}
};
private boolean isNewAccount = false;
private LinphonePreferences mPrefs;
OnPreferenceChangeListener avpfRRIntervalChangedListener =
new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
String value = newValue.toString();
try {
int intValue = Integer.parseInt(value);
if ((intValue < 1) || (intValue > 5)) {
return false;
}
} catch (NumberFormatException nfe) {
}
if (isNewAccount) {
// TODO
} else {
mPrefs.setAvpfRrInterval(n, value);
}
preference.setSummary(value);
return true;
}
};
OnPreferenceChangeListener escapeChangedListener =
new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
boolean value = (Boolean) newValue;
if (isNewAccount) {
// TODO
} else {
mPrefs.setReplacePlusByZeroZero(n, value);
}
return true;
}
};
OnPreferenceChangeListener pushNotificationListener =
new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
boolean value = (Boolean) newValue;
if (isNewAccount) {
// TODO
} else {
mPrefs.enablePushNotifForProxy(n, value);
}
return true;
}
};
OnPreferenceChangeListener iceChangedListener =
new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
boolean value = (Boolean) newValue;
if (isNewAccount) {
} else {
mPrefs.setAccountIce(n, value);
((CheckBoxPreference) preference).setChecked(mPrefs.getAccountIce(n));
}
return true;
}
};
OnPreferenceChangeListener stunTurnChangedListener =
new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
String value = newValue.toString();
if (isNewAccount) {
} else {
mPrefs.setAccountStunServer(n, value);
preference.setSummary(value);
}
return true;
}
};
private EditTextPreference mProxyPreference;
OnPreferenceChangeListener transportChangedListener =
new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
String key = newValue.toString();
if (isNewAccount) {
// TODO
// builder.setTransport(transport);
} else {
mPrefs.setAccountTransport(n, key);
preference.setSummary(mPrefs.getAccountTransportString(n));
preference.setDefaultValue(mPrefs.getAccountTransportKey(n));
if (mProxyPreference != null) {
String newProxy = mPrefs.getAccountProxy(n);
mProxyPreference.setSummary(newProxy);
mProxyPreference.setText(newProxy);
}
}
return true;
}
};
private ListPreference mTransportPreference;
private AccountBuilder builder;
OnPreferenceChangeListener usernameChangedListener =
new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (isEditTextEmpty(newValue.toString())) return false;
if (isNewAccount) {
builder.setUsername(newValue.toString());
} else {
mPrefs.setAccountUsername(n, newValue.toString());
}
preference.setSummary(newValue.toString());
return true;
}
};
OnPreferenceChangeListener useridChangedListener =
new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (isNewAccount) {
builder.setUserid(newValue.toString());
} else {
mPrefs.setAccountUserId(n, newValue.toString());
}
preference.setSummary(newValue.toString());
return true;
}
};
OnPreferenceChangeListener passwordChangedListener =
new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (isEditTextEmpty(newValue.toString())) return false;
if (isNewAccount) {
builder.setPassword(newValue.toString());
} else {
mPrefs.setAccountPassword(n, newValue.toString());
}
return true;
}
};
OnPreferenceChangeListener domainChangedListener =
new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (isEditTextEmpty(newValue.toString())) return false;
if (isNewAccount) {
builder.setDomain(newValue.toString());
} else {
mPrefs.setAccountDomain(n, newValue.toString());
}
preference.setSummary(newValue.toString());
return true;
}
};
OnPreferenceChangeListener displayNameChangedListener =
new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (isNewAccount) {
builder.setDisplayName(newValue.toString());
} else {
mPrefs.setAccountDisplayName(n, newValue.toString());
}
preference.setSummary(newValue.toString());
return true;
}
};
OnPreferenceChangeListener proxyChangedListener =
new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
String value = newValue.toString();
if (isNewAccount) {
builder.setServerAddr(newValue.toString());
preference.setSummary(newValue.toString());
} else {
mPrefs.setAccountProxy(n, value);
preference.setSummary(mPrefs.getAccountProxy(n));
if (mTransportPreference != null) {
mTransportPreference.setSummary(mPrefs.getAccountTransportString(n));
mTransportPreference.setValue(mPrefs.getAccountTransportKey(n));
}
}
return true;
}
};
OnPreferenceChangeListener outboundProxyChangedListener =
new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (isNewAccount) {
builder.setOutboundProxyEnabled((Boolean) newValue);
} else {
mPrefs.setAccountOutboundProxyEnabled(n, (Boolean) newValue);
}
return true;
}
};
OnPreferenceChangeListener expiresChangedListener =
new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (isNewAccount) {
builder.setExpires(newValue.toString());
} else {
mPrefs.setExpires(n, newValue.toString());
}
preference.setSummary(newValue.toString());
return true;
}
};
OnPreferenceChangeListener prefixChangedListener =
new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
String value = newValue.toString();
preference.setSummary(value);
if (isNewAccount) {
builder.setPrefix(value);
} else {
mPrefs.setPrefix(n, value);
}
return true;
}
};
OnPreferenceChangeListener avpfChangedListener =
new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
boolean value = (Boolean) newValue;
if (isNewAccount) {
builder.setAvpfEnabled(value);
} else {
mPrefs.setAvpfMode(n, value);
}
return true;
}
};
OnPreferenceChangeListener disableChangedListener =
new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
boolean value = (Boolean) newValue;
if (isNewAccount) {
builder.setEnabled(!value);
} else {
mPrefs.setAccountEnabled(n, !value);
}
return true;
}
};
private AccountCreator accountCreator;
private ProgressDialog progress;
@ -63,6 +321,20 @@ public class AccountPreferencesFragment extends PreferencesListFragment implemen
mPrefs = LinphonePreferences.instance();
}
public static boolean isEditTextEmpty(String s) {
return s.equals(""); // really empty.
}
private static void setListPreferenceValues(
ListPreference pref, List<CharSequence> entries, List<CharSequence> values) {
CharSequence[] contents = new CharSequence[entries.size()];
entries.toArray(contents);
pref.setEntries(contents);
contents = new CharSequence[values.size()];
values.toArray(contents);
pref.setEntryValues(contents);
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -75,263 +347,17 @@ public class AccountPreferencesFragment extends PreferencesListFragment implemen
initAccountPreferencesFields(screen);
// Force hide keyboard
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
getActivity()
.getWindow()
.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
}
public static boolean isEditTextEmpty(String s) {
return s.equals(""); // really empty.
}
OnPreferenceChangeListener usernameChangedListener = new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (isEditTextEmpty(newValue.toString())) return false;
if (isNewAccount) {
builder.setUsername(newValue.toString());
} else {
mPrefs.setAccountUsername(n, newValue.toString());
}
preference.setSummary(newValue.toString());
return true;
}
};
OnPreferenceChangeListener useridChangedListener = new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (isNewAccount) {
builder.setUserid(newValue.toString());
} else {
mPrefs.setAccountUserId(n, newValue.toString());
}
preference.setSummary(newValue.toString());
return true;
}
};
OnPreferenceChangeListener passwordChangedListener = new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (isEditTextEmpty(newValue.toString())) return false;
if (isNewAccount) {
builder.setPassword(newValue.toString());
} else {
mPrefs.setAccountPassword(n, newValue.toString());
}
return true;
}
};
OnPreferenceChangeListener domainChangedListener = new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (isEditTextEmpty(newValue.toString())) return false;
if (isNewAccount) {
builder.setDomain(newValue.toString());
} else {
mPrefs.setAccountDomain(n, newValue.toString());
}
preference.setSummary(newValue.toString());
return true;
}
};
OnPreferenceChangeListener displayNameChangedListener = new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (isNewAccount) {
builder.setDisplayName(newValue.toString());
} else {
mPrefs.setAccountDisplayName(n, newValue.toString());
}
preference.setSummary(newValue.toString());
return true;
}
};
OnPreferenceChangeListener proxyChangedListener = new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
String value = newValue.toString();
if (isNewAccount) {
builder.setServerAddr(newValue.toString());
preference.setSummary(newValue.toString());
} else {
mPrefs.setAccountProxy(n, value);
preference.setSummary(mPrefs.getAccountProxy(n));
if (mTransportPreference != null) {
mTransportPreference.setSummary(mPrefs.getAccountTransportString(n));
mTransportPreference.setValue(mPrefs.getAccountTransportKey(n));
}
}
return true;
}
};
OnPreferenceChangeListener outboundProxyChangedListener = new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (isNewAccount) {
builder.setOutboundProxyEnabled((Boolean) newValue);
} else {
mPrefs.setAccountOutboundProxyEnabled(n, (Boolean) newValue);
}
return true;
}
};
OnPreferenceChangeListener expiresChangedListener = new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (isNewAccount) {
builder.setExpires(newValue.toString());
} else {
mPrefs.setExpires(n, newValue.toString());
}
preference.setSummary(newValue.toString());
return true;
}
};
OnPreferenceChangeListener prefixChangedListener = new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
String value = newValue.toString();
preference.setSummary(value);
if (isNewAccount) {
builder.setPrefix(value);
} else {
mPrefs.setPrefix(n, value);
}
return true;
}
};
OnPreferenceChangeListener avpfChangedListener = new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
boolean value = (Boolean) newValue;
if (isNewAccount) {
builder.setAvpfEnabled(value);
} else {
mPrefs.setAvpfMode(n, value);
}
return true;
}
};
OnPreferenceChangeListener avpfRRIntervalChangedListener = new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
String value = newValue.toString();
try {
int intValue = Integer.parseInt(value);
if ((intValue < 1) || (intValue > 5)) {
return false;
}
} catch (NumberFormatException nfe) {
}
if (isNewAccount) {
//TODO
} else {
mPrefs.setAvpfRrInterval(n, value);
}
preference.setSummary(value);
return true;
}
};
OnPreferenceChangeListener escapeChangedListener = new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
boolean value = (Boolean) newValue;
if (isNewAccount) {
//TODO
} else {
mPrefs.setReplacePlusByZeroZero(n, value);
}
return true;
}
};
OnPreferenceClickListener linkAccountListener = new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
Intent assistant = new Intent();
assistant.setClass(LinphoneActivity.instance(), AssistantActivity.class);
assistant.putExtra("LinkPhoneNumber", true);
assistant.putExtra("FromPref", true);
assistant.putExtra("AccountNumber", n);
startActivity(assistant);
return true;
}
};
OnPreferenceChangeListener pushNotificationListener = new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
boolean value = (Boolean) newValue;
if (isNewAccount) {
//TODO
} else {
mPrefs.enablePushNotifForProxy(n, value);
}
return true;
}
};
OnPreferenceChangeListener disableChangedListener = new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
boolean value = (Boolean) newValue;
if (isNewAccount) {
builder.setEnabled(!value);
} else {
mPrefs.setAccountEnabled(n, !value);
}
return true;
}
};
OnPreferenceChangeListener transportChangedListener = new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
String key = newValue.toString();
if (isNewAccount) {
//TODO
//builder.setTransport(transport);
} else {
mPrefs.setAccountTransport(n, key);
preference.setSummary(mPrefs.getAccountTransportString(n));
preference.setDefaultValue(mPrefs.getAccountTransportKey(n));
if (mProxyPreference != null) {
String newProxy = mPrefs.getAccountProxy(n);
mProxyPreference.setSummary(newProxy);
mProxyPreference.setText(newProxy);
}
}
return true;
}
};
OnPreferenceChangeListener iceChangedListener = new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
boolean value = (Boolean) newValue;
if (isNewAccount) {
} else {
mPrefs.setAccountIce(n, value);
((CheckBoxPreference) preference).setChecked(mPrefs.getAccountIce(n));
}
return true;
}
};
OnPreferenceChangeListener stunTurnChangedListener = new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
String value = newValue.toString();
if (isNewAccount) {
} else {
mPrefs.setAccountStunServer(n, value);
preference.setSummary(value);
}
return true;
}
};
private void initAccountPreferencesFields(PreferenceScreen parent) {
boolean isDefaultAccount = mPrefs.getDefaultAccountIndex() == n;
NatPolicy natPolicy = null;
if (LinphoneManager.getLcIfManagerNotDestroyedOrNull() != null &&
LinphoneManager.getLc().getProxyConfigList() != null &&
LinphoneManager.getLc().getProxyConfigList().length > n) {
if (LinphoneManager.getLcIfManagerNotDestroyedOrNull() != null
&& LinphoneManager.getLc().getProxyConfigList() != null
&& LinphoneManager.getLc().getProxyConfigList().length > n) {
ProxyConfig proxy = LinphoneManager.getLc().getProxyConfigList()[n];
natPolicy = proxy.getNatPolicy();
if (natPolicy == null) {
@ -342,10 +368,15 @@ public class AccountPreferencesFragment extends PreferencesListFragment implemen
}
}
accountCreator = LinphoneManager.getLc().createAccountCreator(LinphonePreferences.instance().getXmlrpcUrl());
accountCreator =
LinphoneManager.getLc()
.createAccountCreator(LinphonePreferences.instance().getXmlrpcUrl());
accountCreator.setListener(this);
final PreferenceCategory account = (PreferenceCategory) getPreferenceScreen().findPreference(getString(R.string.pref_sipaccount_key));
final PreferenceCategory account =
(PreferenceCategory)
getPreferenceScreen()
.findPreference(getString(R.string.pref_sipaccount_key));
EditTextPreference username = (EditTextPreference) account.getPreference(0);
username.setOnPreferenceChangeListener(usernameChangedListener);
if (!isNewAccount) {
@ -380,7 +411,9 @@ public class AccountPreferencesFragment extends PreferencesListFragment implemen
displayName.setSummary(displayName.getText());
}
PreferenceCategory advanced = (PreferenceCategory) getPreferenceScreen().findPreference(getString(R.string.pref_advanced_key));
PreferenceCategory advanced =
(PreferenceCategory)
getPreferenceScreen().findPreference(getString(R.string.pref_advanced_key));
mTransportPreference = (ListPreference) advanced.getPreference(0);
initializeTransportPreference(mTransportPreference);
mTransportPreference.setOnPreferenceChangeListener(transportChangedListener);
@ -390,8 +423,7 @@ public class AccountPreferencesFragment extends PreferencesListFragment implemen
CheckBoxPreference ice = (CheckBoxPreference) advanced.getPreference(1);
ice.setOnPreferenceChangeListener(iceChangedListener);
if (natPolicy != null)
ice.setChecked(natPolicy.iceEnabled());
if (natPolicy != null) ice.setChecked(natPolicy.iceEnabled());
EditTextPreference stunTurn = (EditTextPreference) advanced.getPreference(2);
stunTurn.setOnPreferenceChangeListener(stunTurnChangedListener);
@ -404,7 +436,10 @@ public class AccountPreferencesFragment extends PreferencesListFragment implemen
mProxyPreference.setOnPreferenceChangeListener(proxyChangedListener);
if (!isNewAccount) {
mProxyPreference.setText(mPrefs.getAccountProxy(n));
mProxyPreference.setSummary("".equals(mProxyPreference.getText()) || (mProxyPreference.getText() == null) ? getString(R.string.pref_help_proxy) : mProxyPreference.getText());
mProxyPreference.setSummary(
"".equals(mProxyPreference.getText()) || (mProxyPreference.getText() == null)
? getString(R.string.pref_help_proxy)
: mProxyPreference.getText());
}
CheckBoxPreference outboundProxy = (CheckBoxPreference) advanced.getPreference(4);
@ -456,7 +491,9 @@ public class AccountPreferencesFragment extends PreferencesListFragment implemen
pushNotif.setChecked(mPrefs.isPushNotifEnabledForProxy(n));
}
PreferenceCategory manage = (PreferenceCategory) getPreferenceScreen().findPreference(getString(R.string.pref_manage_key));
PreferenceCategory manage =
(PreferenceCategory)
getPreferenceScreen().findPreference(getString(R.string.pref_manage_key));
final CheckBoxPreference disable = (CheckBoxPreference) manage.getPreference(0);
disable.setEnabled(true);
disable.setOnPreferenceChangeListener(disableChangedListener);
@ -467,15 +504,16 @@ public class AccountPreferencesFragment extends PreferencesListFragment implemen
CheckBoxPreference mainAccount = (CheckBoxPreference) manage.getPreference(1);
mainAccount.setChecked(isDefaultAccount);
mainAccount.setEnabled(!mainAccount.isChecked());
mainAccount.setOnPreferenceClickListener(new OnPreferenceClickListener() {
public boolean onPreferenceClick(Preference preference) {
mPrefs.setDefaultAccount(n);
disable.setEnabled(false);
disable.setChecked(false);
preference.setEnabled(false);
return true;
}
});
mainAccount.setOnPreferenceClickListener(
new OnPreferenceClickListener() {
public boolean onPreferenceClick(Preference preference) {
mPrefs.setDefaultAccount(n);
disable.setEnabled(false);
disable.setChecked(false);
preference.setEnabled(false);
return true;
}
});
if (!isNewAccount) {
mainAccount.setEnabled(!mainAccount.isChecked());
}
@ -485,14 +523,15 @@ public class AccountPreferencesFragment extends PreferencesListFragment implemen
final Preference delete = manage.getPreference(3);
delete.setEnabled(!isNewAccount);
delete.setOnPreferenceClickListener(new OnPreferenceClickListener() {
public boolean onPreferenceClick(Preference preference) {
mPrefs.deleteAccount(n);
LinphoneActivity.instance().displaySettings();
LinphoneActivity.instance().refreshAccounts();
return true;
}
});
delete.setOnPreferenceClickListener(
new OnPreferenceClickListener() {
public boolean onPreferenceClick(Preference preference) {
mPrefs.deleteAccount(n);
LinphoneActivity.instance().displaySettings();
LinphoneActivity.instance().refreshAccounts();
return true;
}
});
}
private void initializeTransportPreference(ListPreference pref) {
@ -521,15 +560,6 @@ public class AccountPreferencesFragment extends PreferencesListFragment implemen
}
}
private static void setListPreferenceValues(ListPreference pref, List<CharSequence> entries, List<CharSequence> values) {
CharSequence[] contents = new CharSequence[entries.size()];
entries.toArray(contents);
pref.setEntries(contents);
contents = new CharSequence[values.size()];
values.toArray(contents);
pref.setEntryValues(contents);
}
@Override
public void onResume() {
super.onResume();
@ -557,58 +587,57 @@ public class AccountPreferencesFragment extends PreferencesListFragment implemen
}
@Override
public void onUpdateAccount(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
public void onUpdateAccount(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {
if (progress != null) progress.dismiss();
if (status.equals(AccountCreator.Status.RequestOk)) {
mPrefs.setAccountPassword(n, accountCreator.getPassword());
PreferenceCategory account = (PreferenceCategory) getPreferenceScreen().findPreference(getString(R.string.pref_sipaccount_key));
PreferenceCategory account =
(PreferenceCategory)
getPreferenceScreen()
.findPreference(getString(R.string.pref_sipaccount_key));
((EditTextPreference) account.getPreference(2)).setText(mPrefs.getAccountPassword(n));
LinphoneUtils.displayErrorAlert(getString(R.string.pref_password_changed), LinphoneActivity.instance());
LinphoneUtils.displayErrorAlert(
getString(R.string.pref_password_changed), LinphoneActivity.instance());
} else {
LinphoneUtils.displayErrorAlert(LinphoneUtils.errorForStatus(status), LinphoneActivity.instance());
LinphoneUtils.displayErrorAlert(
LinphoneUtils.errorForStatus(status), LinphoneActivity.instance());
}
}
@Override
public void onIsAccountExist(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onIsAccountExist(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onCreateAccount(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onCreateAccount(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onActivateAccount(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onActivateAccount(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onLinkAccount(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onLinkAccount(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onActivateAlias(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onActivateAlias(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onIsAccountActivated(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onIsAccountActivated(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onRecoverAccount(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onRecoverAccount(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onIsAccountLinked(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onIsAccountLinked(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onIsAliasUsed(AccountCreator accountCreator, AccountCreator.Status status, String resp) {
}
public void onIsAliasUsed(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
}

View file

@ -37,34 +37,30 @@ import android.view.ViewGroup;
import android.view.ViewParent;
import android.widget.ListView;
import android.widget.RelativeLayout;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import org.linphone.R;
import org.linphone.mediastream.Log;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
@SuppressLint("ValidFragment")
public class PreferencesListFragment extends ListFragment {
private PreferenceManager mPreferenceManager;
/**
* The starting request code given out to preference framework.
*/
/** The starting request code given out to preference framework. */
private static final int FIRST_REQUEST_CODE = 100;
private static final int MSG_BIND_PREFERENCES = 0;
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_BIND_PREFERENCES:
bindPreferences();
break;
}
}
};
private static final int MSG_BIND_PREFERENCES = 0;
private PreferenceManager mPreferenceManager;
private ListView preferencesList;
private Handler mHandler =
new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_BIND_PREFERENCES:
bindPreferences();
break;
}
}
};
private int xmlResID;
public PreferencesListFragment(int xmlId) {
@ -72,9 +68,7 @@ public class PreferencesListFragment extends ListFragment {
}
// Must be provided
public PreferencesListFragment() {
}
public PreferencesListFragment() {}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle b) {
@ -111,7 +105,10 @@ public class PreferencesListFragment extends ListFragment {
}
mPreferenceManager = onCreatePreferenceManager();
preferencesList = (ListView) LayoutInflater.from(getActivity()).inflate(R.layout.preference_list_content, null);
preferencesList =
(ListView)
LayoutInflater.from(getActivity())
.inflate(R.layout.preference_list_content, null);
preferencesList.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
addPreferencesFromResource(xmlResID);
postBindPreferences();
@ -152,7 +149,9 @@ public class PreferencesListFragment extends ListFragment {
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
try {
Method m = PreferenceManager.class.getDeclaredMethod("dispatchActivityResult", int.class, int.class, Intent.class);
Method m =
PreferenceManager.class.getDeclaredMethod(
"dispatchActivityResult", int.class, int.class, Intent.class);
m.setAccessible(true);
m.invoke(mPreferenceManager, requestCode, resultCode, data);
} catch (Exception e) {
@ -162,9 +161,9 @@ public class PreferencesListFragment extends ListFragment {
/**
* Posts a message to bind the preferences to the list view.
* <p>
* Binding late is preferred as any custom preference types created in
* {@link #onCreate(Bundle)} are able to have their views recycled.
*
* <p>Binding late is preferred as any custom preference types created in {@link
* #onCreate(Bundle)} are able to have their views recycled.
*/
private void postBindPreferences() {
if (mHandler.hasMessages(MSG_BIND_PREFERENCES)) return;
@ -185,9 +184,11 @@ public class PreferencesListFragment extends ListFragment {
*/
private PreferenceManager onCreatePreferenceManager() {
try {
Constructor<PreferenceManager> c = PreferenceManager.class.getDeclaredConstructor(Activity.class, int.class);
Constructor<PreferenceManager> c =
PreferenceManager.class.getDeclaredConstructor(Activity.class, int.class);
c.setAccessible(true);
PreferenceManager preferenceManager = c.newInstance(this.getActivity(), FIRST_REQUEST_CODE);
PreferenceManager preferenceManager =
c.newInstance(this.getActivity(), FIRST_REQUEST_CODE);
return preferenceManager;
} catch (Exception e) {
Log.e("[PreferencesListFragment] onCreatePreferenceManager " + e);
@ -204,29 +205,10 @@ public class PreferencesListFragment extends ListFragment {
return mPreferenceManager;
}
/**
* Sets the root of the preference hierarchy that this activity is showing.
*
* @param preferenceScreen The root {@link PreferenceScreen} of the preference hierarchy.
*/
public void setPreferenceScreen(PreferenceScreen preferenceScreen) {
try {
Method m = PreferenceManager.class.getDeclaredMethod("setPreferences", PreferenceScreen.class);
m.setAccessible(true);
boolean result = (Boolean) m.invoke(mPreferenceManager, preferenceScreen);
if (result && preferenceScreen != null) {
postBindPreferences();
}
} catch (Exception e) {
Log.e("[PreferencesListFragment] setPreferenceScreen " + e);
}
}
/**
* Gets the root of the preference hierarchy that this activity is showing.
*
* @return The {@link PreferenceScreen} that is the root of the preference
* hierarchy.
* @return The {@link PreferenceScreen} that is the root of the preference hierarchy.
*/
public PreferenceScreen getPreferenceScreen() {
try {
@ -241,16 +223,47 @@ public class PreferencesListFragment extends ListFragment {
}
/**
* Inflates the given XML resource and adds the preference hierarchy to the current
* preference hierarchy.
* Sets the root of the preference hierarchy that this activity is showing.
*
* @param preferenceScreen The root {@link PreferenceScreen} of the preference hierarchy.
*/
public void setPreferenceScreen(PreferenceScreen preferenceScreen) {
try {
Method m =
PreferenceManager.class.getDeclaredMethod(
"setPreferences", PreferenceScreen.class);
m.setAccessible(true);
boolean result = (Boolean) m.invoke(mPreferenceManager, preferenceScreen);
if (result && preferenceScreen != null) {
postBindPreferences();
}
} catch (Exception e) {
Log.e("[PreferencesListFragment] setPreferenceScreen " + e);
}
}
/**
* Inflates the given XML resource and adds the preference hierarchy to the current preference
* hierarchy.
*
* @param preferencesResId The XML resource ID to inflate.
*/
public void addPreferencesFromResource(int preferencesResId) {
try {
Method m = PreferenceManager.class.getDeclaredMethod("inflateFromResource", Context.class, int.class, PreferenceScreen.class);
Method m =
PreferenceManager.class.getDeclaredMethod(
"inflateFromResource",
Context.class,
int.class,
PreferenceScreen.class);
m.setAccessible(true);
PreferenceScreen prefScreen = (PreferenceScreen) m.invoke(mPreferenceManager, getActivity(), preferencesResId, getPreferenceScreen());
PreferenceScreen prefScreen =
(PreferenceScreen)
m.invoke(
mPreferenceManager,
getActivity(),
preferencesResId,
getPreferenceScreen());
setPreferenceScreen(prefScreen);
} catch (Exception e) {
Log.e("[PreferencesListFragment] addPreferencesFromResource " + e);
@ -271,4 +284,4 @@ public class PreferencesListFragment extends ListFragment {
}
return mPreferenceManager.findPreference(key);
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -19,7 +19,6 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
@ -37,4 +36,4 @@ public class AuthenticationService extends Service {
public IBinder onBind(Intent intent) {
return mAuthenticator.getIBinder();
}
}
}

Some files were not shown because too many files have changed in this diff Show more