Skip to content

Commit

Permalink
Fixes mozilla-mobile#26245: refactor the WallpaperManager as several …
Browse files Browse the repository at this point in the history
…WallpaperUseCases
  • Loading branch information
MatthewTighe committed Aug 10, 2022
1 parent b3fa1b0 commit 99600c5
Show file tree
Hide file tree
Showing 16 changed files with 605 additions and 449 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import org.mozilla.fenix.helpers.HomeActivityTestRule
*
* Say no to main thread IO! 🙅
*/
private const val EXPECTED_SUPPRESSION_COUNT = 19
private const val EXPECTED_SUPPRESSION_COUNT = 18

/**
* The number of times we call the `runBlocking` coroutine method on the main thread during this
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/org/mozilla/fenix/FenixApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -843,7 +843,7 @@ open class FenixApplication : LocaleAwareApplication(), Provider {
@OptIn(DelicateCoroutinesApi::class)
open fun downloadWallpapers() {
GlobalScope.launch {
components.wallpaperManager.downloadAllRemoteWallpapers()
components.useCases.wallpaperUseCases.initialize()
}
}
}
16 changes: 5 additions & 11 deletions app/src/main/java/org/mozilla/fenix/components/Components.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import mozilla.components.feature.addons.update.DefaultAddonUpdater
import mozilla.components.feature.autofill.AutofillConfiguration
import mozilla.components.lib.publicsuffixlist.PublicSuffixList
import mozilla.components.support.base.worker.Frequency
import mozilla.components.support.locale.LocaleManager
import org.mozilla.fenix.BuildConfig
import org.mozilla.fenix.Config
import org.mozilla.fenix.HomeActivity
Expand All @@ -45,8 +44,6 @@ import org.mozilla.fenix.perf.StrictModeManager
import org.mozilla.fenix.perf.lazyMonitored
import org.mozilla.fenix.utils.ClipboardHandler
import org.mozilla.fenix.utils.Settings
import org.mozilla.fenix.wallpapers.WallpaperDownloader
import org.mozilla.fenix.wallpapers.WallpaperFileManager
import org.mozilla.fenix.wallpapers.WallpaperManager
import org.mozilla.fenix.wifi.WifiConnectionMonitor
import java.util.concurrent.TimeUnit
Expand Down Expand Up @@ -85,7 +82,10 @@ class Components(private val context: Context) {
core.webAppShortcutManager,
core.topSitesStorage,
core.bookmarksStorage,
core.historyStorage
core.historyStorage,
appStore,
core.client,
strictMode,
)
}

Expand Down Expand Up @@ -161,17 +161,11 @@ class Components(private val context: Context) {
val strictMode by lazyMonitored { StrictModeManager(Config, this) }

val wallpaperManager by lazyMonitored {
val currentLocale = strictMode.resetAfter(StrictMode.allowThreadDiskReads()) {
LocaleManager.getCurrentLocale(context)?.toLanguageTag()
?: LocaleManager.getSystemDefault().toLanguageTag()
}
strictMode.resetAfter(StrictMode.allowThreadDiskReads()) {
WallpaperManager(
settings,
appStore,
WallpaperDownloader(context, core.client),
WallpaperFileManager(context.filesDir),
currentLocale
useCases.wallpaperUseCases.selectWallpaper,
)
}
}
Expand Down
12 changes: 11 additions & 1 deletion app/src/main/java/org/mozilla/fenix/components/UseCases.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package org.mozilla.fenix.components
import android.content.Context
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.concept.engine.Engine
import mozilla.components.concept.fetch.Client
import mozilla.components.concept.storage.BookmarksStorage
import mozilla.components.concept.storage.HistoryStorage
import mozilla.components.feature.app.links.AppLinksUseCases
Expand All @@ -24,7 +25,9 @@ import mozilla.components.feature.top.sites.TopSitesStorage
import mozilla.components.feature.top.sites.TopSitesUseCases
import mozilla.components.support.locale.LocaleUseCases
import org.mozilla.fenix.components.bookmarks.BookmarksUseCase
import org.mozilla.fenix.perf.StrictModeManager
import org.mozilla.fenix.perf.lazyMonitored
import org.mozilla.fenix.wallpapers.WallpapersUseCases

/**
* Component group for all use cases. Use cases are provided by feature
Expand All @@ -38,7 +41,10 @@ class UseCases(
private val shortcutManager: WebAppShortcutManager,
private val topSitesStorage: TopSitesStorage,
private val bookmarksStorage: BookmarksStorage,
private val historyStorage: HistoryStorage
private val historyStorage: HistoryStorage,
appStore: AppStore,
client: Client,
strictMode: StrictModeManager,
) {
/**
* Use cases that provide engine interactions for a given browser session.
Expand Down Expand Up @@ -99,4 +105,8 @@ class UseCases(
* Use cases that provide bookmark management.
*/
val bookmarksUseCases by lazyMonitored { BookmarksUseCase(bookmarksStorage, historyStorage) }

val wallpaperUseCases by lazyMonitored {
WallpapersUseCases(context, appStore, client, strictMode)
}
}
48 changes: 48 additions & 0 deletions app/src/main/java/org/mozilla/fenix/ext/Bitmap.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.mozilla.fenix.ext

import android.graphics.Bitmap
import android.graphics.Matrix
import android.view.View
import android.widget.ImageView

/**
* This will scale the received [Bitmap] to the size of the [view]. It retains the bitmap's
* original aspect ratio, but will shrink or enlarge it to fit the viewport. If bitmap does not
* correctly fit the aspect ratio of the view, it will be shifted to prioritize the bottom-left
* of the bitmap.
*/
fun Bitmap.scaleToBottomOfView(view: ImageView) {
val bitmap = this
view.setImageBitmap(bitmap)
view.scaleType = ImageView.ScaleType.MATRIX
val matrix = Matrix()
view.addOnLayoutChangeListener(object : View.OnLayoutChangeListener {
override fun onLayoutChange(
v: View?,
left: Int,
top: Int,
right: Int,
bottom: Int,
oldLeft: Int,
oldTop: Int,
oldRight: Int,
oldBottom: Int
) {
val viewWidth: Float = view.width.toFloat()
val viewHeight: Float = view.height.toFloat()
val bitmapWidth = bitmap.width
val bitmapHeight = bitmap.height
val widthScale = viewWidth / bitmapWidth
val heightScale = viewHeight / bitmapHeight
val scale = widthScale.coerceAtLeast(heightScale)
matrix.postScale(scale, scale)
// The image is translated to its bottom such that any pertinent information is
// guaranteed to be shown.
// Majority of this math borrowed from // https://medium.com/@tokudu/how-to-whitelist-strictmode-violations-on-android-based-on-stacktrace-eb0018e909aa
// except that there is no need to translate horizontally in our case.
matrix.postTranslate(0f, (viewHeight - bitmapHeight * scale))
view.imageMatrix = matrix
view.removeOnLayoutChangeListener(this)
}
})
}
9 changes: 5 additions & 4 deletions app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ import org.mozilla.fenix.ext.hideToolbar
import org.mozilla.fenix.ext.nav
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.runIfFragmentIsAttached
import org.mozilla.fenix.ext.scaleToBottomOfView
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.gleanplumb.DefaultMessageController
import org.mozilla.fenix.gleanplumb.MessagingFeature
Expand Down Expand Up @@ -968,11 +969,11 @@ class HomeFragment : Fragment() {
binding.wallpaperImageView.visibility = View.GONE
}
else -> {
with(requireComponents.wallpaperManager) {
val bitmap = currentWallpaper.load(requireContext()) ?: return@onEach
bitmap.scaleBitmapToBottomOfView(binding.wallpaperImageView)
val bitmap = requireComponents.useCases.wallpaperUseCases.loadBitmap(currentWallpaper)
bitmap?.let {
it.scaleToBottomOfView(binding.wallpaperImageView)
binding.wallpaperImageView.visibility = View.VISIBLE
}
binding.wallpaperImageView.visibility = View.VISIBLE
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import androidx.compose.material.SwitchDefaults
import androidx.compose.material.Text
import androidx.compose.material.rememberScaffoldState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
Expand All @@ -43,7 +43,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
Expand All @@ -53,11 +52,9 @@ import androidx.compose.ui.unit.sp
import kotlinx.coroutines.launch
import org.mozilla.fenix.R
import org.mozilla.fenix.compose.button.TextButton
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.theme.FirefoxTheme
import org.mozilla.fenix.theme.Theme
import org.mozilla.fenix.wallpapers.Wallpaper
import org.mozilla.fenix.wallpapers.WallpaperManager

/**
* The screen for controlling settings around Wallpapers. When a new wallpaper is selected,
Expand All @@ -77,7 +74,7 @@ import org.mozilla.fenix.wallpapers.WallpaperManager
fun WallpaperSettings(
wallpapers: List<Wallpaper>,
defaultWallpaper: Wallpaper,
loadWallpaperResource: (Wallpaper) -> Bitmap?,
loadWallpaperResource: suspend (Wallpaper) -> Bitmap?,
selectedWallpaper: Wallpaper,
onSelectWallpaper: (Wallpaper) -> Unit,
onViewWallpaper: () -> Unit,
Expand Down Expand Up @@ -164,7 +161,7 @@ private fun WallpaperSnackbar(
private fun WallpaperThumbnails(
wallpapers: List<Wallpaper>,
defaultWallpaper: Wallpaper,
loadWallpaperResource: (Wallpaper) -> Bitmap?,
loadWallpaperResource: suspend (Wallpaper) -> Bitmap?,
selectedWallpaper: Wallpaper,
numColumns: Int = 3,
onSelectWallpaper: (Wallpaper) -> Unit,
Expand Down Expand Up @@ -211,14 +208,14 @@ private fun WallpaperThumbnails(
private fun WallpaperThumbnailItem(
wallpaper: Wallpaper,
defaultWallpaper: Wallpaper,
loadWallpaperResource: (Wallpaper) -> Bitmap?,
loadWallpaperResource: suspend (Wallpaper) -> Bitmap?,
isSelected: Boolean,
aspectRatio: Float = 1.1f,
onSelect: (Wallpaper) -> Unit
) {
var bitmap by remember { mutableStateOf(loadWallpaperResource(wallpaper)) }
DisposableEffect(LocalConfiguration.current.orientation) {
onDispose { bitmap = loadWallpaperResource(wallpaper) }
var bitmap: Bitmap? by remember { mutableStateOf(null) }
LaunchedEffect(LocalConfiguration.current.orientation) {
bitmap = loadWallpaperResource(wallpaper)
}
val thumbnailShape = RoundedCornerShape(8.dp)
val border = if (isSelected) {
Expand Down Expand Up @@ -292,16 +289,12 @@ private fun WallpaperLogoSwitch(
@Composable
private fun WallpaperThumbnailsPreview() {
FirefoxTheme(theme = Theme.getTheme()) {
val context = LocalContext.current
val wallpaperManager = context.components.wallpaperManager

WallpaperSettings(
defaultWallpaper = WallpaperManager.defaultWallpaper,
loadWallpaperResource = { wallpaper ->
with(wallpaperManager) { wallpaper.load(context) }
},
wallpapers = wallpaperManager.wallpapers,
selectedWallpaper = wallpaperManager.currentWallpaper,
defaultWallpaper = Wallpaper.Default,
loadWallpaperResource = { null },
wallpapers = listOf(Wallpaper.Default),
selectedWallpaper = Wallpaper.Default,
onSelectWallpaper = {},
onViewWallpaper = {},
tapLogoSwitchChecked = false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,22 @@ import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import mozilla.components.lib.state.ext.observeAsComposableState
import mozilla.components.service.glean.private.NoExtras
import org.mozilla.fenix.GleanMetrics.Wallpapers
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.showToolbar
import org.mozilla.fenix.theme.FirefoxTheme
import org.mozilla.fenix.wallpapers.Wallpaper
import org.mozilla.fenix.wallpapers.WallpaperManager

class WallpaperSettingsFragment : Fragment() {
private val wallpaperManager by lazy {
requireComponents.wallpaperManager
private val appStore by lazy {
requireComponents.appStore
}

private val wallpaperUseCases by lazy {
requireComponents.useCases.wallpaperUseCases
}

private val settings by lazy {
Expand All @@ -44,25 +48,20 @@ class WallpaperSettingsFragment : Fragment() {
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
setContent {
FirefoxTheme {
var currentWallpaper by remember { mutableStateOf(wallpaperManager.currentWallpaper) }
val wallpapers = appStore.observeAsComposableState { state ->
state.wallpaperState.availableWallpapers
}.value ?: listOf()
val currentWallpaper = appStore.observeAsComposableState { state ->
state.wallpaperState.currentWallpaper
}.value ?: Wallpaper.Default
var wallpapersSwitchedByLogo by remember { mutableStateOf(settings.wallpapersSwitchedByLogoTap) }

WallpaperSettings(
wallpapers = wallpaperManager.wallpapers,
defaultWallpaper = WallpaperManager.defaultWallpaper,
loadWallpaperResource = { wallpaper ->
with(wallpaperManager) { wallpaper.load(context) }
},
wallpapers = wallpapers,
defaultWallpaper = Wallpaper.Default,
loadWallpaperResource = { wallpaperUseCases.loadBitmap(it) },
selectedWallpaper = currentWallpaper,
onSelectWallpaper = { selectedWallpaper: Wallpaper ->
currentWallpaper = selectedWallpaper
wallpaperManager.currentWallpaper = selectedWallpaper
Wallpapers.wallpaperSelected.record(
Wallpapers.WallpaperSelectedExtra(
name = selectedWallpaper.name,
themeCollection = selectedWallpaper::class.simpleName
)
)
},
onSelectWallpaper = { wallpaperUseCases.selectWallpaper(it) },
onViewWallpaper = { findNavController().navigate(R.id.homeFragment) },
tapLogoSwitchChecked = wallpapersSwitchedByLogo,
onTapLogoSwitchCheckedChange = {
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/java/org/mozilla/fenix/utils/Settings.kt
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ import org.mozilla.fenix.settings.logins.SortingStrategy
import org.mozilla.fenix.settings.registerOnSharedPreferenceChangeListener
import org.mozilla.fenix.settings.sitepermissions.AUTOPLAY_BLOCK_ALL
import org.mozilla.fenix.settings.sitepermissions.AUTOPLAY_BLOCK_AUDIBLE
import org.mozilla.fenix.wallpapers.WallpaperManager
import org.mozilla.fenix.wallpapers.Wallpaper
import java.security.InvalidParameterException
import java.util.UUID

Expand Down Expand Up @@ -187,7 +187,7 @@ class Settings(private val appContext: Context) : PreferencesHolder {

var currentWallpaper by stringPreference(
appContext.getPreferenceKey(R.string.pref_key_current_wallpaper),
default = WallpaperManager.defaultWallpaper.name
default = Wallpaper.Default.name
)

var wallpapersSwitchedByLogoTap by booleanPreference(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File

class WallpaperFileManager(
Expand All @@ -23,8 +24,8 @@ class WallpaperFileManager(
* files for each of the following orientation and theme combinations:
* light/portrait - light/landscape - dark/portrait - dark/landscape
*/
fun lookupExpiredWallpaper(name: String): Wallpaper.Expired? {
return if (getAllLocalWallpaperPaths(name).all { File(rootDirectory, it).exists() }) {
suspend fun lookupExpiredWallpaper(name: String): Wallpaper.Expired? = withContext(Dispatchers.IO) {
if (getAllLocalWallpaperPaths(name).all { File(rootDirectory, it).exists() }) {
Wallpaper.Expired(name)
} else null
}
Expand Down
Loading

0 comments on commit 99600c5

Please sign in to comment.