Skip to content

Commit 581fd3b

Browse files
committed
Sync v5.33.0
1 parent 84dfe88 commit 581fd3b

File tree

7 files changed

+89
-59
lines changed

7 files changed

+89
-59
lines changed

app/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ abstract class CopyResourcesTask @Inject constructor() : DefaultTask() {
187187
val outputDir = outputDirectory.get().asFile
188188

189189
val drawables = listOf(
190+
"qualitybutton/drawable",
190191
"settings/drawable",
191192
"sponsorblock/drawable",
192193
"swipecontrols/drawable"

app/src/main/java/io/github/chsbuffer/revancedxposed/Helper.kt

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.github.chsbuffer.revancedxposed
22

3+
import android.annotation.SuppressLint
34
import android.content.Context
45
import android.content.res.loader.ResourcesLoader
56
import android.content.res.loader.ResourcesProvider
@@ -100,4 +101,32 @@ fun Context.addModuleAssets() {
100101
// }
101102

102103
resources.assets.callMethod("addAssetPath", XposedInit.modulePath)
104+
}
105+
106+
107+
@SuppressLint("DiscouragedPrivateApi")
108+
fun injectHostClassLoaderToSelf(self: ClassLoader, classLoader: ClassLoader) {
109+
val loader = self.parent
110+
val host = classLoader
111+
val bootClassLoader = Context::class.java.classLoader!!
112+
113+
self.setObjectField("parent", object : ClassLoader(bootClassLoader) {
114+
override fun findClass(name: String?): Class<*> {
115+
try {
116+
return bootClassLoader.loadClass(name)
117+
} catch (_: ClassNotFoundException) {
118+
}
119+
120+
try {
121+
return loader.loadClass(name)
122+
} catch (_: ClassNotFoundException) {
123+
}
124+
try {
125+
return host.loadClass(name)
126+
} catch (_: ClassNotFoundException) {
127+
}
128+
129+
throw ClassNotFoundException(name);
130+
}
131+
})
103132
}

app/src/main/java/io/github/chsbuffer/revancedxposed/spotify/SpotifyHook.kt

Lines changed: 2 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package io.github.chsbuffer.revancedxposed.spotify
22

3-
import android.annotation.SuppressLint
43
import android.app.Application
5-
import android.content.Context
64
import app.revanced.extension.shared.Logger
75
import app.revanced.extension.shared.Utils
86
import app.revanced.extension.spotify.misc.UnlockPremiumPatch
@@ -17,7 +15,7 @@ import io.github.chsbuffer.revancedxposed.callMethod
1715
import io.github.chsbuffer.revancedxposed.findField
1816
import io.github.chsbuffer.revancedxposed.findFirstFieldByExactType
1917
import io.github.chsbuffer.revancedxposed.fingerprint
20-
import io.github.chsbuffer.revancedxposed.setObjectField
18+
import io.github.chsbuffer.revancedxposed.injectHostClassLoaderToSelf
2119
import io.github.chsbuffer.revancedxposed.strings
2220
import org.luckypray.dexkit.DexKitBridge
2321
import org.luckypray.dexkit.query.enums.StringMatchType
@@ -42,34 +40,7 @@ class SpotifyHook(app: Application, lpparam: LoadPackageParam) : BaseHook(app, l
4240
Utils.setContext(app)
4341

4442
// load stubbed spotify classes
45-
injectClassLoader(this::class.java.classLoader!!, classLoader)
46-
}
47-
48-
@SuppressLint("DiscouragedPrivateApi")
49-
fun injectClassLoader(self: ClassLoader, classLoader: ClassLoader) {
50-
val loader = self.parent
51-
val host = classLoader
52-
val bootClassLoader = Context::class.java.classLoader!!
53-
54-
self.setObjectField("parent", object : ClassLoader(bootClassLoader) {
55-
override fun findClass(name: String?): Class<*> {
56-
try {
57-
return bootClassLoader.loadClass(name)
58-
} catch (_: ClassNotFoundException) {
59-
}
60-
61-
try {
62-
return loader.loadClass(name)
63-
} catch (_: ClassNotFoundException) {
64-
}
65-
try {
66-
return host.loadClass(name)
67-
} catch (_: ClassNotFoundException) {
68-
}
69-
70-
throw ClassNotFoundException(name);
71-
}
72-
})
43+
injectHostClassLoaderToSelf(this::class.java.classLoader!!, classLoader)
7344
}
7445
}
7546

app/src/main/java/io/github/chsbuffer/revancedxposed/youtube/YoutubeHook.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam
77
import io.github.chsbuffer.revancedxposed.BaseHook
88
import io.github.chsbuffer.revancedxposed.BuildConfig
99
import io.github.chsbuffer.revancedxposed.addModuleAssets
10+
import io.github.chsbuffer.revancedxposed.injectHostClassLoaderToSelf
1011
import io.github.chsbuffer.revancedxposed.youtube.ad.HideAds
1112
import io.github.chsbuffer.revancedxposed.youtube.ad.VideoAds
1213
import io.github.chsbuffer.revancedxposed.youtube.interaction.SwipeControls
@@ -40,6 +41,7 @@ class YoutubeHook(
4041

4142
fun ExtensionHook() {
4243
Utils.setContext(app)
44+
injectHostClassLoaderToSelf(this::class.java.classLoader!!, classLoader)
4345
app.addModuleAssets()
4446
StringRef.resources = app.resources
4547
StringRef.packageName = BuildConfig.APPLICATION_ID

app/src/main/java/io/github/chsbuffer/revancedxposed/youtube/misc/LithoFilter.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ fun YoutubeHook.LithoFilter() {
105105
val identifier = identifierField.get(conversion) as String?
106106
val pathBuilder = pathBuilderField.get(conversion) as StringBuilder
107107

108-
if (LithoFilterPatch.shouldFilter(identifier, pathBuilder)) {
108+
if (LithoFilterPatch.isFiltered(identifier, pathBuilder)) {
109109
param.result = emptyComponentClazz.new()
110110
}
111111
}

app/src/main/java/io/github/chsbuffer/revancedxposed/youtube/video/RememberVideoQuality.kt

Lines changed: 53 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@ package io.github.chsbuffer.revancedxposed.youtube.video
22

33
import app.revanced.extension.shared.settings.preference.NoTitlePreferenceCategory
44
import app.revanced.extension.youtube.patches.playback.quality.RememberVideoQualityPatch
5+
import com.google.android.libraries.youtube.innertube.model.media.VideoQuality
56
import de.robv.android.xposed.XC_MethodHook
7+
import de.robv.android.xposed.XposedBridge
68
import io.github.chsbuffer.revancedxposed.AccessFlags
79
import io.github.chsbuffer.revancedxposed.Opcode
810
import io.github.chsbuffer.revancedxposed.ScopedHook
11+
import io.github.chsbuffer.revancedxposed.findFirstFieldByExactType
912
import io.github.chsbuffer.revancedxposed.fingerprint
1013
import io.github.chsbuffer.revancedxposed.getIntField
1114
import io.github.chsbuffer.revancedxposed.shared.misc.settings.preference.ListPreference
@@ -14,8 +17,15 @@ import io.github.chsbuffer.revancedxposed.shared.misc.settings.preference.Prefer
1417
import io.github.chsbuffer.revancedxposed.shared.misc.settings.preference.SwitchPreference
1518
import io.github.chsbuffer.revancedxposed.youtube.YoutubeHook
1619
import io.github.chsbuffer.revancedxposed.youtube.misc.PreferenceScreen
20+
import org.luckypray.dexkit.wrap.DexClass
1721
import java.lang.reflect.Modifier
1822

23+
private lateinit var getQualityName: (VideoQuality) -> String
24+
private lateinit var getResolution: (VideoQuality) -> Int
25+
26+
fun VideoQuality.getResolution() = getResolution(this)
27+
fun VideoQuality.getQualityName() = getQualityName(this)
28+
1929
fun YoutubeHook.RememberVideoQuality() {
2030
val settingsMenuVideoQualityGroup = setOf(
2131
ListPreference(
@@ -55,17 +65,32 @@ fun YoutubeHook.RememberVideoQuality() {
5565
)
5666
)
5767

58-
/*
59-
* The following code works by hooking the method which is called when the user selects a video quality
60-
* to remember the last selected video quality.
61-
*
62-
* It also hooks the method which is called when the video quality to set is determined.
63-
* Conveniently, at this point the video quality is overridden to the remembered playback speed.
64-
*/
6568
playerInitHooks.add { controller ->
6669
RememberVideoQualityPatch.newVideoStarted(controller)
6770
}
6871

72+
val YOUTUBE_VIDEO_QUALITY_CLASS_TYPE =
73+
"Lcom/google/android/libraries/youtube/innertube/model/media/VideoQuality;"
74+
75+
val videoQualityClass = DexClass(YOUTUBE_VIDEO_QUALITY_CLASS_TYPE).toClass()
76+
val qualityNameField = videoQualityClass.findFirstFieldByExactType(String::class.java)
77+
val resolutionField = videoQualityClass.findFirstFieldByExactType(Int::class.java)
78+
79+
getQualityName = { quality -> qualityNameField.get(quality) as String }
80+
getResolution = { quality -> resolutionField.get(quality) as Int }
81+
82+
// Fix bad data used by YouTube.
83+
XposedBridge.hookAllConstructors(
84+
videoQualityClass, object : XC_MethodHook() {
85+
override fun afterHookedMethod(param: MethodHookParam) {
86+
val quality = param.thisObject as VideoQuality
87+
val newResolution = RememberVideoQualityPatch.fixVideoQualityResolution(
88+
quality.getQualityName(), quality.getResolution()
89+
)
90+
resolutionField.set(quality, newResolution)
91+
}
92+
})
93+
6994
val videoQualitySetterFingerprint = getDexMethod("videoQualitySetterFingerprint") {
7095
fingerprint {
7196
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
@@ -82,7 +107,7 @@ fun YoutubeHook.RememberVideoQuality() {
82107
}
83108
}
84109

85-
getDexMethod("setQualityByIndexMethodClassFieldReferenceFingerprint") {
110+
getDexMethod("setVideoQualityFingerprint") {
86111
fingerprint {
87112
returns("V")
88113
parameters("L")
@@ -96,40 +121,42 @@ fun YoutubeHook.RememberVideoQuality() {
96121
}
97122
}.also { method ->
98123
val usingFields = method.usingFields
99-
getDexField("getOnItemClickListenerClassReference") {
124+
getDexField("onItemClickListenerClassReference") {
100125
usingFields[0].field
101126
}
102-
getDexField("getSetQualityByIndexMethodClassFieldReference") {
127+
getDexField("setQualityFieldReference") {
103128
usingFields[1].field
104129
}
105-
getDexMethod("setQualityByIndexMethod") {
106-
usingFields[1].field.type.findMethod { matcher { paramTypes("int") } }.single()
130+
getDexMethod("setQualityMenuIndexMethod") {
131+
usingFields[1].field.type.findMethod {
132+
matcher { addParamType { descriptor = YOUTUBE_VIDEO_QUALITY_CLASS_TYPE } }
133+
}.single()
107134
}
108135
}
109136
}
110137

111138
// Inject a call to set the remembered quality once a video loads.
112139
videoQualitySetterFingerprint.hookMethod(object : XC_MethodHook() {
113-
val getOnItemClickListener = getDexField("getOnItemClickListenerClassReference").toField()
114-
val getSetQualityByIndexMethod =
115-
getDexField("getSetQualityByIndexMethodClassFieldReference").toField()
116-
val setQualityByIndexMethod = getDexMethod("setQualityByIndexMethod").name
140+
val onItemClickListenerClass = getDexField("onItemClickListenerClassReference").toField()
141+
val setQualityField = getDexField("setQualityFieldReference").toField()
142+
val setQualityMenuIndexMethod = getDexMethod("setQualityMenuIndexMethod").toMethod()
117143

118144
@Suppress("UNCHECKED_CAST")
119145
override fun beforeHookedMethod(param: MethodHookParam) {
120-
val qualities = param.args[0] as Array<out Any>
146+
val qualities = param.args[0] as Array<out VideoQuality>
121147
val originalQualityIndex = param.args[1] as Int
122-
val qInterface = param.thisObject.let { getOnItemClickListener.get(it) }
123-
.let { getSetQualityByIndexMethod.get(it) }
124-
val qIndexMethod = setQualityByIndexMethod
148+
val menu = param.thisObject.let { onItemClickListenerClass.get(it) }
149+
.let { setQualityField.get(it) }
150+
125151
param.args[1] = RememberVideoQualityPatch.setVideoQuality(
126-
qualities, originalQualityIndex, qInterface, qIndexMethod
152+
qualities,
153+
{ quality -> setQualityMenuIndexMethod(menu, quality) },
154+
originalQualityIndex
127155
)
128156
}
129157
})
130158

131-
132-
// Inject a call to remember the selected quality.
159+
// Inject a call to remember the selected quality for Shorts.
133160
getDexMethod("videoQualityItemOnClickParentFingerprint") {
134161
fingerprint {
135162
returns("V")
@@ -145,8 +172,8 @@ fun YoutubeHook.RememberVideoQuality() {
145172
}
146173
})
147174

148-
// Remember video quality if not using old layout menu.
149-
getDexMethod("newVideoQualityChangedFingerprint") {
175+
// Inject a call to remember the user selected quality for regular videos.
176+
getDexMethod("videoQualityChangedFingerprint") {
150177
fingerprint {
151178
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
152179
methodMatcher {
@@ -172,7 +199,7 @@ fun YoutubeHook.RememberVideoQuality() {
172199
}.hookMethod(ScopedHook(getDexMethod("VideoQualityReceiver").toMember()) {
173200
before {
174201
val selectedQualityIndex = param.args[0].getIntField("a")
175-
RememberVideoQualityPatch.userChangedQualityInNewFlyout(selectedQualityIndex)
202+
RememberVideoQualityPatch.userChangedQuality(selectedQualityIndex)
176203
}
177204
})
178205
}

revanced-patches

Submodule revanced-patches updated 172 files

0 commit comments

Comments
 (0)