package org.thoughtcrime.securesms.dependencies; import android.content.Context; import org.thoughtcrime.securesms.gcm.FcmService; import org.thoughtcrime.securesms.jobs.AttachmentUploadJob; import org.thoughtcrime.securesms.jobs.MultiDeviceConfigurationUpdateJob; import org.thoughtcrime.securesms.jobs.RefreshUnidentifiedDeliveryAbilityJob; import org.thoughtcrime.securesms.jobs.RotateProfileKeyJob; import org.thoughtcrime.securesms.jobs.TypingSendJob; import org.thoughtcrime.securesms.logging.Log; import org.greenrobot.eventbus.EventBus; import org.thoughtcrime.securesms.BuildConfig; import org.thoughtcrime.securesms.CreateProfileActivity; import org.thoughtcrime.securesms.DeviceListFragment; import org.thoughtcrime.securesms.crypto.storage.SignalProtocolStoreImpl; import org.thoughtcrime.securesms.events.ReminderUpdateEvent; import org.thoughtcrime.securesms.jobs.AttachmentDownloadJob; import org.thoughtcrime.securesms.jobs.AvatarDownloadJob; import org.thoughtcrime.securesms.jobs.CleanPreKeysJob; import org.thoughtcrime.securesms.jobs.CreateSignedPreKeyJob; import org.thoughtcrime.securesms.jobs.FcmRefreshJob; import org.thoughtcrime.securesms.jobs.MultiDeviceBlockedUpdateJob; import org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob; import org.thoughtcrime.securesms.jobs.MultiDeviceGroupUpdateJob; import org.thoughtcrime.securesms.jobs.MultiDeviceProfileKeyUpdateJob; import org.thoughtcrime.securesms.jobs.MultiDeviceReadUpdateJob; import org.thoughtcrime.securesms.jobs.MultiDeviceVerifiedUpdateJob; import org.thoughtcrime.securesms.jobs.PushGroupSendJob; import org.thoughtcrime.securesms.jobs.PushGroupUpdateJob; import org.thoughtcrime.securesms.jobs.PushMediaSendJob; import org.thoughtcrime.securesms.jobs.PushNotificationReceiveJob; import org.thoughtcrime.securesms.jobs.PushTextSendJob; import org.thoughtcrime.securesms.jobs.RefreshAttributesJob; import org.thoughtcrime.securesms.jobs.RefreshPreKeysJob; import org.thoughtcrime.securesms.jobs.RequestGroupInfoJob; import org.thoughtcrime.securesms.jobs.RetrieveProfileAvatarJob; import org.thoughtcrime.securesms.jobs.RetrieveProfileJob; import org.thoughtcrime.securesms.jobs.RotateCertificateJob; import org.thoughtcrime.securesms.jobs.RotateSignedPreKeyJob; import org.thoughtcrime.securesms.jobs.SendDeliveryReceiptJob; import org.thoughtcrime.securesms.jobs.SendReadReceiptJob; import org.thoughtcrime.securesms.loki.LokiPreKeyBundleStore; import org.thoughtcrime.securesms.preferences.AppProtectionPreferenceFragment; import org.thoughtcrime.securesms.push.SecurityEventListener; import org.thoughtcrime.securesms.push.SignalServiceNetworkAccess; import org.thoughtcrime.securesms.service.IncomingMessageObserver; import org.thoughtcrime.securesms.service.WebRtcCallService; import org.thoughtcrime.securesms.util.RealtimeSleepTimer; import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.signalservice.api.SignalServiceAccountManager; import org.whispersystems.signalservice.api.SignalServiceMessageReceiver; import org.whispersystems.signalservice.api.SignalServiceMessageSender; import org.whispersystems.signalservice.api.util.CredentialsProvider; import org.whispersystems.signalservice.api.util.SleepTimer; import org.whispersystems.signalservice.api.util.UptimeSleepTimer; import org.whispersystems.signalservice.api.websocket.ConnectivityListener; import dagger.Module; import dagger.Provides; @Module(complete = false, injects = {CleanPreKeysJob.class, CreateSignedPreKeyJob.class, PushGroupSendJob.class, PushTextSendJob.class, PushMediaSendJob.class, AttachmentDownloadJob.class, RefreshPreKeysJob.class, IncomingMessageObserver.class, PushNotificationReceiveJob.class, MultiDeviceContactUpdateJob.class, MultiDeviceGroupUpdateJob.class, MultiDeviceReadUpdateJob.class, MultiDeviceBlockedUpdateJob.class, DeviceListFragment.class, RefreshAttributesJob.class, FcmRefreshJob.class, RequestGroupInfoJob.class, PushGroupUpdateJob.class, AvatarDownloadJob.class, RotateSignedPreKeyJob.class, WebRtcCallService.class, RetrieveProfileJob.class, MultiDeviceVerifiedUpdateJob.class, CreateProfileActivity.class, RetrieveProfileAvatarJob.class, MultiDeviceProfileKeyUpdateJob.class, SendReadReceiptJob.class, AppProtectionPreferenceFragment.class, FcmService.class, RotateCertificateJob.class, SendDeliveryReceiptJob.class, RotateProfileKeyJob.class, MultiDeviceConfigurationUpdateJob.class, RefreshUnidentifiedDeliveryAbilityJob.class, TypingSendJob.class, AttachmentUploadJob.class}) public class SignalCommunicationModule { private static final String TAG = SignalCommunicationModule.class.getSimpleName(); private final Context context; private final SignalServiceNetworkAccess networkAccess; private SignalServiceAccountManager accountManager; private SignalServiceMessageSender messageSender; private SignalServiceMessageReceiver messageReceiver; public SignalCommunicationModule(Context context, SignalServiceNetworkAccess networkAccess) { this.context = context; this.networkAccess = networkAccess; } @Provides synchronized SignalServiceAccountManager provideSignalAccountManager() { if (this.accountManager == null) { this.accountManager = new SignalServiceAccountManager(networkAccess.getConfiguration(context), new DynamicCredentialsProvider(context), BuildConfig.USER_AGENT); } return this.accountManager; } @Provides synchronized SignalServiceMessageSender provideSignalMessageSender() { if (this.messageSender == null) { this.messageSender = new SignalServiceMessageSender(networkAccess.getConfiguration(context), new DynamicCredentialsProvider(context), new SignalProtocolStoreImpl(context), BuildConfig.USER_AGENT, TextSecurePreferences.isMultiDevice(context), Optional.fromNullable(IncomingMessageObserver.getPipe()), Optional.fromNullable(IncomingMessageObserver.getUnidentifiedPipe()), Optional.of(new SecurityEventListener(context))); // LOKI - Set the prekey bundle store // This is something that we MUST have otherwise our loki logic will fail this.messageSender.setPreKeyBundleStore(new LokiPreKeyBundleStore(context)); } else { this.messageSender.setMessagePipe(IncomingMessageObserver.getPipe(), IncomingMessageObserver.getUnidentifiedPipe()); this.messageSender.setIsMultiDevice(TextSecurePreferences.isMultiDevice(context)); } return this.messageSender; } @Provides synchronized SignalServiceMessageReceiver provideSignalMessageReceiver() { if (this.messageReceiver == null) { SleepTimer sleepTimer = TextSecurePreferences.isFcmDisabled(context) ? new RealtimeSleepTimer(context) : new UptimeSleepTimer(); this.messageReceiver = new SignalServiceMessageReceiver(networkAccess.getConfiguration(context), new DynamicCredentialsProvider(context), BuildConfig.USER_AGENT, new PipeConnectivityListener(), sleepTimer); } return this.messageReceiver; } @Provides synchronized SignalServiceNetworkAccess provideSignalServiceNetworkAccess() { return networkAccess; } private static class DynamicCredentialsProvider implements CredentialsProvider { private final Context context; private DynamicCredentialsProvider(Context context) { this.context = context.getApplicationContext(); } @Override public String getUser() { return TextSecurePreferences.getLocalNumber(context); } @Override public String getPassword() { return TextSecurePreferences.getPushServerPassword(context); } @Override public String getSignalingKey() { return TextSecurePreferences.getSignalingKey(context); } } private class PipeConnectivityListener implements ConnectivityListener { @Override public void onConnected() { Log.i(TAG, "onConnected()"); } @Override public void onConnecting() { Log.i(TAG, "onConnecting()"); } @Override public void onDisconnected() { Log.w(TAG, "onDisconnected()"); } @Override public void onAuthenticationFailure() { Log.w(TAG, "onAuthenticationFailure()"); TextSecurePreferences.setUnauthorizedReceived(context, true); EventBus.getDefault().post(new ReminderUpdateEvent()); } } }