package org.mercury_im.messenger; import android.app.Activity; import android.app.Application; import android.app.NotificationChannel; import android.app.NotificationManager; import android.content.Context; import android.content.Intent; import android.os.Build; import org.mercury_im.messenger.core.centers.ConnectionCenter; import org.mercury_im.messenger.core.connection.MercuryConfiguration; import org.mercury_im.messenger.di.component.AppComponent; import org.mercury_im.messenger.di.component.DaggerAppComponent; import org.mercury_im.messenger.di.module.AppModule; import org.mercury_im.messenger.persistence.room.RoomModule; import org.mercury_im.messenger.persistence.room.RoomRepositoryModule; import org.mercury_im.messenger.service.XmppConnectionService; import org.mercury_im.messenger.util.AbstractActivityLifecycleCallbacks; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import javax.inject.Inject; public class MercuryImApplication extends Application { public static final String TAG = "Mercury-IM"; static { // Initialize Smack etc. new MercuryConfiguration(); } private static MercuryImApplication INSTANCE; AppComponent appComponent; // Keep track of activities in "started" state. // This will come in handy for CSI private AtomicInteger activityReferences = new AtomicInteger(0); private AtomicBoolean isActivityChangingConfiguration = new AtomicBoolean(false); @Inject ConnectionCenter connectionCenter; public static MercuryImApplication getApplication() { return INSTANCE; } @Override public void onCreate() { super.onCreate(); registerActivityLifecycleCallbacks(lifecycleCallbacks); INSTANCE = this; appComponent = createAppComponent(); initializeNotificationChannels(this); Intent serviceIntent = new Intent(getApplicationContext(), XmppConnectionService.class); serviceIntent.setAction(XmppConnectionService.ACTION_START); if (Build.VERSION.SDK_INT < 26) { startService(serviceIntent); } else { startForegroundService(serviceIntent); } } /** * Create the Dependency Injection graph. * For testing, overwrite this method with custom modules. */ public AppComponent createAppComponent() { AppComponent appComponent = DaggerAppComponent.builder() .appModule(new AppModule(this)) .roomModule(new RoomModule(this)) .roomRepositoryModule(new RoomRepositoryModule()) .build(); appComponent.inject(this); return appComponent; } public void initializeNotificationChannels(Context context) { // Only necessary on Android O and upwards. if (Build.VERSION.SDK_INT < 26) { return; } NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); // Foreground notification channel String fName = getResources().getString(R.string.channel_name_foreground); String fDescription = getResources().getString(R.string.channel_description_foreground); NotificationChannel foreground = new NotificationChannel(Notifications.NOTIFICATION_CHANNEL__FOREGROUND_SERVICE, fName, NotificationManager.IMPORTANCE_MIN); foreground.setDescription(fDescription); foreground.setShowBadge(false); notificationManager.createNotificationChannel(foreground); // Incoming Messages notification channel String mName = getResources().getString(R.string.channel_name_message); String mDescription = getResources().getString(R.string.channel_description_message); NotificationChannel messages = new NotificationChannel(Notifications.NOTIFICATION_CHANNEL__NEW_MESSAGE, mName, NotificationManager.IMPORTANCE_HIGH); messages.setDescription(mDescription); notificationManager.createNotificationChannel(messages); } public AppComponent getAppComponent() { return appComponent; } private final AbstractActivityLifecycleCallbacks lifecycleCallbacks = new AbstractActivityLifecycleCallbacks() { @Override public void onActivityStarted(Activity activity) { if (activityReferences.incrementAndGet() == 1 && !isActivityChangingConfiguration.get()) { // App enters foreground connectionCenter.clientStateActive(); } } @Override public void onActivityStopped(Activity activity) { isActivityChangingConfiguration.set(activity.isChangingConfigurations()); if (activityReferences.decrementAndGet() == 0 && !isActivityChangingConfiguration.get()) { // App enters background connectionCenter.clientStateInactive(); } } }; }