Compare commits
7 commits
v6.1.0-dev
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b632d0f042 | ||
|
|
fca2470990 | ||
|
|
66b6c8c8ed | ||
|
|
4b699da220 | ||
|
|
e19275fb7d | ||
|
|
4bc8c7c0f6 | ||
|
|
e51c5292c1 |
14 changed files with 611 additions and 96 deletions
30
CHANGELOG.md
30
CHANGELOG.md
|
|
@ -1,3 +1,33 @@
|
|||
# [6.1.0](https://github.com/ReVanced/revanced-patches/compare/v6.0.1...v6.1.0) (2026-03-18)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Export internal data documents provider:** Correct S_IFLNK constant and symlink detection mask ([#6819](https://github.com/ReVanced/revanced-patches/issues/6819)) ([252617b](https://github.com/ReVanced/revanced-patches/commit/252617b8dd3f24e1ff9a04ba1d91b43dc29bd757))
|
||||
* **YouTube - Custom branding:** Fix double icons and change default branding to ReVanced ([#6806](https://github.com/ReVanced/revanced-patches/issues/6806)) ([e51c529](https://github.com/ReVanced/revanced-patches/commit/e51c5292c171325e7cfa0f5ee85474d9b3961a34))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Add `Spoof root of trust` and `Spoof keystore security level` patch ([#6751](https://github.com/ReVanced/revanced-patches/issues/6751)) ([4bc8c7c](https://github.com/ReVanced/revanced-patches/commit/4bc8c7c0f60a095533f07dc281f0320f8eb22f3c))
|
||||
* **Announcements:** Support ReVanced API v5 announcements ([a05386e](https://github.com/ReVanced/revanced-patches/commit/a05386e8bc24c085b5c74f3674c402c5dd5ad468))
|
||||
* Change contact email in patches about ([df1c3a4](https://github.com/ReVanced/revanced-patches/commit/df1c3a4a70fd2595d77b539299f1f7301bc60d24))
|
||||
* **Instagram:** Add `Enable location sticker redesign` patch ([#6808](https://github.com/ReVanced/revanced-patches/issues/6808)) ([4b699da](https://github.com/ReVanced/revanced-patches/commit/4b699da220e5d1527c390792b6228e2d9cffedb7))
|
||||
* **Spoof video streams:** Add Android Reel client to fix playback issues ([#6830](https://github.com/ReVanced/revanced-patches/issues/6830)) ([4b6c3e3](https://github.com/ReVanced/revanced-patches/commit/4b6c3e312328fbf6a1c7065e27d8ff04573e58be))
|
||||
|
||||
# [6.1.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v6.1.0-dev.3...v6.1.0-dev.4) (2026-03-18)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube - Custom branding:** Fix double icons and change default branding to ReVanced ([#6806](https://github.com/ReVanced/revanced-patches/issues/6806)) ([e51c529](https://github.com/ReVanced/revanced-patches/commit/e51c5292c171325e7cfa0f5ee85474d9b3961a34))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Add `Spoof root of trust` and `Spoof keystore security level` patch ([#6751](https://github.com/ReVanced/revanced-patches/issues/6751)) ([4bc8c7c](https://github.com/ReVanced/revanced-patches/commit/4bc8c7c0f60a095533f07dc281f0320f8eb22f3c))
|
||||
* **Instagram:** Add `Enable location sticker redesign` patch ([#6808](https://github.com/ReVanced/revanced-patches/issues/6808)) ([4b699da](https://github.com/ReVanced/revanced-patches/commit/4b699da220e5d1527c390792b6228e2d9cffedb7))
|
||||
|
||||
# [6.1.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v6.1.0-dev.2...v6.1.0-dev.3) (2026-03-18)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
package app.revanced.extension.playintegrity;
|
||||
package app.revanced.extension.play;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
|
@ -114,7 +114,7 @@ public class CustomBrandingPatch {
|
|||
|
||||
/**
|
||||
* Injection point.
|
||||
*
|
||||
* <p>
|
||||
* The total number of app name aliases, including dummy aliases.
|
||||
*/
|
||||
private static int numberOfPresetAppNames() {
|
||||
|
|
@ -146,13 +146,13 @@ public class CustomBrandingPatch {
|
|||
public static int getDefaultAppNameIndex() {
|
||||
return userProvidedCustomName()
|
||||
? numberOfPresetAppNames()
|
||||
: 1;
|
||||
: 2;
|
||||
}
|
||||
|
||||
public static BrandingTheme getDefaultIconStyle() {
|
||||
return userProvidedCustomIcon()
|
||||
? BrandingTheme.CUSTOM
|
||||
: BrandingTheme.ORIGINAL;
|
||||
: BrandingTheme.ROUNDED;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -4,4 +4,4 @@ org.gradle.parallel = true
|
|||
android.useAndroidX = true
|
||||
android.uniquePackageNames = false
|
||||
kotlin.code.style = official
|
||||
version = 6.1.0-dev.3
|
||||
version = 6.1.0
|
||||
|
|
|
|||
|
|
@ -89,10 +89,14 @@ public final class app/revanced/patches/all/misc/packagename/ChangePackageNamePa
|
|||
public static final fun setOrGetFallbackPackageName (Ljava/lang/String;)Ljava/lang/String;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/all/misc/playintegrity/DisablePlayIntegrityKt {
|
||||
public final class app/revanced/patches/all/misc/play/DisablePlayIntegrityKt {
|
||||
public static final fun getDisablePlayIntegrityPatch ()Lapp/revanced/patcher/patch/Patch;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/all/misc/play/SpoofPlayAgeSignalsKt {
|
||||
public static final fun getSpoofPlayAgeSignalsPatch ()Lapp/revanced/patcher/patch/Patch;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/all/misc/resources/AddResourcesPatchKt {
|
||||
public static final fun addResource (Ljava/lang/String;Lapp/revanced/util/resource/BaseResource;)Z
|
||||
public static final fun addResources (Lapp/revanced/patcher/patch/Patch;Lkotlin/jvm/functions/Function1;)Z
|
||||
|
|
@ -125,6 +129,14 @@ public final class app/revanced/patches/all/misc/spoof/EnableRomSignatureSpoofin
|
|||
public static final fun getEnableROMSignatureSpoofingPatch ()Lapp/revanced/patcher/patch/Patch;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/all/misc/spoof/SpoofKeystoreSecurityLevelPatchKt {
|
||||
public static final fun getSpoofKeystoreSecurityLevelPatch ()Lapp/revanced/patcher/patch/Patch;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/all/misc/spoof/SpoofRootOfTrustPatchKt {
|
||||
public static final fun getSpoofRootOfTrustPatch ()Lapp/revanced/patcher/patch/Patch;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/all/misc/targetSdk/SetTargetSdkVersion34Kt {
|
||||
public static final fun getSetTargetSDKVersion34Patch ()Lapp/revanced/patcher/patch/Patch;
|
||||
}
|
||||
|
|
@ -365,6 +377,10 @@ public final class app/revanced/patches/instagram/story/flipping/DisableStoryAut
|
|||
public static final fun getDisableStoryAutoFlippingPatch ()Lapp/revanced/patcher/patch/Patch;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/instagram/story/locationsticker/EnableLocationStickerRedesignPatchKt {
|
||||
public static final fun getEnableLocationStickerRedesignPatch ()Lapp/revanced/patcher/patch/Patch;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/irplus/ad/RemoveAdsPatchKt {
|
||||
public static final fun getRemoveAdsPatch ()Lapp/revanced/patcher/patch/Patch;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ import app.revanced.patcher.extensions.replaceInstruction
|
|||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patcher.patch.intOption
|
||||
import app.revanced.patcher.patch.stringOption
|
||||
import app.revanced.patches.all.misc.transformation.transformInstructionsPatch
|
||||
import app.revanced.util.forEachInstructionAsSequence
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.Instruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
|
@ -33,7 +34,8 @@ val spoofSIMProviderPatch = bytecodePatch(
|
|||
validator = { it: String? -> it == null || it.uppercase() in countries.values },
|
||||
)
|
||||
|
||||
fun isMccMncValid(it: Int?): Boolean = it == null || (it >= 10000 && it <= 999999)
|
||||
fun isMccMncValid(it: Int?) = it == null || (it in 10000..999999)
|
||||
fun isNumericValid(it: String?, length: Int) = it.isNullOrBlank() || it.equals("random", true) || it.length == length
|
||||
|
||||
val networkCountryIso by isoCountryPatchOption("Network ISO country code")
|
||||
|
||||
|
|
@ -61,46 +63,119 @@ val spoofSIMProviderPatch = bytecodePatch(
|
|||
description = "The full name of the SIM operator.",
|
||||
)
|
||||
|
||||
val imei by stringOption(
|
||||
name = "IMEI value",
|
||||
description = "15-digit IMEI to spoof, blank to skip, or 'random'.",
|
||||
validator = { isNumericValid(it, 15) },
|
||||
)
|
||||
|
||||
val meid by stringOption(
|
||||
name = "MEID value",
|
||||
description = "14-char hex MEID to spoof, blank to skip, or 'random'.",
|
||||
validator = { isNumericValid(it, 14) },
|
||||
)
|
||||
|
||||
val imsi by stringOption(
|
||||
name = "IMSI (Subscriber ID)",
|
||||
description = "15-digit IMSI to spoof, blank to skip, or 'random'.",
|
||||
validator = { isNumericValid(it, 15) },
|
||||
)
|
||||
|
||||
val iccid by stringOption(
|
||||
name = "ICCID (SIM Serial)",
|
||||
description = "19-digit ICCID to spoof, blank to skip, or 'random'.",
|
||||
validator = { isNumericValid(it, 19) },
|
||||
)
|
||||
|
||||
val phone by stringOption(
|
||||
name = "Phone number",
|
||||
description = "Phone number to spoof, blank to skip, or 'random'.",
|
||||
validator = { it.isNullOrBlank() || it.equals("random", ignoreCase = true) || it.startsWith("+") },
|
||||
)
|
||||
|
||||
dependsOn(
|
||||
transformInstructionsPatch(
|
||||
filterMap = { _, _, instruction, instructionIndex ->
|
||||
if (instruction !is ReferenceInstruction) return@transformInstructionsPatch null
|
||||
bytecodePatch {
|
||||
apply {
|
||||
fun generateRandomNumeric(length: Int) = (1..length).map { ('0'..'9').random() }.joinToString("")
|
||||
|
||||
val reference = instruction.reference as? MethodReference ?: return@transformInstructionsPatch null
|
||||
|
||||
val match = MethodCall.entries.firstOrNull { search ->
|
||||
MethodUtil.methodSignaturesMatch(reference, search.reference)
|
||||
} ?: return@transformInstructionsPatch null
|
||||
|
||||
val replacement = when (match) {
|
||||
MethodCall.NetworkCountryIso -> networkCountryIso?.lowercase()
|
||||
MethodCall.NetworkOperator -> networkOperator?.toString()
|
||||
MethodCall.NetworkOperatorName -> networkOperatorName
|
||||
MethodCall.SimCountryIso -> simCountryIso?.lowercase()
|
||||
MethodCall.SimOperator -> simOperator?.toString()
|
||||
MethodCall.SimOperatorName -> simOperatorName
|
||||
fun String?.computeSpoof(randomizer: () -> String): String? {
|
||||
if (this.isNullOrBlank()) return null
|
||||
if (this.equals("random", ignoreCase = true)) return randomizer()
|
||||
return this
|
||||
}
|
||||
replacement?.let { instructionIndex to it }
|
||||
},
|
||||
transform = ::transformMethodCall,
|
||||
),
|
||||
|
||||
// Calculate the Luhn checksum (mod 10) to generate a valid 15th digit, standard for IMEI numbers.
|
||||
// Structure of an IMEI is as follows:
|
||||
// TAC (Type Allocation Code): First 8 digits (e.g., "86" + 6 digits)
|
||||
// SNR (Serial Number): Next 6 digits
|
||||
// CD (Check Digit): The 15th digit
|
||||
val computedImei = imei.computeSpoof {
|
||||
val prefix = "86" + generateRandomNumeric(12)
|
||||
|
||||
val sum = prefix.mapIndexed { i, c ->
|
||||
var d = c.digitToInt()
|
||||
// Double every second digit (index 1, 3, 5...).
|
||||
if (i % 2 != 0) {
|
||||
d *= 2
|
||||
// If result is two digits (e.g. 14), sum them (1+4=5).
|
||||
// This is mathematically equivalent to d - 9.
|
||||
if (d > 9) d -= 9
|
||||
}
|
||||
d
|
||||
}.sum()
|
||||
// Append the calculated check digit to the 14-digit prefix.
|
||||
prefix + ((10 - (sum % 10)) % 10)
|
||||
}
|
||||
|
||||
val computedMeid = meid.computeSpoof { (1..14).map { "0123456789ABCDEF".random() }.joinToString("") }?.uppercase()
|
||||
val computedImsi = imsi.computeSpoof { generateRandomNumeric(15) }
|
||||
val computedIccid = iccid.computeSpoof { "89" + generateRandomNumeric(17) }
|
||||
val computedPhone = phone.computeSpoof { "+" + generateRandomNumeric(11) }
|
||||
|
||||
forEachInstructionAsSequence(
|
||||
match = { _, _, instruction, instructionIndex ->
|
||||
if (instruction !is ReferenceInstruction) return@forEachInstructionAsSequence null
|
||||
|
||||
val reference = instruction.reference as? MethodReference ?: return@forEachInstructionAsSequence null
|
||||
|
||||
val match = MethodCall.entries.firstOrNull { search ->
|
||||
MethodUtil.methodSignaturesMatch(reference, search.reference)
|
||||
} ?: return@forEachInstructionAsSequence null
|
||||
|
||||
val replacement = when (match) {
|
||||
MethodCall.NetworkCountryIso -> networkCountryIso?.lowercase()
|
||||
MethodCall.NetworkOperator -> networkOperator?.toString()
|
||||
MethodCall.NetworkOperatorName -> networkOperatorName
|
||||
MethodCall.SimCountryIso -> simCountryIso?.lowercase()
|
||||
MethodCall.SimOperator -> simOperator?.toString()
|
||||
MethodCall.SimOperatorName -> simOperatorName
|
||||
MethodCall.Imei, MethodCall.ImeiWithSlot, MethodCall.DeviceId, MethodCall.DeviceIdWithSlot -> computedImei
|
||||
MethodCall.Meid, MethodCall.MeidWithSlot -> computedMeid
|
||||
MethodCall.SubscriberId, MethodCall.SubscriberIdWithSlot -> computedImsi
|
||||
MethodCall.SimSerialNumber, MethodCall.SimSerialNumberWithSlot -> computedIccid
|
||||
MethodCall.Line1Number, MethodCall.Line1NumberWithSlot -> computedPhone
|
||||
}
|
||||
replacement?.let { instructionIndex to it }
|
||||
},
|
||||
transform = ::transformMethodCall
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private fun transformMethodCall(
|
||||
mutableMethod: MutableMethod,
|
||||
entry: Pair<Int, String>,
|
||||
) {
|
||||
val (instructionIndex, methodCallValue) = entry
|
||||
private fun transformMethodCall(mutableMethod: MutableMethod, entry: Pair<Int, String>) {
|
||||
val (index, value) = entry
|
||||
val nextInstr = mutableMethod.getInstruction<Instruction>(index + 1)
|
||||
|
||||
// Get the register which would have contained the return value
|
||||
val register = mutableMethod.getInstruction<OneRegisterInstruction>(instructionIndex + 1).registerA
|
||||
if (nextInstr.opcode.name != "move-result-object") {
|
||||
mutableMethod.replaceInstruction(index, "nop")
|
||||
return
|
||||
}
|
||||
|
||||
// Replace the move-result instruction with our fake value
|
||||
mutableMethod.replaceInstruction(
|
||||
instructionIndex + 1,
|
||||
"const-string v$register, \"$methodCallValue\"",
|
||||
)
|
||||
val register = (nextInstr as OneRegisterInstruction).registerA
|
||||
mutableMethod.replaceInstruction(index, "const-string v$register, \"$value\"")
|
||||
mutableMethod.replaceInstruction(index + 1, "nop")
|
||||
}
|
||||
|
||||
private enum class MethodCall(
|
||||
|
|
@ -154,4 +229,100 @@ private enum class MethodCall(
|
|||
"Ljava/lang/String;",
|
||||
),
|
||||
),
|
||||
Imei(
|
||||
ImmutableMethodReference(
|
||||
"Landroid/telephony/TelephonyManager;",
|
||||
"getImei",
|
||||
emptyList(),
|
||||
"Ljava/lang/String;"
|
||||
),
|
||||
),
|
||||
ImeiWithSlot(
|
||||
ImmutableMethodReference(
|
||||
"Landroid/telephony/TelephonyManager;",
|
||||
"getImei",
|
||||
listOf("I"),
|
||||
"Ljava/lang/String;"
|
||||
),
|
||||
),
|
||||
DeviceId(
|
||||
ImmutableMethodReference(
|
||||
"Landroid/telephony/TelephonyManager;",
|
||||
"getDeviceId",
|
||||
emptyList(),
|
||||
"Ljava/lang/String;"
|
||||
),
|
||||
),
|
||||
DeviceIdWithSlot(
|
||||
ImmutableMethodReference(
|
||||
"Landroid/telephony/TelephonyManager;",
|
||||
"getDeviceId",
|
||||
listOf("I"),
|
||||
"Ljava/lang/String;"
|
||||
),
|
||||
),
|
||||
Meid(
|
||||
ImmutableMethodReference(
|
||||
"Landroid/telephony/TelephonyManager;",
|
||||
"getMeid",
|
||||
emptyList(),
|
||||
"Ljava/lang/String;"
|
||||
),
|
||||
),
|
||||
MeidWithSlot(
|
||||
ImmutableMethodReference(
|
||||
"Landroid/telephony/TelephonyManager;",
|
||||
"getMeid",
|
||||
listOf("I"),
|
||||
"Ljava/lang/String;"
|
||||
),
|
||||
),
|
||||
SubscriberId(
|
||||
ImmutableMethodReference(
|
||||
"Landroid/telephony/TelephonyManager;",
|
||||
"getSubscriberId",
|
||||
emptyList(),
|
||||
"Ljava/lang/String;"
|
||||
)
|
||||
),
|
||||
SubscriberIdWithSlot(
|
||||
ImmutableMethodReference(
|
||||
"Landroid/telephony/TelephonyManager;",
|
||||
"getSubscriberId",
|
||||
listOf("I"),
|
||||
"Ljava/lang/String;"
|
||||
)
|
||||
),
|
||||
SimSerialNumber(
|
||||
ImmutableMethodReference(
|
||||
"Landroid/telephony/TelephonyManager;",
|
||||
"getSimSerialNumber",
|
||||
emptyList(),
|
||||
"Ljava/lang/String;"
|
||||
)
|
||||
),
|
||||
SimSerialNumberWithSlot(
|
||||
ImmutableMethodReference(
|
||||
"Landroid/telephony/TelephonyManager;",
|
||||
"getSimSerialNumber",
|
||||
listOf("I"),
|
||||
"Ljava/lang/String;"
|
||||
)
|
||||
),
|
||||
Line1Number(
|
||||
ImmutableMethodReference(
|
||||
"Landroid/telephony/TelephonyManager;",
|
||||
"getLine1Number",
|
||||
emptyList(),
|
||||
"Ljava/lang/String;"
|
||||
)
|
||||
),
|
||||
Line1NumberWithSlot(
|
||||
ImmutableMethodReference(
|
||||
"Landroid/telephony/TelephonyManager;",
|
||||
"getLine1Number",
|
||||
listOf("I"),
|
||||
"Ljava/lang/String;"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package app.revanced.patches.all.misc.connectivity.wifi.spoof
|
|||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patches.all.misc.transformation.IMethodCall
|
||||
import app.revanced.patches.all.misc.transformation.filterMapInstruction35c
|
||||
import app.revanced.patches.all.misc.transformation.transformInstructionsPatch
|
||||
import app.revanced.util.forEachInstructionAsSequence
|
||||
|
||||
private const val EXTENSION_CLASS_DESCRIPTOR_PREFIX =
|
||||
"Lapp/revanced/extension/all/misc/connectivity/wifi/spoof/SpoofWifiPatch"
|
||||
|
|
@ -19,29 +19,32 @@ val spoofWiFiConnectionPatch = bytecodePatch(
|
|||
extendWith("extensions/all/misc/connectivity/wifi/spoof/spoof-wifi.rve")
|
||||
|
||||
dependsOn(
|
||||
transformInstructionsPatch(
|
||||
filterMap = { classDef, _, instruction, instructionIndex ->
|
||||
filterMapInstruction35c<MethodCall>(
|
||||
EXTENSION_CLASS_DESCRIPTOR_PREFIX,
|
||||
classDef,
|
||||
instruction,
|
||||
instructionIndex,
|
||||
)
|
||||
},
|
||||
transform = { method, entry ->
|
||||
val (methodType, instruction, instructionIndex) = entry
|
||||
methodType.replaceInvokeVirtualWithExtension(
|
||||
EXTENSION_CLASS_DESCRIPTOR,
|
||||
method,
|
||||
instruction,
|
||||
instructionIndex,
|
||||
)
|
||||
},
|
||||
),
|
||||
bytecodePatch {
|
||||
apply {
|
||||
forEachInstructionAsSequence(
|
||||
match = { classDef, _, instruction, instructionIndex ->
|
||||
filterMapInstruction35c<MethodCall>(
|
||||
EXTENSION_CLASS_DESCRIPTOR_PREFIX,
|
||||
classDef,
|
||||
instruction,
|
||||
instructionIndex,
|
||||
)
|
||||
},
|
||||
transform = { method, entry ->
|
||||
val (methodType, instruction, instructionIndex) = entry
|
||||
methodType.replaceInvokeVirtualWithExtension(
|
||||
EXTENSION_CLASS_DESCRIPTOR,
|
||||
method,
|
||||
instruction,
|
||||
instructionIndex,
|
||||
)
|
||||
})
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// Information about method calls we want to replace
|
||||
// Information about method calls we want to replace.
|
||||
@Suppress("unused")
|
||||
private enum class MethodCall(
|
||||
override val definedClassName: String,
|
||||
|
|
@ -89,13 +92,13 @@ private enum class MethodCall(
|
|||
"Landroid/net/NetworkInfo;",
|
||||
"getState",
|
||||
arrayOf(),
|
||||
"Landroid/net/NetworkInfo\$State;",
|
||||
$$"Landroid/net/NetworkInfo$State;",
|
||||
),
|
||||
GetDetailedState(
|
||||
"Landroid/net/NetworkInfo;",
|
||||
"getDetailedState",
|
||||
arrayOf(),
|
||||
"Landroid/net/NetworkInfo\$DetailedState;",
|
||||
$$"Landroid/net/NetworkInfo$DetailedState;",
|
||||
),
|
||||
IsActiveNetworkMetered(
|
||||
"Landroid/net/ConnectivityManager;",
|
||||
|
|
@ -132,7 +135,7 @@ private enum class MethodCall(
|
|||
"registerBestMatchingNetworkCallback",
|
||||
arrayOf(
|
||||
"Landroid/net/NetworkRequest;",
|
||||
"Landroid/net/ConnectivityManager\$NetworkCallback;",
|
||||
$$"Landroid/net/ConnectivityManager$NetworkCallback;",
|
||||
"Landroid/os/Handler;",
|
||||
),
|
||||
"V",
|
||||
|
|
@ -140,19 +143,19 @@ private enum class MethodCall(
|
|||
RegisterDefaultNetworkCallback1(
|
||||
"Landroid/net/ConnectivityManager;",
|
||||
"registerDefaultNetworkCallback",
|
||||
arrayOf("Landroid/net/ConnectivityManager\$NetworkCallback;"),
|
||||
arrayOf($$"Landroid/net/ConnectivityManager$NetworkCallback;"),
|
||||
"V",
|
||||
),
|
||||
RegisterDefaultNetworkCallback2(
|
||||
"Landroid/net/ConnectivityManager;",
|
||||
"registerDefaultNetworkCallback",
|
||||
arrayOf("Landroid/net/ConnectivityManager\$NetworkCallback;", "Landroid/os/Handler;"),
|
||||
arrayOf($$"Landroid/net/ConnectivityManager$NetworkCallback;", "Landroid/os/Handler;"),
|
||||
"V",
|
||||
),
|
||||
RegisterNetworkCallback1(
|
||||
"Landroid/net/ConnectivityManager;",
|
||||
"registerNetworkCallback",
|
||||
arrayOf("Landroid/net/NetworkRequest;", "Landroid/net/ConnectivityManager\$NetworkCallback;"),
|
||||
arrayOf("Landroid/net/NetworkRequest;", $$"Landroid/net/ConnectivityManager$NetworkCallback;"),
|
||||
"V",
|
||||
),
|
||||
RegisterNetworkCallback2(
|
||||
|
|
@ -166,7 +169,7 @@ private enum class MethodCall(
|
|||
"registerNetworkCallback",
|
||||
arrayOf(
|
||||
"Landroid/net/NetworkRequest;",
|
||||
"Landroid/net/ConnectivityManager\$NetworkCallback;",
|
||||
$$"Landroid/net/ConnectivityManager$NetworkCallback;",
|
||||
"Landroid/os/Handler;",
|
||||
),
|
||||
"V",
|
||||
|
|
@ -174,13 +177,13 @@ private enum class MethodCall(
|
|||
RequestNetwork1(
|
||||
"Landroid/net/ConnectivityManager;",
|
||||
"requestNetwork",
|
||||
arrayOf("Landroid/net/NetworkRequest;", "Landroid/net/ConnectivityManager\$NetworkCallback;"),
|
||||
arrayOf("Landroid/net/NetworkRequest;", $$"Landroid/net/ConnectivityManager$NetworkCallback;"),
|
||||
"V",
|
||||
),
|
||||
RequestNetwork2(
|
||||
"Landroid/net/ConnectivityManager;",
|
||||
"requestNetwork",
|
||||
arrayOf("Landroid/net/NetworkRequest;", "Landroid/net/ConnectivityManager\$NetworkCallback;", "I"),
|
||||
arrayOf("Landroid/net/NetworkRequest;", $$"Landroid/net/ConnectivityManager$NetworkCallback;", "I"),
|
||||
"V",
|
||||
),
|
||||
RequestNetwork3(
|
||||
|
|
@ -188,7 +191,7 @@ private enum class MethodCall(
|
|||
"requestNetwork",
|
||||
arrayOf(
|
||||
"Landroid/net/NetworkRequest;",
|
||||
"Landroid/net/ConnectivityManager\$NetworkCallback;",
|
||||
$$"Landroid/net/ConnectivityManager$NetworkCallback;",
|
||||
"Landroid/os/Handler;",
|
||||
),
|
||||
"V",
|
||||
|
|
@ -204,7 +207,7 @@ private enum class MethodCall(
|
|||
"requestNetwork",
|
||||
arrayOf(
|
||||
"Landroid/net/NetworkRequest;",
|
||||
"Landroid/net/ConnectivityManager\$NetworkCallback;",
|
||||
$$"Landroid/net/ConnectivityManager$NetworkCallback;",
|
||||
"Landroid/os/Handler;",
|
||||
"I",
|
||||
),
|
||||
|
|
@ -213,7 +216,7 @@ private enum class MethodCall(
|
|||
UnregisterNetworkCallback1(
|
||||
"Landroid/net/ConnectivityManager;",
|
||||
"unregisterNetworkCallback",
|
||||
arrayOf("Landroid/net/ConnectivityManager\$NetworkCallback;"),
|
||||
arrayOf($$"Landroid/net/ConnectivityManager$NetworkCallback;"),
|
||||
"V",
|
||||
),
|
||||
UnregisterNetworkCallback2(
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
package app.revanced.patches.all.misc.playintegrity
|
||||
package app.revanced.patches.all.misc.play
|
||||
|
||||
import app.revanced.patcher.extensions.replaceInstruction
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
|
|
@ -9,7 +9,7 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
|||
import com.android.tools.smali.dexlib2.immutable.reference.ImmutableMethodReference
|
||||
import com.android.tools.smali.dexlib2.util.MethodUtil
|
||||
|
||||
private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/playintegrity/DisablePlayIntegrityPatch;"
|
||||
private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/play/DisablePlayIntegrityPatch;"
|
||||
|
||||
private val CONTEXT_BIND_SERVICE_METHOD_REFERENCE = ImmutableMethodReference(
|
||||
"Landroid/content/Context;",
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
package app.revanced.patches.all.misc.play
|
||||
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.extensions.getInstruction
|
||||
import app.revanced.patcher.extensions.removeInstructions
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patcher.patch.intOption
|
||||
import app.revanced.patcher.patch.option
|
||||
import app.revanced.util.forEachInstructionAsSequence
|
||||
import app.revanced.util.getReference
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
import com.android.tools.smali.dexlib2.immutable.reference.ImmutableMethodReference
|
||||
|
||||
@Suppress("unused")
|
||||
val spoofPlayAgeSignalsPatch = bytecodePatch(
|
||||
name = "Spoof Play Age Signals",
|
||||
description = "Spoofs Google Play data about the user's age and verification status.",
|
||||
use = false,
|
||||
) {
|
||||
val lowerAgeBound by intOption(
|
||||
name = "Lower age bound",
|
||||
description = "A positive integer.",
|
||||
default = 18,
|
||||
validator = { it == null || it > 0 },
|
||||
)
|
||||
|
||||
val upperAgeBound by intOption(
|
||||
name = "Upper age bound",
|
||||
description = "A positive integer. Must be greater than the lower age bound.",
|
||||
default = Int.MAX_VALUE,
|
||||
validator = { it == null || it > lowerAgeBound!! },
|
||||
)
|
||||
|
||||
val userStatus by intOption(
|
||||
name = "User status",
|
||||
description = "An integer representing the user status.",
|
||||
default = UserStatus.VERIFIED.value,
|
||||
values = UserStatus.entries.associate { it.name to it.value },
|
||||
)
|
||||
|
||||
apply {
|
||||
forEachInstructionAsSequence(match = { classDef, _, instruction, instructionIndex ->
|
||||
// Avoid patching the library itself.
|
||||
if (classDef.type.startsWith("Lcom/google/android/play/agesignals/")) return@forEachInstructionAsSequence null
|
||||
|
||||
// Keep method calls only.
|
||||
val reference = instruction.getReference<MethodReference>()
|
||||
?: return@forEachInstructionAsSequence null
|
||||
|
||||
val match = MethodCall.entries.firstOrNull {
|
||||
reference == it.reference
|
||||
} ?: return@forEachInstructionAsSequence null
|
||||
|
||||
val replacement = when (match) {
|
||||
MethodCall.AgeLower -> lowerAgeBound!!
|
||||
MethodCall.AgeUpper -> upperAgeBound!!
|
||||
MethodCall.UserStatus -> userStatus!!
|
||||
}
|
||||
|
||||
replacement.let { instructionIndex to it }
|
||||
}, transform = { method, entry ->
|
||||
val (instructionIndex, replacement) = entry
|
||||
|
||||
// Get the register which would have contained the return value.
|
||||
val register = method.getInstruction<OneRegisterInstruction>(instructionIndex + 1).registerA
|
||||
|
||||
// Replace the call instructions with the spoofed value.
|
||||
method.removeInstructions(instructionIndex, 2)
|
||||
method.addInstructions(
|
||||
instructionIndex,
|
||||
"""
|
||||
const v$register, $replacement
|
||||
invoke-static { v$register }, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;
|
||||
move-result-object v$register
|
||||
""".trimIndent(),
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See [AgeSignalsResult](https://developer.android.com/google/play/age-signals/reference/com/google/android/play/agesignals/AgeSignalsResult).
|
||||
*/
|
||||
private enum class MethodCall(
|
||||
val reference: MethodReference,
|
||||
) {
|
||||
AgeLower(
|
||||
ImmutableMethodReference(
|
||||
"Lcom/google/android/play/agesignals/AgeSignalsResult;",
|
||||
"ageLower",
|
||||
emptyList(),
|
||||
"Ljava/lang/Integer;",
|
||||
),
|
||||
),
|
||||
AgeUpper(
|
||||
ImmutableMethodReference(
|
||||
"Lcom/google/android/play/agesignals/AgeSignalsResult;",
|
||||
"ageUpper",
|
||||
emptyList(),
|
||||
"Ljava/lang/Integer;",
|
||||
),
|
||||
),
|
||||
UserStatus(
|
||||
ImmutableMethodReference(
|
||||
"Lcom/google/android/play/agesignals/AgeSignalsResult;",
|
||||
"userStatus",
|
||||
emptyList(),
|
||||
"Ljava/lang/Integer;",
|
||||
),
|
||||
),
|
||||
}
|
||||
|
||||
/**
|
||||
* All possible user verification statuses.
|
||||
*
|
||||
* See [AgeSignalsVerificationStatus](https://developer.android.com/google/play/age-signals/reference/com/google/android/play/agesignals/model/AgeSignalsVerificationStatus).
|
||||
*/
|
||||
private enum class UserStatus(val value: Int) {
|
||||
/** The user provided their age, but it hasn't been verified yet. */
|
||||
DECLARED(5),
|
||||
|
||||
/** The user is 18+. */
|
||||
VERIFIED(0),
|
||||
|
||||
/** The user's guardian has set the age for him. */
|
||||
SUPERVISED(1),
|
||||
|
||||
/** The user's guardian hasn't approved the significant changes yet. */
|
||||
SUPERVISED_APPROVAL_PENDING(2),
|
||||
|
||||
/** The user's guardian has denied approval for one or more pending significant changes. */
|
||||
SUPERVISED_APPROVAL_DENIED(3),
|
||||
|
||||
/** The user is not verified or supervised. */
|
||||
UNKNOWN(4),
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package app.revanced.patches.all.misc.spoof
|
||||
|
||||
import app.revanced.patcher.extensions.replaceInstructions
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.util.forEachInstructionAsSequence
|
||||
|
||||
@Suppress("unused")
|
||||
val spoofKeystoreSecurityLevelPatch = bytecodePatch(
|
||||
name = "Spoof keystore security level",
|
||||
description = "Forces apps to see Keymaster and Attestation security levels as 'StrongBox' (Level 2).",
|
||||
use = false
|
||||
) {
|
||||
apply {
|
||||
forEachInstructionAsSequence(
|
||||
match = { _, method, _, _ ->
|
||||
// Match methods by comparing the current method to a reference criteria.
|
||||
val name = method.name.lowercase()
|
||||
if (name.contains("securitylevel") && method.returnType == "I") method else null
|
||||
},
|
||||
transform = { mutableMethod, _ ->
|
||||
// Ensure the method has an implementation before replacing.
|
||||
if (mutableMethod.implementation?.instructions?.iterator()?.hasNext() == true) {
|
||||
mutableMethod.replaceInstructions(0, "const/4 v0, 0x2\nreturn v0")
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
package app.revanced.patches.all.misc.spoof
|
||||
|
||||
import app.revanced.patcher.extensions.replaceInstructions
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.util.forEachInstructionAsSequence
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
import com.android.tools.smali.dexlib2.immutable.reference.ImmutableMethodReference
|
||||
import com.android.tools.smali.dexlib2.util.MethodUtil
|
||||
|
||||
@Suppress("unused")
|
||||
val spoofRootOfTrustPatch = bytecodePatch(
|
||||
name = "Spoof root of trust",
|
||||
description = "Spoofs device integrity states (Locked Bootloader, Verified OS) for apps that perform local certificate attestation.",
|
||||
use = false
|
||||
) {
|
||||
apply {
|
||||
forEachInstructionAsSequence(
|
||||
match = { _, method, _, _ ->
|
||||
MethodCall.entries.firstOrNull { MethodUtil.methodSignaturesMatch(method, it.reference) }
|
||||
},
|
||||
transform = { mutableMethod, methodCall ->
|
||||
if (mutableMethod.implementation?.instructions?.iterator()?.hasNext() == true) {
|
||||
mutableMethod.replaceInstructions(0, methodCall.replacementInstructions)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private enum class MethodCall(
|
||||
val reference: MethodReference,
|
||||
val replacementInstructions: String,
|
||||
) {
|
||||
IsDeviceLockedRootOfTrust(
|
||||
ImmutableMethodReference(
|
||||
"LRootOfTrust;",
|
||||
"isDeviceLocked",
|
||||
emptyList(),
|
||||
"Z"
|
||||
),
|
||||
"const/4 v0, 0x1\nreturn v0",
|
||||
),
|
||||
GetVerifiedBootStateRootOfTrust(
|
||||
ImmutableMethodReference(
|
||||
"LRootOfTrust;",
|
||||
"getVerifiedBootState",
|
||||
emptyList(),
|
||||
"I"
|
||||
),
|
||||
"const/4 v0, 0x0\nreturn v0",
|
||||
),
|
||||
IsDeviceLockedAttestation(
|
||||
ImmutableMethodReference(
|
||||
"LAttestation;",
|
||||
"isDeviceLocked",
|
||||
emptyList(),
|
||||
"Z"
|
||||
),
|
||||
"const/4 v0, 0x1\nreturn v0",
|
||||
),
|
||||
GetVerifiedBootStateAttestation(
|
||||
ImmutableMethodReference(
|
||||
"LAttestation;",
|
||||
"getVerifiedBootState",
|
||||
emptyList(),
|
||||
"I"
|
||||
),
|
||||
"const/4 v0, 0x0\nreturn v0",
|
||||
),
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package app.revanced.patches.instagram.story.locationsticker
|
||||
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.util.returnEarly
|
||||
|
||||
@Suppress("unused")
|
||||
val enableLocationStickerRedesignPatch = bytecodePatch(
|
||||
name = "Enable location sticker redesign",
|
||||
description = "Unlocks the redesigned location sticker with additional style options.",
|
||||
use = false,
|
||||
) {
|
||||
compatibleWith("com.instagram.android")
|
||||
|
||||
apply {
|
||||
// The gate method reads a MobileConfig boolean flag and returns it directly.
|
||||
// Returning early with true bypasses the flag check entirely,
|
||||
// enabling the redesigned sticker styles regardless of server configuration.
|
||||
locationStickerRedesignGateMethodMatch.method.returnEarly(true)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package app.revanced.patches.instagram.story.locationsticker
|
||||
|
||||
import app.revanced.patcher.composingFirstMethod
|
||||
import app.revanced.patcher.instructions
|
||||
import app.revanced.patcher.invoke
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
|
||||
// MobileConfig boolean key that gates the redesigned location sticker styles.
|
||||
// The method containing this constant reads the flag and returns it directly,
|
||||
// making it the sole control point for the feature. The key is stable across
|
||||
// app updates as MobileConfig keys are server-assigned constants.
|
||||
private const val LOCATION_STICKER_REDESIGN_CONFIG_KEY = 0x8105a100041e0dL
|
||||
|
||||
internal val BytecodePatchContext.locationStickerRedesignGateMethodMatch by composingFirstMethod {
|
||||
instructions(LOCATION_STICKER_REDESIGN_CONFIG_KEY())
|
||||
}
|
||||
|
|
@ -3,7 +3,6 @@ package app.revanced.patches.shared.layout.branding
|
|||
import app.revanced.com.android.tools.smali.dexlib2.mutable.MutableMethod
|
||||
import app.revanced.patcher.extensions.addInstruction
|
||||
import app.revanced.patcher.extensions.getInstruction
|
||||
import app.revanced.patcher.firstImmutableClassDef
|
||||
import app.revanced.patcher.patch.*
|
||||
import app.revanced.patches.all.misc.packagename.setOrGetFallbackPackageName
|
||||
import app.revanced.patches.all.misc.resources.addResources
|
||||
|
|
@ -126,14 +125,14 @@ internal fun baseCustomBrandingPatch(
|
|||
val getBuilderIndex = if (isYouTubeMusic) {
|
||||
// YT Music the field is not a plain object type.
|
||||
indexOfFirstInstructionOrThrow {
|
||||
getReference<FieldReference>()?.type == "Landroid/app/Notification\$Builder;"
|
||||
getReference<FieldReference>()?.type == $$"Landroid/app/Notification$Builder;"
|
||||
}
|
||||
} else {
|
||||
// Find the field name of the notification builder. Field is an Object type.
|
||||
val builderCastIndex = indexOfFirstInstructionOrThrow {
|
||||
val reference = getReference<TypeReference>()
|
||||
opcode == Opcode.CHECK_CAST &&
|
||||
reference?.type == "Landroid/app/Notification\$Builder;"
|
||||
reference?.type == $$"Landroid/app/Notification$Builder;"
|
||||
}
|
||||
indexOfFirstInstructionReversedOrThrow(builderCastIndex) {
|
||||
getReference<FieldReference>()?.type == "Ljava/lang/Object;"
|
||||
|
|
@ -148,11 +147,11 @@ internal fun baseCustomBrandingPatch(
|
|||
).forEach { index ->
|
||||
addInstructionsAtControlFlowLabel(
|
||||
index,
|
||||
"""
|
||||
$$"""
|
||||
move-object/from16 v0, p0
|
||||
iget-object v0, v0, $builderFieldName
|
||||
check-cast v0, Landroid/app/Notification${'$'}Builder;
|
||||
invoke-static { v0 }, $EXTENSION_CLASS_DESCRIPTOR->setNotificationIcon(Landroid/app/Notification${'$'}Builder;)V
|
||||
iget-object v0, v0, $$builderFieldName
|
||||
check-cast v0, Landroid/app/Notification$Builder;
|
||||
invoke-static { v0 }, $$EXTENSION_CLASS_DESCRIPTOR->setNotificationIcon(Landroid/app/Notification$Builder;)V
|
||||
""",
|
||||
)
|
||||
}
|
||||
|
|
@ -162,16 +161,37 @@ internal fun baseCustomBrandingPatch(
|
|||
)
|
||||
|
||||
afterDependents {
|
||||
val useCustomName = customName != null
|
||||
val useCustomIcon = customIcon != null
|
||||
val isRootInstall = setOrGetFallbackPackageName(originalAppPackageName) == originalAppPackageName
|
||||
|
||||
// Can only check if app is root installation by checking if change package name patch is in use.
|
||||
// and can only do that in the afterDependents block here.
|
||||
// The UI preferences cannot be selectively added here, because the settings afterDependents block
|
||||
// may have already run and the settings are already wrote to file.
|
||||
// Instead, show a warning if any patch option was used (A rooted device launcher ignores the manifest changes),
|
||||
// and the non-functional in-app settings are removed on app startup by extension code.
|
||||
if (customName != null || customIcon != null) {
|
||||
if (setOrGetFallbackPackageName(originalAppPackageName) == originalAppPackageName) {
|
||||
Logger.getLogger(this::class.java.name).warning(
|
||||
"Custom branding does not work with root installation. No changes applied.",
|
||||
if (isRootInstall && (useCustomName || useCustomIcon)) {
|
||||
Logger.getLogger(this::class.java.name).warning(
|
||||
"Custom branding does not work with root installation. No changes applied."
|
||||
)
|
||||
}
|
||||
|
||||
if (!isRootInstall || useCustomName) {
|
||||
document("AndroidManifest.xml").use { document ->
|
||||
val application = document.getElementsByTagName("application").item(0) as Element
|
||||
application.setAttribute(
|
||||
"android:label",
|
||||
if (useCustomName) {
|
||||
// Use custom name everywhere.
|
||||
customName
|
||||
} else {
|
||||
// The YT application name can appear in some places alongside the system
|
||||
// YouTube app, such as the settings app list and in the "open with" file picker.
|
||||
// Because the YouTube app cannot be completely uninstalled and only disabled,
|
||||
// use a custom name for this situation to disambiguate which app is which.
|
||||
"@string/revanced_custom_branding_name_entry_2"
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -312,16 +332,19 @@ internal fun baseCustomBrandingPatch(
|
|||
activityAliasNameWithIntents,
|
||||
).childNodes
|
||||
|
||||
// The YT application name can appear in some places alongside the system
|
||||
// YouTube app, such as the settings app list and in the "open with" file picker.
|
||||
// Because the YouTube app cannot be completely uninstalled and only disabled,
|
||||
// use a custom name for this situation to disambiguate which app is which.
|
||||
application.setAttribute(
|
||||
"android:label",
|
||||
"@string/revanced_custom_branding_name_entry_2",
|
||||
)
|
||||
// If user provides a custom icon, then change the application icon ('static' icon)
|
||||
// which shows as the push notification for some devices, in the app settings,
|
||||
// and as the icon for the apk before installing.
|
||||
// This icon cannot be dynamically selected and this change must only be done if the
|
||||
// user provides an icon otherwise there is no way to restore the original YouTube icon.
|
||||
if (useCustomIcon) {
|
||||
application.setAttribute(
|
||||
"android:icon",
|
||||
"@mipmap/revanced_launcher_custom"
|
||||
)
|
||||
}
|
||||
|
||||
val enabledNameIndex = if (useCustomName) numberOfPresetAppNames else 1 // 1 indexing.
|
||||
val enabledNameIndex = if (useCustomName) numberOfPresetAppNames else 2 // 1 indexing.
|
||||
val enabledIconIndex = if (useCustomIcon) iconStyleNames.size else 0 // 0 indexing.
|
||||
|
||||
for (appNameIndex in 1..numberOfPresetAppNames) {
|
||||
|
|
@ -336,7 +359,7 @@ internal fun baseCustomBrandingPatch(
|
|||
iconMipmapName = originalLauncherIconName,
|
||||
appNameIndex = appNameIndex,
|
||||
useCustomName = useCustomNameLabel,
|
||||
enabled = (appNameIndex == 1),
|
||||
enabled = false,
|
||||
intentFilters,
|
||||
),
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue