Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
53b5b5e
feat: skip back to home whitelist
killerprojecte Apr 30, 2026
90adf04
feat: disable double tap sleep/wakeup and high load mode for specific…
killerprojecte Apr 30, 2026
ff84b0f
fix: resolve deadlock by updating foreground activity method
killerprojecte May 2, 2026
a719321
ui: replace CircularProgressIndicator with InfiniteProgressIndicator …
ghhccghk May 1, 2026
1442626
feat: add device and OS information display in About screen
ghhccghk May 1, 2026
42dd4c6
refactor: replace PropTools with DeviceConfigTools for device informa…
ghhccghk May 2, 2026
75c66af
feat: add sub-screen version display and optimize blur effects
ghhccghk May 2, 2026
a75d94c
Merge pull request #15 from ghhccghk/dev
killerprojecte May 3, 2026
106d512
chore: improve about screen layout & the long-press trigger logic for…
killerprojecte May 4, 2026
36f540d
feat: add open-source licenses screen and improve sub-screen version …
ghhccghk May 4, 2026
ff2eafa
feat: add licenses entry to About screen
ghhccghk May 4, 2026
e7ac291
feat: restrict some hook is only load on devices that support rear sc…
killerprojecte May 4, 2026
e535ab8
Merge branch 'dev' into dev
killerprojecte May 4, 2026
e5fe9e2
chore: remove unused import
killerprojecte May 4, 2026
beaae19
Merge pull request #16 from ghhccghk/dev
killerprojecte May 4, 2026
a16532c
chore: move libraries reference card to page bottom & optimized about…
killerprojecte May 4, 2026
7d026cf
feat: widget info add requirements (configs & packages) & post-instal…
killerprojecte May 5, 2026
537ba68
fix: config category favourites will disappear after version change
killerprojecte May 6, 2026
e97dd85
feat: implement interactive license viewing and enhance LibraryItem UI
ghhccghk May 7, 2026
e43b33d
feat: custom app bounds manager & change logo design
killerprojecte May 9, 2026
9364aad
feat: use widget info for specific release versions
killerprojecte May 9, 2026
1764201
chore: improve about screen gradient effect
killerprojecte May 9, 2026
5cb4b1d
feat: custom background fill
killerprojecte May 10, 2026
28294a5
chore: improved license details visibility
killerprojecte May 10, 2026
968ffb5
chore: improved store scroll down effect
killerprojecte May 10, 2026
aedbc1e
feat: nav quick access
killerprojecte May 11, 2026
415fbc8
feat: custom bounds profile export / import
killerprojecte May 11, 2026
8fbaadd
feat: codename & show module version on about screen
killerprojecte May 11, 2026
1f37e9b
chore: remove qodana ci
killerprojecte May 11, 2026
b8baeb0
chore: directly query content schema uri on post-install & upgrade Gr…
killerprojecte May 11, 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
45 changes: 45 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.ksp)
alias(libs.plugins.compose.compiler)
alias(libs.plugins.serialization)
id("com.mikepenz.aboutlibraries.plugin")
}

val gitCommitCount: Int by lazy { runGitCommand("rev-list", "--count", "HEAD")?.toIntOrNull() ?: 0 }
Expand Down Expand Up @@ -42,6 +44,7 @@ android {
versionName = gropify.project.app.versionName
versionCode = gitVersionCode
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
buildConfigField("String", "BUILD_CHANNEL", "\"$buildSuffix\"")
}

signingConfigs {
Expand Down Expand Up @@ -120,6 +123,41 @@ androidComponents {
}
}

aboutLibraries {
offlineMode = false
collect {
configPath.file("config") // TODO(ASAP) libraries json ignored
fetchRemoteLicense.set(false)
}
export {
// Remove the "generated" timestamp to allow for reproducible builds
prettyPrint.set(true)
}
license {
// TODO https://github.com/mikepenz/AboutLibraries/issues/1190
strictMode = com.mikepenz.aboutlibraries.plugin.StrictMode.FAIL
allowedLicensesMap.put("Other", listOf("com.github.bumptech.glide:glide"))
allowedLicenses.addAll(
"Apache-2.0",
"LGPL",
"GNU Lesser General Public License v2.1",
"BSD-2-Clause",
"BSD-3-Clause",
"CC0-1.0",
"MIT",
"EPL-1.0",
"GPL-3.0-only",
"GNU Lesser General Public License v3.0"
)
}
library {
// Enable the duplication mode, allows to merge, or link dependencies which relate
duplicationMode.set(com.mikepenz.aboutlibraries.plugin.DuplicateMode.MERGE)
// Configure the duplication rule, to match "duplicates" with
duplicationRule.set(com.mikepenz.aboutlibraries.plugin.DuplicateRule.GROUP)
}
}

tasks.withType<KotlinJvmCompile>().configureEach {
compilerOptions {
jvmTarget = JvmTarget.JVM_17
Expand Down Expand Up @@ -157,6 +195,12 @@ dependencies {
implementation(libs.androidx.compose.ui.tooling.preview)
implementation(libs.androidx.compose.material3)
implementation(libs.androidx.compose.material.icons.extended)
implementation(libs.compose.icons.material.symbols.outlined.cmp)
implementation(libs.compose.icons.material.symbols.rounded.cmp)
implementation(libs.compose.icons.material.symbols.sharp.cmp)
implementation(libs.compose.icons.material.symbols.outlined.filled.cmp)
implementation(libs.compose.icons.material.symbols.rounded.filled.cmp)
implementation(libs.compose.icons.material.symbols.sharp.filled.cmp)
implementation(libs.androidx.activity.compose)
implementation(libs.androidx.lifecycle.runtime.compose)
implementation(libs.miuix.ui)
Expand All @@ -173,4 +217,5 @@ dependencies {
implementation(libs.lyricon.central)
implementation(libs.lyricon.subscriber)
implementation(libs.superlyric)
implementation(libs.kotlinx.serialization.json)
}
1 change: 1 addition & 0 deletions app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,6 @@

# --- Tool ---
-keep class hk.uwu.reareye.hook.** { *; }
-keep class hk.uwu.reareye.utils.other.AboutLibrariesToolsKt
-keep class com.hchen.superlyricapi.* {*;}
-dontwarn android.os.ServiceManager
11 changes: 11 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@
</intent-filter>
</activity-alias>

<provider
android:name=".provider.RearStoreArchiveContentProvider"
android:authorities="${applicationId}.archive.read"
android:exported="true"
tools:ignore="ExportedContentProvider" />

<service
android:name=".service.SwitchToRearTileService"
android:exported="true"
Expand Down Expand Up @@ -88,5 +94,10 @@
android:value="false" />
</service>


</application>

<queries>
<package android:name="com.xiaomi.subscreencenter" />
</queries>
</manifest>
11 changes: 11 additions & 0 deletions app/src/main/java/hk/uwu/reareye/hook/scopes/Scope.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
package hk.uwu.reareye.hook.scopes

import com.highcapable.kavaref.KavaRef.Companion.resolve
import com.highcapable.kavaref.extension.toClass
import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker

interface Scope {
val hooks: List<YukiBaseHooker>
val isRearDevice
get() = Companion.isRearDevice

companion object {
val isRearDevice: Boolean = "android.os.SystemProperties".toClass().resolve().firstMethod {
name = "getInt"
parameters(String::class.java, Int::class.java)
}.invoke<Int>("persist.sys.multi_display_type", 1) == 6
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package hk.uwu.reareye.hook.scopes.subscreencenter

import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker
import com.highcapable.yukihookapi.hook.log.YLog
import hk.uwu.reareye.hook.scopes.Scope
import hk.uwu.reareye.hook.scopes.subscreencenter.modules.MusicControlWhitelistModule
import hk.uwu.reareye.hook.scopes.subscreencenter.modules.RearWallpaperHook
import hk.uwu.reareye.hook.scopes.subscreencenter.modules.SubScreenBackHomeWhitelistModule
import hk.uwu.reareye.hook.scopes.subscreencenter.modules.VideoLoopModule
import hk.uwu.reareye.hook.scopes.subscreencenter.modules.VideoVolumeHook
import hk.uwu.reareye.hook.scopes.subscreencenter.modules.lyrics.LyriconHook
Expand All @@ -12,14 +14,23 @@ import hk.uwu.reareye.hook.scopes.subscreencenter.modules.rearwidget.RearWidgetH
import hk.uwu.reareye.hook.scopes.subscreencenter.modules.rearwidget.SystemUiNotificationBridgeHook

class SubscreenCenterScope : Scope {
override val hooks: List<YukiBaseHooker> = listOf(
MusicControlWhitelistModule(),
VideoLoopModule(),
RearWallpaperHook(),
RearWidgetHook(),
SystemUiNotificationBridgeHook(),
LyriconHook(),
VideoVolumeHook(),
ExtraTimeTipHook()
)
override val hooks: List<YukiBaseHooker> = buildList {
if (isRearDevice) {
addAll(
listOf(
MusicControlWhitelistModule(),
SubScreenBackHomeWhitelistModule(),
VideoLoopModule(),
RearWallpaperHook(),
RearWidgetHook(),
SystemUiNotificationBridgeHook(),
LyriconHook(),
VideoVolumeHook(),
ExtraTimeTipHook()
)
)
} else {
YLog.debug("This device is not support rear screen, skip load some features that this device is not supported")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -263,73 +263,73 @@ class RearWallpaperHook : YukiBaseHooker() {
YLog.warn(it)
}
}
val saveSelectionPoint =
resolveMainPanelSaveSelectionMethod(bridge)
resolveLauncherMainPanelFieldName()
resolveLauncherMainHandlerFieldName()
resolveMainPanelSelectMethod()
resolveMainPanelEditModeFieldName()
resolveMainPanelResumedFieldName()
resolveMainPanelAodFieldName()
resolveMainPanelSelectedIndexFieldName()
resolveMainPanelWidgetListFieldName()
resolveWidgetFactoryMethod()
resolveWallpaperSpecIdFieldName()
resolveWallpaperSpecExtrasFieldName()
resolveWidgetIdFieldName()
resolveWidgetSpecFieldName()
resolveWidgetExtrasFieldName()
resolveWidgetHostFieldName()
resolveWidgetPreviewModeFieldName()
resolveWidgetSetEditModeMethod()
resolveWidgetCreateViewMethod()
resolveWidgetSetAodMethod()
resolveWidgetResumeMethod()
resolveWidgetCleanupMethod()
resolvePrefStoreClass()
resolvePrefStoreInstanceFieldName()
resolvePrefStoreLoadSpecsMethod()
resolvePrefStoreReadValueMethod()
resolvePrefStoreWriteValueMethod()
resolveWallpaperRuntimeListMethod()
resolveDeviceConfigClass()
resolveDeviceConfigRenderSizeFieldName()
resolveDeviceConfigLocaleSuffixFieldName()

launcherRef.firstMethod {
name = "onResume"
parameterCount = 0
}.hook().after {
runCatching {
capturePanels(instance)
refreshSchedule(forceApply = true)
}.onFailure {
YLog.warn(it)
}
}
val saveSelectionPoint =
resolveMainPanelSaveSelectionMethod(bridge)
resolveLauncherMainPanelFieldName()
resolveLauncherMainHandlerFieldName()
resolveMainPanelSelectMethod()
resolveMainPanelEditModeFieldName()
resolveMainPanelResumedFieldName()
resolveMainPanelAodFieldName()
resolveMainPanelSelectedIndexFieldName()
resolveMainPanelWidgetListFieldName()
resolveWidgetFactoryMethod()
resolveWallpaperSpecIdFieldName()
resolveWallpaperSpecExtrasFieldName()
resolveWidgetIdFieldName()
resolveWidgetSpecFieldName()
resolveWidgetExtrasFieldName()
resolveWidgetHostFieldName()
resolveWidgetPreviewModeFieldName()
resolveWidgetSetEditModeMethod()
resolveWidgetCreateViewMethod()
resolveWidgetSetAodMethod()
resolveWidgetResumeMethod()
resolveWidgetCleanupMethod()
resolvePrefStoreClass()
resolvePrefStoreInstanceFieldName()
resolvePrefStoreLoadSpecsMethod()
resolvePrefStoreReadValueMethod()
resolvePrefStoreWriteValueMethod()
resolveWallpaperRuntimeListMethod()
resolveDeviceConfigClass()
resolveDeviceConfigRenderSizeFieldName()
resolveDeviceConfigLocaleSuffixFieldName()

launcherRef.firstMethod {
name = "onPause"
parameterCount = 0
}.hook().before {
debugLog("launcher onPause keep scheduler nextAt=${readNextSwitchAt()}")
}
launcherRef.firstMethod {
name = "onResume"
parameterCount = 0
}.hook().after {
runCatching {
capturePanels(instance)
refreshSchedule(forceApply = true)
}.onFailure {
YLog.warn(it)
}
}

launcherRef.firstMethod {
name = "onDestroy"
parameterCount = 0
}.hook().before {
stopScheduler()
mainPanel = null
mainHandler = null
}
launcherRef.firstMethod {
name = "onPause"
parameterCount = 0
}.hook().before {
debugLog("launcher onPause keep scheduler nextAt=${readNextSwitchAt()}")
}

saveSelectionPoint.className.toClass().resolve().firstMethod {
name = saveSelectionPoint.methodName
parameterCount = 0
}.hook().after {
updateSelectedWallpaperIdFromPanel(instance)
}
launcherRef.firstMethod {
name = "onDestroy"
parameterCount = 0
}.hook().before {
stopScheduler()
mainPanel = null
mainHandler = null
}

saveSelectionPoint.className.toClass().resolve().firstMethod {
name = saveSelectionPoint.methodName
parameterCount = 0
}.hook().after {
updateSelectedWallpaperIdFromPanel(instance)
}
}
}

Expand Down
Loading
Loading