mirror of
https://github.com/inotia00/revanced-patches.git
synced 2025-06-13 05:37:40 +02:00
feat(YouTube): add support version 19.03.36
~ 19.16.39
This commit is contained in:
@ -8,6 +8,7 @@ import app.revanced.patches.youtube.general.tabletminiplayer.fingerprints.MiniPl
|
|||||||
import app.revanced.patches.youtube.general.tabletminiplayer.fingerprints.MiniPlayerOverrideFingerprint
|
import app.revanced.patches.youtube.general.tabletminiplayer.fingerprints.MiniPlayerOverrideFingerprint
|
||||||
import app.revanced.patches.youtube.general.tabletminiplayer.fingerprints.MiniPlayerOverrideNoContextFingerprint
|
import app.revanced.patches.youtube.general.tabletminiplayer.fingerprints.MiniPlayerOverrideNoContextFingerprint
|
||||||
import app.revanced.patches.youtube.general.tabletminiplayer.fingerprints.MiniPlayerResponseModelSizeCheckFingerprint
|
import app.revanced.patches.youtube.general.tabletminiplayer.fingerprints.MiniPlayerResponseModelSizeCheckFingerprint
|
||||||
|
import app.revanced.patches.youtube.general.tabletminiplayer.fingerprints.ModernMiniPlayerConfigFingerprint
|
||||||
import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE
|
import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE
|
||||||
import app.revanced.patches.youtube.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR
|
import app.revanced.patches.youtube.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR
|
||||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
|
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
|
||||||
@ -33,35 +34,45 @@ object TabletMiniPlayerPatch : BaseBytecodePatch(
|
|||||||
fingerprints = setOf(
|
fingerprints = setOf(
|
||||||
MiniPlayerDimensionsCalculatorFingerprint,
|
MiniPlayerDimensionsCalculatorFingerprint,
|
||||||
MiniPlayerResponseModelSizeCheckFingerprint,
|
MiniPlayerResponseModelSizeCheckFingerprint,
|
||||||
MiniPlayerOverrideFingerprint
|
MiniPlayerOverrideFingerprint,
|
||||||
|
ModernMiniPlayerConfigFingerprint
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
override fun execute(context: BytecodeContext) {
|
override fun execute(context: BytecodeContext) {
|
||||||
|
|
||||||
MiniPlayerDimensionsCalculatorFingerprint.resultOrThrow().let { parentResult ->
|
MiniPlayerOverrideNoContextFingerprint.resolve(
|
||||||
MiniPlayerOverrideNoContextFingerprint.resolve(context, parentResult.classDef)
|
context,
|
||||||
MiniPlayerOverrideNoContextFingerprint.resultOrThrow().let {
|
MiniPlayerDimensionsCalculatorFingerprint.resultOrThrow().classDef
|
||||||
|
)
|
||||||
|
MiniPlayerOverrideNoContextFingerprint.resultOrThrow().let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
hook(getTargetIndex(Opcode.RETURN))
|
||||||
|
hook(getTargetIndexReversed(Opcode.RETURN))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SettingsPatch.upward1912) {
|
||||||
|
ModernMiniPlayerConfigFingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
hook(getTargetIndex(Opcode.RETURN))
|
hook(it.scanResult.patternScanResult!!.endIndex)
|
||||||
hook(getTargetIndexReversed(Opcode.RETURN))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
MiniPlayerOverrideFingerprint.resultOrThrow().let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val walkerMethod = getWalkerMethod(context, getStringInstructionIndex("appName") + 2)
|
||||||
|
|
||||||
MiniPlayerOverrideFingerprint.resultOrThrow().let {
|
walkerMethod.apply {
|
||||||
it.mutableMethod.apply {
|
hook(getTargetIndex(Opcode.RETURN))
|
||||||
val walkerMethod = getWalkerMethod(context, getStringInstructionIndex("appName") + 2)
|
hook(getTargetIndexReversed(Opcode.RETURN))
|
||||||
|
}
|
||||||
walkerMethod.apply {
|
|
||||||
hook(getTargetIndex(Opcode.RETURN))
|
|
||||||
hook(getTargetIndexReversed(Opcode.RETURN))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
MiniPlayerResponseModelSizeCheckFingerprint.resultOrThrow().let {
|
MiniPlayerResponseModelSizeCheckFingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
hook(it.scanResult.patternScanResult!!.endIndex)
|
hook(it.scanResult.patternScanResult!!.endIndex)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,5 +8,5 @@ import com.android.tools.smali.dexlib2.Opcode
|
|||||||
internal object MiniPlayerOverrideNoContextFingerprint : MethodFingerprint(
|
internal object MiniPlayerOverrideNoContextFingerprint : MethodFingerprint(
|
||||||
returnType = "Z",
|
returnType = "Z",
|
||||||
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
|
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
|
||||||
opcodes = listOf(Opcode.RETURN), // anchor to insert the instruction
|
opcodes = listOf(Opcode.IGET_BOOLEAN), // anchor to insert the instruction
|
||||||
)
|
)
|
@ -0,0 +1,18 @@
|
|||||||
|
package app.revanced.patches.youtube.general.tabletminiplayer.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
import app.revanced.util.fingerprint.MethodReferenceNameFingerprint
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
||||||
|
internal object ModernMiniPlayerConfigFingerprint : MethodReferenceNameFingerprint(
|
||||||
|
returnType = "L",
|
||||||
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
|
||||||
|
parameters = listOf("Landroid/content/Context;", "L", "L", "L", "L", "L", "L"),
|
||||||
|
opcodes = listOf(
|
||||||
|
Opcode.INVOKE_VIRTUAL,
|
||||||
|
Opcode.MOVE_RESULT,
|
||||||
|
Opcode.IF_EQZ
|
||||||
|
),
|
||||||
|
reference = { "getClass" }
|
||||||
|
)
|
@ -8,11 +8,10 @@ import app.revanced.patches.youtube.misc.openlinksdirectly.fingerprints.OpenLink
|
|||||||
import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE
|
import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE
|
||||||
import app.revanced.patches.youtube.utils.integrations.Constants.MISC_PATH
|
import app.revanced.patches.youtube.utils.integrations.Constants.MISC_PATH
|
||||||
import app.revanced.patches.youtube.utils.settings.SettingsPatch
|
import app.revanced.patches.youtube.utils.settings.SettingsPatch
|
||||||
|
import app.revanced.util.getTargetIndexWithMethodReferenceName
|
||||||
import app.revanced.util.patch.BaseBytecodePatch
|
import app.revanced.util.patch.BaseBytecodePatch
|
||||||
import app.revanced.util.resultOrThrow
|
import app.revanced.util.resultOrThrow
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
|
|
||||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object OpenLinksDirectlyPatch : BaseBytecodePatch(
|
object OpenLinksDirectlyPatch : BaseBytecodePatch(
|
||||||
@ -33,11 +32,8 @@ object OpenLinksDirectlyPatch : BaseBytecodePatch(
|
|||||||
).forEach { fingerprint ->
|
).forEach { fingerprint ->
|
||||||
fingerprint.resultOrThrow().let {
|
fingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val insertIndex = implementation!!.instructions
|
val insertIndex = getTargetIndexWithMethodReferenceName("parse")
|
||||||
.indexOfFirst { instruction ->
|
val insertRegister = getInstruction<FiveRegisterInstruction>(insertIndex).registerC
|
||||||
((instruction as? ReferenceInstruction)?.reference as? MethodReference)?.name == "parse"
|
|
||||||
}
|
|
||||||
val insertRegister = getInstruction<Instruction35c>(insertIndex).registerC
|
|
||||||
|
|
||||||
replaceInstruction(
|
replaceInstruction(
|
||||||
insertIndex,
|
insertIndex,
|
||||||
|
@ -4,26 +4,36 @@ import app.revanced.patcher.extensions.or
|
|||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||||
|
|
||||||
object OpenLinksDirectlyFingerprintPrimary : MethodFingerprint(
|
object OpenLinksDirectlyFingerprintPrimary : MethodFingerprint(
|
||||||
returnType = "Ljava/lang/Object",
|
returnType = "Ljava/lang/Object",
|
||||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
parameters = listOf("Ljava/lang/Object"),
|
parameters = listOf("Ljava/lang/Object"),
|
||||||
opcodes = listOf(
|
opcodes = listOf(
|
||||||
Opcode.RETURN_OBJECT,
|
|
||||||
Opcode.CHECK_CAST,
|
|
||||||
Opcode.INVOKE_VIRTUAL,
|
|
||||||
Opcode.MOVE_RESULT_OBJECT,
|
|
||||||
Opcode.CHECK_CAST,
|
|
||||||
Opcode.RETURN_OBJECT,
|
|
||||||
Opcode.CHECK_CAST,
|
Opcode.CHECK_CAST,
|
||||||
Opcode.INVOKE_STATIC,
|
Opcode.INVOKE_STATIC,
|
||||||
Opcode.MOVE_RESULT_OBJECT,
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
Opcode.RETURN_OBJECT,
|
Opcode.RETURN_OBJECT
|
||||||
Opcode.CHECK_CAST
|
|
||||||
),
|
),
|
||||||
customFingerprint = { methodDef, classDef ->
|
customFingerprint = custom@{ methodDef, _ ->
|
||||||
methodDef.name == "a"
|
if (methodDef.implementation == null)
|
||||||
&& classDef.methods.count() == 3
|
return@custom false
|
||||||
|
if (methodDef.name != "a")
|
||||||
|
return@custom false
|
||||||
|
|
||||||
|
var count = 0
|
||||||
|
for (instruction in methodDef.implementation!!.instructions) {
|
||||||
|
if (instruction.opcode != Opcode.SGET_OBJECT)
|
||||||
|
continue
|
||||||
|
|
||||||
|
val objectInstruction = instruction as ReferenceInstruction
|
||||||
|
if ((objectInstruction.reference as FieldReference).name != "webviewEndpoint")
|
||||||
|
continue
|
||||||
|
|
||||||
|
count++
|
||||||
|
}
|
||||||
|
count == 1
|
||||||
}
|
}
|
||||||
)
|
)
|
@ -11,15 +11,17 @@ import app.revanced.patches.youtube.shorts.startupshortsreset.fingerprints.UserW
|
|||||||
import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE
|
import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE
|
||||||
import app.revanced.patches.youtube.utils.integrations.Constants.SHORTS_CLASS_DESCRIPTOR
|
import app.revanced.patches.youtube.utils.integrations.Constants.SHORTS_CLASS_DESCRIPTOR
|
||||||
import app.revanced.patches.youtube.utils.settings.SettingsPatch
|
import app.revanced.patches.youtube.utils.settings.SettingsPatch
|
||||||
import app.revanced.util.getStringInstructionIndex
|
import app.revanced.util.getReference
|
||||||
import app.revanced.util.getTargetIndex
|
import app.revanced.util.getTargetIndex
|
||||||
import app.revanced.util.getTargetIndexReversed
|
|
||||||
import app.revanced.util.getWalkerMethod
|
import app.revanced.util.getWalkerMethod
|
||||||
|
import app.revanced.util.indexOfFirstInstruction
|
||||||
import app.revanced.util.patch.BaseBytecodePatch
|
import app.revanced.util.patch.BaseBytecodePatch
|
||||||
import app.revanced.util.resultOrThrow
|
import app.revanced.util.resultOrThrow
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object ResumingShortsOnStartupPatch : BaseBytecodePatch(
|
object ResumingShortsOnStartupPatch : BaseBytecodePatch(
|
||||||
@ -57,27 +59,27 @@ object ResumingShortsOnStartupPatch : BaseBytecodePatch(
|
|||||||
|
|
||||||
UserWasInShortsFingerprint.resultOrThrow().let {
|
UserWasInShortsFingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val startIndex = getStringInstructionIndex("Failed to read user_was_in_shorts proto after successful warmup")
|
val listenableInstructionIndex = indexOfFirstInstruction {
|
||||||
val exceptionIndex = getTargetIndexReversed(startIndex, Opcode.RETURN_VOID) - 1
|
opcode == Opcode.INVOKE_INTERFACE &&
|
||||||
val targetIndex = getTargetIndexReversed(exceptionIndex, Opcode.RETURN_VOID) + 1
|
getReference<MethodReference>()?.definingClass == "Lcom/google/common/util/concurrent/ListenableFuture;" &&
|
||||||
if (getInstruction(targetIndex).opcode != Opcode.IGET_OBJECT)
|
getReference<MethodReference>()?.name == "isDone"
|
||||||
throw PatchException("Failed to find insert index")
|
}
|
||||||
|
if (listenableInstructionIndex < 0) throw PatchException("Could not find instruction index")
|
||||||
val replaceReference = getInstruction<ReferenceInstruction>(targetIndex).reference
|
val originalInstructionRegister = getInstruction<FiveRegisterInstruction>(listenableInstructionIndex).registerC
|
||||||
val replaceInstruction = getInstruction<TwoRegisterInstruction>(targetIndex)
|
val freeRegister = getInstruction<OneRegisterInstruction>(listenableInstructionIndex + 1).registerA
|
||||||
|
|
||||||
addInstructionsWithLabels(
|
addInstructionsWithLabels(
|
||||||
targetIndex + 1,
|
listenableInstructionIndex + 1,
|
||||||
"""
|
"""
|
||||||
invoke-static {}, $SHORTS_CLASS_DESCRIPTOR->disableResumingStartupShortsPlayer()Z
|
invoke-static {}, $SHORTS_CLASS_DESCRIPTOR->disableResumingStartupShortsPlayer()Z
|
||||||
move-result v${replaceInstruction.registerA}
|
move-result v$freeRegister
|
||||||
if-eqz v${replaceInstruction.registerA}, :show
|
if-eqz v$freeRegister, :show
|
||||||
return-void
|
return-void
|
||||||
:show
|
:show
|
||||||
iget-object v${replaceInstruction.registerA}, v${replaceInstruction.registerB}, $replaceReference
|
invoke-interface {v$originalInstructionRegister}, Lcom/google/common/util/concurrent/ListenableFuture;->isDone()Z
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
removeInstruction(targetIndex)
|
removeInstruction(listenableInstructionIndex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +55,21 @@ object Constants {
|
|||||||
"18.48.39",
|
"18.48.39",
|
||||||
"18.49.37",
|
"18.49.37",
|
||||||
"19.01.34",
|
"19.01.34",
|
||||||
"19.02.39"
|
"19.02.39",
|
||||||
|
"19.03.36",
|
||||||
|
"19.04.38",
|
||||||
|
"19.05.36",
|
||||||
|
"19.06.39",
|
||||||
|
"19.07.40",
|
||||||
|
"19.08.36",
|
||||||
|
"19.09.37",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43",
|
||||||
|
"19.12.41",
|
||||||
|
"19.13.37",
|
||||||
|
"19.14.43",
|
||||||
|
"19.15.36",
|
||||||
|
"19.16.39"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -21,7 +21,6 @@ import app.revanced.util.getTargetIndex
|
|||||||
import app.revanced.util.getTargetIndexWithMethodReferenceName
|
import app.revanced.util.getTargetIndexWithMethodReferenceName
|
||||||
import app.revanced.util.resultOrThrow
|
import app.revanced.util.resultOrThrow
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction21c
|
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
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.instruction.ReferenceInstruction
|
||||||
@ -54,7 +53,7 @@ object ReturnYouTubeDislikeRollingNumberPatch : BytecodePatch(
|
|||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val rollingNumberClassIndex = it.scanResult.patternScanResult!!.startIndex
|
val rollingNumberClassIndex = it.scanResult.patternScanResult!!.startIndex
|
||||||
val rollingNumberClassReference =
|
val rollingNumberClassReference =
|
||||||
getInstruction<BuilderInstruction21c>(rollingNumberClassIndex).reference
|
getInstruction<ReferenceInstruction>(rollingNumberClassIndex).reference
|
||||||
val rollingNumberClass =
|
val rollingNumberClass =
|
||||||
context.findClass(rollingNumberClassReference.toString())!!.mutableClass
|
context.findClass(rollingNumberClassReference.toString())!!.mutableClass
|
||||||
|
|
||||||
|
@ -1,16 +1,12 @@
|
|||||||
package app.revanced.patches.youtube.utils.returnyoutubedislike.rollingnumber.fingerprints
|
package app.revanced.patches.youtube.utils.returnyoutubedislike.rollingnumber.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This fingerprint is compatible with YouTube v18.29.38+
|
* This fingerprint is compatible with YouTube v18.29.38+
|
||||||
*/
|
*/
|
||||||
internal object RollingNumberSetterFingerprint : MethodFingerprint(
|
internal object RollingNumberSetterFingerprint : LiteralValueFingerprint(
|
||||||
opcodes = listOf(
|
opcodes = listOf(Opcode.CHECK_CAST),
|
||||||
Opcode.CHECK_CAST,
|
literalSupplier = { 45427773 }
|
||||||
Opcode.IGET,
|
|
||||||
Opcode.AND_INT_LIT8
|
|
||||||
),
|
|
||||||
strings = listOf("RollingNumberType required properties missing! Need updateCount, fontName, color and fontSize.")
|
|
||||||
)
|
)
|
@ -22,5 +22,6 @@ internal object RollingNumberTextViewFingerprint : MethodFingerprint(
|
|||||||
),
|
),
|
||||||
customFingerprint = custom@{ _, classDef ->
|
customFingerprint = custom@{ _, classDef ->
|
||||||
classDef.superclass == "Landroid/support/v7/widget/AppCompatTextView;"
|
classDef.superclass == "Landroid/support/v7/widget/AppCompatTextView;"
|
||||||
|
|| classDef.superclass == "Lcom/google/android/libraries/youtube/rendering/ui/spec/typography/YouTubeAppCompatTextView;"
|
||||||
}
|
}
|
||||||
)
|
)
|
@ -46,6 +46,7 @@ object SettingsPatch : BaseResourcePatch(
|
|||||||
internal var upward1849 = false
|
internal var upward1849 = false
|
||||||
internal var upward1902 = false
|
internal var upward1902 = false
|
||||||
internal var upward1909 = false
|
internal var upward1909 = false
|
||||||
|
internal var upward1912 = false
|
||||||
|
|
||||||
override fun execute(context: ResourceContext) {
|
override fun execute(context: ResourceContext) {
|
||||||
contexts = context
|
contexts = context
|
||||||
@ -80,6 +81,7 @@ object SettingsPatch : BaseResourcePatch(
|
|||||||
upward1849 = 235000000 <= playServicesVersion
|
upward1849 = 235000000 <= playServicesVersion
|
||||||
upward1902 = 240204000 < playServicesVersion
|
upward1902 = 240204000 < playServicesVersion
|
||||||
upward1909 = 241002000 <= playServicesVersion
|
upward1909 = 241002000 <= playServicesVersion
|
||||||
|
upward1912 = 241302000 <= playServicesVersion
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user