fix(TikTok): Vibe updated TikTok/Musically patch compatibility to 43.6.2

This commit is contained in:
Your Name 2026-01-27 00:45:26 +01:00
parent ef052c0d8f
commit 377d4e1501
26 changed files with 614 additions and 186 deletions

View file

@ -1,13 +1,26 @@
package app.revanced.extension.tiktok.cleardisplay;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.settings.BaseSettings;
import app.revanced.extension.tiktok.settings.Settings;
@SuppressWarnings("unused")
public class RememberClearDisplayPatch {
private static volatile Boolean lastLoggedState;
public static boolean getClearDisplayState() {
return Settings.CLEAR_DISPLAY.get();
boolean state = Settings.CLEAR_DISPLAY.get();
if (BaseSettings.DEBUG.get() && (lastLoggedState == null || lastLoggedState != state)) {
lastLoggedState = state;
Logger.printInfo(() -> "[ReVanced ClearDisplay] get state=" + state);
}
return state;
}
public static void rememberClearDisplayState(boolean newState) {
if (BaseSettings.DEBUG.get()) {
boolean oldState = Settings.CLEAR_DISPLAY.get();
Logger.printInfo(() -> "[ReVanced ClearDisplay] remember state " + oldState + " -> " + newState);
}
Settings.CLEAR_DISPLAY.save(newState);
}
}

View file

@ -1,14 +1,29 @@
package app.revanced.extension.tiktok.download;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.settings.BaseSettings;
import app.revanced.extension.tiktok.settings.Settings;
@SuppressWarnings("unused")
public class DownloadsPatch {
private static volatile String lastLoggedPath;
private static volatile Boolean lastLoggedRemoveWatermark;
public static String getDownloadPath() {
return Settings.DOWNLOAD_PATH.get();
String path = Settings.DOWNLOAD_PATH.get();
if (BaseSettings.DEBUG.get() && (lastLoggedPath == null || !lastLoggedPath.equals(path))) {
lastLoggedPath = path;
Logger.printInfo(() -> "[ReVanced Downloads] download_path=\"" + path + "\"");
}
return path;
}
public static boolean shouldRemoveWatermark() {
return Settings.DOWNLOAD_WATERMARK.get();
boolean removeWatermark = Settings.DOWNLOAD_WATERMARK.get();
if (BaseSettings.DEBUG.get() && (lastLoggedRemoveWatermark == null || lastLoggedRemoveWatermark != removeWatermark)) {
lastLoggedRemoveWatermark = removeWatermark;
Logger.printInfo(() -> "[ReVanced Downloads] remove_watermark=" + removeWatermark);
}
return removeWatermark;
}
}

View file

@ -1,11 +1,16 @@
package app.revanced.extension.tiktok.feedfilter;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.settings.BaseSettings;
import app.revanced.extension.tiktok.settings.Settings;
import com.ss.android.ugc.aweme.feed.model.Aweme;
import com.ss.android.ugc.aweme.feed.model.AwemeStatistics;
import com.ss.android.ugc.aweme.feed.model.FeedItemList;
import com.ss.android.ugc.aweme.follow.presenter.FollowFeedList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
public final class FeedItemsFilter {
private static final List<IFilter> FILTERS = List.of(
@ -18,37 +23,150 @@ public final class FeedItemsFilter {
new ShopFilter()
);
private static final int MAX_NULL_ITEMS_LOGS = 3;
private static final AtomicInteger feedItemListNullItemsLogCount = new AtomicInteger();
private static final AtomicInteger followFeedListNullItemsLogCount = new AtomicInteger();
public static void filter(FeedItemList feedItemList) {
filterFeedList(feedItemList.items, item -> item);
boolean verbose = BaseSettings.DEBUG.get();
if (feedItemList == null || feedItemList.items == null) {
if (verbose) {
logNullItems("FeedItemList", feedItemListNullItemsLogCount);
}
return;
}
if (verbose) {
debugLogBatch("FeedItemList", feedItemList.items);
}
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) {
if (verbose) {
logNullItems("FollowFeedList", followFeedListNullItemsLogCount);
}
return;
}
if (verbose) {
debugLogBatch("FollowFeedList", followFeedList.mItems);
}
filterFeedList("FollowFeedList", followFeedList.mItems, feed -> (feed != null) ? feed.aweme : null, verbose);
}
private static <T> void filterFeedList(List<T> list, AwemeExtractor<T> extractor) {
private static <T> void filterFeedList(
String source,
List<T> list,
AwemeExtractor<T> extractor,
boolean verbose
) {
if (list == null) return;
// Could be simplified with removeIf() but requires Android 7.0+ while TikTok supports 4.0+.
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 = getFilterReason(item);
logItem(item, reason, verbose);
if (reason != null) {
removed++;
iterator.remove();
}
}
if (verbose) {
final int removedFinal = removed;
Logger.printInfo(() -> "[ReVanced FeedFilter] filter(" + source + "): size " + initialSize + " -> " + list.size()
+ " (removed=" + removedFinal + ", verbose=" + verbose + ")");
}
}
private static boolean shouldFilter(Aweme item) {
return getFilterReason(item) != null;
}
private static String getFilterReason(Aweme item) {
for (IFilter filter : FILTERS) {
if (filter.getEnabled() && filter.getFiltered(item)) {
return true;
return filter.getClass().getSimpleName();
}
}
return false;
return null;
}
private static void logNullItems(String source, AtomicInteger counter) {
int count = counter.getAndIncrement();
if (count < MAX_NULL_ITEMS_LOGS) {
Logger.printInfo(() -> "[ReVanced FeedFilter] filter(" + source + "): items=null");
} else if (count == MAX_NULL_ITEMS_LOGS) {
Logger.printInfo(() -> "[ReVanced FeedFilter] filter(" + source + "): items=null (further logs suppressed)");
}
}
private static <T> void debugLogBatch(String source, List<T> list) {
int size = list == null ? -1 : list.size();
Logger.printInfo(() ->
"[ReVanced FeedFilter] filter(" + source + "): size=" + size
+ " remove_ads=" + Settings.REMOVE_ADS.get()
+ " hide_shop=" + Settings.HIDE_SHOP.get()
+ " hide_live=" + Settings.HIDE_LIVE.get()
+ " hide_story=" + Settings.HIDE_STORY.get()
+ " hide_image=" + Settings.HIDE_IMAGE.get()
+ " min_max_views=\"" + Settings.MIN_MAX_VIEWS.get() + "\""
+ " min_max_likes=\"" + Settings.MIN_MAX_LIKES.get() + "\""
);
}
private static void logItem(Aweme item, String reason, boolean verbose) {
if (!verbose) return;
String shareUrl = item.getShareUrl();
if (shareUrl != null && shareUrl.length() > 140) {
shareUrl = shareUrl.substring(0, 140) + "...";
}
String finalShareUrl = shareUrl;
Logger.printInfo(() -> {
long playCount = -1;
long likeCount = -1;
AwemeStatistics statistics = item.getStatistics();
if (statistics != null) {
playCount = statistics.getPlayCount();
likeCount = statistics.getDiggCount();
}
var imageInfos = item.getImageInfos();
boolean isImage = imageInfos != null && !imageInfos.isEmpty();
boolean isPhotoMode = item.getPhotoModeImageInfo() != null || item.getPhotoModeTextInfo() != null;
boolean isLive = item.getLiveId() != 0 || item.getLiveType() != null;
return "[ReVanced FeedFilter] item"
+ " aid=" + item.getAid()
+ " ad=" + item.isAd()
+ " promo=" + item.isWithPromotionalMusic()
+ " live=" + isLive
+ " liveReplay=" + item.isLiveReplay()
+ " story=" + item.getIsTikTokStory()
+ " image=" + isImage
+ " photoMode=" + isPhotoMode
+ " playCount=" + playCount
+ " likeCount=" + likeCount
+ " shareUrl=" + (finalShareUrl == null ? "null" : "\"" + finalShareUrl + "\"")
+ " => " + (reason == null ? "KEEP" : "FILTER(" + reason + ")");
});
}
@FunctionalInterface
interface AwemeExtractor<T> {
Aweme extract(T source);
}
}
}

View file

@ -11,6 +11,10 @@ public class ImageVideoFilter implements IFilter {
@Override
public boolean getFiltered(Aweme item) {
return item.isImage() || item.isPhotoMode();
// TikTok 43.6.2: Aweme no longer exposes isImage()/isPhotoMode().
var imageInfos = item.getImageInfos();
boolean isImage = imageInfos != null && !imageInfos.isEmpty();
boolean isPhotoMode = item.getPhotoModeImageInfo() != null || item.getPhotoModeTextInfo() != null;
return isImage || isPhotoMode;
}
}

View file

@ -11,6 +11,7 @@ public class LiveFilter implements IFilter {
@Override
public boolean getFiltered(Aweme item) {
return item.isLive() || item.isLiveReplay();
// TikTok 43.6.2: Aweme no longer exposes isLive(), use liveId/liveType instead.
return item.getLiveId() != 0 || item.isLiveReplay() || item.getLiveType() != null;
}
}

View file

@ -12,6 +12,7 @@ public class ShopFilter implements IFilter {
@Override
public boolean getFiltered(Aweme item) {
return item.getShareUrl().contains(SHOP_INFO);
String shareUrl = item.getShareUrl();
return shareUrl != null && shareUrl.contains(SHOP_INFO);
}
}

View file

@ -43,8 +43,11 @@ public class TikTokActivityHook {
* @return Whether the settings menu should be initialized.
*/
public static boolean initialize(AdPersonalizationActivity base) {
Bundle extras = base.getIntent().getExtras();
if (extras != null && !extras.getBoolean("revanced", false)) return false;
Intent intent = base.getIntent();
Bundle extras = intent.getExtras();
if ((extras == null || !extras.getBoolean("revanced", false)) && !"revanced_settings".equals(intent.getAction())) {
return false;
}
SettingsStatus.load();

View file

@ -4,6 +4,8 @@ import android.content.Context;
import android.preference.PreferenceScreen;
import app.revanced.extension.shared.settings.BaseSettings;
import app.revanced.extension.shared.settings.preference.ClearLogBufferPreference;
import app.revanced.extension.shared.settings.preference.ExportLogToClipboardPreference;
import app.revanced.extension.tiktok.settings.preference.ReVancedTikTokAboutPreference;
import app.revanced.extension.tiktok.settings.preference.TogglePreference;
@ -34,5 +36,15 @@ public class ExtensionPreferenceCategory extends ConditionalPreferenceCategory {
"Show extension debug log.",
BaseSettings.DEBUG
));
var exportLogs = new ExportLogToClipboardPreference(context);
exportLogs.setTitle("Export debug logs");
exportLogs.setSummary("Copy ReVanced debug logs to clipboard.");
addPreference(exportLogs);
var clearLogs = new ClearLogBufferPreference(context);
clearLogs.setTitle("Clear debug logs");
clearLogs.setSummary("Clear stored ReVanced debug logs.");
addPreference(clearLogs);
}
}

View file

@ -24,6 +24,17 @@ public final class ShareUrlSanitizer {
return url;
}
return sanitizer.sanitizeUrlString(url);
String sanitized = sanitizer.sanitizeUrlString(url);
if (BaseSettings.DEBUG.get() && sanitized != null && !sanitized.equals(url)) {
Logger.printInfo(() -> "[ReVanced SanitizeShareUrl] "
+ truncate(url) + " -> " + truncate(sanitized));
}
return sanitized;
}
private static String truncate(String url) {
if (url == null) return "null";
if (url.length() <= 160) return "\"" + url + "\"";
return "\"" + url.substring(0, 160) + "...\"";
}
}

View file

@ -1,13 +1,26 @@
package app.revanced.extension.tiktok.speed;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.settings.BaseSettings;
import app.revanced.extension.tiktok.settings.Settings;
public class PlaybackSpeedPatch {
private static volatile float lastLoggedSpeed = Float.NaN;
public static void rememberPlaybackSpeed(float newSpeed) {
if (BaseSettings.DEBUG.get()) {
float oldSpeed = Settings.REMEMBERED_SPEED.get();
Logger.printInfo(() -> "[ReVanced PlaybackSpeed] remember speed " + oldSpeed + " -> " + newSpeed);
}
Settings.REMEMBERED_SPEED.save(newSpeed);
}
public static float getPlaybackSpeed() {
return Settings.REMEMBERED_SPEED.get();
float speed = Settings.REMEMBERED_SPEED.get();
if (BaseSettings.DEBUG.get() && Float.compare(lastLoggedSpeed, speed) != 0) {
lastLoggedSpeed = speed;
Logger.printInfo(() -> "[ReVanced PlaybackSpeed] get speed=" + speed);
}
return speed;
}
}

View file

@ -1,16 +1,26 @@
package com.ss.android.ugc.aweme.feed.model;
import java.util.List;
//Dummy class
public class Aweme {
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 +32,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");
}

View file

@ -0,0 +1,6 @@
package com.ss.android.ugc.aweme.feed.model;
// Dummy class
public class PhotoModeImageInfo {
}

View file

@ -0,0 +1,6 @@
package com.ss.android.ugc.aweme.feed.model;
// Dummy class
public class PhotoModeTextInfo {
}