no settings or remember speed patches
This commit is contained in:
parent
ef052c0d8f
commit
0ad2464cba
19 changed files with 214 additions and 139 deletions
|
|
@ -5,10 +5,12 @@ import app.revanced.extension.tiktok.settings.Settings;
|
|||
@SuppressWarnings("unused")
|
||||
public class DownloadsPatch {
|
||||
public static String getDownloadPath() {
|
||||
return Settings.DOWNLOAD_PATH.get();
|
||||
return "Pictures/Tiktok";
|
||||
//return Settings.DOWNLOAD_PATH.get();
|
||||
}
|
||||
|
||||
public static boolean shouldRemoveWatermark() {
|
||||
return Settings.DOWNLOAD_WATERMARK.get();
|
||||
return true;
|
||||
//return Settings.DOWNLOAD_WATERMARK.get();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,15 +2,32 @@ package app.revanced.extension.tiktok.feedfilter;
|
|||
|
||||
import app.revanced.extension.tiktok.settings.Settings;
|
||||
import com.ss.android.ugc.aweme.feed.model.Aweme;
|
||||
import com.ss.android.ugc.aweme.commerce.AwemeCommerceStruct;
|
||||
|
||||
public class AdsFilter implements IFilter {
|
||||
@Override
|
||||
public boolean getEnabled() {
|
||||
return Settings.REMOVE_ADS.get();
|
||||
return true;
|
||||
// return Settings.REMOVE_ADS.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getFiltered(Aweme item) {
|
||||
return item.isAd() || item.isWithPromotionalMusic();
|
||||
try {
|
||||
// Standard Ads & Promotional Music
|
||||
if (item.isAd() || item.isWithPromotionalMusic()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Paid Partnerships (Branded Content)
|
||||
if (item.mCommerceVideoAuthInfo != null) {
|
||||
if (item.mCommerceVideoAuthInfo.isBrandedContent()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package app.revanced.extension.tiktok.feedfilter;
|
||||
|
||||
import app.revanced.extension.shared.Logger;
|
||||
import app.revanced.extension.shared.settings.BaseSettings;
|
||||
import com.ss.android.ugc.aweme.feed.model.Aweme;
|
||||
import com.ss.android.ugc.aweme.feed.model.FeedItemList;
|
||||
import com.ss.android.ugc.aweme.follow.presenter.FollowFeedList;
|
||||
|
|
@ -8,43 +10,73 @@ import java.util.Iterator;
|
|||
import java.util.List;
|
||||
|
||||
public final class FeedItemsFilter {
|
||||
private static final List<IFilter> FILTERS = List.of(
|
||||
new AdsFilter(),
|
||||
new LiveFilter(),
|
||||
new StoryFilter(),
|
||||
new ImageVideoFilter(),
|
||||
new ViewCountFilter(),
|
||||
new LikeCountFilter(),
|
||||
new ShopFilter()
|
||||
);
|
||||
|
||||
public static void filter(FeedItemList feedItemList) {
|
||||
filterFeedList(feedItemList.items, item -> item);
|
||||
boolean verbose = BaseSettings.DEBUG.get();
|
||||
if (feedItemList == null || feedItemList.items == null) return;
|
||||
|
||||
filterFeedList("FeedItemList", feedItemList.items, item -> item, verbose);
|
||||
}
|
||||
|
||||
public static void filter(FollowFeedList followFeedList) {
|
||||
filterFeedList(followFeedList.mItems, feed -> (feed != null) ? feed.aweme : null);
|
||||
boolean verbose = BaseSettings.DEBUG.get();
|
||||
if (followFeedList == null || followFeedList.mItems == null) return;
|
||||
|
||||
filterFeedList("FollowFeedList", followFeedList.mItems, feed -> (feed != null) ? feed.aweme : null, verbose);
|
||||
}
|
||||
|
||||
private static <T> void filterFeedList(List<T> list, AwemeExtractor<T> extractor) {
|
||||
// Could be simplified with removeIf() but requires Android 7.0+ while TikTok supports 4.0+.
|
||||
private static <T> void filterFeedList(
|
||||
String source,
|
||||
List<T> list,
|
||||
AwemeExtractor<T> extractor,
|
||||
boolean verbose
|
||||
) {
|
||||
if (list == null) return;
|
||||
|
||||
int initialSize = list.size();
|
||||
int removed = 0;
|
||||
Iterator<T> iterator = list.iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
T container = iterator.next();
|
||||
Aweme item = extractor.extract(container);
|
||||
if (item != null && shouldFilter(item)) {
|
||||
if (item == null) continue;
|
||||
|
||||
String reason = getInternalizedFilterReason(item);
|
||||
|
||||
if (reason != null) {
|
||||
removed++;
|
||||
iterator.remove();
|
||||
if (verbose) {
|
||||
logItem(item, reason);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (verbose && removed > 0) {
|
||||
int finalRemoved = removed;
|
||||
Logger.printInfo(() -> "[ReVanced FeedFilter] " + source + ": removed " + finalRemoved + " items.");
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean shouldFilter(Aweme item) {
|
||||
for (IFilter filter : FILTERS) {
|
||||
if (filter.getEnabled() && filter.getFiltered(item)) {
|
||||
return true;
|
||||
}
|
||||
private static String getInternalizedFilterReason(Aweme item) {
|
||||
if (item.isAd() || item.isWithPromotionalMusic()) {
|
||||
return "AdsFilter";
|
||||
}
|
||||
return false;
|
||||
|
||||
if (item.getLiveId() != 0 || item.getLiveType() != null || item.isLiveReplay()) {
|
||||
return "LiveFilter";
|
||||
}
|
||||
|
||||
String shareUrl = item.getShareUrl();
|
||||
if (shareUrl != null && shareUrl.contains("placeholder_product_id")) {
|
||||
return "ShopFilter";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void logItem(Aweme item, String reason) {
|
||||
Logger.printInfo(() -> "[ReVanced FeedFilter] FILTERED: aid=" + item.getAid() + " Reason=" + reason);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
|
|
|
|||
|
|
@ -11,6 +11,9 @@ public class ImageVideoFilter implements IFilter {
|
|||
|
||||
@Override
|
||||
public boolean getFiltered(Aweme item) {
|
||||
return item.isImage() || item.isPhotoMode();
|
||||
var imageInfos = item.getImageInfos();
|
||||
boolean isImage = imageInfos != null && !imageInfos.isEmpty();
|
||||
boolean isPhotoMode = item.getPhotoModeImageInfo() != null || item.getPhotoModeTextInfo() != null;
|
||||
return isImage || isPhotoMode;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,11 +6,12 @@ import com.ss.android.ugc.aweme.feed.model.Aweme;
|
|||
public class LiveFilter implements IFilter {
|
||||
@Override
|
||||
public boolean getEnabled() {
|
||||
return Settings.HIDE_LIVE.get();
|
||||
// HARDCODED: Always filter live streams
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getFiltered(Aweme item) {
|
||||
return item.isLive() || item.isLiveReplay();
|
||||
return item.getLiveId() != 0 || item.isLiveReplay() || item.getLiveType() != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,11 +7,13 @@ public class ShopFilter implements IFilter {
|
|||
private static final String SHOP_INFO = "placeholder_product_id";
|
||||
@Override
|
||||
public boolean getEnabled() {
|
||||
return Settings.HIDE_SHOP.get();
|
||||
return true;
|
||||
// return Settings.HIDE_SHOP.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getFiltered(Aweme item) {
|
||||
return item.getShareUrl().contains(SHOP_INFO);
|
||||
String shareUrl = item.getShareUrl();
|
||||
return shareUrl != null && shareUrl.contains(SHOP_INFO);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ public final class ShareUrlSanitizer {
|
|||
* Injection point for setting check.
|
||||
*/
|
||||
public static boolean shouldSanitize() {
|
||||
return BaseSettings.SANITIZE_SHARED_LINKS.get();
|
||||
return true;
|
||||
// return BaseSettings.SANITIZE_SHARED_LINKS.get();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
package com.ss.android.ugc.aweme.commerce;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class AwemeCommerceStruct implements Serializable {
|
||||
public long brandedContentType;
|
||||
public long brandOrganicType;
|
||||
|
||||
public boolean isBrandedContent() {
|
||||
return this.brandedContentType > 0;
|
||||
}
|
||||
|
||||
public boolean isBrandOrganicContent() {
|
||||
return this.brandOrganicType > 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +1,29 @@
|
|||
package com.ss.android.ugc.aweme.feed.model;
|
||||
import com.ss.android.ugc.aweme.commerce.AwemeCommerceStruct;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
//Dummy class
|
||||
public class Aweme {
|
||||
|
||||
public AwemeCommerceStruct mCommerceVideoAuthInfo;
|
||||
|
||||
public String getAid() {
|
||||
throw new UnsupportedOperationException("Stub");
|
||||
}
|
||||
|
||||
public boolean isAd() {
|
||||
throw new UnsupportedOperationException("Stub");
|
||||
}
|
||||
|
||||
public boolean isLive() {
|
||||
public boolean isLiveReplay() {
|
||||
throw new UnsupportedOperationException("Stub");
|
||||
}
|
||||
|
||||
public boolean isLiveReplay() {
|
||||
public long getLiveId() {
|
||||
throw new UnsupportedOperationException("Stub");
|
||||
}
|
||||
|
||||
public String getLiveType() {
|
||||
throw new UnsupportedOperationException("Stub");
|
||||
}
|
||||
|
||||
|
|
@ -22,11 +35,15 @@ public class Aweme {
|
|||
throw new UnsupportedOperationException("Stub");
|
||||
}
|
||||
|
||||
public boolean isImage() {
|
||||
public List getImageInfos() {
|
||||
throw new UnsupportedOperationException("Stub");
|
||||
}
|
||||
|
||||
public boolean isPhotoMode() {
|
||||
public PhotoModeImageInfo getPhotoModeImageInfo() {
|
||||
throw new UnsupportedOperationException("Stub");
|
||||
}
|
||||
|
||||
public PhotoModeTextInfo getPhotoModeTextInfo() {
|
||||
throw new UnsupportedOperationException("Stub");
|
||||
}
|
||||
|
||||
|
|
@ -37,4 +54,8 @@ public class Aweme {
|
|||
public String getShareUrl() {
|
||||
throw new UnsupportedOperationException("Stub");
|
||||
}
|
||||
}
|
||||
|
||||
public AwemeCommerceStruct getCommerceAndAdSettingsStruct() {
|
||||
throw new UnsupportedOperationException("Stub");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
package com.ss.android.ugc.aweme.feed.model;
|
||||
|
||||
// Dummy class
|
||||
public class PhotoModeImageInfo {
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
package com.ss.android.ugc.aweme.feed.model;
|
||||
|
||||
// Dummy class
|
||||
public class PhotoModeTextInfo {
|
||||
}
|
||||
|
||||
|
|
@ -1,11 +1,7 @@
|
|||
package app.revanced.patches.tiktok.feedfilter
|
||||
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.instructions
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patches.tiktok.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.patches.tiktok.misc.settings.settingsPatch
|
||||
import app.revanced.patches.tiktok.misc.settings.settingsStatusLoadFingerprint
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
|
||||
|
|
@ -17,33 +13,43 @@ val feedFilterPatch = bytecodePatch(
|
|||
description = "Removes ads, livestreams, stories, image videos " +
|
||||
"and videos with a specific amount of views or likes from the feed.",
|
||||
) {
|
||||
dependsOn(
|
||||
sharedExtensionPatch,
|
||||
settingsPatch,
|
||||
)
|
||||
|
||||
compatibleWith(
|
||||
"com.ss.android.ugc.trill"("36.5.4"),
|
||||
"com.zhiliaoapp.musically"("36.5.4"),
|
||||
"com.ss.android.ugc.trill"("43.8.3"),
|
||||
"com.zhiliaoapp.musically"("43.8.3"),
|
||||
)
|
||||
|
||||
execute {
|
||||
arrayOf(
|
||||
feedApiServiceLIZFingerprint.method to "$EXTENSION_CLASS_DESCRIPTOR->filter(Lcom/ss/android/ugc/aweme/feed/model/FeedItemList;)V",
|
||||
followFeedFingerprint.method to "$EXTENSION_CLASS_DESCRIPTOR->filter(Lcom/ss/android/ugc/aweme/follow/presenter/FollowFeedList;)V"
|
||||
).forEach { (method, filterSignature) ->
|
||||
val returnInstruction = method.instructions.first { it.opcode == Opcode.RETURN_OBJECT }
|
||||
val register = (returnInstruction as OneRegisterInstruction).registerA
|
||||
method.addInstruction(
|
||||
returnInstruction.location.index,
|
||||
"invoke-static { v$register }, $filterSignature"
|
||||
)
|
||||
feedItemListGetItemsFingerprint.method.let { method ->
|
||||
val returnIndices = method.implementation!!.instructions.withIndex()
|
||||
.filter { it.value.opcode == Opcode.RETURN_OBJECT }
|
||||
.map { it.index }
|
||||
.toList()
|
||||
|
||||
returnIndices.asReversed().forEach { returnIndex ->
|
||||
method.addInstructions(
|
||||
returnIndex,
|
||||
"invoke-static {p0}, $EXTENSION_CLASS_DESCRIPTOR->filter(Lcom/ss/android/ugc/aweme/feed/model/FeedItemList;)V"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
settingsStatusLoadFingerprint.method.addInstruction(
|
||||
0,
|
||||
"invoke-static {}, Lapp/revanced/extension/tiktok/settings/SettingsStatus;->enableFeedFilter()V",
|
||||
)
|
||||
}
|
||||
followFeedFingerprint.method.let { method ->
|
||||
val returnIndices = method.implementation!!.instructions.withIndex()
|
||||
.filter { it.value.opcode == Opcode.RETURN_OBJECT }
|
||||
.map { it.index }
|
||||
.toList()
|
||||
|
||||
}
|
||||
returnIndices.asReversed().forEach { returnIndex ->
|
||||
val register = (method.implementation!!.instructions[returnIndex] as OneRegisterInstruction).registerA
|
||||
method.addInstructions(
|
||||
returnIndex,
|
||||
"""
|
||||
if-nez v$register, :skip
|
||||
invoke-static/range { v$register .. v$register }, $EXTENSION_CLASS_DESCRIPTOR->filter(Lcom/ss/android/ugc/aweme/follow/presenter/FollowFeedList;)V
|
||||
:skip
|
||||
"""
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,21 +2,22 @@ package app.revanced.patches.tiktok.feedfilter
|
|||
|
||||
import app.revanced.patcher.fingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal val feedApiServiceLIZFingerprint = fingerprint {
|
||||
|
||||
internal val feedItemListGetItemsFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC)
|
||||
returns("Ljava/util/List;")
|
||||
custom { method, classDef ->
|
||||
classDef.endsWith("/FeedApiService;") && method.name == "fetchFeedList"
|
||||
classDef.endsWith("/FeedItemList;") &&
|
||||
method.name == "getItems" &&
|
||||
method.parameterTypes.isEmpty()
|
||||
}
|
||||
}
|
||||
|
||||
internal val followFeedFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
|
||||
returns("Lcom/ss/android/ugc/aweme/follow/presenter/FollowFeedList;")
|
||||
strings("getFollowFeedList")
|
||||
opcodes(
|
||||
Opcode.INVOKE_INTERFACE_RANGE,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.INVOKE_INTERFACE
|
||||
)
|
||||
custom { method, _ ->
|
||||
method.parameterTypes.size == 2
|
||||
}
|
||||
}
|
||||
|
|
@ -16,8 +16,8 @@ val rememberClearDisplayPatch = bytecodePatch(
|
|||
description = "Remembers the clear display configurations in between videos.",
|
||||
) {
|
||||
compatibleWith(
|
||||
"com.ss.android.ugc.trill"("36.5.4"),
|
||||
"com.zhiliaoapp.musically"("36.5.4"),
|
||||
"com.ss.android.ugc.trill"("43.8.3"),
|
||||
"com.zhiliaoapp.musically"("43.8.3"),
|
||||
)
|
||||
|
||||
execute {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
|||
import app.revanced.patcher.extensions.InstructionExtensions.removeInstructions
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patches.tiktok.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.patches.tiktok.misc.settings.settingsPatch
|
||||
import app.revanced.patches.tiktok.misc.settings.settingsStatusLoadFingerprint
|
||||
import app.revanced.util.findInstructionIndicesReversedOrThrow
|
||||
import app.revanced.util.getReference
|
||||
|
|
@ -25,12 +24,11 @@ val downloadsPatch = bytecodePatch(
|
|||
) {
|
||||
dependsOn(
|
||||
sharedExtensionPatch,
|
||||
settingsPatch,
|
||||
)
|
||||
|
||||
compatibleWith(
|
||||
"com.ss.android.ugc.trill"("36.5.4"),
|
||||
"com.zhiliaoapp.musically"("36.5.4"),
|
||||
"com.ss.android.ugc.trill"("43.8.3"),
|
||||
"com.zhiliaoapp.musically"("43.8.3"),
|
||||
)
|
||||
|
||||
execute {
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ internal val getSpeedFingerprint = fingerprint {
|
|||
}
|
||||
|
||||
internal val setSpeedFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
|
||||
returns("V")
|
||||
parameters("Ljava/lang/String;", "Lcom/ss/android/ugc/aweme/feed/model/Aweme;", "F")
|
||||
strings("enterFrom")
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returns("Ljava/lang/Object;")
|
||||
strings("playback_speed")
|
||||
custom { method, _ -> method.name == "invoke" && method.parameterTypes.isEmpty() }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ val playbackSpeedPatch = bytecodePatch(
|
|||
name = "Playback speed",
|
||||
description = "Enables the playback speed option for all videos and " +
|
||||
"retains the speed configurations in between videos.",
|
||||
use = false
|
||||
) {
|
||||
compatibleWith(
|
||||
"com.ss.android.ugc.trill"("36.5.4"),
|
||||
|
|
|
|||
|
|
@ -5,21 +5,22 @@ import com.android.tools.smali.dexlib2.AccessFlags
|
|||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal val urlShorteningFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC, AccessFlags.FINAL)
|
||||
returns("LX/")
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
|
||||
returns("V")
|
||||
parameters(
|
||||
"I",
|
||||
"L",
|
||||
"Ljava/lang/String;",
|
||||
"Ljava/util/List;",
|
||||
"Ljava/lang/String;",
|
||||
"Ljava/lang/String;"
|
||||
"Z",
|
||||
"I"
|
||||
)
|
||||
opcodes(Opcode.RETURN_OBJECT)
|
||||
opcodes(Opcode.RETURN_VOID)
|
||||
|
||||
// Same Kotlin intrinsics literal on both variants.
|
||||
strings("getShortShareUrlObservab\u2026ongUrl, subBizSceneValue)")
|
||||
strings("share_link_id", "invitation_scene")
|
||||
|
||||
custom { method, _ ->
|
||||
// LIZLLL is obfuscated by ProGuard/R8, but stable across both TikTok and Musically.
|
||||
method.name == "LIZLLL"
|
||||
method.parameterTypes.size == 6
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,58 +26,19 @@ val sanitizeShareUrlsPatch = bytecodePatch(
|
|||
dependsOn(sharedExtensionPatch)
|
||||
|
||||
compatibleWith(
|
||||
"com.ss.android.ugc.trill"("36.5.4"),
|
||||
"com.zhiliaoapp.musically"("36.5.4"),
|
||||
"com.ss.android.ugc.trill"("43.8.3"),
|
||||
"com.zhiliaoapp.musically"("43.8.3"),
|
||||
)
|
||||
|
||||
execute {
|
||||
urlShorteningFingerprint.method.apply {
|
||||
val invokeIndex = indexOfFirstInstructionOrThrow {
|
||||
val ref = getReference<MethodReference>()
|
||||
ref?.name == "LIZ" && ref.definingClass.startsWith("LX/")
|
||||
}
|
||||
val longUrlRegister = implementation!!.registerCount - 6 + 3
|
||||
|
||||
val moveResultIndex = indexOfFirstInstructionOrThrow(invokeIndex, Opcode.MOVE_RESULT_OBJECT)
|
||||
val urlRegister = getInstruction<OneRegisterInstruction>(moveResultIndex).registerA
|
||||
|
||||
// Resolve Observable wrapper classes at runtime
|
||||
val observableWrapperIndex = indexOfFirstInstructionOrThrow(Opcode.NEW_INSTANCE)
|
||||
val observableWrapperClass = getInstruction<ReferenceInstruction>(observableWrapperIndex)
|
||||
.reference.toString()
|
||||
|
||||
val observableFactoryIndex = indexOfFirstInstructionOrThrow {
|
||||
val ref = getReference<MethodReference>()
|
||||
ref?.name == "LJ" && ref.definingClass.startsWith("LX/")
|
||||
}
|
||||
val observableFactoryRef = getInstruction<ReferenceInstruction>(observableFactoryIndex)
|
||||
.reference as MethodReference
|
||||
|
||||
val observableFactoryClass = observableFactoryRef.definingClass
|
||||
val observableInterfaceType = observableFactoryRef.parameterTypes.first()
|
||||
val observableReturnType = observableFactoryRef.returnType
|
||||
|
||||
val wrapperRegister = findFreeRegister(moveResultIndex + 1, urlRegister)
|
||||
|
||||
// Check setting and conditionally sanitize share URL.
|
||||
addInstructionsWithLabels(
|
||||
moveResultIndex + 1,
|
||||
addInstructions(
|
||||
0,
|
||||
"""
|
||||
invoke-static {}, $EXTENSION_CLASS_DESCRIPTOR->shouldSanitize()Z
|
||||
move-result v$wrapperRegister
|
||||
if-eqz v$wrapperRegister, :skip_sanitization
|
||||
|
||||
invoke-static { p1 }, $EXTENSION_CLASS_DESCRIPTOR->sanitizeShareUrl(Ljava/lang/String;)Ljava/lang/String;
|
||||
move-result-object v$urlRegister
|
||||
|
||||
# Wrap sanitized URL and return early to bypass ShareExtService
|
||||
new-instance v$wrapperRegister, $observableWrapperClass
|
||||
invoke-direct { v$wrapperRegister, v$urlRegister }, $observableWrapperClass-><init>(Ljava/lang/String;)V
|
||||
invoke-static { v$wrapperRegister }, $observableFactoryClass->LJ($observableInterfaceType)$observableReturnType
|
||||
move-result-object v$urlRegister
|
||||
return-object v$urlRegister
|
||||
|
||||
:skip_sanitization
|
||||
nop
|
||||
invoke-static/range { v$longUrlRegister .. v$longUrlRegister }, $EXTENSION_CLASS_DESCRIPTOR->sanitizeShareUrl(Ljava/lang/String;)Ljava/lang/String;
|
||||
move-result-object v$longUrlRegister
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue