Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,20 @@ import android.content.Context
import android.content.Intent
import android.util.Log
import androidx.core.content.edit
import kotlinx.coroutines.flow.first
import org.json.JSONArray
import org.json.JSONException
import org.openhab.habdroid.R
import org.openhab.habdroid.core.connection.CloudConnection
import org.openhab.habdroid.core.connection.Connection
import org.openhab.habdroid.core.connection.ConnectionFactory
import org.openhab.habdroid.core.connection.NotACloudServerException
import org.openhab.habdroid.model.CloudMessage
import org.openhab.habdroid.model.toCloudMessage
import org.openhab.habdroid.ui.CloudNotificationListFragment
import org.openhab.habdroid.ui.preference.PushNotificationStatus
import org.openhab.habdroid.util.HttpClient
import org.openhab.habdroid.util.PrefKeys
import org.openhab.habdroid.util.getConnectionFactory
import org.openhab.habdroid.util.getHumanReadableErrorMessage
import org.openhab.habdroid.util.getPrefs
import org.openhab.habdroid.util.getPrimaryServerId
Expand All @@ -51,8 +52,7 @@ object CloudMessagingHelper {
context.getPrefs().getBoolean(PrefKeys.FOSS_NOTIFICATIONS_ENABLED, false)

suspend fun pollForNotifications(context: Context) {
ConnectionFactory.waitForInitialization()
val connection = ConnectionFactory.primaryCloudConnection?.connection
val connection = context.getConnectionFactory().primaryFlow.first().conn?.connection
if (connection == null) {
Log.d(TAG, "No connection for loading notifications")
return
Expand Down Expand Up @@ -96,8 +96,7 @@ object CloudMessagingHelper {
}

suspend fun getPushNotificationStatus(context: Context): PushNotificationStatus {
ConnectionFactory.waitForInitialization()
val cloudFailure = ConnectionFactory.primaryCloudConnection?.failureReason
val cloudResult = context.getConnectionFactory().primaryFlow.first().cloud
val prefs = context.getPrefs()
return when {
!prefs.getBoolean(PrefKeys.FOSS_NOTIFICATIONS_ENABLED, false) -> PushNotificationStatus(
Expand All @@ -112,19 +111,19 @@ object CloudMessagingHelper {
false
)

ConnectionFactory.primaryCloudConnection?.connection != null -> PushNotificationStatus(
cloudResult?.connection != null -> PushNotificationStatus(
context.getString(R.string.push_notification_status_impaired),
R.drawable.ic_bell_ring_outline_grey_24dp,
false
)

cloudFailure != null && cloudFailure !is NotACloudServerException -> {
cloudResult?.failureReason != null && cloudResult.failureReason !is NotACloudServerException -> {
val message = context.getString(
R.string.push_notification_status_http_error,
context.getHumanReadableErrorMessage(
if (cloudFailure is HttpClient.HttpException) cloudFailure.originalUrl else "",
if (cloudFailure is HttpClient.HttpException) cloudFailure.statusCode else 0,
cloudFailure,
(cloudResult.failureReason as? HttpClient.HttpException)?.originalUrl ?: "",
(cloudResult.failureReason as? HttpClient.HttpException)?.statusCode ?: 0,
cloudResult.failureReason,
true
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@ import android.content.Context
import android.content.Intent
import com.google.android.gms.common.ConnectionResult
import com.google.android.gms.common.GoogleApiAvailability
import kotlinx.coroutines.flow.first
import org.openhab.habdroid.R
import org.openhab.habdroid.core.connection.CloudConnection
import org.openhab.habdroid.core.connection.ConnectionFactory
import org.openhab.habdroid.core.connection.NotACloudServerException
import org.openhab.habdroid.ui.preference.PushNotificationStatus
import org.openhab.habdroid.util.HttpClient
import org.openhab.habdroid.util.getConnectionFactory
import org.openhab.habdroid.util.getHumanReadableErrorMessage
import org.openhab.habdroid.util.getPrefs
import org.openhab.habdroid.util.getPrimaryServerId
Expand Down Expand Up @@ -53,10 +54,9 @@ object CloudMessagingHelper {
}

suspend fun getPushNotificationStatus(context: Context): PushNotificationStatus {
ConnectionFactory.waitForInitialization()
val result = context.getConnectionFactory().primaryFlow.first()
val prefs = context.getPrefs()
val cloudConnectionResult = ConnectionFactory.primaryCloudConnection
val cloudFailure = cloudConnectionResult?.failureReason
val cloudFailure = result.cloud?.failureReason
return when {
// No remote server is configured
prefs.getRemoteUrl(prefs.getPrimaryServerId()).isEmpty() -> PushNotificationStatus(
Expand All @@ -80,7 +80,7 @@ object CloudMessagingHelper {
}

// Remote server is configured, but it's not a cloud instance
cloudConnectionResult?.connection == null && ConnectionFactory.hasPrimaryRemoteConnection ->
result.cloud?.connection == null && result.hasRemote ->
PushNotificationStatus(
context.getString(R.string.push_notification_status_remote_no_cloud),
R.drawable.ic_bell_off_outline_grey_24dp,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,14 @@ import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlin.coroutines.suspendCoroutine
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.withContext
import org.openhab.habdroid.R
import org.openhab.habdroid.core.connection.CloudConnection
import org.openhab.habdroid.core.connection.ConnectionFactory
import org.openhab.habdroid.util.HttpClient
import org.openhab.habdroid.util.PendingIntent_Immutable
import org.openhab.habdroid.util.Util
import org.openhab.habdroid.util.getConnectionFactory
import org.openhab.habdroid.util.parcelable

class FcmRegistrationWorker(private val context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {
Expand Down Expand Up @@ -75,10 +76,7 @@ class FcmRegistrationWorker(private val context: Context, params: WorkerParamete
val action = inputData.getString(KEY_ACTION)
Log.d(TAG, "Run with action $action")

ConnectionFactory.waitForInitialization()

val connection = ConnectionFactory.primaryCloudConnection?.connection

val connection = context.getConnectionFactory().primaryFlow.first().cloud?.connection
if (connection == null) {
Log.d(TAG, "Got no connection")
return retryOrFail()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,17 @@ import java.net.SocketTimeoutException
import java.text.SimpleDateFormat
import java.util.Locale
import java.util.TimeZone
import kotlinx.coroutines.flow.first
import kotlinx.parcelize.Parcelize
import org.openhab.habdroid.R
import org.openhab.habdroid.background.NotificationUpdateObserver.Companion.NOTIFICATION_ID_BACKGROUND_WORK_RUNNING
import org.openhab.habdroid.core.connection.Connection
import org.openhab.habdroid.core.connection.ConnectionFactory
import org.openhab.habdroid.model.Item
import org.openhab.habdroid.ui.TaskerItemPickerActivity
import org.openhab.habdroid.util.HttpClient
import org.openhab.habdroid.util.ItemClient
import org.openhab.habdroid.util.TaskerPlugin
import org.openhab.habdroid.util.getConnectionFactory
import org.openhab.habdroid.util.getHumanReadableErrorMessage
import org.openhab.habdroid.util.getPrefixForVoice
import org.openhab.habdroid.util.getPrefs
Expand All @@ -54,15 +55,15 @@ class ItemUpdateWorker(context: Context, params: WorkerParameters) : CoroutineWo
if (isImportant) {
setForegroundAsync(getForegroundInfo())
}
ConnectionFactory.waitForInitialization()

Log.d(TAG, "Trying to get connection")
val connection = if (inputData.getBoolean(INPUT_DATA_PRIMARY_SERVER, false)) {
ConnectionFactory.primaryUsableConnection?.connection
val connectionFlow = if (inputData.getBoolean(INPUT_DATA_PRIMARY_SERVER, false)) {
applicationContext.getConnectionFactory().primaryFlow
} else {
ConnectionFactory.activeUsableConnection?.connection
applicationContext.getConnectionFactory().activeFlow
}

val connection = connectionFlow.first().conn?.connection
val showToast = inputData.getBoolean(INPUT_DATA_SHOW_TOAST, false)
val taskerIntent = inputData.getString(INPUT_DATA_TASKER_INTENT)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ import kotlin.math.max
import kotlin.math.min
import kotlin.math.roundToInt
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.jdk9.flowPublish
import kotlinx.coroutines.launch
import org.openhab.habdroid.R
import org.openhab.habdroid.core.connection.Connection
import org.openhab.habdroid.core.connection.ConnectionFactory
import org.openhab.habdroid.model.Item
import org.openhab.habdroid.model.ServerConfiguration
import org.openhab.habdroid.model.toParsedState
Expand All @@ -53,6 +53,7 @@ import org.openhab.habdroid.util.HttpClient
import org.openhab.habdroid.util.ItemClient
import org.openhab.habdroid.util.PendingIntent_Immutable
import org.openhab.habdroid.util.PrefKeys
import org.openhab.habdroid.util.getConnectionFactory
import org.openhab.habdroid.util.getDeviceControlSubtitle
import org.openhab.habdroid.util.getPrefs
import org.openhab.habdroid.util.getPrimaryServerId
Expand All @@ -62,8 +63,7 @@ import org.openhab.habdroid.util.orDefaultIfEmpty
@RequiresApi(Build.VERSION_CODES.R)
class ItemsControlsProviderService : ControlsProviderService() {
override fun createPublisherForAllAvailable(): Flow.Publisher<Control> = flowPublish {
ConnectionFactory.waitForInitialization()
val connection = ConnectionFactory.primaryUsableConnection?.connection ?: return@flowPublish
val connection = getConnectionFactory().primaryFlow.first().conn?.connection ?: return@flowPublish
val allItems = loadItems(connection) ?: return@flowPublish
val factory = ItemControlFactory(this@ItemsControlsProviderService, allItems, false)
allItems
Expand All @@ -72,8 +72,7 @@ class ItemsControlsProviderService : ControlsProviderService() {
}

override fun createPublisherFor(itemNames: List<String>): Flow.Publisher<Control> = flowPublish {
ConnectionFactory.waitForInitialization()
val connection = ConnectionFactory.primaryUsableConnection?.connection ?: return@flowPublish
val connection = getConnectionFactory().primaryFlow.first().conn?.connection ?: return@flowPublish
val allItems = loadItems(connection) ?: return@flowPublish
val factory = ItemControlFactory(this@ItemsControlsProviderService, allItems, true)
allItems.filterKeys { itemName -> itemName in itemNames }
Expand All @@ -93,8 +92,7 @@ class ItemsControlsProviderService : ControlsProviderService() {

override fun performControlAction(controlId: String, action: ControlAction, consumer: Consumer<Int>) {
GlobalScope.launch {
ConnectionFactory.waitForInitialization()
val connection = ConnectionFactory.primaryUsableConnection?.connection
val connection = getConnectionFactory().primaryFlow.first().conn?.connection
consumer.accept(performItemControl(connection, controlId, action))
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,16 @@ import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.os.Build
import android.service.notification.StatusBarNotification
import android.util.Log
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.core.content.ContextCompat
import kotlinx.coroutines.flow.first
import org.openhab.habdroid.R
import org.openhab.habdroid.background.NotificationUpdateObserver
import org.openhab.habdroid.core.connection.ConnectionFactory
import org.openhab.habdroid.core.connection.Connection
import org.openhab.habdroid.model.CloudMessage
import org.openhab.habdroid.model.CloudNotificationId
import org.openhab.habdroid.model.IconResource
Expand All @@ -39,6 +39,7 @@ import org.openhab.habdroid.util.IconBackground
import org.openhab.habdroid.util.ImageConversionPolicy
import org.openhab.habdroid.util.PendingIntent_Immutable
import org.openhab.habdroid.util.determineDataUsagePolicy
import org.openhab.habdroid.util.getConnectionFactory
import org.openhab.habdroid.util.getIconFallbackColor
import org.openhab.habdroid.util.getNotificationTone
import org.openhab.habdroid.util.getNotificationVibrationPattern
Expand Down Expand Up @@ -145,7 +146,8 @@ class NotificationHelper(private val context: Context) {
active.count { n -> n.id != 0 && (n.groupKey?.endsWith("gcm") == true) }

private suspend fun makeNotification(message: CloudMessage.CloudNotification): Notification {
val iconBitmap = getNotificationIcon(message.icon)
val connection = context.getConnectionFactory().primaryFlow.first().conn?.connection
val iconBitmap = getNotificationIcon(connection, message.icon)

val contentIntent = if (message.onClickAction == null) {
makeNotificationClickIntent(message.id, message.id.notificationId)
Expand Down Expand Up @@ -177,8 +179,7 @@ class NotificationHelper(private val context: Context) {
.setPublicVersion(publicVersion)

val messageImage = if (message.mediaAttachmentUrl != null) {
ConnectionFactory.waitForInitialization()
ConnectionFactory.primaryUsableConnection?.connection?.let {
connection?.let {
message.loadImage(it, context, context.resources.displayMetrics.widthPixels)
}
} else {
Expand All @@ -199,45 +200,41 @@ class NotificationHelper(private val context: Context) {
return builder.build()
}

private suspend fun getNotificationIcon(icon: IconResource?): Bitmap? {
val connection = ConnectionFactory.primaryCloudConnection?.connection
private suspend fun getNotificationIcon(connection: Connection?, icon: IconResource?) = when {
icon == null -> null

return when {
icon == null -> null
connection == null -> {
Log.d(TAG, "Got no connection to load icon")
null
}

connection == null -> {
Log.d(TAG, "Got no connection to load icon")
null
}
!context.determineDataUsagePolicy(connection).canDoLargeTransfers -> {
Log.d(TAG, "Don't load icon: Data usage policy doesn't allow large transfers")
null
}

!context.determineDataUsagePolicy(connection).canDoLargeTransfers -> {
Log.d(TAG, "Don't load icon: Data usage policy doesn't allow large transfers")
else -> {
Log.d(TAG, "Load icon from server")
try {
val targetSize = context.resources.getDimensionPixelSize(R.dimen.notificationlist_icon_size)
val iconUrlPath = icon.toUrl(context, true)
val bitmap = connection.httpClient
.get(
iconUrlPath,
timeoutMillis = 1000,
caching = HttpClient.CachingMode.FORCE_CACHE_IF_POSSIBLE
)
.asBitmap(
targetSize,
context.getIconFallbackColor(IconBackground.OS_THEME),
ImageConversionPolicy.PreferTargetSize
)
.response
bitmap
} catch (e: HttpClient.HttpException) {
Log.e(TAG, "Error getting icon", e)
null
}

else -> {
Log.d(TAG, "Load icon from server")
try {
val targetSize = context.resources.getDimensionPixelSize(R.dimen.notificationlist_icon_size)
val iconUrlPath = icon.toUrl(context, true)
val bitmap = connection.httpClient
.get(
iconUrlPath,
timeoutMillis = 1000,
caching = HttpClient.CachingMode.FORCE_CACHE_IF_POSSIBLE
)
.asBitmap(
targetSize,
context.getIconFallbackColor(IconBackground.OS_THEME),
ImageConversionPolicy.PreferTargetSize
)
.response
bitmap
} catch (e: HttpClient.HttpException) {
Log.e(TAG, "Error getting icon", e)
null
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import org.openhab.habdroid.BuildConfig
import org.openhab.habdroid.R
import org.openhab.habdroid.background.BackgroundTasksManager
import org.openhab.habdroid.core.connection.ConnectionFactory
import org.openhab.habdroid.core.connection.ConnectionManagerHelper
import org.openhab.habdroid.util.CrashReportingHelper
import org.openhab.habdroid.util.getDayNightMode
import org.openhab.habdroid.util.getPrefs
Expand All @@ -61,6 +62,10 @@ class OpenHabApplication : MultiDexApplication() {
}
}

val connectionFactory: ConnectionFactory by lazy {
ConnectionFactory(this, getPrefs(), secretPrefs, ConnectionManagerHelper.create(this))
}

var systemDataSaverStatus: Int = ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED
private set
var batterySaverActive: Boolean = false
Expand Down Expand Up @@ -93,8 +98,8 @@ class OpenHabApplication : MultiDexApplication() {

CrashReportingHelper.initialize(this)
AppCompatDelegate.setDefaultNightMode(getPrefs().getDayNightMode(this))
ConnectionFactory.initialize(this)
BackgroundTasksManager.initialize(this)
connectionFactory.start()

dataSaverChangeListener.let { listener ->
registerExportedReceiver(
Expand Down Expand Up @@ -165,7 +170,7 @@ class OpenHabApplication : MultiDexApplication() {

override fun onTerminate() {
super.onTerminate()
ConnectionFactory.shutdown()
connectionFactory.shutdown()
}

fun registerSystemDataSaverStateChangedListener(l: OnDataUsagePolicyChangedListener) {
Expand Down
Loading