Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
eea1cbd
feat(Patcher): Live progress during resource decoding
secp192k1 Jun 4, 2026
e7c6cc6
feat(Patcher): Add live completion to logs
secp192k1 Jun 4, 2026
a7f151f
ci: Skip PR build while draft
secp192k1 Jun 4, 2026
ad10958
feat(Settings): Add `Clear downloaded APK cache` button
secp192k1 Jun 4, 2026
ca6338e
refactor(Patcher): Heartbeat improvement
secp192k1 Jun 4, 2026
ec63a73
feat(Patcher): Live progress during APK file download
secp192k1 Jun 4, 2026
fbd5321
refactor(Patcher): Pipe log trailing text through an explicit field
secp192k1 Jun 5, 2026
285733d
refactor(Patcher): Polish download step title behavior
secp192k1 Jun 5, 2026
d24a04c
refactor(Patcher): Expose seconds in `Heartbeat`
secp192k1 Jun 5, 2026
eb88d57
enhance(Patcher): Add download apk info to logs
secp192k1 Jun 5, 2026
8d93725
perf(Patcher): Reduce memory allocations in heartbeat UI
secp192k1 Jun 5, 2026
be2eb00
fix(Network): Stop heap growth when streaming downloads
secp192k1 Jun 5, 2026
b382c53
feat(Patcher): Surface subprocess kills and native crashes
secp192k1 Jun 5, 2026
f53b115
feat(Patcher): Soft-skip missing fingerprint
secp192k1 Jun 5, 2026
2658c20
fix(SubStep): Icon not aligned with Step icon
secp192k1 Jun 5, 2026
c33626f
fix(Patcher): Also count failed status for 100% progress bar
secp192k1 Jun 5, 2026
eb8734c
enhance(Patcher): Remove the `[INFO]` prefix
secp192k1 Jun 5, 2026
64463aa
fix(Styling): Make resources styles work
secp192k1 Jun 6, 2026
3d557ab
refactor(Dashboard): Animated notifications
secp192k1 Jun 6, 2026
2df42c5
refactor(Dashboard): Move to separate component
secp192k1 Jun 6, 2026
d93bc84
feat(Settings): Animated battery optimization card
secp192k1 Jun 6, 2026
e74b288
feat(Onboarding): Animated permission items
secp192k1 Jun 7, 2026
71d8aee
refactor(Strings): Applied suggested changes
secp192k1 Jun 11, 2026
b9ebbd3
refactor(Patcher): Localization and better readability log level
secp192k1 Jun 13, 2026
24342ca
refactor: Use time duration DSL for delay
secp192k1 Jun 13, 2026
7f8b231
fix: Github Actions compiler warnings
secp192k1 Jun 13, 2026
3aeb521
chore: Optimize imports
secp192k1 Jun 13, 2026
736319f
chore: Refactor code & cleanup
secp192k1 Jun 13, 2026
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
2 changes: 2 additions & 0 deletions .github/workflows/build_pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ name: Build pull request
on:
workflow_dispatch:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
branches:
- dev

jobs:
release:
name: Build
if: github.event_name == 'workflow_dispatch' || github.event.pull_request.draft == false
runs-on: ubuntu-latest
steps:
- name: Checkout
Expand Down
4 changes: 3 additions & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import com.mikepenz.aboutlibraries.plugin.DuplicateMode
import com.mikepenz.aboutlibraries.plugin.DuplicateRule
import io.github.z4kn4fein.semver.toVersion
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import kotlin.random.Random

plugins {
alias(libs.plugins.android.application)
Expand Down Expand Up @@ -182,6 +181,7 @@ android {
release {
// Causes patching to not work properly, if enabled.
isMinifyEnabled = false
//noinspection NotShrinkingResources
isShrinkResources = false

val keystoreFile = file("keystore.jks")
Expand Down Expand Up @@ -228,6 +228,7 @@ android {
}

androidResources {
@Suppress("UnstableApiUsage")
generateLocaleConfig = true
}

Expand Down Expand Up @@ -318,6 +319,7 @@ aboutLibraries {
tasks {
// Needed by gradle-semantic-release-plugin.
// Tracking: https://github.com/KengoTODA/gradle-semantic-release-plugin/issues/435.
@Suppress("UNUSED")
val publish by registering {
group = "publishing"
description = "Build the release APK"
Expand Down
33 changes: 20 additions & 13 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"
<uses-permission
android:name="android.permission.QUERY_ALL_PACKAGES"
tools:ignore="QueryAllPackagesPermission" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
Expand All @@ -11,8 +12,11 @@
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="29" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="29" />
<uses-permission
android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ENFORCE_UPDATE_OWNERSHIP" />
Expand Down Expand Up @@ -43,14 +47,18 @@

<intent-filter>
<action android:name="android.intent.action.VIEW" />

<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />

<data android:scheme="${deepLinkScheme}" />
</intent-filter>
</activity>

<activity android:name=".DownloaderActivity" android:exported="false" android:theme="@style/Theme.DownloaderActivity" />
<activity
android:name=".DownloaderActivity"
android:exported="false"
android:theme="@style/Theme.DownloaderActivity" />

<service
android:name="androidx.work.impl.foreground.SystemForegroundService"
Expand All @@ -59,19 +67,18 @@
tools:node="merge">
<property
android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"
android:value="patching"
/>
android:value="patching" />
</service>

<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
<meta-data
android:name="androidx.work.WorkManagerInitializer"
android:value="androidx.startup"
tools:node="remove" />
android:name="androidx.work.WorkManagerInitializer"
android:value="androidx.startup"
tools:node="remove" />
</provider>


Expand Down
8 changes: 4 additions & 4 deletions app/src/main/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ project("prop_override")
# for GameActivity/NativeActivity derived applications, the same library name must be
# used in the AndroidManifest.xml file.
add_library(${CMAKE_PROJECT_NAME} SHARED
# List C/C++ source files with relative paths to this CMakeLists.txt.
# List C/C++ source files with relative paths to this CMakeLists.txt.
prop_override.cpp)

# Specifies libraries CMake should link to your target library. You
# can link libraries from various origins, such as libraries defined in this
# build script, prebuilt third-party libraries, or Android system libraries.
target_link_libraries(${CMAKE_PROJECT_NAME}
# List libraries link to the target library
android
log)
# List libraries link to the target library
android
log)
1 change: 1 addition & 0 deletions app/src/main/cpp/prop_override.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#define GET_PROPERTY_MANGLED_NAME "_ZN7android4base11GetPropertyERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEES9_"

extern "C" typedef int (*property_get_ptr)(const char *, char *, const char *);

typedef std::string (*GetProperty_ptr)(const std::string &, const std::string &);

char *GetPropOverride(const std::string &key) {
Expand Down
16 changes: 13 additions & 3 deletions app/src/main/java/app/revanced/manager/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,9 @@ class MainActivity : AppCompatActivity() {
// fixes issue #2857 by preventing an empty locale
override fun applyOverrideConfiguration(overrideConfiguration: Configuration?) {
if (overrideConfiguration != null && overrideConfiguration.locales.isEmpty) {
overrideConfiguration.setLocale(SupportedLocales.getCurrentLocale() ?: Locale.getDefault())
overrideConfiguration.setLocale(
SupportedLocales.getCurrentLocale() ?: Locale.getDefault()
)
}
super.applyOverrideConfiguration(overrideConfiguration)
}
Expand Down Expand Up @@ -363,7 +365,12 @@ private fun ReVancedManager(vm: MainViewModel) {
deepLinkedComposable<Settings.Updates>("settings/updates") {
UpdatesSettingsScreen(
onBackClick = navController::popBackStackSafe,
onChangelogClick = { navController.navigateComplex(Settings.Changelogs, ChangelogSource.Manager) },
onChangelogClick = {
navController.navigateComplex(
Settings.Changelogs,
ChangelogSource.Manager
)
},
onUpdateClick = { navController.navigateSafe(Update()) }
)
}
Expand Down Expand Up @@ -398,7 +405,10 @@ private fun ReVancedManager(vm: MainViewModel) {

composable<Settings.Changelogs> {
val source = it.getComplexArg<ChangelogSource>()
ChangelogsSettingsScreen(source = source, onBackClick = navController::popBackStackSafe)
ChangelogsSettingsScreen(
source = source,
onBackClick = navController::popBackStackSafe
)
}

composable<Settings.Contributors> {
Expand Down
13 changes: 11 additions & 2 deletions app/src/main/java/app/revanced/manager/ManagerApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,26 @@ import android.app.Application
import android.os.Bundle
import android.util.Log
import app.revanced.manager.data.platform.Filesystem
import app.revanced.manager.di.*
import app.revanced.manager.di.ackpineModule
import app.revanced.manager.di.databaseModule
import app.revanced.manager.di.httpModule
import app.revanced.manager.di.managerModule
import app.revanced.manager.di.preferencesModule
import app.revanced.manager.di.repositoryModule
import app.revanced.manager.di.rootModule
import app.revanced.manager.di.serviceModule
import app.revanced.manager.di.viewModelModule
import app.revanced.manager.di.workerModule
import app.revanced.manager.domain.manager.PreferencesManager
import app.revanced.manager.domain.repository.DownloadedAppRepository
import app.revanced.manager.domain.repository.DownloaderRepository
import app.revanced.manager.domain.repository.PatchBundleRepository
import app.revanced.manager.util.tag
import kotlinx.coroutines.Dispatchers
import coil.Coil
import coil.ImageLoader
import com.topjohnwu.superuser.Shell
import com.topjohnwu.superuser.internal.BuilderImpl
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
import me.zhanghai.android.appiconloader.coil.AppIconFetcher
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ 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.apps.installed.InstalledPatchBundle
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 app.revanced.manager.data.room.downloader.DownloaderDao
import app.revanced.manager.data.room.downloader.DownloaderEntity
import app.revanced.manager.data.room.options.Option
import app.revanced.manager.data.room.options.OptionDao
import app.revanced.manager.data.room.options.OptionGroup
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 kotlin.random.Random

@Database(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ interface DownloadedAppDao {
suspend fun upsert(downloadedApp: DownloadedApp)

@Query("UPDATE downloaded_app SET last_used = :newValue WHERE package_name = :packageName AND version = :version")
suspend fun markUsed(packageName: String, version: String, newValue: Long = System.currentTimeMillis())
suspend fun markUsed(
packageName: String,
version: String,
newValue: Long = System.currentTimeMillis()
)

@Delete
suspend fun delete(downloadedApps: Collection<DownloadedApp>)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package app.revanced.manager.data.room.bundles

import androidx.room.*
import androidx.room.Dao
import androidx.room.Query
import androidx.room.Transaction
import androidx.room.Upsert
import app.revanced.manager.data.room.sources.SourceProperties

@Dao
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package app.revanced.manager.data.room.bundles

import androidx.room.*
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import app.revanced.manager.data.room.sources.Source
import app.revanced.manager.domain.manager.SourceManager

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package app.revanced.manager.data.room.downloader

import androidx.room.*
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import app.revanced.manager.data.room.sources.Source
import app.revanced.manager.domain.manager.SourceManager

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ data class Option(
}

fun fromJsonString(value: String) = SerializedValue(json.decodeFromString(value))
fun fromValue(value: Any?) = SerializedValue(when (value) {
fun fromValue(value: Any?) = SerializedValue(
when (value) {
null -> JsonNull
is Number -> JsonPrimitive(value)
is Boolean -> JsonPrimitive(value)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package app.revanced.manager.data.room.selection
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.MapColumn
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Transaction
import app.revanced.manager.data.room.AppDatabase
Expand Down
3 changes: 2 additions & 1 deletion app/src/main/java/app/revanced/manager/di/DatabaseModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import org.koin.android.ext.koin.androidContext
import org.koin.dsl.module

val databaseModule = module {
fun provideAppDatabase(context: Context) = Room.databaseBuilder(context, AppDatabase::class.java, "manager").build()
fun provideAppDatabase(context: Context) =
Room.databaseBuilder(context, AppDatabase::class.java, "manager").build()

single {
provideAppDatabase(androidContext())
Expand Down
15 changes: 10 additions & 5 deletions app/src/main/java/app/revanced/manager/di/HttpModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ package app.revanced.manager.di

import android.content.Context
import app.revanced.manager.BuildConfig
import io.ktor.client.*
import io.ktor.client.engine.okhttp.*
import io.ktor.client.HttpClient
import io.ktor.client.engine.okhttp.OkHttp
import io.ktor.client.plugins.HttpTimeout
import io.ktor.client.plugins.UserAgent
import io.ktor.client.plugins.contentnegotiation.*
import io.ktor.serialization.kotlinx.json.*
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
import io.ktor.serialization.kotlinx.json.json
import kotlinx.serialization.json.Json
import okhttp3.Cache
import okhttp3.Dns
Expand All @@ -31,7 +31,12 @@ val httpModule = module {
}
}
})
cache(Cache(context.cacheDir.resolve("cache").also { it.mkdirs() }, 1024 * 1024 * 100))
cache(
Cache(
context.cacheDir.resolve("cache").also { it.mkdirs() },
1024 * 1024 * 100
)
)
followRedirects(true)
followSslRedirects(true)
}
Expand Down
10 changes: 9 additions & 1 deletion app/src/main/java/app/revanced/manager/di/RepositoryModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,15 @@ package app.revanced.manager.di

import app.revanced.manager.data.platform.Filesystem
import app.revanced.manager.data.platform.NetworkInfo
import app.revanced.manager.domain.repository.*
import app.revanced.manager.domain.repository.AnnouncementRepository
import app.revanced.manager.domain.repository.ChangelogsRepository
import app.revanced.manager.domain.repository.DownloadedAppRepository
import app.revanced.manager.domain.repository.DownloaderRepository
import app.revanced.manager.domain.repository.InstalledAppRepository
import app.revanced.manager.domain.repository.ManagerUpdateRepository
import app.revanced.manager.domain.repository.PatchBundleRepository
import app.revanced.manager.domain.repository.PatchOptionsRepository
import app.revanced.manager.domain.repository.PatchSelectionRepository
import app.revanced.manager.domain.worker.WorkerRepository
import app.revanced.manager.network.api.ReVancedAPI
import org.koin.core.module.dsl.createdAtStart
Expand Down
24 changes: 22 additions & 2 deletions app/src/main/java/app/revanced/manager/di/ViewModelModule.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,27 @@
package app.revanced.manager.di

import app.revanced.manager.ui.viewmodel.*
import org.koin.core.module.dsl.*
import app.revanced.manager.ui.viewmodel.AboutViewModel
import app.revanced.manager.ui.viewmodel.AdvancedSettingsViewModel
import app.revanced.manager.ui.viewmodel.AnnouncementsViewModel
import app.revanced.manager.ui.viewmodel.AppsViewModel
import app.revanced.manager.ui.viewmodel.BundleInformationViewModel
import app.revanced.manager.ui.viewmodel.BundleListViewModel
import app.revanced.manager.ui.viewmodel.ChangelogsViewModel
import app.revanced.manager.ui.viewmodel.ContributorViewModel
import app.revanced.manager.ui.viewmodel.DashboardViewModel
import app.revanced.manager.ui.viewmodel.DeveloperOptionsViewModel
import app.revanced.manager.ui.viewmodel.DownloadsViewModel
import app.revanced.manager.ui.viewmodel.GeneralSettingsViewModel
import app.revanced.manager.ui.viewmodel.ImportExportViewModel
import app.revanced.manager.ui.viewmodel.InstalledAppInfoViewModel
import app.revanced.manager.ui.viewmodel.MainViewModel
import app.revanced.manager.ui.viewmodel.OnboardingViewModel
import app.revanced.manager.ui.viewmodel.PatcherViewModel
import app.revanced.manager.ui.viewmodel.PatchesSelectorViewModel
import app.revanced.manager.ui.viewmodel.SelectedAppInfoViewModel
import app.revanced.manager.ui.viewmodel.UpdateViewModel
import app.revanced.manager.ui.viewmodel.UpdatesSettingsViewModel
import org.koin.core.module.dsl.viewModelOf
import org.koin.dsl.module

val viewModelModule = module {
Expand Down
Loading
Loading