For #26424 - Create wallpaper file migration helper
This commit is contained in:
parent
0f4d711083
commit
817827997f
|
@ -207,6 +207,14 @@ class Settings(private val appContext: Context) : PreferencesHolder {
|
|||
default = 0,
|
||||
)
|
||||
|
||||
/**
|
||||
* Indicates if the current legacy wallpaper should be migrated.
|
||||
*/
|
||||
var shouldMigrateLegacyWallpaper by booleanPreference(
|
||||
key = appContext.getPreferenceKey(R.string.pref_key_should_migrate_wallpaper),
|
||||
default = true,
|
||||
)
|
||||
|
||||
/**
|
||||
* Indicates if the wallpaper onboarding dialog should be shown.
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.fenix.wallpapers
|
||||
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import mozilla.components.support.base.log.logger.Logger
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
|
||||
/**
|
||||
* Manages the migration of legacy wallpapers to the new paths
|
||||
*
|
||||
* @property storageRootDirectory The top level app-local storage directory.
|
||||
*/
|
||||
class LegacyWallpaperMigration(
|
||||
private val storageRootDirectory: File,
|
||||
) {
|
||||
/**
|
||||
* Migrate the legacy wallpaper to the new path and delete the remaining legacy files.
|
||||
*
|
||||
* @param wallpaperName Name of the wallpaper to be migrated.
|
||||
*/
|
||||
suspend fun migrateLegacyWallpaper(
|
||||
wallpaperName: String,
|
||||
) = withContext(Dispatchers.IO) {
|
||||
val legacyPortraitFile =
|
||||
File(storageRootDirectory, "wallpapers/portrait/light/$wallpaperName.png")
|
||||
val legacyLandscapeFile =
|
||||
File(storageRootDirectory, "wallpapers/landscape/light/$wallpaperName.png")
|
||||
// If any of portrait or landscape files of the wallpaper are missing, then we shouldn't
|
||||
// migrate it
|
||||
if (!legacyLandscapeFile.exists() || !legacyPortraitFile.exists()) {
|
||||
return@withContext
|
||||
}
|
||||
// Directory where the legacy wallpaper files should be migrated
|
||||
val targetDirectory = "wallpapers/${wallpaperName.lowercase()}"
|
||||
|
||||
try {
|
||||
// Use the portrait file as thumbnail
|
||||
legacyPortraitFile.copyTo(
|
||||
File(
|
||||
storageRootDirectory,
|
||||
"$targetDirectory/thumbnail.png",
|
||||
),
|
||||
)
|
||||
// Copy the portrait file
|
||||
legacyPortraitFile.copyTo(
|
||||
File(
|
||||
storageRootDirectory,
|
||||
"$targetDirectory/portrait.png",
|
||||
),
|
||||
)
|
||||
// Copy the landscape file
|
||||
legacyLandscapeFile.copyTo(
|
||||
File(
|
||||
storageRootDirectory,
|
||||
"$targetDirectory/landscape.png",
|
||||
),
|
||||
)
|
||||
} catch (e: IOException) {
|
||||
Logger.error("Failed to migrate legacy wallpaper", e)
|
||||
}
|
||||
|
||||
// Delete the remaining legacy files
|
||||
File(storageRootDirectory, "wallpapers/portrait").deleteRecursively()
|
||||
File(storageRootDirectory, "wallpapers/landscape").deleteRecursively()
|
||||
}
|
||||
}
|
|
@ -47,11 +47,13 @@ class WallpapersUseCases(
|
|||
val initialize: InitializeWallpapersUseCase by lazy {
|
||||
if (FeatureFlags.wallpaperV2Enabled) {
|
||||
val metadataFetcher = WallpaperMetadataFetcher(client)
|
||||
val migrationHelper = LegacyWallpaperMigration(storageRootDirectory)
|
||||
DefaultInitializeWallpaperUseCase(
|
||||
store = store,
|
||||
downloader = downloader,
|
||||
fileManager = fileManager,
|
||||
metadataFetcher = metadataFetcher,
|
||||
migrationHelper = migrationHelper,
|
||||
settings = context.settings(),
|
||||
currentLocale = currentLocale,
|
||||
)
|
||||
|
@ -222,12 +224,14 @@ class WallpapersUseCases(
|
|||
}
|
||||
}
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
|
||||
internal class DefaultInitializeWallpaperUseCase(
|
||||
private val store: AppStore,
|
||||
private val downloader: WallpaperDownloader,
|
||||
private val fileManager: WallpaperFileManager,
|
||||
private val metadataFetcher: WallpaperMetadataFetcher,
|
||||
private val migrationHelper: LegacyWallpaperMigration,
|
||||
private val settings: Settings,
|
||||
private val currentLocale: String,
|
||||
) : InitializeWallpapersUseCase {
|
||||
|
@ -236,6 +240,10 @@ class WallpapersUseCases(
|
|||
store.dispatch(AppAction.WallpaperAction.UpdateCurrentWallpaper(it))
|
||||
}
|
||||
val currentWallpaperName = withContext(Dispatchers.IO) { settings.currentWallpaperName }
|
||||
if (settings.shouldMigrateLegacyWallpaper) {
|
||||
migrationHelper.migrateLegacyWallpaper(currentWallpaperName)
|
||||
settings.shouldMigrateLegacyWallpaper = false
|
||||
}
|
||||
val possibleWallpapers = metadataFetcher.downloadWallpaperList().filter {
|
||||
!it.isExpired() && it.isAvailableInLocale()
|
||||
}
|
||||
|
|
|
@ -207,6 +207,7 @@
|
|||
<string name="pref_key_current_wallpaper_text_color" translatable="false">pref_key_current_wallpaper_text_color</string>
|
||||
<string name="pref_key_current_wallpaper_card_color" translatable="false">pref_key_current_wallpaper_card_color</string>
|
||||
<string name="pref_key_wallpapers_onboarding" translatable="false">pref_key_wallpapers_onboarding</string>
|
||||
<string name="pref_key_should_migrate_wallpaper" translatable="false">pref_key_should_migrate_wallpaper</string>
|
||||
|
||||
<string name="pref_key_encryption_key_generated" translatable="false">pref_key_encryption_key_generated</string>
|
||||
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
package org.mozilla.fenix.wallpapers
|
||||
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TemporaryFolder
|
||||
import java.io.File
|
||||
|
||||
class LegacyWallpaperMigrationTest {
|
||||
@Rule
|
||||
@JvmField
|
||||
val tempFolder = TemporaryFolder()
|
||||
private lateinit var wallpapersFolder: File
|
||||
private lateinit var migrationHelper: LegacyWallpaperMigration
|
||||
private lateinit var portraitLightFolder: File
|
||||
private lateinit var portraitDarkFolder: File
|
||||
private lateinit var landscapeLightFolder: File
|
||||
private lateinit var landscapeDarkFolder: File
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
wallpapersFolder = File(tempFolder.root, "wallpapers")
|
||||
migrationHelper = LegacyWallpaperMigration(
|
||||
storageRootDirectory = tempFolder.root,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `WHEN the legacy wallpaper is migrated THEN the legacy wallpapers are deleted`() = runTest {
|
||||
val wallpaperName = "wallpaper1"
|
||||
|
||||
createAllLegacyFiles(wallpaperName)
|
||||
|
||||
migrationHelper.migrateLegacyWallpaper(wallpaperName)
|
||||
|
||||
assertTrue(getAllFiles(wallpaperName).all { it.exists() })
|
||||
assertFalse(File(portraitLightFolder, "$wallpaperName.png").exists())
|
||||
assertFalse(File(portraitDarkFolder, "$wallpaperName.png").exists())
|
||||
assertFalse(File(landscapeLightFolder, "$wallpaperName.png").exists())
|
||||
assertFalse(File(landscapeDarkFolder, "$wallpaperName.png").exists())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN landscape legacy wallpaper is missing WHEN the wallpapers are migrated THEN the wallpaper is not migrated`() =
|
||||
runTest {
|
||||
val portraitOnlyWallpaperName = "portraitOnly"
|
||||
val completeWallpaperName = "legacy"
|
||||
createAllLegacyFiles(completeWallpaperName)
|
||||
File(landscapeLightFolder, "$portraitOnlyWallpaperName.png").apply {
|
||||
createNewFile()
|
||||
}
|
||||
File(landscapeDarkFolder, "$portraitOnlyWallpaperName.png").apply {
|
||||
createNewFile()
|
||||
}
|
||||
|
||||
migrationHelper.migrateLegacyWallpaper(portraitOnlyWallpaperName)
|
||||
migrationHelper.migrateLegacyWallpaper(completeWallpaperName)
|
||||
|
||||
assertTrue(getAllFiles(completeWallpaperName).all { it.exists() })
|
||||
assertFalse(getAllFiles(portraitOnlyWallpaperName).any { it.exists() })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN portrait legacy wallpaper is missing WHEN the wallpapers are migrated THEN the wallpaper is not migrated`() =
|
||||
runTest {
|
||||
val landscapeOnlyWallpaperName = "portraitOnly"
|
||||
val completeWallpaperName = "legacy"
|
||||
createAllLegacyFiles(completeWallpaperName)
|
||||
File(portraitLightFolder, "$landscapeOnlyWallpaperName.png").apply {
|
||||
createNewFile()
|
||||
}
|
||||
File(portraitDarkFolder, "$landscapeOnlyWallpaperName.png").apply {
|
||||
createNewFile()
|
||||
}
|
||||
|
||||
migrationHelper.migrateLegacyWallpaper(landscapeOnlyWallpaperName)
|
||||
migrationHelper.migrateLegacyWallpaper(completeWallpaperName)
|
||||
|
||||
assertTrue(getAllFiles(completeWallpaperName).all { it.exists() })
|
||||
assertFalse(getAllFiles(landscapeOnlyWallpaperName).any { it.exists() })
|
||||
}
|
||||
|
||||
private fun createAllLegacyFiles(name: String) {
|
||||
if (!this::portraitLightFolder.isInitialized) {
|
||||
portraitLightFolder = tempFolder.newFolder("wallpapers", "portrait", "light")
|
||||
portraitDarkFolder = tempFolder.newFolder("wallpapers", "portrait", "dark")
|
||||
landscapeLightFolder = tempFolder.newFolder("wallpapers", "landscape", "light")
|
||||
landscapeDarkFolder = tempFolder.newFolder("wallpapers", "landscape", "dark")
|
||||
}
|
||||
|
||||
File(portraitLightFolder, "$name.png").apply {
|
||||
createNewFile()
|
||||
}
|
||||
File(landscapeLightFolder, "$name.png").apply {
|
||||
createNewFile()
|
||||
}
|
||||
File(portraitDarkFolder, "$name.png").apply {
|
||||
createNewFile()
|
||||
}
|
||||
File(landscapeDarkFolder, "$name.png").apply {
|
||||
createNewFile()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getAllFiles(name: String): List<File> {
|
||||
val folder = File(wallpapersFolder, name)
|
||||
return listOf(
|
||||
folder,
|
||||
File(folder, "portrait.png"),
|
||||
File(folder, "landscape.png"),
|
||||
File(folder, "thumbnail.png"),
|
||||
)
|
||||
}
|
||||
}
|
|
@ -42,11 +42,16 @@ class WallpapersUseCasesTest {
|
|||
every { currentWallpaperTextColor = any() } just Runs
|
||||
every { currentWallpaperCardColor } returns 0L
|
||||
every { currentWallpaperCardColor = any() } just Runs
|
||||
every { shouldMigrateLegacyWallpaper } returns false
|
||||
every { shouldMigrateLegacyWallpaper = any() } just Runs
|
||||
}
|
||||
private val mockLegacyDownloader = mockk<LegacyWallpaperDownloader>(relaxed = true)
|
||||
private val mockLegacyFileManager = mockk<LegacyWallpaperFileManager> {
|
||||
every { clean(any(), any()) } just runs
|
||||
}
|
||||
private val mockMigrationHelper = mockk<LegacyWallpaperMigration> {
|
||||
coEvery { migrateLegacyWallpaper(any()) } just runs
|
||||
}
|
||||
|
||||
private val mockMetadataFetcher = mockk<WallpaperMetadataFetcher>()
|
||||
private val mockDownloader = mockk<WallpaperDownloader> {
|
||||
|
@ -252,6 +257,7 @@ class WallpapersUseCasesTest {
|
|||
mockDownloader,
|
||||
mockFileManager,
|
||||
mockMetadataFetcher,
|
||||
mockMigrationHelper,
|
||||
mockSettings,
|
||||
"en-US",
|
||||
).invoke()
|
||||
|
@ -275,6 +281,7 @@ class WallpapersUseCasesTest {
|
|||
mockDownloader,
|
||||
mockFileManager,
|
||||
mockMetadataFetcher,
|
||||
mockMigrationHelper,
|
||||
mockSettings,
|
||||
"en-US",
|
||||
).invoke()
|
||||
|
@ -302,6 +309,7 @@ class WallpapersUseCasesTest {
|
|||
mockDownloader,
|
||||
mockFileManager,
|
||||
mockMetadataFetcher,
|
||||
mockMigrationHelper,
|
||||
mockSettings,
|
||||
"en-US",
|
||||
).invoke()
|
||||
|
@ -329,6 +337,7 @@ class WallpapersUseCasesTest {
|
|||
mockDownloader,
|
||||
mockFileManager,
|
||||
mockMetadataFetcher,
|
||||
mockMigrationHelper,
|
||||
mockSettings,
|
||||
"en-US",
|
||||
).invoke()
|
||||
|
@ -356,6 +365,7 @@ class WallpapersUseCasesTest {
|
|||
mockDownloader,
|
||||
mockFileManager,
|
||||
mockMetadataFetcher,
|
||||
mockMigrationHelper,
|
||||
mockSettings,
|
||||
locale,
|
||||
).invoke()
|
||||
|
@ -380,6 +390,7 @@ class WallpapersUseCasesTest {
|
|||
mockDownloader,
|
||||
mockFileManager,
|
||||
mockMetadataFetcher,
|
||||
mockMigrationHelper,
|
||||
mockSettings,
|
||||
"en-US",
|
||||
).invoke()
|
||||
|
@ -404,6 +415,7 @@ class WallpapersUseCasesTest {
|
|||
mockDownloader,
|
||||
mockFileManager,
|
||||
mockMetadataFetcher,
|
||||
mockMigrationHelper,
|
||||
mockSettings,
|
||||
"en-US",
|
||||
).invoke()
|
||||
|
@ -436,6 +448,7 @@ class WallpapersUseCasesTest {
|
|||
mockDownloader,
|
||||
mockFileManager,
|
||||
mockMetadataFetcher,
|
||||
mockMigrationHelper,
|
||||
mockSettings,
|
||||
"en-US",
|
||||
).invoke()
|
||||
|
@ -460,6 +473,7 @@ class WallpapersUseCasesTest {
|
|||
mockDownloader,
|
||||
mockFileManager,
|
||||
mockMetadataFetcher,
|
||||
mockMigrationHelper,
|
||||
mockSettings,
|
||||
"en-US",
|
||||
).invoke()
|
||||
|
@ -485,6 +499,7 @@ class WallpapersUseCasesTest {
|
|||
mockDownloader,
|
||||
mockFileManager,
|
||||
mockMetadataFetcher,
|
||||
mockMigrationHelper,
|
||||
mockSettings,
|
||||
"en-US",
|
||||
).invoke()
|
||||
|
|
Loading…
Reference in New Issue