mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-21 09:20:19 +01:00
Observe sharedprefs for banner updates.
This commit is contained in:
committed by
mtang-signal
parent
244a81ef24
commit
d15bb05ae3
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
* Copyright 2024 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.util
|
||||
|
||||
import android.content.Context
|
||||
import androidx.lifecycle.DefaultLifecycleObserver
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.BuildConfig
|
||||
import org.thoughtcrime.securesms.jobs.ServiceOutageDetectionJob
|
||||
import java.net.InetAddress
|
||||
import java.net.UnknownHostException
|
||||
|
||||
/**
|
||||
* A lifecycle aware observer that can be instantiated to monitor the service for outages.
|
||||
*
|
||||
* @see [ServiceOutageDetectionJob]
|
||||
*/
|
||||
class ServiceOutageObserver(private val context: Context) : DefaultLifecycleObserver {
|
||||
companion object {
|
||||
val TAG = Log.tag(ServiceOutageObserver::class)
|
||||
}
|
||||
|
||||
private var observing = false
|
||||
|
||||
override fun onResume(owner: LifecycleOwner) {
|
||||
observing = true
|
||||
}
|
||||
|
||||
override fun onStop(owner: LifecycleOwner) {
|
||||
observing = false
|
||||
}
|
||||
|
||||
val flow: Flow<Boolean> = flow {
|
||||
emit(TextSecurePreferences.getServiceOutage(context))
|
||||
TextSecurePreferences.setLastOutageCheckTime(context, System.currentTimeMillis())
|
||||
|
||||
while (true) {
|
||||
if (observing && getNextCheckTime(context) <= System.currentTimeMillis()) {
|
||||
when (queryAvailability()) {
|
||||
Result.SUCCESS -> {
|
||||
TextSecurePreferences.setServiceOutage(context, false)
|
||||
emit(false)
|
||||
}
|
||||
|
||||
Result.FAILURE -> {
|
||||
Log.w(TAG, "Service is down.")
|
||||
TextSecurePreferences.setServiceOutage(context, true)
|
||||
emit(true)
|
||||
}
|
||||
|
||||
Result.RETRY_LATER -> {
|
||||
Log.w(TAG, "Service status check returned an unrecognized IP address. Could be a weird network state. Prompting retry.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val nextCheckTime = getNextCheckTime(context)
|
||||
val now = System.currentTimeMillis()
|
||||
val delay = nextCheckTime - now
|
||||
if (delay > 0) {
|
||||
delay(delay)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getNextCheckTime(context: Context): Long = TextSecurePreferences.getLastOutageCheckTime(context) + ServiceOutageDetectionJob.CHECK_TIME
|
||||
|
||||
private suspend fun queryAvailability(): Result = withContext(Dispatchers.IO) {
|
||||
try {
|
||||
val now = System.currentTimeMillis()
|
||||
TextSecurePreferences.setLastOutageCheckTime(context, now)
|
||||
|
||||
val address = InetAddress.getByName(BuildConfig.SIGNAL_SERVICE_STATUS_URL)
|
||||
|
||||
if (ServiceOutageDetectionJob.IP_SUCCESS == address.hostAddress) {
|
||||
Result.SUCCESS
|
||||
} else if (ServiceOutageDetectionJob.IP_FAILURE == address.hostAddress) {
|
||||
Result.FAILURE
|
||||
} else {
|
||||
Result.RETRY_LATER
|
||||
}
|
||||
} catch (e: UnknownHostException) {
|
||||
Log.i(TAG, "Received UnknownHostException!", e)
|
||||
Result.RETRY_LATER
|
||||
}
|
||||
}
|
||||
|
||||
private enum class Result {
|
||||
SUCCESS, FAILURE, RETRY_LATER
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2024 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.util
|
||||
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import androidx.lifecycle.DefaultLifecycleObserver
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
|
||||
/**
|
||||
* A lifecycle-aware observer that will let the changes to the [TextSecurePreferences] be observed.
|
||||
*
|
||||
* @param keysToListeners a map of [TextSecurePreferences] string keys to listeners that should be invoked when the values change.
|
||||
*/
|
||||
class SharedPreferencesLifecycleObserver(private val context: Context, keysToListeners: Map<String, () -> Unit>) : DefaultLifecycleObserver {
|
||||
|
||||
private val listener = SharedPreferences.OnSharedPreferenceChangeListener { _, key ->
|
||||
keysToListeners[key]?.invoke()
|
||||
}
|
||||
|
||||
override fun onResume(owner: LifecycleOwner) {
|
||||
TextSecurePreferences.registerListener(context, listener)
|
||||
}
|
||||
|
||||
override fun onPause(owner: LifecycleOwner) {
|
||||
TextSecurePreferences.unregisterListener(context, listener)
|
||||
}
|
||||
}
|
||||
@@ -110,7 +110,7 @@ public class TextSecurePreferences {
|
||||
public static final String ALWAYS_RELAY_CALLS_PREF = "pref_turn_only";
|
||||
public static final String READ_RECEIPTS_PREF = "pref_read_receipts";
|
||||
public static final String INCOGNITO_KEYBORAD_PREF = "pref_incognito_keyboard";
|
||||
private static final String UNAUTHORIZED_RECEIVED = "pref_unauthorized_received";
|
||||
public static final String UNAUTHORIZED_RECEIVED = "pref_unauthorized_received";
|
||||
private static final String SUCCESSFUL_DIRECTORY_PREF = "pref_successful_directory";
|
||||
|
||||
private static final String DATABASE_ENCRYPTED_SECRET = "pref_database_encrypted_secret";
|
||||
@@ -146,7 +146,7 @@ public class TextSecurePreferences {
|
||||
|
||||
public static final String SIGNAL_PIN_CHANGE = "pref_kbs_change";
|
||||
|
||||
private static final String SERVICE_OUTAGE = "pref_service_outage";
|
||||
public static final String SERVICE_OUTAGE = "pref_service_outage";
|
||||
private static final String LAST_OUTAGE_CHECK_TIME = "pref_last_outage_check_time";
|
||||
|
||||
private static final String LAST_FULL_CONTACT_SYNC_TIME = "pref_last_full_contact_sync_time";
|
||||
@@ -293,6 +293,14 @@ public class TextSecurePreferences {
|
||||
}
|
||||
}
|
||||
|
||||
public static void registerListener(@NonNull Context context, SharedPreferences.OnSharedPreferenceChangeListener listener) {
|
||||
getSharedPreferences(context).registerOnSharedPreferenceChangeListener(listener);
|
||||
}
|
||||
|
||||
public static void unregisterListener(@NonNull Context context, SharedPreferences.OnSharedPreferenceChangeListener listener) {
|
||||
getSharedPreferences(context).unregisterOnSharedPreferenceChangeListener(listener);
|
||||
}
|
||||
|
||||
public static boolean isScreenLockEnabled(@NonNull Context context) {
|
||||
return getBooleanPreference(context, SCREEN_LOCK, false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user