From 0a3dbc55a842f95dd3b77e6c6daf8f16cdc8fa43 Mon Sep 17 00:00:00 2001
From: nielsandriesse <andriesseniels@gmail.com>
Date: Fri, 17 Apr 2020 12:11:27 +1000
Subject: [PATCH] Integrate push notifications

---
 .../securesms/ApplicationContext.java         | 11 +++--
 .../loki/LokiPushNotificationManager.kt       |  3 +-
 .../activities/DisplayNameActivity.kt         | 21 ++--------
 .../loki/redesign/activities/HomeActivity.kt  | 41 +++++++------------
 .../redesign/activities/PNModeActivity.kt     | 37 ++++++++++++++++-
 .../redesign/dialogs/PNModeBottomSheet.kt     |  7 ++++
 .../messaging/BackgroundPollWorker.kt         |  2 +-
 .../NotificationsPreferenceFragment.java      | 11 +++++
 .../service/PushNotificationService.kt        |  2 +-
 .../securesms/util/TextSecurePreferences.java |  9 ++++
 10 files changed, 93 insertions(+), 51 deletions(-)

diff --git a/src/org/thoughtcrime/securesms/ApplicationContext.java b/src/org/thoughtcrime/securesms/ApplicationContext.java
index 9e1b633c5e..d8aa43a130 100644
--- a/src/org/thoughtcrime/securesms/ApplicationContext.java
+++ b/src/org/thoughtcrime/securesms/ApplicationContext.java
@@ -205,7 +205,7 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
     // Loki - Set up public chat manager
     lokiPublicChatManager = new LokiPublicChatManager(this);
     updatePublicChatProfilePictureIfNeeded();
-    setUpFCMIfNeeded();
+    registerForFCMIfNeeded();
   }
 
   @Override
@@ -462,7 +462,7 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
     }, this);
   }
 
-  public void setUpFCMIfNeeded() {
+  public void registerForFCMIfNeeded() {
     Context context = this;
     FirebaseInstanceId.getInstance().getInstanceId().addOnCompleteListener(task -> {
       if (!task.isSuccessful()) {
@@ -471,7 +471,12 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
       }
       String token = task.getResult().getToken();
       String userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context);
-      LokiPushNotificationManager.register(token, userHexEncodedPublicKey, context);
+      if (userHexEncodedPublicKey == null) return;
+      if (TextSecurePreferences.isUsingFCM(this)) {
+        LokiPushNotificationManager.register(token, userHexEncodedPublicKey, context);
+      } else {
+        LokiPushNotificationManager.unregister(token, context);
+      }
     });
   }
 
diff --git a/src/org/thoughtcrime/securesms/loki/LokiPushNotificationManager.kt b/src/org/thoughtcrime/securesms/loki/LokiPushNotificationManager.kt
index 336c9f8484..3fa225dca8 100644
--- a/src/org/thoughtcrime/securesms/loki/LokiPushNotificationManager.kt
+++ b/src/org/thoughtcrime/securesms/loki/LokiPushNotificationManager.kt
@@ -17,7 +17,8 @@ object LokiPushNotificationManager {
 
     private const val tokenExpirationInterval = 2 * 24 * 60 * 60 * 1000
 
-    fun disableFCM(token: String, context: Context?) {
+    @JvmStatic
+    fun unregister(token: String, context: Context?) {
         val parameters = mapOf( "token" to token )
         val url = "${server}/register"
         val body = RequestBody.create(MediaType.get("application/json"), JsonUtil.toJson(parameters))
diff --git a/src/org/thoughtcrime/securesms/loki/redesign/activities/DisplayNameActivity.kt b/src/org/thoughtcrime/securesms/loki/redesign/activities/DisplayNameActivity.kt
index 2c9b06e47e..1a6040398c 100644
--- a/src/org/thoughtcrime/securesms/loki/redesign/activities/DisplayNameActivity.kt
+++ b/src/org/thoughtcrime/securesms/loki/redesign/activities/DisplayNameActivity.kt
@@ -9,11 +9,9 @@ import android.widget.TextView.OnEditorActionListener
 import android.widget.Toast
 import kotlinx.android.synthetic.main.activity_display_name.*
 import network.loki.messenger.R
-import org.thoughtcrime.securesms.ApplicationContext
 import org.thoughtcrime.securesms.BaseActionBarActivity
-import org.thoughtcrime.securesms.database.DatabaseFactory
+import org.thoughtcrime.securesms.loki.redesign.utilities.push
 import org.thoughtcrime.securesms.loki.redesign.utilities.setUpActionBarSessionLogo
-import org.thoughtcrime.securesms.loki.redesign.utilities.show
 import org.thoughtcrime.securesms.util.TextSecurePreferences
 import org.whispersystems.signalservice.api.crypto.ProfileCipher
 
@@ -54,20 +52,7 @@ class DisplayNameActivity : BaseActionBarActivity() {
         val inputMethodManager = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
         inputMethodManager.hideSoftInputFromWindow(displayNameEditText.windowToken, 0)
         TextSecurePreferences.setProfileName(this, displayName)
-        TextSecurePreferences.setHasSeenWelcomeScreen(this, true)
-        TextSecurePreferences.setPromptedPushRegistration(this, true)
-        val application = ApplicationContext.getInstance(this)
-        application.setUpStorageAPIIfNeeded()
-        application.setUpP2PAPI()
-        val publicChatAPI = ApplicationContext.getInstance(this).lokiPublicChatAPI
-        if (publicChatAPI != null) {
-            // TODO: This won't be necessary anymore when we don't auto-join the Loki Public Chat anymore
-            application.createDefaultPublicChatsIfNeeded()
-            val servers = DatabaseFactory.getLokiThreadDatabase(this).getAllPublicChatServers()
-            servers.forEach { publicChatAPI.setDisplayName(displayName, it) }
-        }
-        val intent = Intent(this, HomeActivity::class.java)
-        intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
-        show(intent)
+        val intent = Intent(this, PNModeActivity::class.java)
+        push(intent)
     }
 }
\ No newline at end of file
diff --git a/src/org/thoughtcrime/securesms/loki/redesign/activities/HomeActivity.kt b/src/org/thoughtcrime/securesms/loki/redesign/activities/HomeActivity.kt
index 7e99a11ac7..c351bf0a24 100644
--- a/src/org/thoughtcrime/securesms/loki/redesign/activities/HomeActivity.kt
+++ b/src/org/thoughtcrime/securesms/loki/redesign/activities/HomeActivity.kt
@@ -32,6 +32,7 @@ import org.thoughtcrime.securesms.database.DatabaseFactory
 import org.thoughtcrime.securesms.database.ThreadDatabase
 import org.thoughtcrime.securesms.database.model.ThreadRecord
 import org.thoughtcrime.securesms.loki.getColorWithID
+import org.thoughtcrime.securesms.loki.redesign.dialogs.PNModeBottomSheet
 import org.thoughtcrime.securesms.loki.redesign.utilities.push
 import org.thoughtcrime.securesms.loki.redesign.utilities.show
 import org.thoughtcrime.securesms.loki.redesign.views.ConversationView
@@ -156,32 +157,20 @@ class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListe
         if (hasViewedSeed || !isMasterDevice) {
             seedReminderView.visibility = View.GONE
         }
-//        if (!TextSecurePreferences.getHasSeenOpenGroupSuggestionSheet(this)) {
-//            val bottomSheet = OpenGroupSuggestionBottomSheet()
-//            bottomSheet.onJoinTapped = {
-//                TextSecurePreferences.setHasSeenOpenGroupSuggestionSheet(this)
-//                bottomSheet.dismiss()
-//                // TODO: Duplication of the code in JoinPublicChatActivity
-//                val application = ApplicationContext.getInstance(this)
-//                val channel: Long = 1
-//                val displayName = TextSecurePreferences.getProfileName(this)
-//                val lokiPublicChatAPI = application.lokiPublicChatAPI!!
-//                val url = "https://chat.getsession.org"
-//                application.lokiPublicChatManager.addChat(url, channel).successUi {
-//                    lokiPublicChatAPI.getMessages(channel, url)
-//                    lokiPublicChatAPI.setDisplayName(displayName, url)
-//                    lokiPublicChatAPI.join(channel, url)
-//                    val profileKey: ByteArray = ProfileKeyUtil.getProfileKey(this)
-//                    val profileUrl: String? = TextSecurePreferences.getProfileAvatarUrl(this)
-//                    lokiPublicChatAPI.setProfilePicture(url, profileKey, profileUrl)
-//                }
-//            }
-//            bottomSheet.onDismissTapped = {
-//                TextSecurePreferences.setHasSeenOpenGroupSuggestionSheet(this)
-//                bottomSheet.dismiss()
-//            }
-//            bottomSheet.show(supportFragmentManager, bottomSheet.tag)
-//        }
+        if (!TextSecurePreferences.hasSeenPNModeSheet(this)) {
+            val bottomSheet = PNModeBottomSheet()
+            bottomSheet.onConfirmTapped = { isUsingFCM ->
+                TextSecurePreferences.setHasSeenPNModeSheet(this, true)
+                TextSecurePreferences.setIsUsingFCM(this, isUsingFCM)
+                ApplicationContext.getInstance(this).registerForFCMIfNeeded()
+                bottomSheet.dismiss()
+            }
+            bottomSheet.onSkipTapped = {
+                TextSecurePreferences.setHasSeenPNModeSheet(this, true)
+                bottomSheet.dismiss()
+            }
+            bottomSheet.show(supportFragmentManager, bottomSheet.tag)
+        }
     }
 
     override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
diff --git a/src/org/thoughtcrime/securesms/loki/redesign/activities/PNModeActivity.kt b/src/org/thoughtcrime/securesms/loki/redesign/activities/PNModeActivity.kt
index 9e2e2c1b6b..c79af2a295 100644
--- a/src/org/thoughtcrime/securesms/loki/redesign/activities/PNModeActivity.kt
+++ b/src/org/thoughtcrime/securesms/loki/redesign/activities/PNModeActivity.kt
@@ -1,15 +1,25 @@
 package org.thoughtcrime.securesms.loki.redesign.activities
 
+import android.app.AlertDialog
+import android.content.Intent
 import android.graphics.drawable.TransitionDrawable
 import android.os.Bundle
+import android.os.Handler
 import android.support.annotation.DrawableRes
 import android.view.View
 import android.widget.LinearLayout
+import android.widget.Toast
 import kotlinx.android.synthetic.main.activity_display_name.registerButton
+import kotlinx.android.synthetic.main.activity_home.*
 import kotlinx.android.synthetic.main.activity_pn_mode.*
 import network.loki.messenger.R
+import org.thoughtcrime.securesms.ApplicationContext
 import org.thoughtcrime.securesms.BaseActionBarActivity
+import org.thoughtcrime.securesms.database.DatabaseFactory
 import org.thoughtcrime.securesms.loki.redesign.utilities.setUpActionBarSessionLogo
+import org.thoughtcrime.securesms.loki.redesign.utilities.show
+import org.thoughtcrime.securesms.util.GroupUtil
+import org.thoughtcrime.securesms.util.TextSecurePreferences
 
 class PNModeActivity : BaseActionBarActivity() {
     private var selectedOptionView: LinearLayout? = null
@@ -71,7 +81,32 @@ class PNModeActivity : BaseActionBarActivity() {
     }
 
     private fun register() {
-        // TODO: Implement
+        if (selectedOptionView == null) {
+            val dialog = AlertDialog.Builder(this)
+            dialog.setMessage(R.string.activity_pn_mode_no_option_picked_dialog_title)
+            dialog.setPositiveButton(R.string.ok) { _, _ -> }
+            dialog.create().show()
+            return
+        }
+        val displayName = TextSecurePreferences.getProfileName(this)
+        TextSecurePreferences.setHasSeenWelcomeScreen(this, true)
+        TextSecurePreferences.setPromptedPushRegistration(this, true)
+        TextSecurePreferences.setIsUsingFCM(this, (selectedOptionView == fcmOptionView))
+        TextSecurePreferences.setHasSeenPNModeSheet(this, true) // Shouldn't be shown to users who've done the new onboarding
+        val application = ApplicationContext.getInstance(this)
+        application.setUpStorageAPIIfNeeded()
+        application.setUpP2PAPI()
+        val publicChatAPI = ApplicationContext.getInstance(this).lokiPublicChatAPI
+        if (publicChatAPI != null) {
+            // TODO: This won't be necessary anymore when we don't auto-join the Loki Public Chat anymore
+            application.createDefaultPublicChatsIfNeeded()
+            val servers = DatabaseFactory.getLokiThreadDatabase(this).getAllPublicChatServers()
+            servers.forEach { publicChatAPI.setDisplayName(displayName, it) }
+        }
+        application.registerForFCMIfNeeded()
+        val intent = Intent(this, HomeActivity::class.java)
+        intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
+        show(intent)
     }
     // endregion
 }
\ No newline at end of file
diff --git a/src/org/thoughtcrime/securesms/loki/redesign/dialogs/PNModeBottomSheet.kt b/src/org/thoughtcrime/securesms/loki/redesign/dialogs/PNModeBottomSheet.kt
index 32ccbd4b0b..583307e2ac 100644
--- a/src/org/thoughtcrime/securesms/loki/redesign/dialogs/PNModeBottomSheet.kt
+++ b/src/org/thoughtcrime/securesms/loki/redesign/dialogs/PNModeBottomSheet.kt
@@ -1,5 +1,6 @@
 package org.thoughtcrime.securesms.loki.redesign.dialogs
 
+import android.content.DialogInterface
 import android.graphics.drawable.TransitionDrawable
 import android.os.Bundle
 import android.support.annotation.DrawableRes
@@ -10,6 +11,7 @@ import android.view.ViewGroup
 import android.widget.LinearLayout
 import kotlinx.android.synthetic.main.fragment_pn_mode_bottom_sheet.*
 import network.loki.messenger.R
+import org.thoughtcrime.securesms.util.TextSecurePreferences
 
 class PNModeBottomSheet : BottomSheetDialogFragment() {
     private var selectedOptionView: LinearLayout? = null
@@ -33,6 +35,11 @@ class PNModeBottomSheet : BottomSheetDialogFragment() {
         skipButton.setOnClickListener { onSkipTapped?.invoke() }
     }
 
+    override fun onDismiss(dialog: DialogInterface?) {
+        TextSecurePreferences.setHasSeenPNModeSheet(context, true)
+        super.onDismiss(dialog)
+    }
+
     // region Animation
     private fun performTransition(@DrawableRes transitionID: Int, subject: View) {
         val drawable = resources.getDrawable(transitionID, context!!.theme) as TransitionDrawable
diff --git a/src/org/thoughtcrime/securesms/loki/redesign/messaging/BackgroundPollWorker.kt b/src/org/thoughtcrime/securesms/loki/redesign/messaging/BackgroundPollWorker.kt
index 7205e624de..46f0251afd 100644
--- a/src/org/thoughtcrime/securesms/loki/redesign/messaging/BackgroundPollWorker.kt
+++ b/src/org/thoughtcrime/securesms/loki/redesign/messaging/BackgroundPollWorker.kt
@@ -6,7 +6,6 @@ import nl.komponents.kovenant.functional.map
 import org.thoughtcrime.securesms.ApplicationContext
 import org.thoughtcrime.securesms.database.DatabaseFactory
 import org.thoughtcrime.securesms.jobs.PushContentReceiveJob
-import org.thoughtcrime.securesms.loki.LokiPushNotificationManager
 import org.thoughtcrime.securesms.service.PersistentAlarmManagerListener
 import org.thoughtcrime.securesms.util.TextSecurePreferences
 import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope
@@ -29,6 +28,7 @@ class BackgroundPollWorker : PersistentAlarmManagerListener() {
     }
 
     override fun onAlarm(context: Context, scheduledTime: Long): Long {
+        if (TextSecurePreferences.isUsingFCM(context)) { return 0L }
         if (scheduledTime != 0L) {
             val userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context)
             val lokiAPIDatabase = DatabaseFactory.getLokiAPIDatabase(context)
diff --git a/src/org/thoughtcrime/securesms/preferences/NotificationsPreferenceFragment.java b/src/org/thoughtcrime/securesms/preferences/NotificationsPreferenceFragment.java
index fd58d1d4b2..795874f406 100644
--- a/src/org/thoughtcrime/securesms/preferences/NotificationsPreferenceFragment.java
+++ b/src/org/thoughtcrime/securesms/preferences/NotificationsPreferenceFragment.java
@@ -14,6 +14,7 @@ import android.support.v7.preference.ListPreference;
 import android.support.v7.preference.Preference;
 import android.text.TextUtils;
 
+import org.thoughtcrime.securesms.ApplicationContext;
 import org.thoughtcrime.securesms.components.SwitchPreferenceCompat;
 import org.thoughtcrime.securesms.notifications.MessageNotifier;
 import org.thoughtcrime.securesms.notifications.NotificationChannels;
@@ -32,6 +33,16 @@ public class NotificationsPreferenceFragment extends ListSummaryPreferenceFragme
   public void onCreate(Bundle paramBundle) {
     super.onCreate(paramBundle);
 
+    // Set up FCM toggle
+    String fcmKey = "pref_key_use_fcm";
+    ((SwitchPreferenceCompat)findPreference(fcmKey)).setChecked(TextSecurePreferences.isUsingFCM(getContext()));
+    this.findPreference(fcmKey)
+        .setOnPreferenceChangeListener((preference, newValue) -> {
+          TextSecurePreferences.setIsUsingFCM(getContext(), (boolean) newValue);
+          ApplicationContext.getInstance(getContext()).registerForFCMIfNeeded();
+          return true;
+        });
+
     Preference ledBlinkPref = this.findPreference(TextSecurePreferences.LED_BLINK_PREF);
 
     if (NotificationChannels.supported()) {
diff --git a/src/org/thoughtcrime/securesms/service/PushNotificationService.kt b/src/org/thoughtcrime/securesms/service/PushNotificationService.kt
index 362442e1a0..20b206c4a2 100644
--- a/src/org/thoughtcrime/securesms/service/PushNotificationService.kt
+++ b/src/org/thoughtcrime/securesms/service/PushNotificationService.kt
@@ -15,7 +15,7 @@ class PushNotificationService : FirebaseMessagingService() {
     override fun onNewToken(token: String) {
         super.onNewToken(token)
         Log.d("Loki", "New FCM token: $token.")
-        val userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(this)
+        val userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(this) ?: return
         LokiPushNotificationManager.register(token, userHexEncodedPublicKey, this)
     }
 
diff --git a/src/org/thoughtcrime/securesms/util/TextSecurePreferences.java b/src/org/thoughtcrime/securesms/util/TextSecurePreferences.java
index f4fc8b20ec..d306ab259d 100644
--- a/src/org/thoughtcrime/securesms/util/TextSecurePreferences.java
+++ b/src/org/thoughtcrime/securesms/util/TextSecurePreferences.java
@@ -189,6 +189,7 @@ public class TextSecurePreferences {
   private static final String IS_USING_FCM = "pref_is_using_fcm";
   private static final String FCM_TOKEN = "pref_fcm_token";
   private static final String LAST_FCM_TOKEN_UPLOAD_TIME = "pref_last_fcm_token_upload_time";
+  private static final String HAS_SEEN_PN_MODE_SHEET = "pref_has_seen_pn_mode_sheet";
 
   public static boolean isUsingFCM(Context context) {
     return getBooleanPreference(context, IS_USING_FCM, false);
@@ -213,6 +214,14 @@ public class TextSecurePreferences {
   public static void setLastFCMUploadTime(Context context, long value) {
     setLongPreference(context, LAST_FCM_TOKEN_UPLOAD_TIME, value);
   }
+
+  public static boolean hasSeenPNModeSheet(Context context) {
+    return getBooleanPreference(context, HAS_SEEN_PN_MODE_SHEET, false);
+  }
+
+  public static void setHasSeenPNModeSheet(Context context, boolean value) {
+    setBooleanPreference(context, HAS_SEEN_PN_MODE_SHEET, value);
+  }
   // endregion
 
   public static boolean isScreenLockEnabled(@NonNull Context context) {