For #26424 - Create wallpaper file migration helper

This commit is contained in:
Alexandru2909 2022-09-05 15:56:56 +03:00 committed by mergify[bot]
parent 0f4d711083
commit 817827997f
6 changed files with 220 additions and 0 deletions

View File

@ -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.
*/

View File

@ -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()
}
}

View File

@ -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()
}

View File

@ -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>

View File

@ -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"),
)
}
}

View File

@ -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()