Skip to content

Commit

Permalink
Refactor preferences into a new core_preferences proto file (#122)
Browse files Browse the repository at this point in the history
  • Loading branch information
jkuester authored Sep 4, 2022
1 parent b42ec63 commit 8afcc8d
Show file tree
Hide file tree
Showing 17 changed files with 321 additions and 194 deletions.
84 changes: 6 additions & 78 deletions app/src/main/java/com/sduduzog/slimlauncher/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,46 +1,37 @@
package com.sduduzog.slimlauncher

import android.annotation.SuppressLint
import android.app.WallpaperManager
import android.content.SharedPreferences
import android.content.res.Resources
import android.graphics.Bitmap
import android.graphics.Canvas
import android.os.Bundle
import android.util.Log
import android.view.GestureDetector
import android.view.GestureDetector.SimpleOnGestureListener
import android.view.MotionEvent
import android.view.View
import androidx.annotation.ColorInt
import androidx.annotation.StyleRes
import androidx.annotation.WorkerThread
import androidx.appcompat.app.AppCompatActivity
import androidx.constraintlayout.motion.widget.MotionLayout
import androidx.lifecycle.lifecycleScope
import androidx.navigation.NavController
import androidx.navigation.Navigation.findNavController
import com.sduduzog.slimlauncher.datasource.UnlauncherDataSource
import com.sduduzog.slimlauncher.di.MainFragmentFactoryEntryPoint
import com.sduduzog.slimlauncher.utils.*
import dagger.hilt.android.AndroidEntryPoint
import dagger.hilt.android.EntryPointAccessors
import kotlin.math.absoluteValue
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.IOException
import java.lang.reflect.Method
import kotlin.math.absoluteValue


@AndroidEntryPoint
class MainActivity : AppCompatActivity(),
SharedPreferences.OnSharedPreferenceChangeListener,
HomeWatcher.OnHomePressedListener, IPublisher {

private val wallpaperManager = WallpaperManager(this)

private lateinit var settings: SharedPreferences
private lateinit var navigator: NavController
private lateinit var homeWatcher: HomeWatcher
private lateinit var unlauncherDataSource: UnlauncherDataSource

private val subscribers: MutableSet<BaseFragment> = mutableSetOf()

Expand Down Expand Up @@ -115,70 +106,15 @@ class MainActivity : AppCompatActivity(),

override fun onApplyThemeResource(theme: Resources.Theme?, @StyleRes resid: Int, first: Boolean) {
super.onApplyThemeResource(theme, resid, first)
getUnlaucherDataSource().unlauncherAppsRepo.liveData().observe(this, {
if (!it.setThemeWallpaper && getUserSelectedThemeRes() == resid) {
// only change the wallpaper when user has allowed it and
// preventing to change the wallpaper multiple times once it is rechecked in the settings
return@observe
}
@ColorInt val backgroundColor = getThemeBackgroundColor(theme, resid)
if (backgroundColor == Int.MIN_VALUE) {
return@observe
}
lifecycleScope.launch(Dispatchers.IO) {
setWallpaperBackgroundColor(backgroundColor)
}
})
}

/**
* @return `Int.MIN_VALUE` if `android.R.attr.colorBackground` of `theme` could not be obtained.
*/
@ColorInt
private fun getThemeBackgroundColor(theme: Resources.Theme?, @StyleRes themeRes: Int): Int {
val array = theme?.obtainStyledAttributes(themeRes, intArrayOf(android.R.attr.colorBackground))
try {
return array?.getColor(0, Int.MIN_VALUE) ?: Int.MIN_VALUE
} finally {
array?.recycle()
}
}

@Throws(IOException::class)
@WorkerThread
private fun setWallpaperBackgroundColor(@ColorInt color: Int) {
val wallpaperManager = WallpaperManager.getInstance(applicationContext)
var width = wallpaperManager.desiredMinimumWidth
if (width <= 0) {
width = getScreenWidth(this)
}
var height = wallpaperManager.desiredMinimumHeight
if (height <= 0) {
height = getScreenHeight(this)
}
val wallpaperBitmap = createColoredWallpaperBitmap(color, width, height)
wallpaperManager.setBitmap(wallpaperBitmap)
}

private fun createColoredWallpaperBitmap(@ColorInt color: Int, width: Int, height: Int): Bitmap {
val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
canvas.drawColor(color)
return bitmap
wallpaperManager.onApplyThemeResource(theme, resid)
}

override fun setTheme(resId: Int) {
val userThemeId = getUserSelectedThemeRes()
val id = if (resId != userThemeId) {
userThemeId
} else {
resId
}
super.setTheme(id)
super.setTheme(getUserSelectedThemeRes())
}

@StyleRes
private fun getUserSelectedThemeRes(): Int {
fun getUserSelectedThemeRes(): Int {
settings = getSharedPreferences(getString(R.string.prefs_settings), MODE_PRIVATE)
val active = settings.getInt(getString(R.string.prefs_settings_key_theme), 0)
return resolveTheme(active)
Expand Down Expand Up @@ -211,15 +147,7 @@ class MainActivity : AppCompatActivity(),
}
}

private fun getUnlaucherDataSource(): UnlauncherDataSource {
if (!::unlauncherDataSource.isInitialized) {
unlauncherDataSource = UnlauncherDataSource(this, lifecycleScope)
}
return unlauncherDataSource
}

companion object {

@StyleRes
fun resolveTheme(i: Int): Int {
return when (i) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
package com.sduduzog.slimlauncher.datasource

import android.content.Context
import androidx.datastore.core.DataMigration
import androidx.datastore.core.DataStore
import androidx.datastore.dataStore
import androidx.datastore.migrations.SharedPreferencesMigration
import androidx.datastore.migrations.SharedPreferencesView
import androidx.lifecycle.LifecycleCoroutineScope
import com.jkuester.unlauncher.datastore.CorePreferences
import com.jkuester.unlauncher.datastore.QuickButtonPreferences
import com.jkuester.unlauncher.datastore.UnlauncherApps
import com.sduduzog.slimlauncher.datasource.apps.UnlauncherAppsMigrations
import com.sduduzog.slimlauncher.datasource.apps.UnlauncherAppsRepository
import com.sduduzog.slimlauncher.datasource.apps.UnlauncherAppsSerializer
import com.sduduzog.slimlauncher.datasource.coreprefs.CorePreferencesRepository
import com.sduduzog.slimlauncher.datasource.coreprefs.CorePreferencesSerializer
import com.sduduzog.slimlauncher.datasource.quickbuttonprefs.QuickButtonPreferencesRepository
import com.sduduzog.slimlauncher.datasource.quickbuttonprefs.QuickButtonPreferencesSerializer

Expand Down Expand Up @@ -66,8 +68,14 @@ private val Context.unlauncherAppsStore: DataStore<UnlauncherApps> by dataStore(
produceMigrations = { context -> UnlauncherAppsMigrations().get(context) }
)

private val Context.corePreferencesStore: DataStore<CorePreferences> by dataStore(
fileName = "core_preferences.proto",
serializer = CorePreferencesSerializer
)

class UnlauncherDataSource(context: Context, lifecycleScope: LifecycleCoroutineScope) {
val quickButtonPreferencesRepo =
QuickButtonPreferencesRepository(context.quickButtonPreferencesStore, lifecycleScope)
val unlauncherAppsRepo = UnlauncherAppsRepository(context.unlauncherAppsStore, lifecycleScope)
val corePreferencesRepo = CorePreferencesRepository(context.corePreferencesStore, lifecycleScope)
}
Original file line number Diff line number Diff line change
Expand Up @@ -139,14 +139,6 @@ class UnlauncherAppsRepository(
}
}

fun updateActivateKeyboardInDrawer(activateKeyboardInDrawer: Boolean) {
lifecycleScope.launch {
unlauncherAppsStore.updateData {
it.toBuilder().setActivateKeyboardInDrawer(activateKeyboardInDrawer).build()
}
}
}

private fun findApp(
unlauncherApps: List<UnlauncherApp>,
packageName: String,
Expand All @@ -156,14 +148,6 @@ class UnlauncherAppsRepository(
packageName == app.packageName && className == app.className
}
}

fun updateSetAutomaticDeviceWallpaper(setDeviceWallpaper: Boolean) {
lifecycleScope.launch {
unlauncherAppsStore.updateData {
it.toBuilder().setSetThemeWallpaper(setDeviceWallpaper).build()
}
}
}
}

fun sortAppsAlphabetically(unlauncherAppsBuilder: UnlauncherApps.Builder) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.sduduzog.slimlauncher.datasource.coreprefs

import android.util.Log
import androidx.datastore.core.DataStore
import androidx.lifecycle.LifecycleCoroutineScope
import androidx.lifecycle.LiveData
import androidx.lifecycle.asLiveData
import com.jkuester.unlauncher.datastore.CorePreferences
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import java.io.IOException

class CorePreferencesRepository(
private val corePreferencesStore: DataStore<CorePreferences>,
private val lifecycleScope: LifecycleCoroutineScope
) {
private val corereferencesFlow: Flow<CorePreferences> =
corePreferencesStore.data
.catch { exception ->
if (exception is IOException) {
Log.e(
"CorePrefRepo",
"Error reading core preferences.",
exception
)
emit(CorePreferences.getDefaultInstance())
} else {
throw exception
}
}

fun liveData(): LiveData<CorePreferences> {
return corereferencesFlow.asLiveData()
}

fun get(): CorePreferences {
return runBlocking {
corereferencesFlow.first()
}
}

fun updateActivateKeyboardInDrawer(activateKeyboardInDrawer: Boolean) {
lifecycleScope.launch {
corePreferencesStore.updateData {
it.toBuilder().setActivateKeyboardInDrawer(activateKeyboardInDrawer).build()
}
}
}

fun updateSetAutomaticDeviceWallpaper(setDeviceWallpaper: Boolean) {
lifecycleScope.launch {
corePreferencesStore.updateData {
it.toBuilder().setSetThemeWallpaper(setDeviceWallpaper).build()
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.sduduzog.slimlauncher.datasource.coreprefs

import androidx.datastore.core.CorruptionException
import androidx.datastore.core.Serializer
import com.google.protobuf.InvalidProtocolBufferException
import com.jkuester.unlauncher.datastore.CorePreferences
import java.io.InputStream
import java.io.OutputStream

/**
* Serializer for the [CorePreferences] object defined in core_preferences.proto.
*/
object CorePreferencesSerializer : Serializer<CorePreferences> {
override val defaultValue: CorePreferences = CorePreferences.getDefaultInstance()

@Suppress("BlockingMethodInNonBlockingContext")
override suspend fun readFrom(input: InputStream): CorePreferences {
try {
return CorePreferences.parseFrom(input)
} catch (exception: InvalidProtocolBufferException) {
throw CorruptionException("Cannot read proto.", exception)
}
}

@Suppress("BlockingMethodInNonBlockingContext")
override suspend fun writeTo(t: CorePreferences, output: OutputStream) =
t.writeTo(output)
}
27 changes: 27 additions & 0 deletions app/src/main/java/com/sduduzog/slimlauncher/di/ActivityModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.sduduzog.slimlauncher.di

import android.app.Activity
import androidx.core.app.ComponentActivity
import androidx.lifecycle.LifecycleCoroutineScope
import androidx.lifecycle.lifecycleScope
import com.sduduzog.slimlauncher.datasource.UnlauncherDataSource
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ActivityComponent
import dagger.hilt.android.scopes.ActivityScoped

@Module
@InstallIn(ActivityComponent::class)
class ActivityModule {
@Provides
fun provideLifecycleCoroutineScope(activity: Activity): LifecycleCoroutineScope =
(activity as ComponentActivity).lifecycleScope

@Provides
@ActivityScoped
fun providesUnlauncherDataSource(
activity: Activity,
lifecycleCoroutineScope: LifecycleCoroutineScope
) = UnlauncherDataSource(activity, lifecycleCoroutineScope)
}
Loading

0 comments on commit 8afcc8d

Please sign in to comment.