From 9d83619811cf0706e3a5dafc6a293a86d53263e1 Mon Sep 17 00:00:00 2001 From: OxygenCobalt Date: Sat, 13 Mar 2021 10:50:39 -0700 Subject: [PATCH] Unify system service calls Unify the calls to getSystemService to a custom function that uses the ContextCompat getSystemService instead of the clunky vanilla getSystemService code. --- .../auxio/playback/system/AudioReactor.kt | 6 ++---- .../playback/system/PlaybackNotification.kt | 13 ++++++------- .../auxio/playback/system/PlaybackService.kt | 5 +++-- .../java/org/oxycblt/auxio/ui/InterfaceUtils.kt | 16 +++++++++++++++- 4 files changed, 26 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/org/oxycblt/auxio/playback/system/AudioReactor.kt b/app/src/main/java/org/oxycblt/auxio/playback/system/AudioReactor.kt index 7565c7373..a512a9e19 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/system/AudioReactor.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/system/AudioReactor.kt @@ -4,12 +4,12 @@ import android.animation.ValueAnimator import android.content.Context import android.media.AudioManager import androidx.core.animation.addListener -import androidx.core.content.ContextCompat import androidx.media.AudioFocusRequestCompat import androidx.media.AudioManagerCompat import com.google.android.exoplayer2.SimpleExoPlayer import org.oxycblt.auxio.playback.state.PlaybackStateManager import org.oxycblt.auxio.settings.SettingsManager +import org.oxycblt.auxio.ui.getSystemServiceSafe /** * Object that manages the AudioFocus state. @@ -20,9 +20,7 @@ class AudioReactor( context: Context, private val player: SimpleExoPlayer ) : AudioManager.OnAudioFocusChangeListener { - private val audioManager = ContextCompat.getSystemService( - context, AudioManager::class.java - ) ?: error("Cannot obtain AudioManager.") + private val audioManager = context.getSystemServiceSafe(AudioManager::class) private val settingsManager = SettingsManager.getInstance() private val playbackManager = PlaybackStateManager.getInstance() diff --git a/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackNotification.kt b/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackNotification.kt index f8f245bce..cbb0f3763 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackNotification.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackNotification.kt @@ -182,15 +182,14 @@ class PlaybackNotification private constructor( const val ACTION_EXIT = "ACTION_AUXIO_EXIT_" + BuildConfig.BUILD_TYPE /** - * Build a new instance of [PlaybackNotification] from a [context] and [mediaSession] + * Build a new instance of [PlaybackNotification]. */ - fun from(context: Context, mediaSession: MediaSessionCompat): PlaybackNotification { + fun from( + context: Context, + notificationManager: NotificationManager, + mediaSession: MediaSessionCompat + ): PlaybackNotification { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - // Create the notification channel if required. - val notificationManager = context.getSystemService( - Context.NOTIFICATION_SERVICE - ) as NotificationManager - val channel = NotificationChannel( CHANNEL_ID, context.getString(R.string.info_channel_name), NotificationManager.IMPORTANCE_DEFAULT diff --git a/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackService.kt b/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackService.kt index d2fa007d1..1c389968f 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackService.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackService.kt @@ -43,6 +43,7 @@ import org.oxycblt.auxio.music.toURI import org.oxycblt.auxio.playback.state.LoopMode import org.oxycblt.auxio.playback.state.PlaybackStateManager import org.oxycblt.auxio.settings.SettingsManager +import org.oxycblt.auxio.ui.getSystemServiceSafe /** * A service that manages the system-side aspects of playback, such as: @@ -135,8 +136,8 @@ class PlaybackService : Service(), Player.EventListener, PlaybackStateManager.Ca // --- NOTIFICATION SETUP --- - notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager - notification = PlaybackNotification.from(this, mediaSession) + notificationManager = getSystemServiceSafe(NotificationManager::class) + notification = PlaybackNotification.from(this, notificationManager, mediaSession) // --- PLAYBACKSTATEMANAGER SETUP --- diff --git a/app/src/main/java/org/oxycblt/auxio/ui/InterfaceUtils.kt b/app/src/main/java/org/oxycblt/auxio/ui/InterfaceUtils.kt index 78dbb784a..368b3f8ed 100644 --- a/app/src/main/java/org/oxycblt/auxio/ui/InterfaceUtils.kt +++ b/app/src/main/java/org/oxycblt/auxio/ui/InterfaceUtils.kt @@ -27,6 +27,7 @@ import com.reddit.indicatorfastscroll.FastScrollItemIndicator import com.reddit.indicatorfastscroll.FastScrollerView import org.oxycblt.auxio.R import org.oxycblt.auxio.logE +import kotlin.reflect.KClass // --- VIEW CONFIGURATION --- @@ -79,6 +80,19 @@ fun Context.getPlural(@PluralsRes pluralsRes: Int, value: Int): String { return resources.getQuantityString(pluralsRes, value, value) } +/** + * Convenience method for getting a system service without nullability issues. + * @param T The system service in question. + * @param serviceClass The service's kotlin class [Java class will be used in function call] + * @return The system service + * @throws IllegalStateException If the system service cannot be retrieved. + */ +fun Context.getSystemServiceSafe(serviceClass: KClass): T { + return checkNotNull(ContextCompat.getSystemService(this, serviceClass.java)) { + "System service ${serviceClass.simpleName} could not be instantiated" + } +} + /** * Resolve a color. * @param context [Context] required @@ -221,7 +235,7 @@ private fun isSystemBarOnBottom(activity: Activity): Boolean { } } } else { - (activity.getSystemService(Context.WINDOW_SERVICE) as WindowManager).apply { + (activity.getSystemServiceSafe(WindowManager::class)).apply { defaultDisplay.getRealSize(realPoint) defaultDisplay.getMetrics(metrics)