Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Andriod DeviceManager.kt cleanup #1462

Merged
merged 3 commits into from
Feb 2, 2025
Merged
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
181 changes: 111 additions & 70 deletions android/app/src/main/java/com/audiobookshelf/app/device/DeviceManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,74 +12,92 @@ import com.audiobookshelf.app.managers.DbManager
import com.audiobookshelf.app.player.PlayerNotificationService
import com.audiobookshelf.app.updateAppWidget

/** Interface for widget event handling. */
interface WidgetEventEmitter {
fun onPlayerChanged(pns:PlayerNotificationService)
/**
* Called when the player state changes.
* @param pns The PlayerNotificationService instance.
*/
fun onPlayerChanged(pns: PlayerNotificationService)

/** Called when the player is closed. */
fun onPlayerClosed()
}

/** Singleton object for managing device-related operations. */
object DeviceManager {
const val tag = "DeviceManager"

val dbManager: DbManager = DbManager()
var deviceData: DeviceData = dbManager.getDeviceData()
var serverConnectionConfig: ServerConnectionConfig? = null

val serverConnectionConfigId get() = serverConnectionConfig?.id ?: ""
val serverAddress get() = serverConnectionConfig?.address ?: ""
val serverUserId get() = serverConnectionConfig?.userId ?: ""
val token get() = serverConnectionConfig?.token ?: ""
val isConnectedToServer get() = serverConnectionConfig != null
val serverConnectionConfigId
get() = serverConnectionConfig?.id ?: ""
val serverAddress
get() = serverConnectionConfig?.address ?: ""
val serverUserId
get() = serverConnectionConfig?.userId ?: ""
val token
get() = serverConnectionConfig?.token ?: ""
val isConnectedToServer
get() = serverConnectionConfig != null

var widgetUpdater:WidgetEventEmitter? = null
var widgetUpdater: WidgetEventEmitter? = null

init {
Log.d(tag, "Device Manager Singleton invoked")

// Initialize new sleep timer settings and shake sensitivity added in v0.9.61
if (deviceData.deviceSettings?.autoSleepTimerStartTime == null || deviceData.deviceSettings?.autoSleepTimerEndTime == null) {
deviceData.deviceSettings?.autoSleepTimerStartTime = "22:00"
deviceData.deviceSettings?.autoSleepTimerStartTime = "06:00"
deviceData.deviceSettings?.sleepTimerLength = 900000L
}
if (deviceData.deviceSettings?.shakeSensitivity == null) {
deviceData.deviceSettings?.shakeSensitivity = ShakeSensitivitySetting.MEDIUM
}
// Initialize auto sleep timer auto rewind added in v0.9.64
if (deviceData.deviceSettings?.autoSleepTimerAutoRewindTime == null) {
deviceData.deviceSettings?.autoSleepTimerAutoRewindTime = 300000L // 5 minutes
}

// Language added in v0.9.69
if (deviceData.deviceSettings?.languageCode == null) {
deviceData.deviceSettings?.languageCode = "en-us"
}

if (deviceData.deviceSettings?.downloadUsingCellular == null) {
deviceData.deviceSettings?.downloadUsingCellular = DownloadUsingCellularSetting.ALWAYS
}

if (deviceData.deviceSettings?.streamingUsingCellular == null) {
deviceData.deviceSettings?.streamingUsingCellular = StreamingUsingCellularSetting.ALWAYS
}
if (deviceData.deviceSettings?.androidAutoBrowseLimitForGrouping == null) {
deviceData.deviceSettings?.androidAutoBrowseLimitForGrouping = 100
}
if (deviceData.deviceSettings?.androidAutoBrowseSeriesSequenceOrder == null) {
deviceData.deviceSettings?.androidAutoBrowseSeriesSequenceOrder = AndroidAutoBrowseSeriesSequenceOrderSetting.ASC
// Default settings if they have not been set yet. Removes Elvis operator for null safety due to
// variables being non-nullable.
deviceData.deviceSettings?.apply {
// Sleep timer settings, added v0.9.61
autoSleepTimerStartTime = "22:00"
autoSleepTimerEndTime = "06:00"
sleepTimerLength = 900000L
shakeSensitivity = ShakeSensitivitySetting.MEDIUM
// Auto sleep timer auto rewind, added v0.9.64
autoSleepTimerAutoRewindTime = 300000L // 5 minutes
// Langugage code, added v0.9.69
languageCode = "en-us"
// Download and streaming using cellular, added v0.9.75
downloadUsingCellular = DownloadUsingCellularSetting.ALWAYS
streamingUsingCellular = StreamingUsingCellularSetting.ALWAYS
// Android Auto settings, added v0.9.78
androidAutoBrowseLimitForGrouping = 100
androidAutoBrowseSeriesSequenceOrder = AndroidAutoBrowseSeriesSequenceOrderSetting.ASC
}
}

fun getBase64Id(id:String):String {
return android.util.Base64.encodeToString(id.toByteArray(), android.util.Base64.URL_SAFE or android.util.Base64.NO_WRAP)
/**
* Encodes the given ID to a Base64 string.
* @param id The ID to encode.
* @return The Base64 encoded string.
*/
fun getBase64Id(id: String): String {
return android.util.Base64.encodeToString(
id.toByteArray(),
android.util.Base64.URL_SAFE or android.util.Base64.NO_WRAP
)
}

fun getServerConnectionConfig(id:String?):ServerConnectionConfig? {
if (id == null) return null
return deviceData.serverConnectionConfigs.find { it.id == id }
/**
* Retrieves the server connection configuration for the given ID.
* @param id The ID of the server connection configuration.
* @return The ServerConnectionConfig instance or null if not found.
*/
fun getServerConnectionConfig(id: String?): ServerConnectionConfig? {
return id?.let { deviceData.serverConnectionConfigs.find { it.id == id } }
}

fun checkConnectivity(ctx:Context): Boolean {
val connectivityManager = ctx.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
/**
* Checks the network connectivity status.
* @param ctx The context to use for checking connectivity.
* @return True if connected to the internet, false otherwise.
*/
fun checkConnectivity(ctx: Context): Boolean {
val connectivityManager =
ctx.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val capabilities = connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)
if (capabilities != null) {
if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
Expand All @@ -96,35 +114,58 @@ object DeviceManager {
return false
}

fun setLastPlaybackSession(playbackSession:PlaybackSession) {
/**
* Sets the last playback session.
* @param playbackSession The playback session to set.
*/
fun setLastPlaybackSession(playbackSession: PlaybackSession) {
deviceData.lastPlaybackSession = playbackSession
dbManager.saveDeviceData(deviceData)
}

fun initializeWidgetUpdater(context:Context) {
/**
* Initializes the widget updater.
* @param context The context to use for initializing the widget updater.
*/
fun initializeWidgetUpdater(context: Context) {
Log.d(tag, "Initializing widget updater")
widgetUpdater = (object : WidgetEventEmitter {
override fun onPlayerChanged(pns: PlayerNotificationService) {

val isPlaying = pns.currentPlayer.isPlaying

val appWidgetManager = AppWidgetManager.getInstance(context)
val componentName = ComponentName(context, MediaPlayerWidget::class.java)
val ids = appWidgetManager.getAppWidgetIds(componentName)
val playbackSession = pns.getCurrentPlaybackSessionCopy()

for (widgetId in ids) {
updateAppWidget(context, appWidgetManager, widgetId, playbackSession, isPlaying, PlayerNotificationService.isClosed)
}
}
override fun onPlayerClosed() {
val appWidgetManager = AppWidgetManager.getInstance(context)
val componentName = ComponentName(context, MediaPlayerWidget::class.java)
val ids = appWidgetManager.getAppWidgetIds(componentName)
for (widgetId in ids) {
updateAppWidget(context, appWidgetManager, widgetId, deviceData.lastPlaybackSession, false, PlayerNotificationService.isClosed)
}
}
})
widgetUpdater =
(object : WidgetEventEmitter {
override fun onPlayerChanged(pns: PlayerNotificationService) {
val isPlaying = pns.currentPlayer.isPlaying

val appWidgetManager = AppWidgetManager.getInstance(context)
val componentName = ComponentName(context, MediaPlayerWidget::class.java)
val ids = appWidgetManager.getAppWidgetIds(componentName)
val playbackSession = pns.getCurrentPlaybackSessionCopy()

for (widgetId in ids) {
updateAppWidget(
context,
appWidgetManager,
widgetId,
playbackSession,
isPlaying,
PlayerNotificationService.isClosed
)
}
}

override fun onPlayerClosed() {
val appWidgetManager = AppWidgetManager.getInstance(context)
val componentName = ComponentName(context, MediaPlayerWidget::class.java)
val ids = appWidgetManager.getAppWidgetIds(componentName)
for (widgetId in ids) {
updateAppWidget(
context,
appWidgetManager,
widgetId,
deviceData.lastPlaybackSession,
false,
PlayerNotificationService.isClosed
)
}
}
})
}
}