Skip to content

Commit

Permalink
feat: store patched apps (ReVanced#79)
Browse files Browse the repository at this point in the history
* feat: store patched apps

* fix: missing string

* feat: save patch selection

* feat: things

* fix: fix broken query

* fix: remove redundant `withContext`

* fix: fix
  • Loading branch information
CnC-Robert authored Aug 17, 2023
1 parent ac4c7e0 commit a0b9255
Show file tree
Hide file tree
Showing 33 changed files with 842 additions and 89 deletions.
109 changes: 107 additions & 2 deletions app/schemas/app.revanced.manager.data.room.AppDatabase/1.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"formatVersion": 1,
"database": {
"version": 1,
"identityHash": "7142188e25ce489eb233aed8fb76e4cc",
"identityHash": "5515d164bc8f713201506d42a02d337f",
"entities": [
{
"tableName": "patch_bundles",
Expand Down Expand Up @@ -190,12 +190,117 @@
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "installed_app",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`current_package_name` TEXT NOT NULL, `original_package_name` TEXT NOT NULL, `version` TEXT NOT NULL, `install_type` TEXT NOT NULL, PRIMARY KEY(`current_package_name`))",
"fields": [
{
"fieldPath": "currentPackageName",
"columnName": "current_package_name",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "originalPackageName",
"columnName": "original_package_name",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "version",
"columnName": "version",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "installType",
"columnName": "install_type",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"current_package_name"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "applied_patch",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`package_name` TEXT NOT NULL, `bundle` INTEGER NOT NULL, `patch_name` TEXT NOT NULL, PRIMARY KEY(`package_name`, `bundle`, `patch_name`), FOREIGN KEY(`package_name`) REFERENCES `installed_app`(`current_package_name`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`bundle`) REFERENCES `patch_bundles`(`uid`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
"fields": [
{
"fieldPath": "packageName",
"columnName": "package_name",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "bundle",
"columnName": "bundle",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "patchName",
"columnName": "patch_name",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"package_name",
"bundle",
"patch_name"
]
},
"indices": [
{
"name": "index_applied_patch_bundle",
"unique": false,
"columnNames": [
"bundle"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_applied_patch_bundle` ON `${TABLE_NAME}` (`bundle`)"
}
],
"foreignKeys": [
{
"table": "installed_app",
"onDelete": "CASCADE",
"onUpdate": "NO ACTION",
"columns": [
"package_name"
],
"referencedColumns": [
"current_package_name"
]
},
{
"table": "patch_bundles",
"onDelete": "NO ACTION",
"onUpdate": "NO ACTION",
"columns": [
"bundle"
],
"referencedColumns": [
"uid"
]
}
]
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '7142188e25ce489eb233aed8fb76e4cc')"
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '5515d164bc8f713201506d42a02d337f')"
]
}
}
41 changes: 21 additions & 20 deletions app/src/main/java/app/revanced/manager/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import androidx.compose.runtime.getValue
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import app.revanced.manager.ui.component.AutoUpdatesDialog
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
Expand All @@ -18,19 +19,14 @@ import app.revanced.manager.ui.screen.SettingsScreen
import app.revanced.manager.ui.theme.ReVancedManagerTheme
import app.revanced.manager.ui.theme.Theme
import app.revanced.manager.ui.viewmodel.MainViewModel
import coil.Coil
import coil.ImageLoader
import dev.olshevski.navigation.reimagined.AnimatedNavHost
import dev.olshevski.navigation.reimagined.NavBackHandler
import dev.olshevski.navigation.reimagined.navigate
import dev.olshevski.navigation.reimagined.pop
import dev.olshevski.navigation.reimagined.popUpTo
import dev.olshevski.navigation.reimagined.rememberNavController
import me.zhanghai.android.appiconloader.coil.AppIconFetcher
import me.zhanghai.android.appiconloader.coil.AppIconKeyer
import org.koin.androidx.compose.getViewModel
import org.koin.core.parameter.parametersOf
import kotlin.math.roundToInt
import org.koin.androidx.viewmodel.ext.android.getViewModel as getActivityViewModel

class MainActivity : ComponentActivity() {
Expand All @@ -42,17 +38,6 @@ class MainActivity : ComponentActivity() {

installSplashScreen()

val scale = this.resources.displayMetrics.density
val pixels = (36 * scale).roundToInt()
Coil.setImageLoader(
ImageLoader.Builder(this)
.components {
add(AppIconKeyer())
add(AppIconFetcher.Factory(pixels, true, this@MainActivity))
}
.build()
)

setContent {
val theme by vm.prefs.theme.getAsState()
val dynamicColor by vm.prefs.dynamicColor.getAsState()
Expand All @@ -77,7 +62,16 @@ class MainActivity : ComponentActivity() {
when (destination) {
is Destination.Dashboard -> DashboardScreen(
onSettingsClick = { navController.navigate(Destination.Settings) },
onAppSelectorClick = { navController.navigate(Destination.AppSelector) }
onAppSelectorClick = { navController.navigate(Destination.AppSelector) },
onAppClick = { installedApp -> navController.navigate(Destination.ApplicationInfo(installedApp)) }
)

is Destination.ApplicationInfo -> AppInfoScreen(
onPatchClick = { packageName, patchesSelection ->
navController.navigate(Destination.VersionSelector(packageName, patchesSelection))
},
onBackClick = { navController.pop() },
viewModel = getViewModel { parametersOf(destination.installedApp) }
)

is Destination.Settings -> SettingsScreen(
Expand All @@ -92,8 +86,15 @@ class MainActivity : ComponentActivity() {

is Destination.VersionSelector -> VersionSelectorScreen(
onBackClick = { navController.pop() },
onAppClick = { navController.navigate(Destination.PatchesSelector(it)) },
viewModel = getViewModel { parametersOf(destination.packageName) }
onAppClick = { selectedApp ->
navController.navigate(
Destination.PatchesSelector(
selectedApp,
destination.patchesSelection
)
)
},
viewModel = getViewModel { parametersOf(destination.packageName, destination.patchesSelection) }
)

is Destination.PatchesSelector -> PatchesSelectorScreen(
Expand All @@ -107,7 +108,7 @@ class MainActivity : ComponentActivity() {
)
)
},
vm = getViewModel { parametersOf(destination.selectedApp) }
vm = getViewModel { parametersOf(destination) }
)

is Destination.Installer -> InstallerScreen(
Expand Down
14 changes: 14 additions & 0 deletions app/src/main/java/app/revanced/manager/ManagerApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@ import app.revanced.manager.di.*
import app.revanced.manager.domain.manager.PreferencesManager
import app.revanced.manager.domain.repository.PatchBundleRepository
import kotlinx.coroutines.Dispatchers
import coil.Coil
import coil.ImageLoader
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
import me.zhanghai.android.appiconloader.coil.AppIconFetcher
import me.zhanghai.android.appiconloader.coil.AppIconKeyer
import org.koin.android.ext.android.inject
import org.koin.android.ext.koin.androidContext
import org.koin.android.ext.koin.androidLogger
Expand Down Expand Up @@ -36,6 +40,16 @@ class ManagerApplication : Application() {
)
}

val pixels = 512
Coil.setImageLoader(
ImageLoader.Builder(this)
.components {
add(AppIconKeyer())
add(AppIconFetcher.Factory(pixels, true, this@ManagerApplication))
}
.build()
)

scope.launch {
prefs.preload()
}
Expand Down
12 changes: 8 additions & 4 deletions app/src/main/java/app/revanced/manager/data/room/AppDatabase.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,25 @@ package app.revanced.manager.data.room
import androidx.room.Database
import androidx.room.RoomDatabase
import androidx.room.TypeConverters
import app.revanced.manager.data.room.apps.AppDao
import app.revanced.manager.data.room.apps.DownloadedApp
import app.revanced.manager.data.room.apps.downloaded.DownloadedAppDao
import app.revanced.manager.data.room.apps.downloaded.DownloadedApp
import app.revanced.manager.data.room.apps.installed.AppliedPatch
import app.revanced.manager.data.room.apps.installed.InstalledApp
import app.revanced.manager.data.room.apps.installed.InstalledAppDao
import app.revanced.manager.data.room.selection.PatchSelection
import app.revanced.manager.data.room.selection.SelectedPatch
import app.revanced.manager.data.room.selection.SelectionDao
import app.revanced.manager.data.room.bundles.PatchBundleDao
import app.revanced.manager.data.room.bundles.PatchBundleEntity
import kotlin.random.Random

@Database(entities = [PatchBundleEntity::class, PatchSelection::class, SelectedPatch::class, DownloadedApp::class], version = 1)
@Database(entities = [PatchBundleEntity::class, PatchSelection::class, SelectedPatch::class, DownloadedApp::class, InstalledApp::class, AppliedPatch::class], version = 1)
@TypeConverters(Converters::class)
abstract class AppDatabase : RoomDatabase() {
abstract fun patchBundleDao(): PatchBundleDao
abstract fun selectionDao(): SelectionDao
abstract fun appDao(): AppDao
abstract fun downloadedAppDao(): DownloadedAppDao
abstract fun installedAppDao(): InstalledAppDao

companion object {
fun generateUid() = Random.Default.nextInt()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package app.revanced.manager.data.room.apps
package app.revanced.manager.data.room.apps.downloaded

import androidx.room.ColumnInfo
import androidx.room.Entity
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package app.revanced.manager.data.room.apps
package app.revanced.manager.data.room.apps.downloaded

import androidx.room.Dao
import androidx.room.Delete
Expand All @@ -7,7 +7,7 @@ import androidx.room.Query
import kotlinx.coroutines.flow.Flow

@Dao
interface AppDao {
interface DownloadedAppDao {
@Query("SELECT * FROM downloaded_app")
fun getAllApps(): Flow<List<DownloadedApp>>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package app.revanced.manager.data.room.apps.installed

import android.os.Parcelable
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.Index
import app.revanced.manager.data.room.bundles.PatchBundleEntity
import kotlinx.parcelize.Parcelize

@Parcelize
@Entity(
tableName = "applied_patch",
primaryKeys = ["package_name", "bundle", "patch_name"],
foreignKeys = [
ForeignKey(
InstalledApp::class,
parentColumns = ["current_package_name"],
childColumns = ["package_name"],
onDelete = ForeignKey.CASCADE
),
ForeignKey(
PatchBundleEntity::class,
parentColumns = ["uid"],
childColumns = ["bundle"]
)
],
indices = [Index(value = ["bundle"], unique = false)]
)
data class AppliedPatch(
@ColumnInfo(name = "package_name") val packageName: String,
@ColumnInfo(name = "bundle") val bundle: Int,
@ColumnInfo(name = "patch_name") val patchName: String
) : Parcelable
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package app.revanced.manager.data.room.apps.installed

import android.os.Parcelable
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import app.revanced.manager.R
import kotlinx.parcelize.Parcelize

enum class InstallType(val stringResource: Int) {
DEFAULT(R.string.default_install),
ROOT(R.string.root_install)
}

@Parcelize
@Entity(tableName = "installed_app")
data class InstalledApp(
@PrimaryKey
@ColumnInfo(name = "current_package_name") val currentPackageName: String,
@ColumnInfo(name = "original_package_name") val originalPackageName: String,
@ColumnInfo(name = "version") val version: String,
@ColumnInfo(name = "install_type") val installType: InstallType
) : Parcelable
Loading

0 comments on commit a0b9255

Please sign in to comment.