Skip to content

Commit 1501c6b

Browse files
authored
chore: Merge branch dev to main (#874)
2 parents fff144b + 918af5d commit 1501c6b

147 files changed

Lines changed: 3577 additions & 2542 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,95 @@
1+
# [1.27.0-dev.8](https://github.com/MorpheApp/morphe-manager/compare/v1.27.0-dev.7...v1.27.0-dev.8) (2026-08-21)
2+
3+
4+
### Bug Fixes
5+
6+
* Remove Simple mode theme color options and leftover dead code ([840eb7f](https://github.com/MorpheApp/morphe-manager/commit/840eb7fb2157b47986001af15254d283e55b2a4f))
7+
8+
# [1.27.0-dev.7](https://github.com/MorpheApp/morphe-manager/compare/v1.27.0-dev.6...v1.27.0-dev.7) (2026-08-21)
9+
10+
11+
### Bug Fixes
12+
13+
* Sources added after an app was configured stay out of its batch selection ([29262ce](https://github.com/MorpheApp/morphe-manager/commit/29262ce0b7793220817169f6712586e5ec82e6b7))
14+
15+
# [1.27.0-dev.6](https://github.com/MorpheApp/morphe-manager/compare/v1.27.0-dev.5...v1.27.0-dev.6) (2026-08-20)
16+
17+
18+
### Bug Fixes
19+
20+
* Retained patched APKs land in place only once written in full ([4228f3e](https://github.com/MorpheApp/morphe-manager/commit/4228f3ea7dedd8852a7cdb9584fe5da238c8ad4c))
21+
22+
23+
### Features
24+
25+
* Category rows in the patches list carry the color of the source they belong to ([29e4951](https://github.com/MorpheApp/morphe-manager/commit/29e49513f134991ea3d17cc338044ca08cd48f8a))
26+
27+
# [1.27.0-dev.5](https://github.com/MorpheApp/morphe-manager/compare/v1.27.0-dev.4...v1.27.0-dev.5) (2026-08-19)
28+
29+
30+
### Bug Fixes
31+
32+
* Keep the apksig ASN.1 members that signing builds by reflection ([222c6ca](https://github.com/MorpheApp/morphe-manager/commit/222c6cae56ffd016669a1c9dd6bb8a611f857738))
33+
34+
35+
### Features
36+
37+
* Batch patching offers the download helper and checks what it hands back ([f69f03a](https://github.com/MorpheApp/morphe-manager/commit/f69f03ae36d76d3086cc41145f016611b54b7ee2))
38+
39+
# [1.27.0-dev.4](https://github.com/MorpheApp/morphe-manager/compare/v1.27.0-dev.3...v1.27.0-dev.4) (2026-08-19)
40+
41+
42+
### Bug Fixes
43+
44+
* Badges only restyle their text where the background is actually known ([6a129fb](https://github.com/MorpheApp/morphe-manager/commit/6a129fbc319f8d4cd332358a6d7433b8d225974b))
45+
* Dialog status bar stays all white in light theme ([#879](https://github.com/MorpheApp/morphe-manager/issues/879)) ([d56be32](https://github.com/MorpheApp/morphe-manager/commit/d56be3283f8d3fbaec626e06a8cf8f83fe9bcbb0))
46+
* Fills and text on tinted cards stay distinct from what they sit on ([c29f375](https://github.com/MorpheApp/morphe-manager/commit/c29f375be5b1c6907a00657b4f0ae620913a2cdf))
47+
* Filter chips no longer blend into the sheet behind them ([b9f5a6a](https://github.com/MorpheApp/morphe-manager/commit/b9f5a6a5700d0a3e7c8e0ddf4093b21490e7ed88))
48+
* Hero card and monochrome section icons pick a tint their own fill supports ([5b81845](https://github.com/MorpheApp/morphe-manager/commit/5b81845e4a2db89a76fd2dc614a76e8ef3df80c5))
49+
* Hero card subtitles stay readable on their own tinted background ([ac77444](https://github.com/MorpheApp/morphe-manager/commit/ac77444301917dd341b170a73989c2410b0e69fc))
50+
* Home cards pick content and skeleton colors from the gradient they land on ([91e557e](https://github.com/MorpheApp/morphe-manager/commit/91e557e6fac9e6a8e7b78d66274f88771b35844c))
51+
* Selected tiles and tabs no longer invert their content on light accents ([cd57a13](https://github.com/MorpheApp/morphe-manager/commit/cd57a1333194f4ce207b164d03174849560b98c8))
52+
* Sticky search rows match the dialog body instead of the surface role ([f617a80](https://github.com/MorpheApp/morphe-manager/commit/f617a80438b486a82045d433015359e7cd7d6660))
53+
54+
55+
### Features
56+
57+
* Color picker works in hue, saturation and value instead of RGB sliders ([eb8b0c3](https://github.com/MorpheApp/morphe-manager/commit/eb8b0c3daf632bb8887b3dcacd8bea51550550bd))
58+
* Source sheet shows placeholders while the bundle store is still loading ([be9e7ba](https://github.com/MorpheApp/morphe-manager/commit/be9e7ba427843d1913d6399ae4c99af421687ee3))
59+
60+
# [1.27.0-dev.3](https://github.com/MorpheApp/morphe-manager/compare/v1.27.0-dev.2...v1.27.0-dev.3) (2026-08-18)
61+
62+
63+
### Bug Fixes
64+
65+
* Clone warning stays quiet for renames no selected patch asked for ([1ada7a7](https://github.com/MorpheApp/morphe-manager/commit/1ada7a783abd16fc219757391f1722299dedbd3c))
66+
* Content on a translucent fill keeps a readable contrast ([8fbd162](https://github.com/MorpheApp/morphe-manager/commit/8fbd1625b0a83dee12c4bf903279657942e31f9e))
67+
68+
# [1.27.0-dev.2](https://github.com/MorpheApp/morphe-manager/compare/v1.27.0-dev.1...v1.27.0-dev.2) (2026-08-18)
69+
70+
71+
### Bug Fixes
72+
73+
* Clone warning is read from the built APK instead of guessed from the patch list ([834aa4a](https://github.com/MorpheApp/morphe-manager/commit/834aa4a8b5d97ac79aab19817c22aef82d6d5d14))
74+
75+
76+
### Features
77+
78+
* Home app list can be filtered down to clones ([ba9ebda](https://github.com/MorpheApp/morphe-manager/commit/ba9ebdae3da2007b11bd89eefb935d7fce483d31))
79+
80+
# [1.27.0-dev.1](https://github.com/MorpheApp/morphe-manager/compare/v1.26.1...v1.27.0-dev.1) (2026-08-18)
81+
82+
83+
### Bug Fixes
84+
85+
* Expert mode patch cards are no longer covered by the scroll to top button ([fefcf97](https://github.com/MorpheApp/morphe-manager/commit/fefcf9755fcbd4ede6a374b8f8903372983f4051))
86+
* Universal patches carry the installer lock state like app-specific ones ([65988ee](https://github.com/MorpheApp/morphe-manager/commit/65988ee8aca7aadc346d61a033de805e20112ec9))
87+
88+
89+
### Features
90+
91+
* Universal patches fold behind a collapsible header in the patch lists ([f88d403](https://github.com/MorpheApp/morphe-manager/commit/f88d403245d4fa0915463b23bac3b0007db7e504))
92+
193
## [1.26.1](https://github.com/MorpheApp/morphe-manager/compare/v1.26.0...v1.26.1) (2026-08-18)
294

395

app-release.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
2-
"created_at": "2026-08-18T07:38:47",
3-
"description": "## [1.26.1](https://github.com/MorpheApp/morphe-manager/compare/v1.26.0...v1.26.1) (2026-08-18)\n\n\n### Bug Fixes\n\n* Progress gradient and card swipe actions mirror in RTL layouts ([9e0a087](https://github.com/MorpheApp/morphe-manager/commit/9e0a08757bf6196d2fe41d441dd3076ebd772437))",
4-
"download_url": "https://github.com/MorpheApp/morphe-manager/releases/download/v1.26.1/morphe-manager-1.26.1.apk",
5-
"signature_download_url": "https://github.com/MorpheApp/morphe-manager/releases/download/v1.26.1/morphe-manager-1.26.1.apk.asc",
6-
"version": "1.26.1"
2+
"created_at": "2026-08-21T21:17:56",
3+
"description": "# [1.27.0-dev.8](https://github.com/MorpheApp/morphe-manager/compare/v1.27.0-dev.7...v1.27.0-dev.8) (2026-08-21)\n\n\n### Bug Fixes\n\n* Remove Simple mode theme color options and leftover dead code ([840eb7f](https://github.com/MorpheApp/morphe-manager/commit/840eb7fb2157b47986001af15254d283e55b2a4f))",
4+
"download_url": "https://github.com/MorpheApp/morphe-manager/releases/download/v1.27.0-dev.8/morphe-manager-1.27.0-dev.8.apk",
5+
"signature_download_url": "https://github.com/MorpheApp/morphe-manager/releases/download/v1.27.0-dev.8/morphe-manager-1.27.0-dev.8.apk.asc",
6+
"version": "1.27.0-dev.8"
77
}

app/gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
version = 1.26.1
1+
version = 1.27.0-dev.8

app/proguard-rules.pro

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@
99
-keepnames class com.android.apksig.internal.** { *; }
1010
-keepnames class org.xmlpull.** { *; }
1111

12+
# apksig builds its ASN.1 models reflectively, so the no-arg constructors and the annotated
13+
# fields must survive shrinking or signing degrades to a fallback public key encoding
14+
-keepclassmembers class com.android.apksig.internal.** {
15+
<init>();
16+
<fields>;
17+
}
18+
1219
-dontwarn android.content.res.**
1320
-dontwarn com.google.j2objc.annotations.*
1421
-dontwarn java.awt.**

app/src/main/java/app/morphe/manager/MainActivity.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,8 @@ private fun MorpheManager(vm: MainViewModel) {
550550
Patcher.ViewModelParams(
551551
selectedApp = params.selectedApp,
552552
selectedPatches = params.patches,
553-
options = params.options
553+
options = params.options,
554+
targetPackageName = params.targetPackageName
554555
)
555556
)
556557
}

app/src/main/java/app/morphe/manager/domain/batch/BatchPatchCoordinator.kt

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,26 @@ class BatchPatchCoordinator(
181181
}
182182
}
183183

184+
/**
185+
* Accepts an APK the bundles do not vouch for, mirroring the single-app warning dialog.
186+
*
187+
* The item is resolved again rather than just flipped to runnable, because everything the
188+
* run needs was left unresolved while the file was in question.
189+
*/
190+
fun acceptUnverifiedSignature(itemId: String) {
191+
val current = _state.value ?: return
192+
if (current.phase != BatchPhase.PREFLIGHT) return
193+
val item = current.items.firstOrNull { it.id == itemId } ?: return
194+
if (item.state != BatchItemState.UNVERIFIED_SIGNATURE) return
195+
196+
scope.launch {
197+
val resolved = resolver.acceptUnverifiedSignature(item, current.useMount)
198+
_state.update { state ->
199+
state.copy(items = state.items.map { if (it.id == itemId) resolved else it })
200+
}
201+
}
202+
}
203+
184204
/**
185205
* Replaces what one queued app will be patched with, after the user edited it on the
186206
* preflight screen. Deselecting everything leaves nothing to run, which is the same
@@ -640,7 +660,9 @@ class BatchPatchCoordinator(
640660
val retained = fs.getPatchedAppFile(currentPackageName, version)
641661
val stored = runCatching {
642662
retained.parentFile?.mkdirs()
643-
outputFile.copyTo(retained, overwrite = true)
663+
// Staged, so a reader that refreshes while the copy runs never opens a half
664+
// written archive at the path the app already reports as the saved build
665+
copyThroughStaging(outputFile, retained)
644666
retained
645667
}.getOrElse {
646668
Log.w(TAG, "Failed to retain patched APK for ${item.packageName}", it)

app/src/main/java/app/morphe/manager/domain/batch/BatchPatchModels.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ enum class BatchItemState {
7979
/** The source version is not covered by any enabled bundle. */
8080
VERSION_MISMATCH,
8181

82+
/** The attached APK is not signed with a certificate the bundles declare for this app. */
83+
UNVERIFIED_SIGNATURE,
84+
8285
/** No enabled bundle contributes any patch for this package. */
8386
NO_PATCHES,
8487

@@ -94,7 +97,8 @@ enum class BatchItemState {
9497
val isRunnable get() = this == READY
9598

9699
/** True when the item is blocked by something the user can fix on the preflight screen. */
97-
val needsAttention get() = this == NEEDS_APK || this == VERSION_MISMATCH || this == NO_PATCHES
100+
val needsAttention get() =
101+
this == NEEDS_APK || this == VERSION_MISMATCH || this == UNVERIFIED_SIGNATURE || this == NO_PATCHES
98102

99103
val isTerminal get() = this == SUCCEEDED || this == FAILED || this == CANCELLED
100104
}
@@ -126,6 +130,8 @@ data class BatchBundleRef(
126130
* @param bundles Every enabled source that contributes patches to this app. An app covered by
127131
* more than one source is patched with all of them at once, exactly like the single-app flow.
128132
* @param forceVersionMismatch Set when the user chose to patch despite an unsupported version.
133+
* @param forceUnverifiedSignature Set when the user chose to patch an APK whose signing certificate
134+
* none of the bundles vouch for. Carried along so re-resolving the item does not ask again.
129135
* @param restoreState State to return to when the user un-excludes the item.
130136
* @param patchedFile Populated after a successful run with the retained patched APK.
131137
* @param installOutcome Set once the user installs from the summary, so a failure is visible
@@ -145,6 +151,7 @@ data class BatchPatchItem(
145151
/** Version the sources recommend, offered for download when the APK is missing or wrong. */
146152
val suggestedVersion: String? = null,
147153
val forceVersionMismatch: Boolean = false,
154+
val forceUnverifiedSignature: Boolean = false,
148155
/** Selection before the user narrowed it to one source, so another can still be chosen. */
149156
val resolvedSelection: PatchSelection? = null,
150157
val restoreState: BatchItemState? = null,

0 commit comments

Comments
 (0)