Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: settings migration (compose) #1309

Merged
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 27 additions & 3 deletions app/src/main/java/app/revanced/manager/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package app.revanced.manager

import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
Expand All @@ -8,14 +10,15 @@ import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.runtime.getValue
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import app.revanced.manager.ui.component.AutoUpdatesDialog
import app.revanced.manager.ui.component.LegacySettingsImportDialog
import app.revanced.manager.ui.destination.Destination
import app.revanced.manager.ui.screen.AppInfoScreen
import app.revanced.manager.ui.screen.VersionSelectorScreen
import app.revanced.manager.ui.screen.AppSelectorScreen
import app.revanced.manager.ui.screen.DashboardScreen
import app.revanced.manager.ui.screen.InstallerScreen
import app.revanced.manager.ui.screen.PatchesSelectorScreen
import app.revanced.manager.ui.screen.SettingsScreen
import app.revanced.manager.ui.screen.VersionSelectorScreen
import app.revanced.manager.ui.theme.ReVancedManagerTheme
import app.revanced.manager.ui.theme.Theme
import app.revanced.manager.ui.viewmodel.MainViewModel
Expand Down Expand Up @@ -51,8 +54,16 @@ class MainActivity : ComponentActivity() {

NavBackHandler(navController)

val showImportLegacySettingsDialog by vm.prefs.showImportLegacySettingsDialog.getAsState()
val showAutoUpdatesDialog by vm.prefs.showAutoUpdatesDialog.getAsState()
if (showAutoUpdatesDialog) {

if (showImportLegacySettingsDialog) {
if (isPackageInstalled("app.revanced.manager.flutter") || isPackageInstalled("app.revanced.manager.flutter.debug")) {
BenjaminHalko marked this conversation as resolved.
Show resolved Hide resolved
LegacySettingsImportDialog(vm::legacySettingsImportOnDismiss, vm::getLegacySettings)
} else {
vm.legacySettingsImportOnDismiss()
}
} else if (showAutoUpdatesDialog) {
AutoUpdatesDialog(vm::applyAutoUpdatePrefs)
}

Expand Down Expand Up @@ -120,4 +131,17 @@ class MainActivity : ComponentActivity() {
}
}
}
}

private fun isPackageInstalled(packageName: String): Boolean {
return try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
packageManager.getPackageInfo(packageName, PackageManager.PackageInfoFlags.of(0))
} else {
@Suppress("DEPRECATION") packageManager.getPackageInfo(packageName, 0)
}
true
} catch (e: PackageManager.NameNotFoundException) {
false
}
}
BenjaminHalko marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,6 @@ class PreferencesManager(

val showAutoUpdatesDialog = booleanPreference("show_auto_updates_dialog", true)
val managerAutoUpdates = booleanPreference("manager_auto_updates", false)

val showImportLegacySettingsDialog = booleanPreference("show_import_legacy_settings_dialog", true)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package app.revanced.manager.ui.component

import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Update
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import app.revanced.manager.R

@Composable
fun LegacySettingsImportDialog(onDismiss: () -> Unit, onSubmit: () -> Unit) {
AlertDialog(
onDismissRequest = {},
dismissButton = {
TextButton(
onClick = onDismiss
) {
Text(stringResource(R.string.legacy_settings_import_dialog_dismiss))
}
},
confirmButton = {
Button(
onClick = onSubmit
) {
Text(stringResource(R.string.import_))
}
},
icon = {
Icon(Icons.Outlined.Update, null)
},
title = {
Text(
text = stringResource(R.string.legacy_settings_import_dialog_title),
style = MaterialTheme.typography.headlineSmall.copy(textAlign = TextAlign.Center),
color = MaterialTheme.colorScheme.onSurface,
)
},
text = {
Text(
text = stringResource(R.string.legacy_settings_import_dialog_description),
style = MaterialTheme.typography.bodyMedium,
)
}
)
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
package app.revanced.manager.ui.viewmodel

import android.app.Application
import android.content.Context
import android.database.Cursor
import android.net.Uri
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import app.revanced.manager.domain.bundles.PatchBundleSource.Companion.asRemoteOrNull
import app.revanced.manager.domain.manager.PreferencesManager
import app.revanced.manager.domain.repository.PatchBundleRepository
import kotlinx.coroutines.Dispatchers
import app.revanced.manager.domain.repository.PatchSelectionRepository
import app.revanced.manager.domain.repository.SerializedSelection
import app.revanced.manager.ui.theme.Theme
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import kotlinx.serialization.json.Json
import org.json.JSONObject
import java.util.Base64

class MainViewModel(
private val app: Application,
private val patchBundleRepository: PatchBundleRepository,
private val patchSelectionRepository: PatchSelectionRepository,
val prefs: PreferencesManager
) : ViewModel() {

Expand All @@ -30,4 +41,88 @@ class MainViewModel(
}
}
}

fun legacySettingsImportOnDismiss() = viewModelScope.launch {
prefs.showImportLegacySettingsDialog.update(false)
}

fun getLegacySettings() = viewModelScope.launch {
prefs.showAutoUpdatesDialog.update(false)
BenjaminHalko marked this conversation as resolved.
Show resolved Hide resolved
prefs.showImportLegacySettingsDialog.update(false)

val contentResolver = app.contentResolver
val contentProviderUri = Uri.parse("content://app.revanced.manager.flutter.provider/settings")
val cursor: Cursor? = contentResolver.query(contentProviderUri, null, null, null, null)

if (cursor != null) {
if (cursor.moveToFirst()) {
val column = cursor.getColumnIndex("settings")
if (column != -1) {
val jsonData = JSONObject(cursor.getString(column))
val keysIterator = jsonData.keys()
while (keysIterator.hasNext()) {
try {
val key = keysIterator.next()
val value = jsonData.get(key)

when (key) {
"themeMode" -> {
val themeMap = mapOf(
0 to Theme.SYSTEM,
1 to Theme.LIGHT,
2 to Theme.DARK
)
val theme = themeMap[value as Int]!!
prefs.theme.update(theme)
}
"useDynamicTheme" -> {
prefs.dynamicColor.update(value == 1)
}
"apiUrl" -> {
prefs.api.update(value as String)
}
"experimentalPatchesEnabled" -> {
prefs.allowExperimental.update(value == 1)
}
"patchesAutoUpdate" -> {
with(patchBundleRepository) {
sources
.first()
.find { it.uid == 0 }
?.asRemoteOrNull
?.setAutoUpdate(value == 1)

updateCheck()
}
}
"patchesChangeEnabled" -> {
// TODO: Implement setting
}
"showPatchesChangeWarning" -> {
// TODO: Implement setting
}
"keystore" -> {
prefs.keystoreCommonName.update("ReVanced")
prefs.keystorePass.update(jsonData.get("keystorePassword") as String)

val keystorePath = app.getDir("signing", Context.MODE_PRIVATE)
.resolve("manager.keystore").toPath()
val keystoreBytes = Base64.getDecoder().decode(value as String)
keystorePath.toFile().writeBytes(keystoreBytes)
}
"savedPatches" -> {
val bundleUid = patchBundleRepository.sources.first().first().uid
val selection = Json.decodeFromString<SerializedSelection>(value as String)
patchSelectionRepository.import(bundleUid, selection)
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}
}
}
cursor.close()
}
}
}
4 changes: 4 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
<string name="auto_updates_dialog_patches">Patches</string>
<string name="auto_updates_dialog_note">These settings can be changed later.</string>

<string name="legacy_settings_import_dialog_title">Import settings</string>
<string name="legacy_settings_import_dialog_description">Would you like to import your settings from the previous version of ReVanced Manager?</string>
<string name="legacy_settings_import_dialog_dismiss">No thanks</string>

<string name="general">General</string>
<string name="general_description">General settings</string>
<string name="advanced">Advanced</string>
Expand Down