diff --git a/app/src/main/java/org/mercury_im/messenger/android/MercuryImApplication.java b/app/src/main/java/org/mercury_im/messenger/android/MercuryImApplication.java index c4d9ec9..7528646 100644 --- a/app/src/main/java/org/mercury_im/messenger/android/MercuryImApplication.java +++ b/app/src/main/java/org/mercury_im/messenger/android/MercuryImApplication.java @@ -51,7 +51,6 @@ public class MercuryImApplication extends Application { appComponent.inject(this); setupClientStateIndication(); - ServerPingWithAlarmManager.onCreate(this); Notifications.initializeNotificationChannels(this); diff --git a/app/src/main/java/org/mercury_im/messenger/android/service/MercuryForegroundService.java b/app/src/main/java/org/mercury_im/messenger/android/service/MercuryForegroundService.java index 1585380..bc1e665 100644 --- a/app/src/main/java/org/mercury_im/messenger/android/service/MercuryForegroundService.java +++ b/app/src/main/java/org/mercury_im/messenger/android/service/MercuryForegroundService.java @@ -1,6 +1,7 @@ package org.mercury_im.messenger.android.service; import android.app.Notification; +import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.Context; @@ -15,6 +16,21 @@ import org.mercury_im.messenger.R; import org.mercury_im.messenger.android.MercuryImApplication; import org.mercury_im.messenger.android.Notifications; import org.mercury_im.messenger.android.ui.MainActivity; +import org.mercury_im.messenger.core.connection.MercuryConnectionManager; +import org.mercury_im.messenger.core.connection.state.ConnectionPoolState; +import org.mercury_im.messenger.core.connection.state.ConnectionState; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.UUID; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.inject.Inject; + +import io.reactivex.disposables.CompositeDisposable; +import io.reactivex.disposables.Disposable; /** * Started, Bound Service, which is responsible keeping the application alive when the app is not open. @@ -30,6 +46,12 @@ public class MercuryForegroundService extends Service { public static final String ACTION_START = ACTION + ".START"; public static final String ACTION_STOP = ACTION + ".STOP"; + private static final Logger LOGGER = Logger.getLogger(MercuryForegroundService.class.getName()); + + @Inject + MercuryConnectionManager connectionManager; + + CompositeDisposable disposable; @NonNull @Override @@ -42,6 +64,14 @@ public class MercuryForegroundService extends Service { super.onCreate(); MercuryImApplication.getApplication().getAppComponent().inject(this); beginLifecycleOfPingManager(); + disposable = new CompositeDisposable(); + disposable.add(connectionManager.observeConnectionPool() + .subscribe(state -> { + Notification notification = buildForegroundNotification(getApplicationContext(), state); + NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + notificationManager.notify(Notifications.FOREGROUND_SERVICE_ID, notification); + })); + LOGGER.log(Level.INFO, "onCreate"); } /** @@ -54,8 +84,9 @@ public class MercuryForegroundService extends Service { @Override public void onDestroy() { super.onDestroy(); - + disposable.dispose(); endLifecycleOfPingManager(); + LOGGER.log(Level.INFO, "onDestroy"); } private void endLifecycleOfPingManager() { @@ -87,20 +118,82 @@ public class MercuryForegroundService extends Service { } private void startAndDisplayForegroundNotification() { - Notification notification = buildForegroundNotification(getApplicationContext()); + Notification notification = buildForegroundNotification(getApplicationContext(), + connectionManager.observeConnectionPool().blockingFirst()); startForeground(Notifications.FOREGROUND_SERVICE_ID, notification); } - private static Notification buildForegroundNotification(Context context) { + private static Notification buildForegroundNotification(Context context, ConnectionPoolState state) { Intent startMainActivityIntent = new Intent(context, MainActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, startMainActivityIntent, 0); + + String notificationText = notificationTextFrom(state); + return new NotificationCompat.Builder(context, Notifications.NOTIFICATION_CHANNEL__FOREGROUND_SERVICE) - .setSmallIcon(R.drawable.ic_send_black_24dp) + .setSmallIcon(R.drawable.ic_mercury_black_24dp) + .setContentTitle("Mercury-IM is running!") + .setContentText(notificationText) + .setStyle(new NotificationCompat.BigTextStyle().bigText(notificationText)) .setContentIntent(pendingIntent) .build(); } + private static String notificationTextFrom(ConnectionPoolState state) { + List connecting = new ArrayList<>(); + List authenticated = new ArrayList<>(); + List erred = new ArrayList<>(); + for (UUID id : state.getConnectionStates().keySet()) { + ConnectionState connectionState = state.getConnectionStates().get(id); + switch (connectionState.getConnectivity()) { + case disconnected: + break; + case connecting: + case connected: + connecting.add(id); + break; + case authenticated: + authenticated.add(id); + break; + case disconnectedOnError: + erred.add(id); + break; + } + } + + StringBuilder sb = new StringBuilder(); + if (!authenticated.isEmpty()) { + sb.append(authenticated.size()) + .append(authenticated.size() == 1 ? " account" : " accounts") + .append(" connected."); + } + if (!connecting.isEmpty()) { + if (!sb.toString().isEmpty()) { + sb.append("\n"); + } + sb.append(connecting.size()) + .append(authenticated.size() == 1 ? " account" : " accounts") + .append(" connecting."); + } + if (!erred.isEmpty()) { + if (!sb.toString().isEmpty()) { + sb.append("\n"); + } + Iterator iterator = erred.iterator(); + while (iterator.hasNext()) { + UUID id = iterator.next(); + sb.append(getAddress(state, id)); + if (iterator.hasNext()) sb.append(", "); + } + sb.append(erred.size() == 1 ? " has an error." : " have errors."); + } + return sb.toString(); + } + + private static String getAddress(ConnectionPoolState state, UUID uuid) { + return state.getConnectionStates().get(uuid).getConnection().getAccount().getAddress(); + } + public class Binder extends android.os.Binder { private final MercuryForegroundService service; diff --git a/app/src/main/res/drawable/ic_mercury_black_24dp.xml b/app/src/main/res/drawable/ic_mercury_black_24dp.xml new file mode 100644 index 0000000..a532ee6 --- /dev/null +++ b/app/src/main/res/drawable/ic_mercury_black_24dp.xml @@ -0,0 +1,26 @@ + + + + + diff --git a/mercury_black_24dp.svg b/mercury_black_24dp.svg new file mode 100644 index 0000000..e137a32 --- /dev/null +++ b/mercury_black_24dp.svg @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + +