mirror of
https://github.com/revanced/revanced-integrations.git
synced 2024-11-07 12:47:02 +01:00
chore: merge branch dev
to main
(#299)
This commit is contained in:
commit
bb8cdc494f
49
CHANGELOG.md
49
CHANGELOG.md
@ -1,3 +1,52 @@
|
|||||||
|
# [0.94.0-dev.6](https://github.com/revanced/revanced-integrations/compare/v0.94.0-dev.5...v0.94.0-dev.6) (2023-01-28)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **youtube:** show toasts along exceptions ([#293](https://github.com/revanced/revanced-integrations/issues/293)) ([dbf1f3f](https://github.com/revanced/revanced-integrations/commit/dbf1f3f0ce0500752e5d6c4ce49d7d2b27cc6dc4))
|
||||||
|
|
||||||
|
# [0.94.0-dev.5](https://github.com/revanced/revanced-integrations/compare/v0.94.0-dev.4...v0.94.0-dev.5) (2023-01-28)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **youtube/return-youtube-dislike:** do not fetch voting stats when watching shorts ([#302](https://github.com/revanced/revanced-integrations/issues/302)) ([7551f01](https://github.com/revanced/revanced-integrations/commit/7551f0104c463714749acc6abedbea5cd7afb52f))
|
||||||
|
|
||||||
|
# [0.94.0-dev.4](https://github.com/revanced/revanced-integrations/compare/v0.94.0-dev.3...v0.94.0-dev.4) (2023-01-28)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **youtube/general-ads:** remove hiding video shelf ([04147c1](https://github.com/revanced/revanced-integrations/commit/04147c17c98bccea27e0293a71ffccc97f5a155d))
|
||||||
|
|
||||||
|
# [0.94.0-dev.3](https://github.com/revanced/revanced-integrations/compare/v0.94.0-dev.2...v0.94.0-dev.3) (2023-01-22)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **youtube/return-youtube-dislike:** gracefully exit if Vanced MicroG is missing or not running ([#303](https://github.com/revanced/revanced-integrations/issues/303)) ([03764bc](https://github.com/revanced/revanced-integrations/commit/03764bcc651c6b723a999a58ed9cc9d253075905))
|
||||||
|
|
||||||
|
# [0.94.0-dev.2](https://github.com/revanced/revanced-integrations/compare/v0.94.0-dev.1...v0.94.0-dev.2) (2023-01-22)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **youtube/microg-support:** check if Vanced MicroG is running in the background ([#301](https://github.com/revanced/revanced-integrations/issues/301)) ([6e31b78](https://github.com/revanced/revanced-integrations/commit/6e31b7889a2488b3d61042111437a6ed4eec019c))
|
||||||
|
|
||||||
|
# [0.94.0-dev.1](https://github.com/revanced/revanced-integrations/compare/v0.93.2-dev.1...v0.94.0-dev.1) (2023-01-22)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **youtube:** `open-links-externally` patch ([4cbe833](https://github.com/revanced/revanced-integrations/commit/4cbe8338b3f4ab49139168d7a3d0c9ebebf68952))
|
||||||
|
|
||||||
|
## [0.93.2-dev.1](https://github.com/revanced/revanced-integrations/compare/v0.93.1...v0.93.2-dev.1) (2023-01-21)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **youtube:** save new instead of default value ([#298](https://github.com/revanced/revanced-integrations/issues/298)) ([559bbf9](https://github.com/revanced/revanced-integrations/commit/559bbf9778f20ac0f5ce3af677230a1ec28a55ff))
|
||||||
|
|
||||||
## [0.93.1](https://github.com/revanced/revanced-integrations/compare/v0.93.0...v0.93.1) (2023-01-17)
|
## [0.93.1](https://github.com/revanced/revanced-integrations/compare/v0.93.0...v0.93.1) (2023-01-17)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package app.revanced.integrations.patches;
|
package app.revanced.integrations.patches;
|
||||||
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import app.revanced.integrations.adremover.AdRemoverAPI;
|
import app.revanced.integrations.adremover.AdRemoverAPI;
|
||||||
import app.revanced.integrations.settings.SettingsEnum;
|
import app.revanced.integrations.settings.SettingsEnum;
|
||||||
import app.revanced.integrations.utils.LogHelper;
|
import app.revanced.integrations.utils.LogHelper;
|
||||||
@ -32,7 +31,6 @@ public final class GeneralAdsPatch extends Filter {
|
|||||||
var paidContent = new BlockRule(SettingsEnum.ADREMOVER_PAID_CONTENT_REMOVAL, "paid_content_overlay");
|
var paidContent = new BlockRule(SettingsEnum.ADREMOVER_PAID_CONTENT_REMOVAL, "paid_content_overlay");
|
||||||
var merchandise = new BlockRule(SettingsEnum.ADREMOVER_MERCHANDISE_REMOVAL, "product_carousel");
|
var merchandise = new BlockRule(SettingsEnum.ADREMOVER_MERCHANDISE_REMOVAL, "product_carousel");
|
||||||
var infoPanel = new BlockRule(SettingsEnum.ADREMOVER_INFO_PANEL_REMOVAL, "publisher_transparency_panel", "single_item_information_panel");
|
var infoPanel = new BlockRule(SettingsEnum.ADREMOVER_INFO_PANEL_REMOVAL, "publisher_transparency_panel", "single_item_information_panel");
|
||||||
var suggestions = new BlockRule(SettingsEnum.ADREMOVER_SUGGESTIONS_REMOVAL, "horizontal_video_shelf");
|
|
||||||
var latestPosts = new BlockRule(SettingsEnum.ADREMOVER_HIDE_LATEST_POSTS, "post_shelf");
|
var latestPosts = new BlockRule(SettingsEnum.ADREMOVER_HIDE_LATEST_POSTS, "post_shelf");
|
||||||
var channelGuidelines = new BlockRule(SettingsEnum.ADREMOVER_HIDE_CHANNEL_GUIDELINES, "channel_guidelines_entry_banner");
|
var channelGuidelines = new BlockRule(SettingsEnum.ADREMOVER_HIDE_CHANNEL_GUIDELINES, "channel_guidelines_entry_banner");
|
||||||
var artistCard = new BlockRule(SettingsEnum.HIDE_ARTIST_CARD, "official_card");
|
var artistCard = new BlockRule(SettingsEnum.HIDE_ARTIST_CARD, "official_card");
|
||||||
@ -69,7 +67,6 @@ public final class GeneralAdsPatch extends Filter {
|
|||||||
buttonedAd,
|
buttonedAd,
|
||||||
communityPosts,
|
communityPosts,
|
||||||
paidContent,
|
paidContent,
|
||||||
suggestions,
|
|
||||||
latestPosts,
|
latestPosts,
|
||||||
movieAds,
|
movieAds,
|
||||||
chapterTeaser,
|
chapterTeaser,
|
||||||
@ -115,7 +112,7 @@ public final class GeneralAdsPatch extends Filter {
|
|||||||
else
|
else
|
||||||
result = BlockResult.UNBLOCKED;
|
result = BlockResult.UNBLOCKED;
|
||||||
|
|
||||||
log(String.format("%s (ID: %s): %s", result.message, identifier, path));
|
LogHelper.printDebug(() -> String.format("%s (ID: %s): %s", result.message, identifier, path));
|
||||||
|
|
||||||
return result.filter;
|
return result.filter;
|
||||||
}
|
}
|
||||||
@ -144,7 +141,7 @@ public final class GeneralAdsPatch extends Filter {
|
|||||||
private static void hideView(SettingsEnum condition, View view) {
|
private static void hideView(SettingsEnum condition, View view) {
|
||||||
if (!condition.getBoolean()) return;
|
if (!condition.getBoolean()) return;
|
||||||
|
|
||||||
log("Hiding view with setting: " + condition);
|
LogHelper.printDebug(() -> "Hiding view with setting: " + condition);
|
||||||
|
|
||||||
AdRemoverAPI.HideViewWithLayout1dp(view);
|
AdRemoverAPI.HideViewWithLayout1dp(view);
|
||||||
}
|
}
|
||||||
@ -167,7 +164,4 @@ public final class GeneralAdsPatch extends Filter {
|
|||||||
hideView(SettingsEnum.ADREMOVER_SHORTS_REMOVAL, view);
|
hideView(SettingsEnum.ADREMOVER_SHORTS_REMOVAL, view);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void log(String message) {
|
|
||||||
LogHelper.printDebug(() -> message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -10,8 +10,7 @@ public class HideCreateButtonPatch {
|
|||||||
//Used by app.revanced.patches.youtube.layout.createbutton.patch.CreateButtonRemoverPatch
|
//Used by app.revanced.patches.youtube.layout.createbutton.patch.CreateButtonRemoverPatch
|
||||||
public static void hideCreateButton(View view) {
|
public static void hideCreateButton(View view) {
|
||||||
boolean hidden = SettingsEnum.HIDE_CREATE_BUTTON.getBoolean();
|
boolean hidden = SettingsEnum.HIDE_CREATE_BUTTON.getBoolean();
|
||||||
String message = "Create button: " + (hidden ? "hidden" : "shown");
|
LogHelper.printDebug(() -> "Create button: " + (hidden ? "hidden" : "shown"));
|
||||||
LogHelper.printDebug(() -> message);
|
|
||||||
view.setVisibility(hidden ? View.GONE : View.VISIBLE);
|
view.setVisibility(hidden ? View.GONE : View.VISIBLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,10 +12,9 @@ public class HideShortsButtonPatch {
|
|||||||
public static void hideShortsButton(View view) {
|
public static void hideShortsButton(View view) {
|
||||||
if (lastPivotTab != null && lastPivotTab.name() == "TAB_SHORTS") {
|
if (lastPivotTab != null && lastPivotTab.name() == "TAB_SHORTS") {
|
||||||
boolean hide = SettingsEnum.HIDE_SHORTS_BUTTON.getBoolean();
|
boolean hide = SettingsEnum.HIDE_SHORTS_BUTTON.getBoolean();
|
||||||
String message = hide ? "Shorts button: hidden" : "Shorts button: shown";
|
LogHelper.printDebug(() -> hide ? "Shorts button: hidden" : "Shorts button: shown");
|
||||||
LogHelper.printDebug(() -> message);
|
|
||||||
if (hide) {
|
if (hide) {
|
||||||
view.setVisibility(hide ? View.GONE : View.VISIBLE);
|
view.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,14 @@ package app.revanced.integrations.patches;
|
|||||||
|
|
||||||
import static app.revanced.integrations.sponsorblock.StringRef.str;
|
import static app.revanced.integrations.sponsorblock.StringRef.str;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import app.revanced.integrations.utils.LogHelper;
|
import app.revanced.integrations.utils.LogHelper;
|
||||||
import app.revanced.integrations.utils.ReVancedUtils;
|
import app.revanced.integrations.utils.ReVancedUtils;
|
||||||
|
|
||||||
@ -14,21 +17,35 @@ public class MicroGSupport {
|
|||||||
private static final String MICROG_VENDOR = "com.mgoogle";
|
private static final String MICROG_VENDOR = "com.mgoogle";
|
||||||
private static final String MICROG_PACKAGE_NAME = "com.mgoogle.android.gms";
|
private static final String MICROG_PACKAGE_NAME = "com.mgoogle.android.gms";
|
||||||
private static final String VANCED_MICROG_DOWNLOAD_LINK = "https://github.com/TeamVanced/VancedMicroG/releases/latest";
|
private static final String VANCED_MICROG_DOWNLOAD_LINK = "https://github.com/TeamVanced/VancedMicroG/releases/latest";
|
||||||
|
private static final String DONT_KILL_MY_APP_LINK = "https://dontkillmyapp.com";
|
||||||
|
private static final Uri VANCED_MICROG_PROVIDER = Uri.parse("content://com.mgoogle.android.gsf.gservices/prefix");
|
||||||
|
|
||||||
|
private static void startIntent(Context context, String uriString, String message) {
|
||||||
|
Toast.makeText(context, message, Toast.LENGTH_LONG).show();
|
||||||
|
|
||||||
|
var intent = new Intent(Intent.ACTION_VIEW);
|
||||||
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
|
intent.setData(Uri.parse(uriString));
|
||||||
|
context.startActivity(intent);
|
||||||
|
}
|
||||||
|
|
||||||
public static void checkAvailability() {
|
public static void checkAvailability() {
|
||||||
var context = ReVancedUtils.getContext();
|
var context = Objects.requireNonNull(ReVancedUtils.getContext());
|
||||||
assert context != null;
|
|
||||||
try {
|
try {
|
||||||
context.getPackageManager().getPackageInfo(MICROG_PACKAGE_NAME, PackageManager.GET_ACTIVITIES);
|
context.getPackageManager().getPackageInfo(MICROG_PACKAGE_NAME, PackageManager.GET_ACTIVITIES);
|
||||||
LogHelper.printDebug(() -> "MicroG is installed on the device");
|
|
||||||
} catch (PackageManager.NameNotFoundException exception) {
|
} catch (PackageManager.NameNotFoundException exception) {
|
||||||
LogHelper.printException(() -> ("MicroG was not found"), exception);
|
LogHelper.printInfo(() -> "Vanced MicroG was not found", exception);
|
||||||
Toast.makeText(context, str("microg_not_installed_warning"), Toast.LENGTH_LONG).show();
|
startIntent(context, VANCED_MICROG_DOWNLOAD_LINK, str("microg_not_installed_warning"));
|
||||||
|
|
||||||
var intent = new Intent(Intent.ACTION_VIEW);
|
// Gracefully exit the app, so it does not crash.
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
System.exit(0);
|
||||||
intent.setData(Uri.parse(VANCED_MICROG_DOWNLOAD_LINK));
|
}
|
||||||
context.startActivity(intent);
|
|
||||||
|
try (var client = context.getContentResolver().acquireContentProviderClient(VANCED_MICROG_PROVIDER)) {
|
||||||
|
if (client != null) return;
|
||||||
|
LogHelper.printInfo(() -> "Vanced MicroG is not running in the background");
|
||||||
|
startIntent(context, DONT_KILL_MY_APP_LINK, str("microg_not_running_warning"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,19 @@
|
|||||||
|
package app.revanced.integrations.patches;
|
||||||
|
|
||||||
|
import app.revanced.integrations.settings.SettingsEnum;
|
||||||
|
|
||||||
|
public class OpenLinksExternallyPatch {
|
||||||
|
/**
|
||||||
|
* Override 'android.support.customtabs.action.CustomTabsService',
|
||||||
|
* in order to open links in the default browser. This is done by returning an empty string,
|
||||||
|
* for the service that handles custom tabs in the Android support library
|
||||||
|
* which opens links in the default service instead.
|
||||||
|
*
|
||||||
|
* @param original The original custom tabs service.
|
||||||
|
* @return The new, default service to open links with or the original service.
|
||||||
|
*/
|
||||||
|
public static String enableExternalBrowser(String original) {
|
||||||
|
if (SettingsEnum.ENABLE_EXTERNAL_BROWSER.getBoolean()) original = "";
|
||||||
|
return original;
|
||||||
|
}
|
||||||
|
}
|
@ -2,8 +2,8 @@ package app.revanced.integrations.patches;
|
|||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import app.revanced.integrations.utils.LogHelper;
|
|
||||||
import app.revanced.integrations.shared.PlayerType;
|
import app.revanced.integrations.shared.PlayerType;
|
||||||
|
import app.revanced.integrations.utils.LogHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook receiver class for 'player-type-hook' patch
|
* Hook receiver class for 'player-type-hook' patch
|
||||||
@ -24,7 +24,9 @@ public class PlayerTypeHookPatch {
|
|||||||
|
|
||||||
// update current player type
|
// update current player type
|
||||||
final PlayerType newType = PlayerType.safeParseFromString(type.toString());
|
final PlayerType newType = PlayerType.safeParseFromString(type.toString());
|
||||||
if (newType != null) {
|
if (newType == null) {
|
||||||
|
LogHelper.printException(() -> "Unknown PlayerType encountered: " + type);
|
||||||
|
} else {
|
||||||
PlayerType.setCurrent(newType);
|
PlayerType.setCurrent(newType);
|
||||||
LogHelper.printDebug(() -> "YouTubePlayerOverlaysLayout player type was updated to " + newType);
|
LogHelper.printDebug(() -> "YouTubePlayerOverlaysLayout player type was updated to " + newType);
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ public final class VideoInformation {
|
|||||||
seekMethod = thisRef.getClass().getMethod(SEEK_METHOD_NAME, Long.TYPE);
|
seekMethod = thisRef.getClass().getMethod(SEEK_METHOD_NAME, Long.TYPE);
|
||||||
seekMethod.setAccessible(true);
|
seekMethod.setAccessible(true);
|
||||||
} catch (NoSuchMethodException ex) {
|
} catch (NoSuchMethodException ex) {
|
||||||
LogHelper.printDebug(() -> "Failed to initialize: " + ex.getMessage());
|
LogHelper.printException(() -> "Failed to initialize", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,7 +87,7 @@ public final class VideoInformation {
|
|||||||
LogHelper.printDebug(() -> "Seeking to " + millisecond);
|
LogHelper.printDebug(() -> "Seeking to " + millisecond);
|
||||||
seekMethod.invoke(playerController.get(), millisecond);
|
seekMethod.invoke(playerController.get(), millisecond);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
LogHelper.printDebug(() -> "Failed to seek: " + ex.getMessage());
|
LogHelper.printException(() -> "Failed to seek", ex);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package app.revanced.integrations.patches.playback.quality;
|
package app.revanced.integrations.patches.playback.quality;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
import android.net.NetworkInfo;
|
import android.net.NetworkInfo;
|
||||||
@ -26,24 +27,25 @@ public class RememberVideoQualityPatch {
|
|||||||
if (isConnectedWifi(context)) {
|
if (isConnectedWifi(context)) {
|
||||||
try {
|
try {
|
||||||
SharedPrefHelper.saveString(SharedPrefHelper.SharedPrefNames.REVANCED_PREFS, "wifi_quality", defaultQuality + "");
|
SharedPrefHelper.saveString(SharedPrefHelper.SharedPrefNames.REVANCED_PREFS, "wifi_quality", defaultQuality + "");
|
||||||
|
String message = "Changing default Wi-Fi quality to: " + defaultQuality;
|
||||||
|
LogHelper.printDebug(() -> message);
|
||||||
|
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
LogHelper.printException(() -> ("Failed to change default WI-FI quality:" + ex));
|
LogHelper.printException(() -> "Failed to change default WI-FI quality", ex);
|
||||||
Toast.makeText(context, "Failed to change default WI-FI quality:", Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
}
|
||||||
LogHelper.printDebug(() -> "Changing default Wi-Fi quality to: " + defaultQuality);
|
|
||||||
Toast.makeText(context, "Changing default Wi-Fi quality to: " + defaultQuality, Toast.LENGTH_SHORT).show();
|
|
||||||
} else if (isConnectedMobile(context)) {
|
} else if (isConnectedMobile(context)) {
|
||||||
try {
|
try {
|
||||||
SharedPrefHelper.saveString(SharedPrefHelper.SharedPrefNames.REVANCED_PREFS, "mobile_quality", defaultQuality + "");
|
SharedPrefHelper.saveString(SharedPrefHelper.SharedPrefNames.REVANCED_PREFS, "mobile_quality", defaultQuality + "");
|
||||||
|
String message = "Changing default mobile data quality to:" + defaultQuality;
|
||||||
|
LogHelper.printDebug(() -> message);
|
||||||
|
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
LogHelper.printDebug(() -> "Failed to change default mobile data quality" + ex);
|
LogHelper.printException(() -> "Failed to change default mobile data quality", ex);
|
||||||
Toast.makeText(context, "Failed to change default mobile data quality", Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
}
|
||||||
LogHelper.printDebug(() -> "Changing default mobile data quality to:" + defaultQuality);
|
|
||||||
Toast.makeText(context, "Changing default mobile data quality to:" + defaultQuality, Toast.LENGTH_SHORT).show();
|
|
||||||
} else {
|
} else {
|
||||||
LogHelper.printDebug(() -> "No internet connection.");
|
String message = "No internet connection.";
|
||||||
Toast.makeText(context, "No internet connection.", Toast.LENGTH_SHORT).show();
|
LogHelper.printDebug(() -> message);
|
||||||
|
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
userChangedQuality = false;
|
userChangedQuality = false;
|
||||||
}
|
}
|
||||||
@ -88,7 +90,7 @@ public class RememberVideoQualityPatch {
|
|||||||
LogHelper.printDebug(() -> "Quality: " + qualityToLog);
|
LogHelper.printDebug(() -> "Quality: " + qualityToLog);
|
||||||
Context context = ReVancedUtils.getContext();
|
Context context = ReVancedUtils.getContext();
|
||||||
if (context == null) {
|
if (context == null) {
|
||||||
LogHelper.printException(() -> ("Context is null or settings not initialized, returning quality: " + qualityToLog));
|
LogHelper.printException(() -> "Context is null or settings not initialized, returning quality: " + qualityToLog);
|
||||||
return quality;
|
return quality;
|
||||||
}
|
}
|
||||||
if (isConnectedWifi(context)) {
|
if (isConnectedWifi(context)) {
|
||||||
@ -129,8 +131,7 @@ public class RememberVideoQualityPatch {
|
|||||||
LogHelper.printDebug(() -> "Quality changed to: " + qualityIndex);
|
LogHelper.printDebug(() -> "Quality changed to: " + qualityIndex);
|
||||||
return qualityIndex;
|
return qualityIndex;
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
LogHelper.printException(() -> ("Failed to set quality"), ex);
|
LogHelper.printException(() -> "Failed to set quality", ex);
|
||||||
Toast.makeText(context, "Failed to set quality", Toast.LENGTH_SHORT).show();
|
|
||||||
return qualityIndex;
|
return qualityIndex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -147,6 +148,7 @@ public class RememberVideoQualityPatch {
|
|||||||
newVideo = true;
|
newVideo = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("MissingPermission")
|
||||||
private static NetworkInfo getNetworkInfo(Context context) {
|
private static NetworkInfo getNetworkInfo(Context context) {
|
||||||
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||||
return cm.getActiveNetworkInfo();
|
return cm.getActiveNetworkInfo();
|
||||||
|
@ -2,7 +2,6 @@ package app.revanced.integrations.returnyoutubedislike;
|
|||||||
|
|
||||||
import static app.revanced.integrations.sponsorblock.StringRef.str;
|
import static app.revanced.integrations.sponsorblock.StringRef.str;
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.icu.text.CompactDecimalFormat;
|
import android.icu.text.CompactDecimalFormat;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.text.Spannable;
|
import android.text.Spannable;
|
||||||
@ -13,7 +12,6 @@ import android.text.style.CharacterStyle;
|
|||||||
import android.text.style.ForegroundColorSpan;
|
import android.text.style.ForegroundColorSpan;
|
||||||
import android.text.style.RelativeSizeSpan;
|
import android.text.style.RelativeSizeSpan;
|
||||||
import android.text.style.ScaleXSpan;
|
import android.text.style.ScaleXSpan;
|
||||||
import android.util.DisplayMetrics;
|
|
||||||
|
|
||||||
import androidx.annotation.GuardedBy;
|
import androidx.annotation.GuardedBy;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
@ -31,6 +29,7 @@ import java.util.concurrent.atomic.AtomicReference;
|
|||||||
import app.revanced.integrations.returnyoutubedislike.requests.RYDVoteData;
|
import app.revanced.integrations.returnyoutubedislike.requests.RYDVoteData;
|
||||||
import app.revanced.integrations.returnyoutubedislike.requests.ReturnYouTubeDislikeApi;
|
import app.revanced.integrations.returnyoutubedislike.requests.ReturnYouTubeDislikeApi;
|
||||||
import app.revanced.integrations.settings.SettingsEnum;
|
import app.revanced.integrations.settings.SettingsEnum;
|
||||||
|
import app.revanced.integrations.shared.PlayerType;
|
||||||
import app.revanced.integrations.utils.LogHelper;
|
import app.revanced.integrations.utils.LogHelper;
|
||||||
import app.revanced.integrations.utils.ReVancedUtils;
|
import app.revanced.integrations.utils.ReVancedUtils;
|
||||||
import app.revanced.integrations.utils.SharedPrefHelper;
|
import app.revanced.integrations.utils.SharedPrefHelper;
|
||||||
@ -96,7 +95,16 @@ public class ReturnYouTubeDislike {
|
|||||||
private static NumberFormat dislikePercentageFormatter;
|
private static NumberFormat dislikePercentageFormatter;
|
||||||
|
|
||||||
public static void onEnabledChange(boolean enabled) {
|
public static void onEnabledChange(boolean enabled) {
|
||||||
isEnabled = enabled;
|
synchronized (videoIdLockObject) {
|
||||||
|
isEnabled = enabled;
|
||||||
|
if (!enabled) {
|
||||||
|
// must clear old values, to protect against using stale data
|
||||||
|
// if the user re-enables RYD while watching a video
|
||||||
|
LogHelper.printDebug(() -> "Clearing previously fetched RYD vote data");
|
||||||
|
currentVideoId = null;
|
||||||
|
voteFetchFuture = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getCurrentVideoId() {
|
private static String getCurrentVideoId() {
|
||||||
@ -117,8 +125,12 @@ public class ReturnYouTubeDislike {
|
|||||||
if (!isEnabled) return;
|
if (!isEnabled) return;
|
||||||
try {
|
try {
|
||||||
Objects.requireNonNull(videoId);
|
Objects.requireNonNull(videoId);
|
||||||
LogHelper.printDebug(() -> "New video loaded: " + videoId);
|
PlayerType currentPlayerType = PlayerType.getCurrent();
|
||||||
|
if (currentPlayerType == PlayerType.INLINE_MINIMAL) {
|
||||||
|
LogHelper.printDebug(() -> "Ignoring inline playback of video: "+ videoId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
LogHelper.printDebug(() -> " new video loaded: " + videoId + " playerType: " + currentPlayerType);
|
||||||
synchronized (videoIdLockObject) {
|
synchronized (videoIdLockObject) {
|
||||||
currentVideoId = videoId;
|
currentVideoId = videoId;
|
||||||
// no need to wrap the call in a try/catch,
|
// no need to wrap the call in a try/catch,
|
||||||
@ -157,6 +169,10 @@ public class ReturnYouTubeDislike {
|
|||||||
long fetchStartTime = 0;
|
long fetchStartTime = 0;
|
||||||
try {
|
try {
|
||||||
Future<RYDVoteData> fetchFuture = getVoteFetchFuture();
|
Future<RYDVoteData> fetchFuture = getVoteFetchFuture();
|
||||||
|
if (fetchFuture == null) {
|
||||||
|
LogHelper.printDebug(() -> "fetch future not available (user enabled RYD while video was playing?)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (SettingsEnum.DEBUG.getBoolean() && !fetchFuture.isDone()) {
|
if (SettingsEnum.DEBUG.getBoolean() && !fetchFuture.isDone()) {
|
||||||
fetchStartTime = System.currentTimeMillis();
|
fetchStartTime = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
@ -175,8 +191,7 @@ public class ReturnYouTubeDislike {
|
|||||||
if (updateDislike(textRef, isSegmentedButton, votingData)) {
|
if (updateDislike(textRef, isSegmentedButton, votingData)) {
|
||||||
LogHelper.printDebug(() -> "Updated dislike span to: " + textRef.get());
|
LogHelper.printDebug(() -> "Updated dislike span to: " + textRef.get());
|
||||||
} else {
|
} else {
|
||||||
LogHelper.printDebug(() -> "Ignoring dislike span: " + textRef.get()
|
LogHelper.printDebug(() -> "Ignoring already updated dislike span: " + textRef.get());
|
||||||
+ " that appears to already show voting data: " + votingData);
|
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
LogHelper.printException(() -> "Error while trying to update dislikes", ex);
|
LogHelper.printException(() -> "Error while trying to update dislikes", ex);
|
||||||
@ -187,12 +202,24 @@ public class ReturnYouTubeDislike {
|
|||||||
if (!isEnabled) return;
|
if (!isEnabled) return;
|
||||||
try {
|
try {
|
||||||
Objects.requireNonNull(vote);
|
Objects.requireNonNull(vote);
|
||||||
|
|
||||||
|
if (PlayerType.getCurrent() == PlayerType.NONE) { // should occur if shorts is playing
|
||||||
|
LogHelper.printDebug(() -> "Ignoring vote during Shorts playback");
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (SharedPrefHelper.getBoolean(SharedPrefHelper.SharedPrefNames.YOUTUBE, "user_signed_out", true)) {
|
if (SharedPrefHelper.getBoolean(SharedPrefHelper.SharedPrefNames.YOUTUBE, "user_signed_out", true)) {
|
||||||
|
LogHelper.printDebug(() -> "User is logged out, ignoring voting");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Must make a local copy of videoId, since it may change between now and when the vote thread runs
|
// Must make a local copy of videoId, since it may change between now and when the vote thread runs
|
||||||
String videoIdToVoteFor = getCurrentVideoId();
|
String videoIdToVoteFor = getCurrentVideoId();
|
||||||
|
if (videoIdToVoteFor == null) {
|
||||||
|
// user enabled RYD after starting playback of a video
|
||||||
|
LogHelper.printException(() -> "Cannot vote, current video is is null (user enabled RYD while video was playing?)",
|
||||||
|
null, str("revanced_ryd_failure_ryd_enabled_while_playing_video_then_user_voted"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
voteSerialExecutor.execute(() -> {
|
voteSerialExecutor.execute(() -> {
|
||||||
// must wrap in try/catch to properly log exceptions
|
// must wrap in try/catch to properly log exceptions
|
||||||
@ -278,9 +305,6 @@ public class ReturnYouTubeDislike {
|
|||||||
//
|
//
|
||||||
// Change the "Likes" string to show that likes and dislikes are hidden
|
// Change the "Likes" string to show that likes and dislikes are hidden
|
||||||
//
|
//
|
||||||
LogHelper.printDebug(() -> "Like count is hidden by video creator. "
|
|
||||||
+ "RYD does not provide data for videos with hidden likes.");
|
|
||||||
|
|
||||||
String hiddenMessageString = str("revanced_ryd_video_likes_hidden_by_video_owner");
|
String hiddenMessageString = str("revanced_ryd_video_likes_hidden_by_video_owner");
|
||||||
if (hiddenMessageString.equals(oldLikesString)) {
|
if (hiddenMessageString.equals(oldLikesString)) {
|
||||||
return false;
|
return false;
|
||||||
@ -449,7 +473,6 @@ public class ReturnYouTubeDislike {
|
|||||||
|
|
||||||
private static String formatDislikeCount(long dislikeCount) {
|
private static String formatDislikeCount(long dislikeCount) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
String formatted;
|
|
||||||
synchronized (ReturnYouTubeDislike.class) { // number formatter is not thread safe, must synchronize
|
synchronized (ReturnYouTubeDislike.class) { // number formatter is not thread safe, must synchronize
|
||||||
if (dislikeCountFormatter == null) {
|
if (dislikeCountFormatter == null) {
|
||||||
// Note: Java number formatters will use the locale specific number characters.
|
// Note: Java number formatters will use the locale specific number characters.
|
||||||
@ -460,18 +483,15 @@ public class ReturnYouTubeDislike {
|
|||||||
LogHelper.printDebug(() -> "Locale: " + locale);
|
LogHelper.printDebug(() -> "Locale: " + locale);
|
||||||
dislikeCountFormatter = CompactDecimalFormat.getInstance(locale, CompactDecimalFormat.CompactStyle.SHORT);
|
dislikeCountFormatter = CompactDecimalFormat.getInstance(locale, CompactDecimalFormat.CompactStyle.SHORT);
|
||||||
}
|
}
|
||||||
formatted = dislikeCountFormatter.format(dislikeCount);
|
return dislikeCountFormatter.format(dislikeCount);
|
||||||
}
|
}
|
||||||
LogHelper.printDebug(() -> "Dislike count: " + dislikeCount + " formatted as: " + formatted);
|
|
||||||
return formatted;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// never will be reached, as the oldest supported YouTube app requires Android N or greater
|
// will never be reached, as the oldest supported YouTube app requires Android N or greater
|
||||||
return String.valueOf(dislikeCount);
|
return String.valueOf(dislikeCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String formatDislikePercentage(float dislikePercentage) {
|
private static String formatDislikePercentage(float dislikePercentage) {
|
||||||
String formatted;
|
|
||||||
synchronized (ReturnYouTubeDislike.class) { // number formatter is not thread safe, must synchronize
|
synchronized (ReturnYouTubeDislike.class) { // number formatter is not thread safe, must synchronize
|
||||||
if (dislikePercentageFormatter == null) {
|
if (dislikePercentageFormatter == null) {
|
||||||
Locale locale = ReVancedUtils.getContext().getResources().getConfiguration().locale;
|
Locale locale = ReVancedUtils.getContext().getResources().getConfiguration().locale;
|
||||||
@ -483,10 +503,8 @@ public class ReturnYouTubeDislike {
|
|||||||
} else {
|
} else {
|
||||||
dislikePercentageFormatter.setMaximumFractionDigits(1); // show up to 1 digit precision
|
dislikePercentageFormatter.setMaximumFractionDigits(1); // show up to 1 digit precision
|
||||||
}
|
}
|
||||||
formatted = dislikePercentageFormatter.format(dislikePercentage);
|
return dislikePercentageFormatter.format(dislikePercentage);
|
||||||
}
|
}
|
||||||
LogHelper.printDebug(() -> "Dislike percentage: " + dislikePercentage + " formatted as: " + formatted);
|
|
||||||
return formatted;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -500,6 +518,7 @@ public class ReturnYouTubeDislike {
|
|||||||
*/
|
*/
|
||||||
private static volatile long totalTimeUIWaitedOnNetworkCalls;
|
private static volatile long totalTimeUIWaitedOnNetworkCalls;
|
||||||
|
|
||||||
|
@SuppressWarnings("NonAtomicOperationOnVolatileField")
|
||||||
private static void recordTimeUISpentWaitingForNetworkCall(long timeUIWaitStarted) {
|
private static void recordTimeUISpentWaitingForNetworkCall(long timeUIWaitStarted) {
|
||||||
if (timeUIWaitStarted == 0 || !SettingsEnum.DEBUG.getBoolean()) {
|
if (timeUIWaitStarted == 0 || !SettingsEnum.DEBUG.getBoolean()) {
|
||||||
return;
|
return;
|
||||||
|
@ -185,11 +185,15 @@ public class ReturnYouTubeDislikeApi {
|
|||||||
lastTimeRateLimitWasHit = System.currentTimeMillis();
|
lastTimeRateLimitWasHit = System.currentTimeMillis();
|
||||||
LogHelper.printDebug(() -> "API rate limit was hit. Stopping API calls for the next "
|
LogHelper.printDebug(() -> "API rate limit was hit. Stopping API calls for the next "
|
||||||
+ RATE_LIMIT_BACKOFF_SECONDS + " seconds");
|
+ RATE_LIMIT_BACKOFF_SECONDS + " seconds");
|
||||||
|
ReVancedUtils.runOnMainThread(() -> { // must show toasts on main thread
|
||||||
|
Toast.makeText(ReVancedUtils.getContext(), str("revanced_ryd_failure_client_rate_limit_requested"), Toast.LENGTH_LONG).show();
|
||||||
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("NonAtomicOperationOnVolatileField") // do not want to pay performance cost of full synchronization for debug fields that are only estimates anyways
|
||||||
private static void updateStatistics(long timeNetworkCallStarted, long timeNetworkCallEnded, boolean connectionError, boolean rateLimitHit) {
|
private static void updateStatistics(long timeNetworkCallStarted, long timeNetworkCallEnded, boolean connectionError, boolean rateLimitHit) {
|
||||||
if (connectionError && rateLimitHit) {
|
if (connectionError && rateLimitHit) {
|
||||||
throw new IllegalArgumentException("both connection error and rate limit parameter were true");
|
throw new IllegalArgumentException("both connection error and rate limit parameter were true");
|
||||||
@ -202,11 +206,9 @@ public class ReturnYouTubeDislikeApi {
|
|||||||
if (connectionError) {
|
if (connectionError) {
|
||||||
fetchCallResponseTimeLast = responseTimeOfFetchCall;
|
fetchCallResponseTimeLast = responseTimeOfFetchCall;
|
||||||
fetchCallNumberOfFailures++;
|
fetchCallNumberOfFailures++;
|
||||||
showToast("revanced_ryd_failure_connection_timeout");
|
|
||||||
} else if (rateLimitHit) {
|
} else if (rateLimitHit) {
|
||||||
fetchCallResponseTimeLast = FETCH_CALL_RESPONSE_TIME_VALUE_RATE_LIMIT;
|
fetchCallResponseTimeLast = FETCH_CALL_RESPONSE_TIME_VALUE_RATE_LIMIT;
|
||||||
numberOfRateLimitRequestsEncountered++;
|
numberOfRateLimitRequestsEncountered++;
|
||||||
showToast("revanced_ryd_failure_client_rate_limit_requested");
|
|
||||||
} else {
|
} else {
|
||||||
fetchCallResponseTimeLast = responseTimeOfFetchCall;
|
fetchCallResponseTimeLast = responseTimeOfFetchCall;
|
||||||
}
|
}
|
||||||
@ -226,6 +228,7 @@ public class ReturnYouTubeDislikeApi {
|
|||||||
LogHelper.printDebug(() -> "Fetching votes for: " + videoId);
|
LogHelper.printDebug(() -> "Fetching votes for: " + videoId);
|
||||||
final long timeNetworkCallStarted = System.currentTimeMillis();
|
final long timeNetworkCallStarted = System.currentTimeMillis();
|
||||||
|
|
||||||
|
String connectionErrorMessageStringKey = "revanced_ryd_failure_connection_timeout";
|
||||||
try {
|
try {
|
||||||
HttpURLConnection connection = getRYDConnectionFromRoute(ReturnYouTubeDislikeRoutes.GET_DISLIKES, videoId);
|
HttpURLConnection connection = getRYDConnectionFromRoute(ReturnYouTubeDislikeRoutes.GET_DISLIKES, videoId);
|
||||||
// request headers, as per https://returnyoutubedislike.com/docs/fetching
|
// request headers, as per https://returnyoutubedislike.com/docs/fetching
|
||||||
@ -261,12 +264,12 @@ public class ReturnYouTubeDislikeApi {
|
|||||||
// fall thru to update statistics
|
// fall thru to update statistics
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LogHelper.printDebug(() -> "Failed to fetch votes for video: " + videoId
|
LogHelper.printException(() -> "Failed to fetch votes for video: " + videoId
|
||||||
+ " response code was: " + responseCode);
|
+ " response code was: " + responseCode, null, str(connectionErrorMessageStringKey));
|
||||||
connection.disconnect(); // something went wrong, might as well disconnect
|
connection.disconnect(); // something went wrong, might as well disconnect
|
||||||
}
|
}
|
||||||
} catch (Exception ex) { // connection timed out, response timeout, or some other network error
|
} catch (Exception ex) { // connection timed out, response timeout, or some other network error
|
||||||
LogHelper.printException(() -> "Failed to fetch votes", ex);
|
LogHelper.printException(() -> "Failed to fetch votes", ex, str(connectionErrorMessageStringKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
updateStatistics(timeNetworkCallStarted, System.currentTimeMillis(), true, false);
|
updateStatistics(timeNetworkCallStarted, System.currentTimeMillis(), true, false);
|
||||||
@ -304,13 +307,12 @@ public class ReturnYouTubeDislikeApi {
|
|||||||
String solution = solvePuzzle(challenge, difficulty);
|
String solution = solvePuzzle(challenge, difficulty);
|
||||||
return confirmRegistration(userId, solution);
|
return confirmRegistration(userId, solution);
|
||||||
}
|
}
|
||||||
LogHelper.printDebug(() -> "Failed to register new user: " + userId
|
LogHelper.printException(() -> "Failed to register new user: " + userId
|
||||||
+ " response code was: " + responseCode);
|
+ " response code was: " + responseCode);
|
||||||
connection.disconnect();
|
connection.disconnect();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
LogHelper.printException(() -> "Failed to register user", ex);
|
LogHelper.printException(() -> "Failed to register user", ex);
|
||||||
}
|
}
|
||||||
showToast("revanced_ryd_failure_register_user");
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -344,10 +346,10 @@ public class ReturnYouTubeDislikeApi {
|
|||||||
LogHelper.printDebug(() -> "Registration confirmation successful for user: " + userId);
|
LogHelper.printDebug(() -> "Registration confirmation successful for user: " + userId);
|
||||||
return userId;
|
return userId;
|
||||||
}
|
}
|
||||||
LogHelper.printDebug(() -> "Failed to confirm registration for user: " + userId
|
LogHelper.printException(() -> "Failed to confirm registration for user: " + userId
|
||||||
+ " solution: " + solution + " response string was: " + result);
|
+ " solution: " + solution + " response string was: " + result);
|
||||||
} else {
|
} else {
|
||||||
LogHelper.printDebug(() -> "Failed to confirm registration for user: " + userId
|
LogHelper.printException(() -> "Failed to confirm registration for user: " + userId
|
||||||
+ " solution: " + solution + " response code was: " + responseCode);
|
+ " solution: " + solution + " response code was: " + responseCode);
|
||||||
}
|
}
|
||||||
connection.disconnect(); // something went wrong, might as well disconnect
|
connection.disconnect(); // something went wrong, might as well disconnect
|
||||||
@ -355,8 +357,6 @@ public class ReturnYouTubeDislikeApi {
|
|||||||
LogHelper.printException(() -> "Failed to confirm registration for user: " + userId
|
LogHelper.printException(() -> "Failed to confirm registration for user: " + userId
|
||||||
+ "solution: " + solution, ex);
|
+ "solution: " + solution, ex);
|
||||||
}
|
}
|
||||||
showToast("revanced_ryd_failure_confirm_user");
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -395,14 +395,13 @@ public class ReturnYouTubeDislikeApi {
|
|||||||
String solution = solvePuzzle(challenge, difficulty);
|
String solution = solvePuzzle(challenge, difficulty);
|
||||||
return confirmVote(videoId, userId, solution);
|
return confirmVote(videoId, userId, solution);
|
||||||
}
|
}
|
||||||
LogHelper.printDebug(() -> "Failed to send vote for video: " + videoId
|
LogHelper.printException(() -> "Failed to send vote for video: " + videoId
|
||||||
+ " userId: " + userId + " vote: " + vote + " response code was: " + responseCode);
|
+ " userId: " + userId + " vote: " + vote + " response code was: " + responseCode);
|
||||||
connection.disconnect(); // something went wrong, might as well disconnect
|
connection.disconnect(); // something went wrong, might as well disconnect
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
LogHelper.printException(() -> "Failed to send vote for video: " + videoId
|
LogHelper.printException(() -> "Failed to send vote for video: " + videoId
|
||||||
+ " user: " + userId + " vote: " + vote, ex);
|
+ " user: " + userId + " vote: " + vote, ex);
|
||||||
}
|
}
|
||||||
showToast("revanced_ryd_failure_send_vote_failed");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -438,10 +437,10 @@ public class ReturnYouTubeDislikeApi {
|
|||||||
LogHelper.printDebug(() -> "Vote confirm successful for video: " + videoId);
|
LogHelper.printDebug(() -> "Vote confirm successful for video: " + videoId);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
LogHelper.printDebug(() -> "Failed to confirm vote for video: " + videoId
|
LogHelper.printException(() -> "Failed to confirm vote for video: " + videoId
|
||||||
+ " user: " + userId + " solution: " + solution + " response string was: " + result);
|
+ " user: " + userId + " solution: " + solution + " response string was: " + result);
|
||||||
} else {
|
} else {
|
||||||
LogHelper.printDebug(() -> "Failed to confirm vote for video: " + videoId
|
LogHelper.printException(() -> "Failed to confirm vote for video: " + videoId
|
||||||
+ " user: " + userId + " solution: " + solution + " response code was: " + responseCode);
|
+ " user: " + userId + " solution: " + solution + " response code was: " + responseCode);
|
||||||
}
|
}
|
||||||
connection.disconnect(); // something went wrong, might as well disconnect
|
connection.disconnect(); // something went wrong, might as well disconnect
|
||||||
@ -449,16 +448,9 @@ public class ReturnYouTubeDislikeApi {
|
|||||||
LogHelper.printException(() -> "Failed to confirm vote for video: " + videoId
|
LogHelper.printException(() -> "Failed to confirm vote for video: " + videoId
|
||||||
+ " user: " + userId + " solution: " + solution, ex);
|
+ " user: " + userId + " solution: " + solution, ex);
|
||||||
}
|
}
|
||||||
showToast("revanced_ryd_failure_confirm_vote_failed");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void showToast(String toastTextStringKey) {
|
|
||||||
ReVancedUtils.runOnMainThread(() -> { // must show toasts on main thread
|
|
||||||
Toast.makeText(ReVancedUtils.getContext(), str(toastTextStringKey), Toast.LENGTH_LONG).show();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void applyCommonPostRequestSettings(HttpURLConnection connection) throws ProtocolException {
|
private static void applyCommonPostRequestSettings(HttpURLConnection connection) throws ProtocolException {
|
||||||
connection.setRequestMethod("POST");
|
connection.setRequestMethod("POST");
|
||||||
connection.setRequestProperty("Content-Type", "application/json");
|
connection.setRequestProperty("Content-Type", "application/json");
|
||||||
@ -477,7 +469,7 @@ public class ReturnYouTubeDislikeApi {
|
|||||||
byte[] decodedChallenge = Base64.decode(challenge, Base64.NO_WRAP);
|
byte[] decodedChallenge = Base64.decode(challenge, Base64.NO_WRAP);
|
||||||
|
|
||||||
byte[] buffer = new byte[20];
|
byte[] buffer = new byte[20];
|
||||||
for (int i = 4; i < 20; i++) {
|
for (int i = 4; i < 20; i++) { // FIXME replace with System.arrayCopy
|
||||||
buffer[i] = decodedChallenge[i - 4];
|
buffer[i] = decodedChallenge[i - 4];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
package app.revanced.integrations.settings;
|
package app.revanced.integrations.settings;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import app.revanced.integrations.utils.LogHelper;
|
import app.revanced.integrations.utils.LogHelper;
|
||||||
import app.revanced.integrations.utils.ReVancedUtils;
|
import app.revanced.integrations.utils.ReVancedUtils;
|
||||||
import app.revanced.integrations.utils.SharedPrefHelper;
|
import app.revanced.integrations.utils.SharedPrefHelper;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public enum SettingsEnum {
|
public enum SettingsEnum {
|
||||||
//Download Settings
|
//Download Settings
|
||||||
// TODO: DOWNLOAD_PATH("revanced_download_path", Environment.getExternalStorageDirectory().getPath() + "/Download", ReturnType.STRING),
|
// TODO: DOWNLOAD_PATH("revanced_download_path", Environment.getExternalStorageDirectory().getPath() + "/Download", ReturnType.STRING),
|
||||||
@ -47,7 +46,6 @@ public enum SettingsEnum {
|
|||||||
ADREMOVER_INFO_PANEL_REMOVAL("revanced_adremover_info_panel", true, ReturnType.BOOLEAN),
|
ADREMOVER_INFO_PANEL_REMOVAL("revanced_adremover_info_panel", true, ReturnType.BOOLEAN),
|
||||||
ADREMOVER_MEDICAL_PANEL_REMOVAL("revanced_adremover_medical_panel", true, ReturnType.BOOLEAN),
|
ADREMOVER_MEDICAL_PANEL_REMOVAL("revanced_adremover_medical_panel", true, ReturnType.BOOLEAN),
|
||||||
ADREMOVER_PAID_CONTENT_REMOVAL("revanced_adremover_paid_content", true, ReturnType.BOOLEAN),
|
ADREMOVER_PAID_CONTENT_REMOVAL("revanced_adremover_paid_content", true, ReturnType.BOOLEAN),
|
||||||
ADREMOVER_SUGGESTIONS_REMOVAL("revanced_adremover_hide_suggestions", true, ReturnType.BOOLEAN),
|
|
||||||
ADREMOVER_HIDE_LATEST_POSTS("revanced_adremover_hide_latest_posts", true, ReturnType.BOOLEAN),
|
ADREMOVER_HIDE_LATEST_POSTS("revanced_adremover_hide_latest_posts", true, ReturnType.BOOLEAN),
|
||||||
ADREMOVER_HIDE_CHANNEL_GUIDELINES("revanced_adremover_hide_channel_guidelines", true, ReturnType.BOOLEAN),
|
ADREMOVER_HIDE_CHANNEL_GUIDELINES("revanced_adremover_hide_channel_guidelines", true, ReturnType.BOOLEAN),
|
||||||
ADREMOVER_SELF_SPONSOR_REMOVAL("revanced_adremover_self_sponsor", true, ReturnType.BOOLEAN),
|
ADREMOVER_SELF_SPONSOR_REMOVAL("revanced_adremover_self_sponsor", true, ReturnType.BOOLEAN),
|
||||||
@ -100,6 +98,7 @@ public enum SettingsEnum {
|
|||||||
ENABLE_MINIMIZED_PLAYBACK("revanced_enable_minimized_playback", true, ReturnType.BOOLEAN),
|
ENABLE_MINIMIZED_PLAYBACK("revanced_enable_minimized_playback", true, ReturnType.BOOLEAN),
|
||||||
OPEN_LINKS_DIRECTLY("revanced_uri_redirect", true, ReturnType.BOOLEAN, true),
|
OPEN_LINKS_DIRECTLY("revanced_uri_redirect", true, ReturnType.BOOLEAN, true),
|
||||||
DISABLE_ZOOM_HAPTICS("revanced_disable_zoom_haptics", true, ReturnType.BOOLEAN, false),
|
DISABLE_ZOOM_HAPTICS("revanced_disable_zoom_haptics", true, ReturnType.BOOLEAN, false),
|
||||||
|
ENABLE_EXTERNAL_BROWSER("revanced_enable_external_browser", true, ReturnType.BOOLEAN, true),
|
||||||
|
|
||||||
// Swipe controls
|
// Swipe controls
|
||||||
ENABLE_SWIPE_BRIGHTNESS("revanced_enable_swipe_brightness", true, ReturnType.BOOLEAN),
|
ENABLE_SWIPE_BRIGHTNESS("revanced_enable_swipe_brightness", true, ReturnType.BOOLEAN),
|
||||||
@ -116,9 +115,10 @@ public enum SettingsEnum {
|
|||||||
PLAYBACK_MAX_BUFFER("revanced_pref_buffer_for_playback_ms", 2500, ReturnType.INTEGER),
|
PLAYBACK_MAX_BUFFER("revanced_pref_buffer_for_playback_ms", 2500, ReturnType.INTEGER),
|
||||||
MAX_PLAYBACK_BUFFER_AFTER_REBUFFER("revanced_pref_buffer_for_playback_after_rebuffer_ms", 5000, ReturnType.INTEGER),
|
MAX_PLAYBACK_BUFFER_AFTER_REBUFFER("revanced_pref_buffer_for_playback_after_rebuffer_ms", 5000, ReturnType.INTEGER),
|
||||||
|
|
||||||
// ReVanced settings
|
// Debug settings
|
||||||
DEBUG("revanced_debug_enabled", false, ReturnType.BOOLEAN),
|
DEBUG("revanced_debug_enabled", false, ReturnType.BOOLEAN),
|
||||||
DEBUG_STACKTRACE("revanced_debug_stacktrace_enabled", false, ReturnType.BOOLEAN),
|
DEBUG_STACKTRACE("revanced_debug_stacktrace_enabled", false, ReturnType.BOOLEAN),
|
||||||
|
DEBUG_SHOW_TOAST_ON_ERROR("revanced_debug_toast_on_error_enabled", true, ReturnType.BOOLEAN),
|
||||||
|
|
||||||
USE_DARK_THEME("app_theme_dark", false, ReturnType.BOOLEAN),
|
USE_DARK_THEME("app_theme_dark", false, ReturnType.BOOLEAN),
|
||||||
|
|
||||||
@ -224,7 +224,7 @@ public enum SettingsEnum {
|
|||||||
//
|
//
|
||||||
|
|
||||||
// old/new settings where old is default off, and new has inverted value and is default on
|
// old/new settings where old is default off, and new has inverted value and is default on
|
||||||
SettingsEnum invertedSettingsToMigrate[][] = {
|
SettingsEnum[][] invertedSettingsToMigrate = {
|
||||||
{DEPRECATED_FULLSCREEN_PANELS_SHOWN, HIDE_FULLSCREEN_PANELS},
|
{DEPRECATED_FULLSCREEN_PANELS_SHOWN, HIDE_FULLSCREEN_PANELS},
|
||||||
{DEPRECATED_CREATE_BUTTON_ENABLED, HIDE_CREATE_BUTTON},
|
{DEPRECATED_CREATE_BUTTON_ENABLED, HIDE_CREATE_BUTTON},
|
||||||
{DEPRECATED_SHORTS_BUTTON_SHOWN, HIDE_SHORTS_BUTTON},
|
{DEPRECATED_SHORTS_BUTTON_SHOWN, HIDE_SHORTS_BUTTON},
|
||||||
@ -234,7 +234,7 @@ public enum SettingsEnum {
|
|||||||
{DEPRECATED_BRANDING_SHOWN, HIDE_VIDEO_WATERMARK},
|
{DEPRECATED_BRANDING_SHOWN, HIDE_VIDEO_WATERMARK},
|
||||||
{DEPRECATED_REMEMBER_VIDEO_QUALITY, REMEMBER_VIDEO_QUALITY_LAST_SELECTED},
|
{DEPRECATED_REMEMBER_VIDEO_QUALITY, REMEMBER_VIDEO_QUALITY_LAST_SELECTED},
|
||||||
};
|
};
|
||||||
for (SettingsEnum oldNewSetting[] : invertedSettingsToMigrate) {
|
for (SettingsEnum[] oldNewSetting : invertedSettingsToMigrate) {
|
||||||
// by default, old setting was default off
|
// by default, old setting was default off
|
||||||
// migrate to new setting of default on
|
// migrate to new setting of default on
|
||||||
SettingsEnum oldSetting = oldNewSetting[0];
|
SettingsEnum oldSetting = oldNewSetting[0];
|
||||||
@ -253,7 +253,7 @@ public enum SettingsEnum {
|
|||||||
//
|
//
|
||||||
// migrate preference of prior 'default off' settings, into replacement setting with different path name but otherwise is identical
|
// migrate preference of prior 'default off' settings, into replacement setting with different path name but otherwise is identical
|
||||||
//
|
//
|
||||||
SettingsEnum renamedSettings[][] = {
|
SettingsEnum[][] renamedSettings = {
|
||||||
{DEPRECATED_HIDE_MIX_PLAYLISTS, HIDE_MIX_PLAYLISTS},
|
{DEPRECATED_HIDE_MIX_PLAYLISTS, HIDE_MIX_PLAYLISTS},
|
||||||
{DEPRECATED_HIDE_LIKE_BUTTON, HIDE_LIKE_BUTTON},
|
{DEPRECATED_HIDE_LIKE_BUTTON, HIDE_LIKE_BUTTON},
|
||||||
{DEPRECATED_HIDE_DISLIKE_BUTTON, HIDE_DISLIKE_BUTTON},
|
{DEPRECATED_HIDE_DISLIKE_BUTTON, HIDE_DISLIKE_BUTTON},
|
||||||
@ -262,7 +262,7 @@ public enum SettingsEnum {
|
|||||||
{DEPRECATED_HIDE_ACTION_BUTTON, HIDE_ACTION_BUTTON},
|
{DEPRECATED_HIDE_ACTION_BUTTON, HIDE_ACTION_BUTTON},
|
||||||
{DEPRECATED_HIDE_SHARE_BUTTON, HIDE_SHARE_BUTTON},
|
{DEPRECATED_HIDE_SHARE_BUTTON, HIDE_SHARE_BUTTON},
|
||||||
};
|
};
|
||||||
for (SettingsEnum oldNewSetting[] : renamedSettings) {
|
for (SettingsEnum[] oldNewSetting : renamedSettings) {
|
||||||
SettingsEnum oldSetting = oldNewSetting[0];
|
SettingsEnum oldSetting = oldNewSetting[0];
|
||||||
SettingsEnum newSetting = oldNewSetting[1];
|
SettingsEnum newSetting = oldNewSetting[1];
|
||||||
|
|
||||||
@ -304,7 +304,7 @@ public enum SettingsEnum {
|
|||||||
defaultValue = SharedPrefHelper.getString(setting.sharedPref, path, (String) defaultValue);
|
defaultValue = SharedPrefHelper.getString(setting.sharedPref, path, (String) defaultValue);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LogHelper.printException(() -> ("Setting does not have a valid Type. Name is: " + setting.name()));
|
LogHelper.printException(() -> "Setting does not have a valid Type. Name is: " + setting.name());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
setting.setValue(defaultValue);
|
setting.setValue(defaultValue);
|
||||||
@ -337,28 +337,28 @@ public enum SettingsEnum {
|
|||||||
Context context = ReVancedUtils.getContext();
|
Context context = ReVancedUtils.getContext();
|
||||||
|
|
||||||
if (context == null) {
|
if (context == null) {
|
||||||
LogHelper.printException(() -> ("Context on SaveValue is null!"));
|
LogHelper.printException(() -> "Context on SaveValue is null!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (getReturnType()) {
|
switch (getReturnType()) {
|
||||||
case FLOAT:
|
case FLOAT:
|
||||||
SharedPrefHelper.saveFloat(sharedPref, path, (float) defaultValue);
|
SharedPrefHelper.saveFloat(sharedPref, path, (float) newValue);
|
||||||
break;
|
break;
|
||||||
case LONG:
|
case LONG:
|
||||||
SharedPrefHelper.saveLong(sharedPref, path, (long) defaultValue);
|
SharedPrefHelper.saveLong(sharedPref, path, (long) newValue);
|
||||||
break;
|
break;
|
||||||
case BOOLEAN:
|
case BOOLEAN:
|
||||||
SharedPrefHelper.saveBoolean(sharedPref, path, (boolean) newValue);
|
SharedPrefHelper.saveBoolean(sharedPref, path, (boolean) newValue);
|
||||||
break;
|
break;
|
||||||
case INTEGER:
|
case INTEGER:
|
||||||
SharedPrefHelper.saveInt(sharedPref, path, (int) defaultValue);
|
SharedPrefHelper.saveInt(sharedPref, path, (int) newValue);
|
||||||
break;
|
break;
|
||||||
case STRING:
|
case STRING:
|
||||||
SharedPrefHelper.saveString(sharedPref, path, (String) defaultValue);
|
SharedPrefHelper.saveString(sharedPref, path, (String) newValue);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LogHelper.printException(() -> ("Setting does not have a valid Type. Name is: " + name()));
|
LogHelper.printException(() -> "Setting does not have a valid Type. Name is: " + name());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,8 @@ import android.view.ViewGroup;
|
|||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import com.google.android.libraries.social.licenses.LicenseActivity;
|
import com.google.android.libraries.social.licenses.LicenseActivity;
|
||||||
|
|
||||||
import app.revanced.integrations.utils.LogHelper;
|
import app.revanced.integrations.utils.LogHelper;
|
||||||
@ -44,15 +46,23 @@ public class ReVancedSettingActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
getTextView((ViewGroup) base.findViewById(getIdentifier("toolbar", "id"))).setText(preferenceIdentifier);
|
TextView toolbar = getTextView((ViewGroup) base.findViewById(getIdentifier("toolbar", "id")));
|
||||||
|
if (toolbar == null) {
|
||||||
|
// FIXME
|
||||||
|
// https://github.com/revanced/revanced-patches/issues/1384
|
||||||
|
LogHelper.printDebug(() -> "Could not find toolbar");
|
||||||
|
} else {
|
||||||
|
toolbar.setText(preferenceIdentifier);
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogHelper.printException(() -> ("Couldn't set Toolbar title"), e);
|
LogHelper.printException(() -> "Could not set Toolbar title", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
base.getFragmentManager().beginTransaction().replace(getIdentifier("revanced_settings_fragments", "id"), preferenceFragment).commit();
|
base.getFragmentManager().beginTransaction().replace(getIdentifier("revanced_settings_fragments", "id"), preferenceFragment).commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Nullable
|
||||||
public static <T extends View> T getView(Class<T> typeClass, ViewGroup viewGroup) {
|
public static <T extends View> T getView(Class<T> typeClass, ViewGroup viewGroup) {
|
||||||
if (viewGroup == null) {
|
if (viewGroup == null) {
|
||||||
return null;
|
return null;
|
||||||
@ -67,10 +77,12 @@ public class ReVancedSettingActivity {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
public static ImageButton getImageButton(ViewGroup viewGroup) {
|
public static ImageButton getImageButton(ViewGroup viewGroup) {
|
||||||
return getView(ImageButton.class, viewGroup);
|
return getView(ImageButton.class, viewGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
public static TextView getTextView(ViewGroup viewGroup) {
|
public static TextView getTextView(ViewGroup viewGroup) {
|
||||||
return getView(TextView.class, viewGroup);
|
return getView(TextView.class, viewGroup);
|
||||||
}
|
}
|
||||||
|
@ -66,12 +66,12 @@ public class ReVancedSettingsFragment extends PreferenceFragment {
|
|||||||
value = Integer.parseInt(editPref.getText());
|
value = Integer.parseInt(editPref.getText());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LogHelper.printException(() -> ("Setting has no valid return type! " + setting.getReturnType()));
|
LogHelper.printException(() -> "Setting has no valid return type! " + setting.getReturnType());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
setting.setValue(value);
|
setting.setValue(value);
|
||||||
} else {
|
} else {
|
||||||
LogHelper.printException(() -> ("Setting cannot be handled! " + pref.toString()));
|
LogHelper.printException(() -> "Setting cannot be handled: " + pref.getClass() + " " + pref.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ReVancedUtils.getContext() != null && settingsInitialized && setting.shouldRebootOnChange()) {
|
if (ReVancedUtils.getContext() != null && settingsInitialized && setting.shouldRebootOnChange()) {
|
||||||
@ -96,7 +96,7 @@ public class ReVancedSettingsFragment extends PreferenceFragment {
|
|||||||
|
|
||||||
this.settingsInitialized = true;
|
this.settingsInitialized = true;
|
||||||
} catch (Throwable th) {
|
} catch (Throwable th) {
|
||||||
LogHelper.printException(() -> ("Error during onCreate()"), th);
|
LogHelper.printException(() -> "Error during onCreate()", th);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,7 +111,7 @@ public class ReVancedSettingsFragment extends PreferenceFragment {
|
|||||||
|
|
||||||
private Preference findPreferenceOnScreen(CharSequence key) {
|
private Preference findPreferenceOnScreen(CharSequence key) {
|
||||||
if (key == null) {
|
if (key == null) {
|
||||||
LogHelper.printException(() -> ("Key cannot be null!"));
|
LogHelper.printException(() -> "Key cannot be null!");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Preference pref = null;
|
Preference pref = null;
|
||||||
@ -144,7 +144,7 @@ public class ReVancedSettingsFragment extends PreferenceFragment {
|
|||||||
private String getPackageName() {
|
private String getPackageName() {
|
||||||
Context context = ReVancedUtils.getContext();
|
Context context = ReVancedUtils.getContext();
|
||||||
if (context == null) {
|
if (context == null) {
|
||||||
LogHelper.printException(() -> ("Context is null, returning com.google.android.youtube!"));
|
LogHelper.printException(() -> "Context is null, returning com.google.android.youtube!");
|
||||||
return "com.google.android.youtube";
|
return "com.google.android.youtube";
|
||||||
}
|
}
|
||||||
String PACKAGE_NAME = context.getPackageName();
|
String PACKAGE_NAME = context.getPackageName();
|
||||||
@ -169,7 +169,7 @@ public class ReVancedSettingsFragment extends PreferenceFragment {
|
|||||||
Resources res = context.getResources();
|
Resources res = context.getResources();
|
||||||
return res.getString(res.getIdentifier(name, "string", context.getPackageName()));
|
return res.getString(res.getIdentifier(name, "string", context.getPackageName()));
|
||||||
} catch (Throwable exception) {
|
} catch (Throwable exception) {
|
||||||
LogHelper.printException(() -> ("Resource not found."), exception);
|
LogHelper.printException(() -> "Resource not found.", exception);
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import app.revanced.integrations.utils.Event
|
|||||||
*/
|
*/
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
enum class PlayerType {
|
enum class PlayerType {
|
||||||
NONE,
|
NONE, // this also includes when shorts are playing
|
||||||
HIDDEN,
|
HIDDEN,
|
||||||
WATCH_WHILE_MINIMIZED,
|
WATCH_WHILE_MINIMIZED,
|
||||||
WATCH_WHILE_MAXIMIZED,
|
WATCH_WHILE_MAXIMIZED,
|
||||||
|
@ -1,17 +1,18 @@
|
|||||||
package app.revanced.integrations.sponsorblock;
|
package app.revanced.integrations.sponsorblock;
|
||||||
|
|
||||||
import static app.revanced.integrations.sponsorblock.SponsorBlockUtils.timeWithoutSegments;
|
|
||||||
import static app.revanced.integrations.sponsorblock.SponsorBlockUtils.videoHasSegments;
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.Looper;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import app.revanced.integrations.patches.VideoInformation;
|
||||||
|
import app.revanced.integrations.settings.SettingsEnum;
|
||||||
|
import app.revanced.integrations.shared.PlayerType;
|
||||||
|
import app.revanced.integrations.sponsorblock.objects.SponsorSegment;
|
||||||
|
import app.revanced.integrations.sponsorblock.requests.SBRequester;
|
||||||
|
import app.revanced.integrations.utils.LogHelper;
|
||||||
|
import app.revanced.integrations.utils.ReVancedUtils;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
@ -19,14 +20,9 @@ import java.util.Arrays;
|
|||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
|
|
||||||
import app.revanced.integrations.patches.VideoInformation;
|
import static app.revanced.integrations.sponsorblock.SponsorBlockUtils.timeWithoutSegments;
|
||||||
import app.revanced.integrations.settings.SettingsEnum;
|
import static app.revanced.integrations.sponsorblock.SponsorBlockUtils.videoHasSegments;
|
||||||
import app.revanced.integrations.sponsorblock.objects.SponsorSegment;
|
|
||||||
import app.revanced.integrations.sponsorblock.requests.SBRequester;
|
|
||||||
import app.revanced.integrations.utils.LogHelper;
|
|
||||||
import app.revanced.integrations.utils.ReVancedUtils;
|
|
||||||
|
|
||||||
@SuppressLint({"LongLogTag"})
|
|
||||||
public class PlayerController {
|
public class PlayerController {
|
||||||
|
|
||||||
private static final Timer sponsorTimer = new Timer("sponsor-skip-timer");
|
private static final Timer sponsorTimer = new Timer("sponsor-skip-timer");
|
||||||
@ -43,126 +39,149 @@ public class PlayerController {
|
|||||||
private static float sponsorBarThickness = 2f;
|
private static float sponsorBarThickness = 2f;
|
||||||
private static TimerTask skipSponsorTask = null;
|
private static TimerTask skipSponsorTask = null;
|
||||||
|
|
||||||
public static boolean shorts_playing = false;
|
|
||||||
|
|
||||||
public static String getCurrentVideoId() {
|
public static String getCurrentVideoId() {
|
||||||
return currentVideoId;
|
return currentVideoId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setCurrentVideoId(final String videoId) {
|
public static void setCurrentVideoId(final String videoId) {
|
||||||
if (videoId == null) {
|
try {
|
||||||
currentVideoId = null;
|
if (videoId == null) {
|
||||||
sponsorSegmentsOfCurrentVideo = null;
|
currentVideoId = null;
|
||||||
return;
|
sponsorSegmentsOfCurrentVideo = null;
|
||||||
}
|
return;
|
||||||
|
|
||||||
SponsorBlockSettings.update(null);
|
|
||||||
|
|
||||||
if (!SettingsEnum.SB_ENABLED.getBoolean()) {
|
|
||||||
currentVideoId = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (videoId.equals(currentVideoId))
|
|
||||||
return;
|
|
||||||
|
|
||||||
currentVideoId = videoId;
|
|
||||||
sponsorSegmentsOfCurrentVideo = null;
|
|
||||||
LogHelper.printDebug(() -> "setCurrentVideoId: videoId=" + videoId);
|
|
||||||
|
|
||||||
sponsorTimer.schedule(new TimerTask() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
executeDownloadSegments(currentVideoId);
|
|
||||||
}
|
}
|
||||||
}, 0);
|
|
||||||
|
// currently this runs every time a video is loaded (regardless if sponsorblock is turned on or off)
|
||||||
|
// FIXME: change this so if sponsorblock is disabled, then run this method exactly once and once only
|
||||||
|
SponsorBlockSettings.update(null);
|
||||||
|
|
||||||
|
if (!SettingsEnum.SB_ENABLED.getBoolean()) {
|
||||||
|
currentVideoId = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (PlayerType.getCurrent() == PlayerType.NONE) {
|
||||||
|
LogHelper.printDebug(() -> "ignoring shorts video");
|
||||||
|
currentVideoId = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (videoId.equals(currentVideoId))
|
||||||
|
return;
|
||||||
|
|
||||||
|
currentVideoId = videoId;
|
||||||
|
sponsorSegmentsOfCurrentVideo = null;
|
||||||
|
LogHelper.printDebug(() -> "setCurrentVideoId: videoId=" + videoId);
|
||||||
|
|
||||||
|
sponsorTimer.schedule(new TimerTask() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
executeDownloadSegments(currentVideoId);
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogHelper.printException(() -> "Failed to download segments", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 0);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
LogHelper.printException(() -> "setCurrentVideoId failure", ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when creating some kind of youtube internal player controlled, every time when new video starts to play
|
* Called when creating some kind of youtube internal player controlled, every time when new video starts to play
|
||||||
*/
|
*/
|
||||||
public static void initialize(Object _o) {
|
public static void initialize(Object _o) {
|
||||||
lastKnownVideoTime = 0;
|
try {
|
||||||
SkipSegmentView.hide();
|
lastKnownVideoTime = 0;
|
||||||
NewSegmentHelperLayout.hide();
|
SkipSegmentView.hide();
|
||||||
|
NewSegmentHelperLayout.hide();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
LogHelper.printException(() -> "initialize failure", ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void executeDownloadSegments(String videoId) {
|
public static void executeDownloadSegments(String videoId) {
|
||||||
videoHasSegments = false;
|
try {
|
||||||
timeWithoutSegments = "";
|
videoHasSegments = false;
|
||||||
if (shorts_playing) {
|
timeWithoutSegments = "";
|
||||||
return;
|
|
||||||
}
|
|
||||||
SponsorSegment[] segments = SBRequester.getSegments(videoId);
|
|
||||||
Arrays.sort(segments);
|
|
||||||
|
|
||||||
for (SponsorSegment segment : segments) {
|
SponsorSegment[] segments = SBRequester.getSegments(videoId);
|
||||||
LogHelper.printDebug(() -> "Detected segment: " + segment.toString());
|
Arrays.sort(segments);
|
||||||
}
|
|
||||||
|
|
||||||
sponsorSegmentsOfCurrentVideo = segments;
|
for (SponsorSegment segment : segments) {
|
||||||
// new Handler(Looper.getMainLooper()).post(findAndSkipSegmentRunnable);
|
LogHelper.printDebug(() -> "Detected segment: " + segment.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
sponsorSegmentsOfCurrentVideo = segments;
|
||||||
|
// new Handler(Looper.getMainLooper()).post(findAndSkipSegmentRunnable);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
LogHelper.printException(() -> "executeDownloadSegments failure", ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void setVideoTime(long millis) {
|
public static void setVideoTime(long millis) {
|
||||||
LogHelper.printDebug(() -> "setCurrentVideoTime: current video time: " + millis);
|
try {
|
||||||
if (!SettingsEnum.SB_ENABLED.getBoolean()) return;
|
if (!SettingsEnum.SB_ENABLED.getBoolean()) return;
|
||||||
lastKnownVideoTime = millis;
|
LogHelper.printDebug(() -> "setCurrentVideoTime: current video time: " + millis);
|
||||||
if (millis <= 0) return;
|
// fixme? if (millis == lastKnownVideoTime), should it return here and not continue?
|
||||||
//findAndSkipSegment(false);
|
lastKnownVideoTime = millis;
|
||||||
|
if (millis <= 0) return;
|
||||||
|
//findAndSkipSegment(false);
|
||||||
|
|
||||||
if (millis == VideoInformation.getCurrentVideoLength()) {
|
if (millis == VideoInformation.getCurrentVideoLength()) {
|
||||||
SponsorBlockUtils.hideShieldButton();
|
SponsorBlockUtils.hideShieldButton();
|
||||||
SponsorBlockUtils.hideVoteButton();
|
SponsorBlockUtils.hideVoteButton();
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SponsorSegment[] segments = sponsorSegmentsOfCurrentVideo;
|
|
||||||
if (segments == null || segments.length == 0) return;
|
|
||||||
|
|
||||||
final long START_TIMER_BEFORE_SEGMENT_MILLIS = 1200;
|
|
||||||
final long startTimerAtMillis = millis + START_TIMER_BEFORE_SEGMENT_MILLIS;
|
|
||||||
|
|
||||||
for (final SponsorSegment segment : segments) {
|
|
||||||
if (segment.start > millis) {
|
|
||||||
if (segment.start > startTimerAtMillis)
|
|
||||||
break; // it's more then START_TIMER_BEFORE_SEGMENT_MILLIS far away
|
|
||||||
if (!segment.category.behaviour.skip)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (skipSponsorTask == null) {
|
|
||||||
LogHelper.printDebug(() -> "Scheduling skipSponsorTask");
|
|
||||||
skipSponsorTask = new TimerTask() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
skipSponsorTask = null;
|
|
||||||
lastKnownVideoTime = segment.start + 1;
|
|
||||||
new Handler(Looper.getMainLooper()).post(findAndSkipSegmentRunnable);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
sponsorTimer.schedule(skipSponsorTask, segment.start - millis);
|
|
||||||
} else {
|
|
||||||
LogHelper.printDebug(() -> "skipSponsorTask is already scheduled...");
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (segment.end < millis)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// we are in the segment!
|
|
||||||
if (segment.category.behaviour.skip && !(segment.category.behaviour.key.equals("skip-once") && segment.didAutoSkipped)) {
|
|
||||||
sendViewRequestAsync(millis, segment);
|
|
||||||
skipSegment(segment, false);
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
SkipSegmentView.show();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SponsorSegment[] segments = sponsorSegmentsOfCurrentVideo;
|
||||||
|
if (segments == null || segments.length == 0) return;
|
||||||
|
|
||||||
|
final long START_TIMER_BEFORE_SEGMENT_MILLIS = 1200;
|
||||||
|
final long startTimerAtMillis = millis + START_TIMER_BEFORE_SEGMENT_MILLIS;
|
||||||
|
|
||||||
|
for (final SponsorSegment segment : segments) {
|
||||||
|
if (segment.start > millis) {
|
||||||
|
if (segment.start > startTimerAtMillis)
|
||||||
|
break; // it's more then START_TIMER_BEFORE_SEGMENT_MILLIS far away
|
||||||
|
if (!segment.category.behaviour.skip)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (skipSponsorTask == null) {
|
||||||
|
LogHelper.printDebug(() -> "Scheduling skipSponsorTask");
|
||||||
|
skipSponsorTask = new TimerTask() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
skipSponsorTask = null;
|
||||||
|
lastKnownVideoTime = segment.start + 1;
|
||||||
|
ReVancedUtils.runOnMainThread(findAndSkipSegmentRunnable);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
sponsorTimer.schedule(skipSponsorTask, segment.start - millis);
|
||||||
|
} else {
|
||||||
|
LogHelper.printDebug(() -> "skipSponsorTask is already scheduled...");
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (segment.end < millis)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// we are in the segment!
|
||||||
|
if (segment.category.behaviour.skip && !(segment.category.behaviour.key.equals("skip-once") && segment.didAutoSkipped)) {
|
||||||
|
sendViewRequestAsync(millis, segment);
|
||||||
|
skipSegment(segment, false);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
SkipSegmentView.show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SkipSegmentView.hide();
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogHelper.printException(() -> "setVideoTime failure", e);
|
||||||
}
|
}
|
||||||
SkipSegmentView.hide();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void sendViewRequestAsync(final long millis, final SponsorSegment segment) {
|
private static void sendViewRequestAsync(final long millis, final SponsorSegment segment) {
|
||||||
@ -174,7 +193,7 @@ public class PlayerController {
|
|||||||
SettingsEnum.SB_SKIPPED_SEGMENTS_TIME.saveValue(newSkippedTime);
|
SettingsEnum.SB_SKIPPED_SEGMENTS_TIME.saveValue(newSkippedTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
new Thread(() -> {
|
new Thread(() -> { // fixme: use ReVancedUtils#runOnBackgroundThread
|
||||||
if (SettingsEnum.SB_COUNT_SKIPS.getBoolean() &&
|
if (SettingsEnum.SB_COUNT_SKIPS.getBoolean() &&
|
||||||
segment.category != SponsorBlockSettings.SegmentInfo.UNSUBMITTED &&
|
segment.category != SponsorBlockSettings.SegmentInfo.UNSUBMITTED &&
|
||||||
millis - segment.start < 2000) {
|
millis - segment.start < 2000) {
|
||||||
@ -185,14 +204,18 @@ public class PlayerController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void setHighPrecisionVideoTime(final long millis) {
|
public static void setHighPrecisionVideoTime(final long millis) {
|
||||||
if ((millis < lastKnownVideoTime && lastKnownVideoTime >= VideoInformation.getCurrentVideoLength()) || millis == 0) {
|
try {
|
||||||
SponsorBlockUtils.showShieldButton(); // skipping from end to the video will show the buttons again
|
if ((millis < lastKnownVideoTime && lastKnownVideoTime >= VideoInformation.getCurrentVideoLength()) || millis == 0) {
|
||||||
SponsorBlockUtils.showVoteButton();
|
SponsorBlockUtils.showShieldButton(); // skipping from end to the video will show the buttons again
|
||||||
|
SponsorBlockUtils.showVoteButton();
|
||||||
|
}
|
||||||
|
if (lastKnownVideoTime > 0) {
|
||||||
|
lastKnownVideoTime = millis;
|
||||||
|
} else
|
||||||
|
setVideoTime(millis);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
LogHelper.printException(() -> "setHighPrecisionVideoTime failure", ex);
|
||||||
}
|
}
|
||||||
if (lastKnownVideoTime > 0) {
|
|
||||||
lastKnownVideoTime = millis;
|
|
||||||
} else
|
|
||||||
setVideoTime(millis);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long getCurrentVideoLength() {
|
public static long getCurrentVideoLength() {
|
||||||
@ -222,8 +245,8 @@ public class PlayerController {
|
|||||||
setSponsorBarAbsoluteLeft(rect.left);
|
setSponsorBarAbsoluteLeft(rect.left);
|
||||||
setSponsorBarAbsoluteRight(rect.right);
|
setSponsorBarAbsoluteRight(rect.right);
|
||||||
}
|
}
|
||||||
} catch (IllegalAccessException | NoSuchFieldException e) {
|
} catch (Exception ex) {
|
||||||
e.printStackTrace();
|
LogHelper.printException(() -> "setSponsorBarRect failure", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,7 +261,11 @@ public class PlayerController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void setSponsorBarThickness(final int thickness) {
|
public static void setSponsorBarThickness(final int thickness) {
|
||||||
setSponsorBarThickness((float) thickness);
|
try {
|
||||||
|
setSponsorBarThickness((float) thickness);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
LogHelper.printException(() -> "setSponsorBarThickness failure", ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setSponsorBarThickness(final float thickness) {
|
public static void setSponsorBarThickness(final float thickness) {
|
||||||
@ -255,24 +282,33 @@ public class PlayerController {
|
|||||||
|
|
||||||
|
|
||||||
public static void addSkipSponsorView15(final View view) {
|
public static void addSkipSponsorView15(final View view) {
|
||||||
playerActivity = new WeakReference<>((Activity) view.getContext());
|
try {
|
||||||
LogHelper.printDebug(() -> "addSkipSponsorView15: view=" + view.toString());
|
playerActivity = new WeakReference<>((Activity) view.getContext());
|
||||||
|
LogHelper.printDebug(() -> "addSkipSponsorView15: view=" + view.toString());
|
||||||
|
|
||||||
new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
ReVancedUtils.runOnMainThreadDelayed(() -> {
|
||||||
final ViewGroup viewGroup = (ViewGroup) ((ViewGroup) view).getChildAt(2);
|
final ViewGroup viewGroup = (ViewGroup) ((ViewGroup) view).getChildAt(2);
|
||||||
Activity context = ((Activity) viewGroup.getContext());
|
Activity context = ((Activity) viewGroup.getContext());
|
||||||
NewSegmentHelperLayout.context = context;
|
NewSegmentHelperLayout.context = context;
|
||||||
}, 500);
|
}, 500);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
LogHelper.printException(() -> "addSkipSponsorView15 failure", ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Edit: Is this method ever called? Where is the patch code that calls this?
|
||||||
public static void addSkipSponsorView14(final View view) {
|
public static void addSkipSponsorView14(final View view) {
|
||||||
playerActivity = new WeakReference<>((Activity) view.getContext());
|
try {
|
||||||
LogHelper.printDebug(() -> "addSkipSponsorView14: view=" + view.toString());
|
playerActivity = new WeakReference<>((Activity) view.getContext());
|
||||||
new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
LogHelper.printDebug(() -> "addSkipSponsorView14: view=" + view.toString());
|
||||||
final ViewGroup viewGroup = (ViewGroup) view.getParent();
|
ReVancedUtils.runOnMainThreadDelayed(() -> {
|
||||||
Activity activity = (Activity) viewGroup.getContext();
|
final ViewGroup viewGroup = (ViewGroup) view.getParent();
|
||||||
NewSegmentHelperLayout.context = activity;
|
Activity activity = (Activity) viewGroup.getContext();
|
||||||
}, 500);
|
NewSegmentHelperLayout.context = activity;
|
||||||
|
}, 500);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
LogHelper.printException(() -> "addSkipSponsorView14 failure", ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -280,21 +316,25 @@ public class PlayerController {
|
|||||||
* Called when it's time to draw time bar
|
* Called when it's time to draw time bar
|
||||||
*/
|
*/
|
||||||
public static void drawSponsorTimeBars(final Canvas canvas, final float posY) {
|
public static void drawSponsorTimeBars(final Canvas canvas, final float posY) {
|
||||||
if (sponsorBarThickness < 0.1) return;
|
try {
|
||||||
if (sponsorSegmentsOfCurrentVideo == null) return;
|
if (sponsorBarThickness < 0.1) return;
|
||||||
|
if (sponsorSegmentsOfCurrentVideo == null) return;
|
||||||
|
|
||||||
|
|
||||||
final float thicknessDiv2 = sponsorBarThickness / 2;
|
final float thicknessDiv2 = sponsorBarThickness / 2;
|
||||||
final float top = posY - thicknessDiv2;
|
final float top = posY - thicknessDiv2;
|
||||||
final float bottom = posY + thicknessDiv2;
|
final float bottom = posY + thicknessDiv2;
|
||||||
final float absoluteLeft = sponsorBarLeft;
|
final float absoluteLeft = sponsorBarLeft;
|
||||||
final float absoluteRight = sponsorBarRight;
|
final float absoluteRight = sponsorBarRight;
|
||||||
|
|
||||||
final float tmp1 = 1f / (float) VideoInformation.getCurrentVideoLength() * (absoluteRight - absoluteLeft);
|
final float tmp1 = 1f / (float) VideoInformation.getCurrentVideoLength() * (absoluteRight - absoluteLeft);
|
||||||
for (SponsorSegment segment : sponsorSegmentsOfCurrentVideo) {
|
for (SponsorSegment segment : sponsorSegmentsOfCurrentVideo) {
|
||||||
float left = segment.start * tmp1 + absoluteLeft;
|
float left = segment.start * tmp1 + absoluteLeft;
|
||||||
float right = segment.end * tmp1 + absoluteLeft;
|
float right = segment.end * tmp1 + absoluteLeft;
|
||||||
canvas.drawRect(left, top, right, bottom, segment.category.paint);
|
canvas.drawRect(left, top, right, bottom, segment.category.paint);
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
LogHelper.printException(() -> "drawSponsorTimeBars failure", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,7 +366,7 @@ public class PlayerController {
|
|||||||
lastKnownVideoTime = finalMillisecond;
|
lastKnownVideoTime = finalMillisecond;
|
||||||
VideoInformation.seekTo(finalMillisecond);
|
VideoInformation.seekTo(finalMillisecond);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogHelper.printException(() -> ("Cannot skip to millisecond"), e);
|
LogHelper.printException(() -> "Cannot skip to millisecond", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -334,51 +374,59 @@ public class PlayerController {
|
|||||||
|
|
||||||
|
|
||||||
private static void findAndSkipSegment(boolean wasClicked) {
|
private static void findAndSkipSegment(boolean wasClicked) {
|
||||||
if (sponsorSegmentsOfCurrentVideo == null)
|
try {
|
||||||
return;
|
if (sponsorSegmentsOfCurrentVideo == null)
|
||||||
|
|
||||||
final long millis = lastKnownVideoTime;
|
|
||||||
|
|
||||||
for (SponsorSegment segment : sponsorSegmentsOfCurrentVideo) {
|
|
||||||
if (segment.start > millis)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (segment.end < millis)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
SkipSegmentView.show();
|
|
||||||
if (!((segment.category.behaviour.skip && !(segment.category.behaviour.key.equals("skip-once") && segment.didAutoSkipped)) || wasClicked))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
sendViewRequestAsync(millis, segment);
|
final long millis = lastKnownVideoTime;
|
||||||
skipSegment(segment, wasClicked);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
SkipSegmentView.hide();
|
for (SponsorSegment segment : sponsorSegmentsOfCurrentVideo) {
|
||||||
|
if (segment.start > millis)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (segment.end < millis)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
SkipSegmentView.show();
|
||||||
|
if (!((segment.category.behaviour.skip && !(segment.category.behaviour.key.equals("skip-once") && segment.didAutoSkipped)) || wasClicked))
|
||||||
|
return;
|
||||||
|
|
||||||
|
sendViewRequestAsync(millis, segment);
|
||||||
|
skipSegment(segment, wasClicked);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
SkipSegmentView.hide();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
LogHelper.printException(() -> "findAndSkipSegment failure", ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void skipSegment(SponsorSegment segment, boolean wasClicked) {
|
private static void skipSegment(SponsorSegment segment, boolean wasClicked) {
|
||||||
// if (lastSkippedSegment == segment) return;
|
try {
|
||||||
// lastSkippedSegment = segment;
|
// if (lastSkippedSegment == segment) return;
|
||||||
LogHelper.printDebug(() -> "Skipping segment: " + segment.toString());
|
// lastSkippedSegment = segment;
|
||||||
|
LogHelper.printDebug(() -> "Skipping segment: " + segment.toString());
|
||||||
|
|
||||||
if (SettingsEnum.SB_SHOW_TOAST_WHEN_SKIP.getBoolean() && !wasClicked)
|
if (SettingsEnum.SB_SHOW_TOAST_WHEN_SKIP.getBoolean() && !wasClicked)
|
||||||
SkipSegmentView.notifySkipped(segment);
|
SkipSegmentView.notifySkipped(segment);
|
||||||
|
|
||||||
boolean didSucceed = skipToMillisecond(segment.end + 2);
|
boolean didSucceed = skipToMillisecond(segment.end + 2);
|
||||||
if (didSucceed && !wasClicked) {
|
if (didSucceed && !wasClicked) {
|
||||||
segment.didAutoSkipped = true;
|
segment.didAutoSkipped = true;
|
||||||
}
|
|
||||||
SkipSegmentView.hide();
|
|
||||||
if (segment.category == SponsorBlockSettings.SegmentInfo.UNSUBMITTED) {
|
|
||||||
SponsorSegment[] newSegments = new SponsorSegment[sponsorSegmentsOfCurrentVideo.length - 1];
|
|
||||||
int i = 0;
|
|
||||||
for (SponsorSegment sponsorSegment : sponsorSegmentsOfCurrentVideo) {
|
|
||||||
if (sponsorSegment != segment)
|
|
||||||
newSegments[i++] = sponsorSegment;
|
|
||||||
}
|
}
|
||||||
sponsorSegmentsOfCurrentVideo = newSegments;
|
SkipSegmentView.hide();
|
||||||
|
if (segment.category == SponsorBlockSettings.SegmentInfo.UNSUBMITTED) {
|
||||||
|
SponsorSegment[] newSegments = new SponsorSegment[sponsorSegmentsOfCurrentVideo.length - 1];
|
||||||
|
int i = 0;
|
||||||
|
for (SponsorSegment sponsorSegment : sponsorSegmentsOfCurrentVideo) {
|
||||||
|
if (sponsorSegment != segment)
|
||||||
|
newSegments[i++] = sponsorSegment;
|
||||||
|
}
|
||||||
|
sponsorSegmentsOfCurrentVideo = newSegments;
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
LogHelper.printException(() -> "skipSegment failure", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ public class ShieldButton {
|
|||||||
isShowing = true;
|
isShowing = true;
|
||||||
changeVisibilityImmediate(false);
|
changeVisibilityImmediate(false);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
LogHelper.printException(() -> ("Unable to set RelativeLayout"), ex);
|
LogHelper.printException(() -> "Unable to set RelativeLayout", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,29 +69,33 @@ public class ShieldButton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void changeVisibility(boolean visible, boolean immediate) {
|
public static void changeVisibility(boolean visible, boolean immediate) {
|
||||||
if (isShowing == visible) return;
|
try {
|
||||||
isShowing = visible;
|
if (isShowing == visible) return;
|
||||||
|
isShowing = visible;
|
||||||
|
|
||||||
ImageView iView = _shieldBtn.get();
|
ImageView iView = _shieldBtn.get();
|
||||||
if (_youtubeControlsLayout == null || iView == null) return;
|
if (_youtubeControlsLayout == null || iView == null) return;
|
||||||
|
|
||||||
if (visible && shouldBeShown()) {
|
if (visible && shouldBeShown()) {
|
||||||
if (getLastKnownVideoTime() >= getCurrentVideoLength()) {
|
if (getLastKnownVideoTime() >= getCurrentVideoLength()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
LogHelper.printDebug(() -> "Fading in");
|
||||||
|
|
||||||
|
iView.setVisibility(View.VISIBLE);
|
||||||
|
if (!immediate)
|
||||||
|
iView.startAnimation(fadeIn);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LogHelper.printDebug(() -> "Fading in");
|
|
||||||
|
|
||||||
iView.setVisibility(View.VISIBLE);
|
if (iView.getVisibility() == View.VISIBLE) {
|
||||||
if (!immediate)
|
LogHelper.printDebug(() -> "Fading out");
|
||||||
iView.startAnimation(fadeIn);
|
if (!immediate)
|
||||||
return;
|
iView.startAnimation(fadeOut);
|
||||||
}
|
iView.setVisibility(shouldBeShown() ? View.INVISIBLE : View.GONE);
|
||||||
|
}
|
||||||
if (iView.getVisibility() == View.VISIBLE) {
|
} catch (Exception ex) {
|
||||||
LogHelper.printDebug(() -> "Fading out");
|
LogHelper.printException(() -> "changeVisibility failure", ex);
|
||||||
if (!immediate)
|
|
||||||
iView.startAnimation(fadeOut);
|
|
||||||
iView.setVisibility(shouldBeShown() ? View.INVISIBLE : View.GONE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ import app.revanced.integrations.utils.ReVancedUtils;
|
|||||||
import static app.revanced.integrations.sponsorblock.player.ui.SponsorBlockView.hideSkipButton;
|
import static app.revanced.integrations.sponsorblock.player.ui.SponsorBlockView.hideSkipButton;
|
||||||
import static app.revanced.integrations.sponsorblock.player.ui.SponsorBlockView.showSkipButton;
|
import static app.revanced.integrations.sponsorblock.player.ui.SponsorBlockView.showSkipButton;
|
||||||
|
|
||||||
@SuppressLint({"RtlHardcoded", "SetTextI18n", "LongLogTag", "AppCompatCustomView"})
|
@SuppressLint({"RtlHardcoded", "SetTextI18n", "AppCompatCustomView"})
|
||||||
public class SkipSegmentView {
|
public class SkipSegmentView {
|
||||||
|
|
||||||
private static SponsorSegment lastNotifiedSegment;
|
private static SponsorSegment lastNotifiedSegment;
|
||||||
|
@ -51,7 +51,6 @@ import app.revanced.integrations.sponsorblock.objects.SponsorSegment;
|
|||||||
import app.revanced.integrations.sponsorblock.objects.UserStats;
|
import app.revanced.integrations.sponsorblock.objects.UserStats;
|
||||||
import app.revanced.integrations.sponsorblock.requests.SBRequester;
|
import app.revanced.integrations.sponsorblock.requests.SBRequester;
|
||||||
|
|
||||||
@SuppressWarnings({"LongLogTag"})
|
|
||||||
public abstract class SponsorBlockUtils {
|
public abstract class SponsorBlockUtils {
|
||||||
public static final String DATE_FORMAT = "HH:mm:ss.SSS";
|
public static final String DATE_FORMAT = "HH:mm:ss.SSS";
|
||||||
@SuppressLint("SimpleDateFormat")
|
@SuppressLint("SimpleDateFormat")
|
||||||
@ -154,7 +153,7 @@ public abstract class SponsorBlockUtils {
|
|||||||
Toast.makeText(context, str("submit_started"), Toast.LENGTH_SHORT).show();
|
Toast.makeText(context, str("submit_started"), Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
appContext = new WeakReference<>(context);
|
appContext = new WeakReference<>(context);
|
||||||
new Thread(submitRunnable).start();
|
new Thread(submitRunnable).start(); // fixme: use ReVancedUtils#runOnBackgroundThread
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
public static String messageToToast = "";
|
public static String messageToToast = "";
|
||||||
@ -233,13 +232,13 @@ public abstract class SponsorBlockUtils {
|
|||||||
final SponsorBlockSettings.SegmentInfo segmentType = SponsorBlockUtils.newSponsorBlockSegmentType;
|
final SponsorBlockSettings.SegmentInfo segmentType = SponsorBlockUtils.newSponsorBlockSegmentType;
|
||||||
try {
|
try {
|
||||||
if (start < 0 || end < 0 || start >= end || segmentType == null || videoId == null || uuid == null) {
|
if (start < 0 || end < 0 || start >= end || segmentType == null || videoId == null || uuid == null) {
|
||||||
LogHelper.printException(() -> ("Unable to submit times, invalid parameters"));
|
LogHelper.printException(() -> "Unable to submit times, invalid parameters");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SBRequester.submitSegments(videoId, uuid, ((float) start) / 1000f, ((float) end) / 1000f, segmentType.key, toastRunnable);
|
SBRequester.submitSegments(videoId, uuid, ((float) start) / 1000f, ((float) end) / 1000f, segmentType.key, toastRunnable);
|
||||||
newSponsorSegmentEndMillis = newSponsorSegmentStartMillis = -1;
|
newSponsorSegmentEndMillis = newSponsorSegmentStartMillis = -1;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogHelper.printException(() -> ("Unable to submit segment"), e);
|
LogHelper.printException(() -> "Unable to submit segment", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (videoId != null)
|
if (videoId != null)
|
||||||
@ -403,11 +402,15 @@ public abstract class SponsorBlockUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static String appendTimeWithoutSegments(String totalTime) {
|
public static String appendTimeWithoutSegments(String totalTime) {
|
||||||
if (videoHasSegments && (SettingsEnum.SB_ENABLED.getBoolean() && SettingsEnum.SB_SHOW_TIME_WITHOUT_SEGMENTS.getBoolean()) && !TextUtils.isEmpty(totalTime) && getCurrentVideoLength() > 1) {
|
try {
|
||||||
if (timeWithoutSegments.isEmpty()) {
|
if (videoHasSegments && (SettingsEnum.SB_ENABLED.getBoolean() && SettingsEnum.SB_SHOW_TIME_WITHOUT_SEGMENTS.getBoolean()) && !TextUtils.isEmpty(totalTime) && getCurrentVideoLength() > 1) {
|
||||||
timeWithoutSegments = getTimeWithoutSegments(sponsorSegmentsOfCurrentVideo);
|
if (timeWithoutSegments.isEmpty()) {
|
||||||
|
timeWithoutSegments = getTimeWithoutSegments(sponsorSegmentsOfCurrentVideo);
|
||||||
|
}
|
||||||
|
return totalTime + timeWithoutSegments;
|
||||||
}
|
}
|
||||||
return totalTime + timeWithoutSegments;
|
} catch (Exception ex) {
|
||||||
|
LogHelper.printException(() -> "appendTimeWithoutSegments failure", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return totalTime;
|
return totalTime;
|
||||||
@ -436,7 +439,7 @@ public abstract class SponsorBlockUtils {
|
|||||||
PlayerController.setCurrentVideoId(null);
|
PlayerController.setCurrentVideoId(null);
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
LogHelper.printException(() -> ("Player type changed caused a crash."), ex);
|
LogHelper.printException(() -> "Player type changed caused a crash.", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -558,8 +561,8 @@ public abstract class SponsorBlockUtils {
|
|||||||
|
|
||||||
Toast.makeText(context, str("settings_import_successful"), Toast.LENGTH_SHORT).show();
|
Toast.makeText(context, str("settings_import_successful"), Toast.LENGTH_SHORT).show();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
|
LogHelper.printInfo(() -> "failed to import settings", ex); // use info level, as we are showing our own toast
|
||||||
Toast.makeText(context, str("settings_import_failed"), Toast.LENGTH_SHORT).show();
|
Toast.makeText(context, str("settings_import_failed"), Toast.LENGTH_SHORT).show();
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -598,8 +601,8 @@ public abstract class SponsorBlockUtils {
|
|||||||
|
|
||||||
return json.toString();
|
return json.toString();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
|
LogHelper.printInfo(() -> "failed to export settings", ex); // use info level, as we are showing our own toast
|
||||||
Toast.makeText(context, str("settings_export_failed"), Toast.LENGTH_SHORT).show();
|
Toast.makeText(context, str("settings_export_failed"), Toast.LENGTH_SHORT).show();
|
||||||
ex.printStackTrace();
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,11 +103,11 @@ public class StringRef {
|
|||||||
if (resources != null) {
|
if (resources != null) {
|
||||||
final int identifier = resources.getIdentifier(value, "string", packageName);
|
final int identifier = resources.getIdentifier(value, "string", packageName);
|
||||||
if (identifier == 0)
|
if (identifier == 0)
|
||||||
LogHelper.printException(() -> ("Resource not found: " + value));
|
LogHelper.printException(() -> "Resource not found: " + value);
|
||||||
else
|
else
|
||||||
value = resources.getString(identifier);
|
value = resources.getString(identifier);
|
||||||
} else {
|
} else {
|
||||||
LogHelper.printException(() -> ("Could not resolve resources!"));
|
LogHelper.printException(() -> "Could not resolve resources!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
|
@ -25,7 +25,7 @@ public class SwipeHelper {
|
|||||||
isTabletMode = true;
|
isTabletMode = true;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogHelper.printException(() -> ("Unable to set FrameLayout"), e);
|
LogHelper.printException(() -> "Unable to set FrameLayout", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ public class SwipeHelper {
|
|||||||
try {
|
try {
|
||||||
nextGenWatchLayout = (ViewGroup) obj;
|
nextGenWatchLayout = (ViewGroup) obj;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogHelper.printException(() -> ("Unable to set _nextGenWatchLayout"), e);
|
LogHelper.printException(() -> "Unable to set _nextGenWatchLayout", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ public class SwipeHelper {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogHelper.printException(() -> ("Unable to get related_endscreen_results visibility"), e);
|
LogHelper.printException(() -> "Unable to get related_endscreen_results visibility", e);
|
||||||
}
|
}
|
||||||
if (_frameLayout.getChildCount() > 0) {
|
if (_frameLayout.getChildCount() > 0) {
|
||||||
return _frameLayout.getChildAt(0).getVisibility() == View.VISIBLE;
|
return _frameLayout.getChildAt(0).getVisibility() == View.VISIBLE;
|
||||||
@ -61,7 +61,7 @@ public class SwipeHelper {
|
|||||||
LogHelper.printDebug(() -> "related_endscreen_results refreshed");
|
LogHelper.printDebug(() -> "related_endscreen_results refreshed");
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogHelper.printException(() -> ("Unable to refresh related_endscreen_results layout"), e);
|
LogHelper.printException(() -> "Unable to refresh related_endscreen_results layout", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ public class VotingButton {
|
|||||||
isShowing = true;
|
isShowing = true;
|
||||||
changeVisibilityImmediate(false);
|
changeVisibilityImmediate(false);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
LogHelper.printException(() -> ("Unable to set RelativeLayout"), ex);
|
LogHelper.printException(() -> "Unable to set RelativeLayout", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,28 +68,32 @@ public class VotingButton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void changeVisibility(boolean visible, boolean immediate) {
|
public static void changeVisibility(boolean visible, boolean immediate) {
|
||||||
if (isShowing == visible) return;
|
try {
|
||||||
isShowing = visible;
|
if (isShowing == visible) return;
|
||||||
|
isShowing = visible;
|
||||||
|
|
||||||
ImageView iView = _votingButton.get();
|
ImageView iView = _votingButton.get();
|
||||||
if (_youtubeControlsLayout == null || iView == null) return;
|
if (_youtubeControlsLayout == null || iView == null) return;
|
||||||
|
|
||||||
if (visible && shouldBeShown()) {
|
if (visible && shouldBeShown()) {
|
||||||
if (getLastKnownVideoTime() >= getCurrentVideoLength()) {
|
if (getLastKnownVideoTime() >= getCurrentVideoLength()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
LogHelper.printDebug(() -> "Fading in");
|
||||||
|
iView.setVisibility(View.VISIBLE);
|
||||||
|
if (!immediate)
|
||||||
|
iView.startAnimation(fadeIn);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LogHelper.printDebug(() -> "Fading in");
|
|
||||||
iView.setVisibility(View.VISIBLE);
|
|
||||||
if (!immediate)
|
|
||||||
iView.startAnimation(fadeIn);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (iView.getVisibility() == View.VISIBLE) {
|
if (iView.getVisibility() == View.VISIBLE) {
|
||||||
LogHelper.printDebug(() -> "Fading out");
|
LogHelper.printDebug(() -> "Fading out");
|
||||||
if (!immediate)
|
if (!immediate)
|
||||||
iView.startAnimation(fadeOut);
|
iView.startAnimation(fadeOut);
|
||||||
iView.setVisibility(shouldBeShown() ? View.INVISIBLE : View.GONE);
|
iView.setVisibility(shouldBeShown() ? View.INVISIBLE : View.GONE);
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
LogHelper.printException(() -> "changeVisibility failure", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ public abstract class SlimButton implements View.OnClickListener {
|
|||||||
}
|
}
|
||||||
setContainerVisibility();
|
setContainerVisibility();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
LogHelper.printException(() -> ("Error while changing button visibility"), ex);
|
LogHelper.printException(() -> "Error while changing button visibility", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ public class SponsorBlockView {
|
|||||||
|
|
||||||
addView();
|
addView();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
LogHelper.printException(() -> ("Unable to set ViewGroup"), ex);
|
LogHelper.printException(() -> "Unable to set ViewGroup", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +62,7 @@ public class SponsorBlockView {
|
|||||||
setSkipBtnMargins(false);
|
setSkipBtnMargins(false);
|
||||||
setNewSegmentLayoutMargins(false);
|
setNewSegmentLayoutMargins(false);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
LogHelper.printException(() -> ("Player type changed caused a crash."), ex);
|
LogHelper.printException(() -> "Player type changed caused a crash.", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,13 +87,13 @@ public class SponsorBlockView {
|
|||||||
private static void setSkipBtnMargins(boolean fullScreen) {
|
private static void setSkipBtnMargins(boolean fullScreen) {
|
||||||
SkipSponsorButton skipSponsorButton = _skipSponsorButton.get();
|
SkipSponsorButton skipSponsorButton = _skipSponsorButton.get();
|
||||||
if (skipSponsorButton == null) {
|
if (skipSponsorButton == null) {
|
||||||
LogHelper.printException(() -> ("Unable to setSkipBtnMargins"));
|
LogHelper.printException(() -> "Unable to setSkipBtnMargins");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) skipSponsorButton.getLayoutParams();
|
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) skipSponsorButton.getLayoutParams();
|
||||||
if (params == null) {
|
if (params == null) {
|
||||||
LogHelper.printException(() -> ("Unable to setSkipBtnMargins"));
|
LogHelper.printException(() -> "Unable to setSkipBtnMargins");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
params.bottomMargin = fullScreen ? skipSponsorButton.ctaBottomMargin : skipSponsorButton.defaultBottomMargin;
|
params.bottomMargin = fullScreen ? skipSponsorButton.ctaBottomMargin : skipSponsorButton.defaultBottomMargin;
|
||||||
@ -103,7 +103,7 @@ public class SponsorBlockView {
|
|||||||
private static void skipSponsorButtonVisibility(boolean visible) {
|
private static void skipSponsorButtonVisibility(boolean visible) {
|
||||||
SkipSponsorButton skipSponsorButton = _skipSponsorButton.get();
|
SkipSponsorButton skipSponsorButton = _skipSponsorButton.get();
|
||||||
if (skipSponsorButton == null) {
|
if (skipSponsorButton == null) {
|
||||||
LogHelper.printException(() -> ("Unable to skipSponsorButtonVisibility"));
|
LogHelper.printException(() -> "Unable to skipSponsorButtonVisibility");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,13 +116,13 @@ public class SponsorBlockView {
|
|||||||
private static void setNewSegmentLayoutMargins(boolean fullScreen) {
|
private static void setNewSegmentLayoutMargins(boolean fullScreen) {
|
||||||
NewSegmentLayout newSegmentLayout = _newSegmentLayout.get();
|
NewSegmentLayout newSegmentLayout = _newSegmentLayout.get();
|
||||||
if (newSegmentLayout == null) {
|
if (newSegmentLayout == null) {
|
||||||
LogHelper.printException(() -> ("Unable to setNewSegmentLayoutMargins"));
|
LogHelper.printException(() -> "Unable to setNewSegmentLayoutMargins");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) newSegmentLayout.getLayoutParams();
|
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) newSegmentLayout.getLayoutParams();
|
||||||
if (params == null) {
|
if (params == null) {
|
||||||
LogHelper.printException(() -> ("Unable to setNewSegmentLayoutMargins"));
|
LogHelper.printException(() -> "Unable to setNewSegmentLayoutMargins");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
params.bottomMargin = fullScreen ? newSegmentLayout.ctaBottomMargin : newSegmentLayout.defaultBottomMargin;
|
params.bottomMargin = fullScreen ? newSegmentLayout.ctaBottomMargin : newSegmentLayout.defaultBottomMargin;
|
||||||
@ -132,7 +132,7 @@ public class SponsorBlockView {
|
|||||||
private static void newSegmentLayoutVisibility(boolean visible) {
|
private static void newSegmentLayoutVisibility(boolean visible) {
|
||||||
NewSegmentLayout newSegmentLayout = _newSegmentLayout.get();
|
NewSegmentLayout newSegmentLayout = _newSegmentLayout.get();
|
||||||
if (newSegmentLayout == null) {
|
if (newSegmentLayout == null) {
|
||||||
LogHelper.printException(() -> ("Unable to newSegmentLayoutVisibility"));
|
LogHelper.printException(() -> "Unable to newSegmentLayoutVisibility");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@ import app.revanced.integrations.sponsorblock.SponsorBlockUtils;
|
|||||||
import app.revanced.integrations.sponsorblock.SponsorBlockUtils.VoteOption;
|
import app.revanced.integrations.sponsorblock.SponsorBlockUtils.VoteOption;
|
||||||
import app.revanced.integrations.sponsorblock.objects.SponsorSegment;
|
import app.revanced.integrations.sponsorblock.objects.SponsorSegment;
|
||||||
import app.revanced.integrations.sponsorblock.objects.UserStats;
|
import app.revanced.integrations.sponsorblock.objects.UserStats;
|
||||||
|
import app.revanced.integrations.utils.LogHelper;
|
||||||
|
|
||||||
public class SBRequester {
|
public class SBRequester {
|
||||||
private static final String TIME_TEMPLATE = "%.3f";
|
private static final String TIME_TEMPLATE = "%.3f";
|
||||||
@ -79,7 +80,7 @@ public class SBRequester {
|
|||||||
}
|
}
|
||||||
connection.disconnect();
|
connection.disconnect();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
ex.printStackTrace();
|
LogHelper.printException(() -> "failed to get segments", ex);
|
||||||
}
|
}
|
||||||
return segments.toArray(new SponsorSegment[0]);
|
return segments.toArray(new SponsorSegment[0]);
|
||||||
}
|
}
|
||||||
@ -115,7 +116,7 @@ public class SBRequester {
|
|||||||
runOnMainThread(toastRunnable);
|
runOnMainThread(toastRunnable);
|
||||||
connection.disconnect();
|
connection.disconnect();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
ex.printStackTrace();
|
LogHelper.printException(() -> "failed to submit segments", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,12 +125,12 @@ public class SBRequester {
|
|||||||
HttpURLConnection connection = getConnectionFromRoute(SBRoutes.VIEWED_SEGMENT, segment.UUID);
|
HttpURLConnection connection = getConnectionFromRoute(SBRoutes.VIEWED_SEGMENT, segment.UUID);
|
||||||
connection.disconnect();
|
connection.disconnect();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
ex.printStackTrace();
|
LogHelper.printException(() -> "failed to send view count request", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void voteForSegment(SponsorSegment segment, VoteOption voteOption, Context context, String... args) {
|
public static void voteForSegment(SponsorSegment segment, VoteOption voteOption, Context context, String... args) {
|
||||||
new Thread(() -> {
|
new Thread(() -> { // fixme: use ReVancedUtils#runOnBackgroundThread
|
||||||
try {
|
try {
|
||||||
String segmentUuid = segment.UUID;
|
String segmentUuid = segment.UUID;
|
||||||
String uuid = SettingsEnum.SB_UUID.getString();
|
String uuid = SettingsEnum.SB_UUID.getString();
|
||||||
@ -156,7 +157,7 @@ public class SBRequester {
|
|||||||
runOnMainThread(() -> Toast.makeText(context, SponsorBlockUtils.messageToToast, Toast.LENGTH_LONG).show());
|
runOnMainThread(() -> Toast.makeText(context, SponsorBlockUtils.messageToToast, Toast.LENGTH_LONG).show());
|
||||||
connection.disconnect();
|
connection.disconnect();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
ex.printStackTrace();
|
LogHelper.printException(() -> "failed to vote for segment", ex);
|
||||||
}
|
}
|
||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
@ -167,20 +168,20 @@ public class SBRequester {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
new Thread(() -> {
|
new Thread(() -> { // fixme: use ReVancedUtils#runOnBackgroundThread
|
||||||
try {
|
try {
|
||||||
JSONObject json = getJSONObject(SBRoutes.GET_USER_STATS, SettingsEnum.SB_UUID.getString());
|
JSONObject json = getJSONObject(SBRoutes.GET_USER_STATS, SettingsEnum.SB_UUID.getString());
|
||||||
UserStats stats = new UserStats(json.getString("userName"), json.getDouble("minutesSaved"), json.getInt("segmentCount"),
|
UserStats stats = new UserStats(json.getString("userName"), json.getDouble("minutesSaved"), json.getInt("segmentCount"),
|
||||||
json.getInt("viewCount"));
|
json.getInt("viewCount"));
|
||||||
SponsorBlockUtils.addUserStats(category, loadingPreference, stats);
|
SponsorBlockUtils.addUserStats(category, loadingPreference, stats);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
ex.printStackTrace();
|
LogHelper.printException(() -> "failed to retrieve user stats", ex);
|
||||||
}
|
}
|
||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setUsername(String username, EditTextPreference preference, Runnable toastRunnable) {
|
public static void setUsername(String username, EditTextPreference preference, Runnable toastRunnable) {
|
||||||
new Thread(() -> {
|
new Thread(() -> { // fixme: use ReVancedUtils#runOnBackgroundThread
|
||||||
try {
|
try {
|
||||||
HttpURLConnection connection = getConnectionFromRoute(SBRoutes.CHANGE_USERNAME, SettingsEnum.SB_UUID.getString(), username);
|
HttpURLConnection connection = getConnectionFromRoute(SBRoutes.CHANGE_USERNAME, SettingsEnum.SB_UUID.getString(), username);
|
||||||
int responseCode = connection.getResponseCode();
|
int responseCode = connection.getResponseCode();
|
||||||
@ -197,7 +198,7 @@ public class SBRequester {
|
|||||||
runOnMainThread(toastRunnable);
|
runOnMainThread(toastRunnable);
|
||||||
connection.disconnect();
|
connection.disconnect();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
ex.printStackTrace();
|
LogHelper.printException(() -> "failed to set username", ex);
|
||||||
}
|
}
|
||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
@ -213,7 +214,7 @@ public class SBRequester {
|
|||||||
SettingsEnum.SB_IS_VIP.saveValue(vip);
|
SettingsEnum.SB_IS_VIP.saveValue(vip);
|
||||||
SettingsEnum.SB_LAST_VIP_CHECK.saveValue(now);
|
SettingsEnum.SB_LAST_VIP_CHECK.saveValue(now);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
ex.printStackTrace();
|
LogHelper.printException(() -> "failed to check VIP", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ import android.content.Context
|
|||||||
import android.media.AudioManager
|
import android.media.AudioManager
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import app.revanced.integrations.swipecontrols.misc.clamp
|
import app.revanced.integrations.swipecontrols.misc.clamp
|
||||||
import app.revanced.integrations.utils.LogHelper.printDebug
|
import app.revanced.integrations.utils.LogHelper.printException
|
||||||
import kotlin.properties.Delegates
|
import kotlin.properties.Delegates
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -29,7 +29,7 @@ class AudioVolumeController(
|
|||||||
// bind audio service
|
// bind audio service
|
||||||
val mgr = context.getSystemService(Context.AUDIO_SERVICE) as? AudioManager
|
val mgr = context.getSystemService(Context.AUDIO_SERVICE) as? AudioManager
|
||||||
if (mgr == null) {
|
if (mgr == null) {
|
||||||
printDebug { "failed to acquire AUDIO_SERVICE" }
|
printException { "failed to acquire AUDIO_SERVICE" }
|
||||||
} else {
|
} else {
|
||||||
audioManager = mgr
|
audioManager = mgr
|
||||||
maximumVolumeIndex = audioManager.getStreamMaxVolume(targetStream)
|
maximumVolumeIndex = audioManager.getStreamMaxVolume(targetStream)
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
package app.revanced.integrations.utils;
|
package app.revanced.integrations.utils;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
@ -13,16 +18,19 @@ public class LogHelper {
|
|||||||
* Log messages using lambdas.
|
* Log messages using lambdas.
|
||||||
*/
|
*/
|
||||||
public interface LogMessage {
|
public interface LogMessage {
|
||||||
|
@NonNull
|
||||||
String buildMessageString();
|
String buildMessageString();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return For non inner classes, this returns {@link Class#getSimpleName()}.
|
* @return For outer classes, this returns {@link Class#getSimpleName()}.
|
||||||
* For inner classes (static and anonymous), this returns the enclosing class simple name.<br>
|
* For inner, static, or anonymous classes, this returns the simple name of the enclosing class.<br>
|
||||||
* <br>
|
* <br>
|
||||||
* For example, each of these classes return 'SomethingView':<br>
|
* For example, each of these classes return 'SomethingView':
|
||||||
* com.company.SomethingView<br>
|
* <code>
|
||||||
* com.company.SomethingView$StaticClass<br>
|
* com.company.SomethingView
|
||||||
* com.company.SomethingView$1<br>
|
* com.company.SomethingView$StaticClass
|
||||||
|
* com.company.SomethingView$1
|
||||||
|
* </code>
|
||||||
*/
|
*/
|
||||||
private String findOuterClassSimpleName() {
|
private String findOuterClassSimpleName() {
|
||||||
var selfClass = this.getClass();
|
var selfClass = this.getClass();
|
||||||
@ -32,8 +40,8 @@ public class LogHelper {
|
|||||||
if (dollarSignIndex == -1) {
|
if (dollarSignIndex == -1) {
|
||||||
return selfClass.getSimpleName(); // already an outer class
|
return selfClass.getSimpleName(); // already an outer class
|
||||||
}
|
}
|
||||||
// else, class is inner class (static or anonymous)
|
|
||||||
|
|
||||||
|
// class is inner, static, or anonymous
|
||||||
// parse the simple name full name
|
// parse the simple name full name
|
||||||
// a class with no package returns index of -1, but incrementing gives index zero which is correct
|
// a class with no package returns index of -1, but incrementing gives index zero which is correct
|
||||||
final int simpleClassNameStartIndex = fullClassName.lastIndexOf('.') + 1;
|
final int simpleClassNameStartIndex = fullClassName.lastIndexOf('.') + 1;
|
||||||
@ -41,17 +49,14 @@ public class LogHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private static final String REVANCED_LOG_PREFIX = "revanced: ";
|
||||||
* Logs information messages with the most outer class name of the code that is calling this method.
|
|
||||||
*/
|
|
||||||
public static void printInfo(LogMessage message) {
|
|
||||||
Log.i("revanced: " + message.findOuterClassSimpleName(), message.buildMessageString());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs debug messages with the most outer class name of the code that is calling this method.
|
* Logs debug messages under the outer class name of the code calling this method.
|
||||||
|
* Whenever possible, the log string should be constructed entirely inside {@link LogMessage#buildMessageString()}
|
||||||
|
* so the performance cost of building strings is paid only if {@link SettingsEnum#DEBUG} is enabled.
|
||||||
*/
|
*/
|
||||||
public static void printDebug(LogMessage message) {
|
public static void printDebug(@NonNull LogMessage message) {
|
||||||
if (SettingsEnum.DEBUG.getBoolean()) {
|
if (SettingsEnum.DEBUG.getBoolean()) {
|
||||||
var messageString = message.buildMessageString();
|
var messageString = message.buildMessageString();
|
||||||
|
|
||||||
@ -60,62 +65,79 @@ public class LogHelper {
|
|||||||
var sw = new StringWriter();
|
var sw = new StringWriter();
|
||||||
new Throwable().printStackTrace(new PrintWriter(sw));
|
new Throwable().printStackTrace(new PrintWriter(sw));
|
||||||
|
|
||||||
builder.append(String.format("\n%s", sw));
|
builder.append('\n').append(sw);
|
||||||
messageString = builder.toString();
|
messageString = builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.d("revanced: " + message.findOuterClassSimpleName(), messageString);
|
Log.d(REVANCED_LOG_PREFIX + message.findOuterClassSimpleName(), messageString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs messages with the most outer class name of the code that is calling this method.
|
* Logs information messages using the outer class name of the code calling this method.
|
||||||
*/
|
*/
|
||||||
public static void printException(LogMessage message) {
|
public static void printInfo(@NonNull LogMessage message) {
|
||||||
Log.e("revanced: " + message.findOuterClassSimpleName(), message.buildMessageString());
|
printInfo(message, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs exceptions with the most outer class name of the code that is calling this method.
|
* Logs information messages using the outer class name of the code calling this method.
|
||||||
*/
|
*/
|
||||||
public static void printException(LogMessage message, Throwable ex) {
|
public static void printInfo(@NonNull LogMessage message, @Nullable Exception ex) {
|
||||||
Log.e("revanced: " + message.findOuterClassSimpleName(), message.buildMessageString(), ex);
|
String logTag = REVANCED_LOG_PREFIX + message.findOuterClassSimpleName();
|
||||||
|
String logMessage = message.buildMessageString();
|
||||||
|
if (ex == null) {
|
||||||
|
Log.i(logTag, logMessage);
|
||||||
|
} else {
|
||||||
|
Log.i(logTag, logMessage, ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deprecated. Instead call {@link #printDebug(LogMessage)},
|
* Logs exceptions under the outer class name of the code calling this method.
|
||||||
* which does not cause log messages to be constructed unless logging is enabled.
|
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
public static void printException(@NonNull LogMessage message) {
|
||||||
public static void debug(Class _clazz, String message) {
|
printException(message, null, null);
|
||||||
printDebug(() -> message); // this fails to show the correct calling class name, but it's deprecated who cares
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deprecated. Instead call {@link #printException(LogMessage, Throwable)}
|
* Logs exceptions under the outer class name of the code calling this method.
|
||||||
* or {@link #printException(LogMessage)}
|
|
||||||
* which does not cause log messages to be constructed unless logging is enabled.
|
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
public static void printException(@NonNull LogMessage message, @Nullable Throwable ex) {
|
||||||
public static void printException(Class _clazz, String message, Throwable ex) {
|
printException(message, ex, null);
|
||||||
printException(() -> message, ex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deprecated. Instead call {@link #printException(LogMessage)},
|
* Logs exceptions under the outer class name of the code calling this method.
|
||||||
* which does not cause log messages to be constructed unless logging is enabled.
|
* <p>
|
||||||
|
* If the calling code is showing it's own error toast,
|
||||||
|
* instead use {@link #printInfo(LogMessage, Exception)}
|
||||||
|
*
|
||||||
|
* @param message log message
|
||||||
|
* @param ex exception (optional)
|
||||||
|
* @param userToastMessage user specific toast message to show instead of the log message (optional)
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
public static void printException(@NonNull LogMessage message, @Nullable Throwable ex,
|
||||||
public static void printException(Class _clazz, String message) {
|
@Nullable String userToastMessage) {
|
||||||
printException(() -> message);
|
String messageString = message.buildMessageString();
|
||||||
|
String outerClassSimpleName = message.findOuterClassSimpleName();
|
||||||
|
String logMessage = REVANCED_LOG_PREFIX + outerClassSimpleName;
|
||||||
|
if (ex == null) {
|
||||||
|
Log.e(logMessage, messageString);
|
||||||
|
} else {
|
||||||
|
Log.e(logMessage, messageString, ex);
|
||||||
|
}
|
||||||
|
if (SettingsEnum.DEBUG_SHOW_TOAST_ON_ERROR.getBoolean()) {
|
||||||
|
String toastMessageToDisplay = (userToastMessage != null)
|
||||||
|
? userToastMessage
|
||||||
|
: outerClassSimpleName + ": " + messageString;
|
||||||
|
ReVancedUtils.runOnMainThread(() -> {
|
||||||
|
Context context = ReVancedUtils.getContext();
|
||||||
|
if (context != null) {
|
||||||
|
Toast.makeText(context, toastMessageToDisplay, Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Deprecated. Instead call {@link #printInfo(LogMessage)},
|
|
||||||
* which does not cause log messages to be constructed unless logging is enabled.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public static void info(Class _clazz, String message) {
|
|
||||||
printInfo(() -> message);
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -6,6 +6,8 @@ import android.content.res.Resources;
|
|||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import java.text.Bidi;
|
import java.text.Bidi;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
@ -58,10 +60,6 @@ public class ReVancedUtils {
|
|||||||
// or some ReVanced code is submitting an unexpected number of background tasks.
|
// or some ReVanced code is submitting an unexpected number of background tasks.
|
||||||
LogHelper.printException(() -> "Reached maximum background thread count of "
|
LogHelper.printException(() -> "Reached maximum background thread count of "
|
||||||
+ SHARED_THREAD_POOL_MAXIMUM_BACKGROUND_THREADS + " threads");
|
+ SHARED_THREAD_POOL_MAXIMUM_BACKGROUND_THREADS + " threads");
|
||||||
|
|
||||||
// Because this condition will manifest as a slow running app or a memory leak,
|
|
||||||
// it might be best to show the user a toast or some other suggestion to restart the app.
|
|
||||||
// TODO? if debug is enabled, show a toast?
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,7 +94,7 @@ public class ReVancedUtils {
|
|||||||
Resources res = context.getResources();
|
Resources res = context.getResources();
|
||||||
return res.getIdentifier(name, type, context.getPackageName());
|
return res.getIdentifier(name, type, context.getPackageName());
|
||||||
} catch (Throwable exception) {
|
} catch (Throwable exception) {
|
||||||
LogHelper.printException(() -> ("Resource not found."), exception);
|
LogHelper.printException(() -> "Resource not found.", exception);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -118,7 +116,7 @@ public class ReVancedUtils {
|
|||||||
if (context != null) {
|
if (context != null) {
|
||||||
return context;
|
return context;
|
||||||
} else {
|
} else {
|
||||||
LogHelper.printException(() -> ("Context is null, returning null!"));
|
LogHelper.printException(() -> "Context is null, returning null!");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -149,37 +147,44 @@ public class ReVancedUtils {
|
|||||||
* Automatically logs any exceptions the runnable throws
|
* Automatically logs any exceptions the runnable throws
|
||||||
*/
|
*/
|
||||||
public static void runOnMainThread(Runnable runnable) {
|
public static void runOnMainThread(Runnable runnable) {
|
||||||
Runnable exceptLoggingRunnable = () -> {
|
runOnMainThreadDelayed(runnable, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Automatically logs any exceptions the runnable throws
|
||||||
|
*/
|
||||||
|
public static void runOnMainThreadDelayed(Runnable runnable, long delayMillis) {
|
||||||
|
Runnable loggingRunnable = () -> {
|
||||||
try {
|
try {
|
||||||
runnable.run();
|
runnable.run();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
LogHelper.printException(() -> "Exception on main thread from runnable: " + runnable.toString(), ex);
|
LogHelper.printException(() -> runnable.getClass() + ": " + ex.getMessage(), ex);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
new Handler(Looper.getMainLooper()).post(exceptLoggingRunnable);
|
new Handler(Looper.getMainLooper()).postDelayed(loggingRunnable, delayMillis);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return if the calling thread is on the main thread
|
* @return if the calling thread is on the main thread
|
||||||
*/
|
*/
|
||||||
public static boolean currentIsOnMainThread() {
|
public static boolean currentlyIsOnMainThread() {
|
||||||
return Looper.getMainLooper().isCurrentThread();
|
return Looper.getMainLooper().isCurrentThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws IllegalStateException if the calling thread is _not_ on the main thread
|
* @throws IllegalStateException if the calling thread is _off_ the main thread
|
||||||
*/
|
*/
|
||||||
public static void verifyOnMainThread() throws IllegalStateException {
|
public static void verifyOnMainThread() throws IllegalStateException {
|
||||||
if (!currentIsOnMainThread()) {
|
if (!currentlyIsOnMainThread()) {
|
||||||
throw new IllegalStateException("Must call _on_ the main thread");
|
throw new IllegalStateException("Must call _on_ the main thread");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws IllegalStateException if the calling thread _is_ on the main thread
|
* @throws IllegalStateException if the calling thread is _on_ the main thread
|
||||||
*/
|
*/
|
||||||
public static void verifyOffMainThread() throws IllegalStateException {
|
public static void verifyOffMainThread() throws IllegalStateException {
|
||||||
if (currentIsOnMainThread()) {
|
if (currentlyIsOnMainThread()) {
|
||||||
throw new IllegalStateException("Must call _off_ the main thread");
|
throw new IllegalStateException("Must call _off_ the main thread");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,7 @@ public class DownloadButton extends BottomControlButton {
|
|||||||
|
|
||||||
LogHelper.printDebug(() -> "Launched the intent with the content: " + content);
|
LogHelper.printDebug(() -> "Launched the intent with the content: " + content);
|
||||||
} catch (Exception error) {
|
} catch (Exception error) {
|
||||||
LogHelper.printDebug(() -> "Failed to launch the intent: " + error);
|
LogHelper.printException(() -> "Failed to launch the intent: " + error, error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,11 @@ import android.util.Log;
|
|||||||
|
|
||||||
import app.revanced.tiktok.settings.SettingsEnum;
|
import app.revanced.tiktok.settings.SettingsEnum;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: replace this with the higher performance logging code from {@link app.revanced.integrations.utils.LogHelper}
|
||||||
|
*/
|
||||||
public class LogHelper {
|
public class LogHelper {
|
||||||
|
|
||||||
//ToDo: Get Calling classname using Reflection
|
|
||||||
|
|
||||||
public static void debug(Class clazz, String message) {
|
public static void debug(Class clazz, String message) {
|
||||||
if (SettingsEnum.TIK_DEBUG.getBoolean()) {
|
if (SettingsEnum.TIK_DEBUG.getBoolean()) {
|
||||||
Log.d("revanced: " + (clazz != null ? clazz.getSimpleName() : ""), message);
|
Log.d("revanced: " + (clazz != null ? clazz.getSimpleName() : ""), message);
|
||||||
|
@ -5,8 +5,14 @@ import android.widget.Toast;
|
|||||||
|
|
||||||
import app.revanced.twitch.settings.SettingsEnum;
|
import app.revanced.twitch.settings.SettingsEnum;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: replace this with the higher performance logging code from {@link app.revanced.integrations.utils.LogHelper}
|
||||||
|
*/
|
||||||
public class LogHelper {
|
public class LogHelper {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: replace this with {@link app.revanced.integrations.utils.LogHelper.LogMessage#findOuterClassSimpleName()}
|
||||||
|
*/
|
||||||
public static String getCallOrigin()
|
public static String getCallOrigin()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
org.gradle.jvmargs = -Xmx2048m
|
org.gradle.jvmargs = -Xmx2048m
|
||||||
android.useAndroidX = true
|
android.useAndroidX = true
|
||||||
version = 0.93.1
|
version = 0.94.0-dev.6
|
||||||
|
Loading…
Reference in New Issue
Block a user