From caebd7c106b6cfaf72212ecb79e029cb027cc5e4 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Sun, 17 Sep 2023 20:44:55 +0200 Subject: [PATCH 01/10] feat(YouTube): Add `Announcements` patch --- .../announcements/AnnouncementsPatch.java | 120 ++++++++++++++++++ .../requests/AnnouncementsRoutes.java | 23 ++++ .../integrations/settings/SettingsEnum.java | 8 +- 3 files changed, 147 insertions(+), 4 deletions(-) create mode 100644 app/src/main/java/app/revanced/integrations/patches/announcements/AnnouncementsPatch.java create mode 100644 app/src/main/java/app/revanced/integrations/patches/announcements/requests/AnnouncementsRoutes.java diff --git a/app/src/main/java/app/revanced/integrations/patches/announcements/AnnouncementsPatch.java b/app/src/main/java/app/revanced/integrations/patches/announcements/AnnouncementsPatch.java new file mode 100644 index 0000000000..094090c4d5 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/patches/announcements/AnnouncementsPatch.java @@ -0,0 +1,120 @@ +package app.revanced.integrations.patches.announcements; + +import android.app.Activity; +import android.os.Build; +import androidx.annotation.RequiresApi; +import app.revanced.integrations.patches.announcements.requests.AnnouncementsRoutes; +import app.revanced.integrations.requests.Requester; +import app.revanced.integrations.settings.SettingsEnum; +import app.revanced.integrations.utils.LogHelper; +import app.revanced.integrations.utils.ReVancedUtils; +import org.json.JSONObject; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.util.UUID; + +import static app.revanced.integrations.patches.announcements.requests.AnnouncementsRoutes.GET_LATEST_ANNOUNCEMENT; + +public final class AnnouncementsPatch { + private final static String CONSUMER = getOrSetConsumer(); + + private AnnouncementsPatch() { + } + + @RequiresApi(api = Build.VERSION_CODES.O) + public static void showAnnouncement(final Activity context) { + if (!SettingsEnum.ANNOUNCEMENTS.getBoolean()) return; + + ReVancedUtils.runOnBackgroundThread(() -> { + try { + HttpURLConnection connection = AnnouncementsRoutes.getAnnouncementsConnectionFromRoute(GET_LATEST_ANNOUNCEMENT, CONSUMER); + + LogHelper.printDebug(() -> "Get latest announcement route connection url: " + connection.getURL().toString()); + + try { + // Do not show the announcement if the request failed. + if (connection.getResponseCode() != 200) { + if (SettingsEnum.LAST_ANNOUNCEMENT_HASH.getString().isEmpty()) return; + + SettingsEnum.LAST_ANNOUNCEMENT_HASH.saveValue(""); + ReVancedUtils.showToastLong("Failed to get announcement"); + + return; + } + } catch (IOException ex) { + final var message = "Failed connecting to announcements provider"; + + LogHelper.printException(() -> message, ex); + return; + } + + var jsonString = Requester.parseInputStreamAndClose(connection.getInputStream(), false); + + // Do not show the announcement if it is older or the same as the last one. + final byte[] hashBytes = MessageDigest.getInstance("SHA-256").digest(jsonString.getBytes(StandardCharsets.UTF_8)); + final var hash = java.util.Base64.getEncoder().encodeToString(hashBytes); + if (hash.equals(SettingsEnum.LAST_ANNOUNCEMENT_HASH.getString())) return; + + // Parse the announcement. Fall-back to raw string if it fails. + String title; + String message; + try { + final var announcement = new JSONObject(jsonString); + + title = announcement.getString("title"); + message = announcement.getJSONObject("content").getString("message"); + } catch (Throwable ex) { + LogHelper.printException(() -> "Failed to parse announcement. Fall-backing to raw string", ex); + + title = "Announcement"; + message = jsonString; + } + + final var finalTitle = title; + final var finalMessage = message; + + ReVancedUtils.runOnMainThread(() -> { + // Show the announcement. + new android.app.AlertDialog.Builder(context).setTitle(finalTitle) + .setMessage(finalMessage) + .setPositiveButton("Ok", (dialog, which) -> { + SettingsEnum.LAST_ANNOUNCEMENT_HASH.saveValue(hash); + dialog.dismiss(); + }).setNegativeButton("Dismiss", (dialog, which) -> { + dialog.dismiss(); + }) + .setCancelable(false) + .show(); + }); + } catch (Exception e) { + final var message = "Failed to get announcement"; + + LogHelper.printException(() -> message, e); + } + }); + } + + /** + * Clears the last announcement hash if it is not empty. + * + * @return true if the last announcement hash was empty. + */ + private static boolean emptyLastAnnouncementHash() { + if (SettingsEnum.LAST_ANNOUNCEMENT_HASH.getString().isEmpty()) return true; + SettingsEnum.LAST_ANNOUNCEMENT_HASH.saveValue(""); + + return false; + } + + private static String getOrSetConsumer() { + final var consumer = SettingsEnum.ANNOUNCEMENT_CONSUMER.getString(); + if (!consumer.isEmpty()) return consumer; + + final var uuid = UUID.randomUUID().toString(); + SettingsEnum.ANNOUNCEMENT_CONSUMER.saveValue(uuid); + return uuid; + } +} diff --git a/app/src/main/java/app/revanced/integrations/patches/announcements/requests/AnnouncementsRoutes.java b/app/src/main/java/app/revanced/integrations/patches/announcements/requests/AnnouncementsRoutes.java new file mode 100644 index 0000000000..fc39090b2d --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/patches/announcements/requests/AnnouncementsRoutes.java @@ -0,0 +1,23 @@ +package app.revanced.integrations.patches.announcements.requests; + +import app.revanced.integrations.requests.Requester; +import app.revanced.integrations.requests.Route; + +import java.io.IOException; +import java.net.HttpURLConnection; + +import static app.revanced.integrations.requests.Route.Method.GET; + +public class AnnouncementsRoutes { + private static final String ANNOUNCEMENTS_PROVIDER = "https://api.revanced.app/v2"; + + + public static final Route GET_LATEST_ANNOUNCEMENT = new Route(GET, "/announcements/youtube/latest?consumer={consumer}"); + + private AnnouncementsRoutes() { + } + + public static HttpURLConnection getAnnouncementsConnectionFromRoute(Route route, String... params) throws IOException { + return Requester.getConnectionFromRoute(ANNOUNCEMENTS_PROVIDER, route, params); + } +} \ No newline at end of file diff --git a/app/src/main/java/app/revanced/integrations/settings/SettingsEnum.java b/app/src/main/java/app/revanced/integrations/settings/SettingsEnum.java index ac1605af31..d320e8711e 100644 --- a/app/src/main/java/app/revanced/integrations/settings/SettingsEnum.java +++ b/app/src/main/java/app/revanced/integrations/settings/SettingsEnum.java @@ -10,10 +10,7 @@ import org.json.JSONException; import org.json.JSONObject; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; +import java.util.*; import static app.revanced.integrations.settings.SettingsEnum.ReturnType.*; import static app.revanced.integrations.settings.SharedPrefCategory.RETURN_YOUTUBE_DISLIKE; @@ -179,6 +176,9 @@ public enum SettingsEnum { parents(SPOOF_SIGNATURE)), SPOOF_DEVICE_DIMENSIONS("revanced_spoof_device_dimensions", BOOLEAN, FALSE, true), BYPASS_URL_REDIRECTS("revanced_bypass_url_redirects", BOOLEAN, TRUE), + ANNOUNCEMENTS("revanced_announcements", BOOLEAN, TRUE, false), + ANNOUNCEMENT_CONSUMER("revanced_announcement_consumer", STRING, ""), + LAST_ANNOUNCEMENT_HASH("revanced_last_announcement_hash", STRING, ""), // Swipe controls SWIPE_BRIGHTNESS("revanced_swipe_brightness", BOOLEAN, TRUE), From 4b1db6ce5b2b36f25edec56ab38c29d933e90970 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Fri, 20 Oct 2023 01:04:08 +0200 Subject: [PATCH 02/10] feat(YouTube - Announcements): Parse HTML --- .../patches/announcements/AnnouncementsPatch.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/app/revanced/integrations/patches/announcements/AnnouncementsPatch.java b/app/src/main/java/app/revanced/integrations/patches/announcements/AnnouncementsPatch.java index 094090c4d5..b5c4dfb252 100644 --- a/app/src/main/java/app/revanced/integrations/patches/announcements/AnnouncementsPatch.java +++ b/app/src/main/java/app/revanced/integrations/patches/announcements/AnnouncementsPatch.java @@ -2,6 +2,7 @@ import android.app.Activity; import android.os.Build; +import android.text.Html; import androidx.annotation.RequiresApi; import app.revanced.integrations.patches.announcements.requests.AnnouncementsRoutes; import app.revanced.integrations.requests.Requester; @@ -16,6 +17,7 @@ import java.security.MessageDigest; import java.util.UUID; +import static android.text.Html.FROM_HTML_MODE_COMPACT; import static app.revanced.integrations.patches.announcements.requests.AnnouncementsRoutes.GET_LATEST_ANNOUNCEMENT; public final class AnnouncementsPatch { @@ -74,7 +76,7 @@ public static void showAnnouncement(final Activity context) { } final var finalTitle = title; - final var finalMessage = message; + final var finalMessage = Html.fromHtml(message, FROM_HTML_MODE_COMPACT); ReVancedUtils.runOnMainThread(() -> { // Show the announcement. From b9244234eace488d02fc32cde1dcb725a9cb015a Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Fri, 20 Oct 2023 01:17:01 +0200 Subject: [PATCH 03/10] feat(YouTube - Announcements): Set dialog icon according to announcement level --- .../announcements/AnnouncementsPatch.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/app/src/main/java/app/revanced/integrations/patches/announcements/AnnouncementsPatch.java b/app/src/main/java/app/revanced/integrations/patches/announcements/AnnouncementsPatch.java index b5c4dfb252..cb39c0966a 100644 --- a/app/src/main/java/app/revanced/integrations/patches/announcements/AnnouncementsPatch.java +++ b/app/src/main/java/app/revanced/integrations/patches/announcements/AnnouncementsPatch.java @@ -63,11 +63,14 @@ public static void showAnnouncement(final Activity context) { // Parse the announcement. Fall-back to raw string if it fails. String title; String message; + Level level = Level.INFO; try { final var announcement = new JSONObject(jsonString); title = announcement.getString("title"); message = announcement.getJSONObject("content").getString("message"); + + if (announcement.has("level")) level = Level.fromInt(announcement.getInt("level")); } catch (Throwable ex) { LogHelper.printException(() -> "Failed to parse announcement. Fall-backing to raw string", ex); @@ -77,11 +80,13 @@ public static void showAnnouncement(final Activity context) { final var finalTitle = title; final var finalMessage = Html.fromHtml(message, FROM_HTML_MODE_COMPACT); + final Level finalLevel = level; ReVancedUtils.runOnMainThread(() -> { // Show the announcement. new android.app.AlertDialog.Builder(context).setTitle(finalTitle) .setMessage(finalMessage) + .setIcon(finalLevel.icon) .setPositiveButton("Ok", (dialog, which) -> { SettingsEnum.LAST_ANNOUNCEMENT_HASH.saveValue(hash); dialog.dismiss(); @@ -119,4 +124,20 @@ private static String getOrSetConsumer() { SettingsEnum.ANNOUNCEMENT_CONSUMER.saveValue(uuid); return uuid; } + + private enum Level { + INFO(android.R.drawable.ic_dialog_info), + WARNING(android.R.drawable.ic_dialog_alert), + SEVERE(android.R.drawable.ic_dialog_alert); + + public final int icon; + + Level(int icon) { + this.icon = icon; + } + + public static Level fromInt(int value) { + return values()[Math.min(value, values().length - 1)]; + } + } } From dd23cef8d565e466be71201a4cb594735b346302 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Fri, 20 Oct 2023 01:34:32 +0200 Subject: [PATCH 04/10] chore: Add comments --- .../patches/announcements/AnnouncementsPatch.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/app/revanced/integrations/patches/announcements/AnnouncementsPatch.java b/app/src/main/java/app/revanced/integrations/patches/announcements/AnnouncementsPatch.java index cb39c0966a..2f99bd1861 100644 --- a/app/src/main/java/app/revanced/integrations/patches/announcements/AnnouncementsPatch.java +++ b/app/src/main/java/app/revanced/integrations/patches/announcements/AnnouncementsPatch.java @@ -79,12 +79,14 @@ public static void showAnnouncement(final Activity context) { } final var finalTitle = title; + // TODO: Fix links not working. final var finalMessage = Html.fromHtml(message, FROM_HTML_MODE_COMPACT); final Level finalLevel = level; ReVancedUtils.runOnMainThread(() -> { // Show the announcement. - new android.app.AlertDialog.Builder(context).setTitle(finalTitle) + new android.app.AlertDialog.Builder(context) + .setTitle(finalTitle) .setMessage(finalMessage) .setIcon(finalLevel.icon) .setPositiveButton("Ok", (dialog, which) -> { @@ -125,6 +127,7 @@ private static String getOrSetConsumer() { return uuid; } + // TODO: Use better icons. private enum Level { INFO(android.R.drawable.ic_dialog_info), WARNING(android.R.drawable.ic_dialog_alert), From 187312582029d8c0e62c8bbee4907598d09d40a5 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Fri, 20 Oct 2023 01:46:02 +0200 Subject: [PATCH 05/10] chore: Simplify code --- .../java/app/revanced/integrations/settings/SettingsEnum.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/app/revanced/integrations/settings/SettingsEnum.java b/app/src/main/java/app/revanced/integrations/settings/SettingsEnum.java index d320e8711e..40cb6ca365 100644 --- a/app/src/main/java/app/revanced/integrations/settings/SettingsEnum.java +++ b/app/src/main/java/app/revanced/integrations/settings/SettingsEnum.java @@ -176,7 +176,7 @@ public enum SettingsEnum { parents(SPOOF_SIGNATURE)), SPOOF_DEVICE_DIMENSIONS("revanced_spoof_device_dimensions", BOOLEAN, FALSE, true), BYPASS_URL_REDIRECTS("revanced_bypass_url_redirects", BOOLEAN, TRUE), - ANNOUNCEMENTS("revanced_announcements", BOOLEAN, TRUE, false), + ANNOUNCEMENTS("revanced_announcements", BOOLEAN, TRUE), ANNOUNCEMENT_CONSUMER("revanced_announcement_consumer", STRING, ""), LAST_ANNOUNCEMENT_HASH("revanced_last_announcement_hash", STRING, ""), From b6e4d7f8836d655b525bd874f626205b5c74cd47 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Fri, 20 Oct 2023 01:46:40 +0200 Subject: [PATCH 06/10] fix: Do not export announcement consumer --- .../java/app/revanced/integrations/settings/SettingsEnum.java | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/app/revanced/integrations/settings/SettingsEnum.java b/app/src/main/java/app/revanced/integrations/settings/SettingsEnum.java index 40cb6ca365..8b5743ac20 100644 --- a/app/src/main/java/app/revanced/integrations/settings/SettingsEnum.java +++ b/app/src/main/java/app/revanced/integrations/settings/SettingsEnum.java @@ -555,6 +555,7 @@ public Object getObjectValue() { private boolean includeWithImportExport() { switch (this) { case RYD_USER_ID: // Not useful to export, no reason to include it. + case ANNOUNCEMENT_CONSUMER: // Not useful to export, no reason to include it. case SB_LAST_VIP_CHECK: case SB_HIDE_EXPORT_WARNING: case SB_SEEN_GUIDELINES: From 9edecae4f36c687e80e5b91d368bca09ef1fd23a Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Fri, 20 Oct 2023 01:47:29 +0200 Subject: [PATCH 07/10] fix(YouTube - Announcements): Make links clickable --- .../patches/announcements/AnnouncementsPatch.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/app/revanced/integrations/patches/announcements/AnnouncementsPatch.java b/app/src/main/java/app/revanced/integrations/patches/announcements/AnnouncementsPatch.java index 2f99bd1861..ab5a119d5b 100644 --- a/app/src/main/java/app/revanced/integrations/patches/announcements/AnnouncementsPatch.java +++ b/app/src/main/java/app/revanced/integrations/patches/announcements/AnnouncementsPatch.java @@ -3,6 +3,8 @@ import android.app.Activity; import android.os.Build; import android.text.Html; +import android.text.method.LinkMovementMethod; +import android.widget.TextView; import androidx.annotation.RequiresApi; import app.revanced.integrations.patches.announcements.requests.AnnouncementsRoutes; import app.revanced.integrations.requests.Requester; @@ -79,13 +81,12 @@ public static void showAnnouncement(final Activity context) { } final var finalTitle = title; - // TODO: Fix links not working. final var finalMessage = Html.fromHtml(message, FROM_HTML_MODE_COMPACT); final Level finalLevel = level; ReVancedUtils.runOnMainThread(() -> { // Show the announcement. - new android.app.AlertDialog.Builder(context) + var alertDialog = new android.app.AlertDialog.Builder(context) .setTitle(finalTitle) .setMessage(finalMessage) .setIcon(finalLevel.icon) @@ -97,6 +98,10 @@ public static void showAnnouncement(final Activity context) { }) .setCancelable(false) .show(); + + // Make links clickable. + ((TextView)alertDialog.findViewById(android.R.id.message)) + .setMovementMethod(LinkMovementMethod.getInstance()); }); } catch (Exception e) { final var message = "Failed to get announcement"; From 73f1e648e7d5b616e8ae10838ae4570f40fde421 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Fri, 20 Oct 2023 01:51:03 +0200 Subject: [PATCH 08/10] refactor: Restore consistency --- .../patches/announcements/AnnouncementsPatch.java | 12 ++++++------ .../revanced/integrations/settings/SettingsEnum.java | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/app/revanced/integrations/patches/announcements/AnnouncementsPatch.java b/app/src/main/java/app/revanced/integrations/patches/announcements/AnnouncementsPatch.java index ab5a119d5b..6e723ee575 100644 --- a/app/src/main/java/app/revanced/integrations/patches/announcements/AnnouncementsPatch.java +++ b/app/src/main/java/app/revanced/integrations/patches/announcements/AnnouncementsPatch.java @@ -41,9 +41,9 @@ public static void showAnnouncement(final Activity context) { try { // Do not show the announcement if the request failed. if (connection.getResponseCode() != 200) { - if (SettingsEnum.LAST_ANNOUNCEMENT_HASH.getString().isEmpty()) return; + if (SettingsEnum.ANNOUNCEMENT_LAST_HASH.getString().isEmpty()) return; - SettingsEnum.LAST_ANNOUNCEMENT_HASH.saveValue(""); + SettingsEnum.ANNOUNCEMENT_LAST_HASH.saveValue(""); ReVancedUtils.showToastLong("Failed to get announcement"); return; @@ -60,7 +60,7 @@ public static void showAnnouncement(final Activity context) { // Do not show the announcement if it is older or the same as the last one. final byte[] hashBytes = MessageDigest.getInstance("SHA-256").digest(jsonString.getBytes(StandardCharsets.UTF_8)); final var hash = java.util.Base64.getEncoder().encodeToString(hashBytes); - if (hash.equals(SettingsEnum.LAST_ANNOUNCEMENT_HASH.getString())) return; + if (hash.equals(SettingsEnum.ANNOUNCEMENT_LAST_HASH.getString())) return; // Parse the announcement. Fall-back to raw string if it fails. String title; @@ -91,7 +91,7 @@ public static void showAnnouncement(final Activity context) { .setMessage(finalMessage) .setIcon(finalLevel.icon) .setPositiveButton("Ok", (dialog, which) -> { - SettingsEnum.LAST_ANNOUNCEMENT_HASH.saveValue(hash); + SettingsEnum.ANNOUNCEMENT_LAST_HASH.saveValue(hash); dialog.dismiss(); }).setNegativeButton("Dismiss", (dialog, which) -> { dialog.dismiss(); @@ -117,8 +117,8 @@ public static void showAnnouncement(final Activity context) { * @return true if the last announcement hash was empty. */ private static boolean emptyLastAnnouncementHash() { - if (SettingsEnum.LAST_ANNOUNCEMENT_HASH.getString().isEmpty()) return true; - SettingsEnum.LAST_ANNOUNCEMENT_HASH.saveValue(""); + if (SettingsEnum.ANNOUNCEMENT_LAST_HASH.getString().isEmpty()) return true; + SettingsEnum.ANNOUNCEMENT_LAST_HASH.saveValue(""); return false; } diff --git a/app/src/main/java/app/revanced/integrations/settings/SettingsEnum.java b/app/src/main/java/app/revanced/integrations/settings/SettingsEnum.java index 8b5743ac20..a6f47755c6 100644 --- a/app/src/main/java/app/revanced/integrations/settings/SettingsEnum.java +++ b/app/src/main/java/app/revanced/integrations/settings/SettingsEnum.java @@ -178,7 +178,7 @@ public enum SettingsEnum { BYPASS_URL_REDIRECTS("revanced_bypass_url_redirects", BOOLEAN, TRUE), ANNOUNCEMENTS("revanced_announcements", BOOLEAN, TRUE), ANNOUNCEMENT_CONSUMER("revanced_announcement_consumer", STRING, ""), - LAST_ANNOUNCEMENT_HASH("revanced_last_announcement_hash", STRING, ""), + ANNOUNCEMENT_LAST_HASH("revanced_announcement_last_hash", STRING, ""), // Swipe controls SWIPE_BRIGHTNESS("revanced_swipe_brightness", BOOLEAN, TRUE), From 7075d800048c2bdf1820e157f0f6bd5353dde99b Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Fri, 20 Oct 2023 02:26:52 +0200 Subject: [PATCH 09/10] feat: Add version name to user agent header in ReVanced requests --- .../patches/spoof/requests/PlayerRoutes.java | 8 ++++- .../integrations/requests/Requester.java | 3 +- .../integrations/utils/ReVancedUtils.java | 30 +++++++++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/app/revanced/integrations/patches/spoof/requests/PlayerRoutes.java b/app/src/main/java/app/revanced/integrations/patches/spoof/requests/PlayerRoutes.java index db3971ba6a..a37dd6f3e8 100644 --- a/app/src/main/java/app/revanced/integrations/patches/spoof/requests/PlayerRoutes.java +++ b/app/src/main/java/app/revanced/integrations/patches/spoof/requests/PlayerRoutes.java @@ -3,6 +3,7 @@ import app.revanced.integrations.requests.Requester; import app.revanced.integrations.requests.Route; import app.revanced.integrations.utils.LogHelper; +import app.revanced.integrations.utils.ReVancedUtils; import org.json.JSONException; import org.json.JSONObject; @@ -75,7 +76,12 @@ private PlayerRoutes() { /** @noinspection SameParameterValue*/ static HttpURLConnection getPlayerResponseConnectionFromRoute(Route.CompiledRoute route) throws IOException { var connection = Requester.getConnectionFromCompiledRoute(YT_API_URL, route); - connection.setRequestProperty("User-Agent", "com.google.android.youtube/18.37.36 (Linux; U; Android 12; GB) gzip"); + + connection.setRequestProperty( + "User-Agent", "com.google.android.youtube/" + + ReVancedUtils.getVersionName() + + " (Linux; U; Android 12; GB) gzip" + ); connection.setRequestProperty("X-Goog-Api-Format-Version", "2"); connection.setRequestProperty("Content-Type", "application/json"); diff --git a/app/src/main/java/app/revanced/integrations/requests/Requester.java b/app/src/main/java/app/revanced/integrations/requests/Requester.java index c756dfe855..0a49ecacb2 100644 --- a/app/src/main/java/app/revanced/integrations/requests/Requester.java +++ b/app/src/main/java/app/revanced/integrations/requests/Requester.java @@ -1,5 +1,6 @@ package app.revanced.integrations.requests; +import app.revanced.integrations.utils.ReVancedUtils; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -23,7 +24,7 @@ public static HttpURLConnection getConnectionFromCompiledRoute(String apiUrl, Ro String url = apiUrl + route.getCompiledRoute(); HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(); connection.setRequestMethod(route.getMethod().name()); - connection.setRequestProperty("User-agent", System.getProperty("http.agent") + ";revanced"); + connection.setRequestProperty("User-Agent", System.getProperty("http.agent") + "; ReVanced/" + ReVancedUtils.getVersionName()); return connection; } diff --git a/app/src/main/java/app/revanced/integrations/utils/ReVancedUtils.java b/app/src/main/java/app/revanced/integrations/utils/ReVancedUtils.java index 286a03bf23..918d55b7f3 100644 --- a/app/src/main/java/app/revanced/integrations/utils/ReVancedUtils.java +++ b/app/src/main/java/app/revanced/integrations/utils/ReVancedUtils.java @@ -2,8 +2,11 @@ import android.annotation.SuppressLint; import android.content.Context; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; import android.content.res.Resources; import android.net.ConnectivityManager; +import android.os.Build; import android.os.Handler; import android.os.Looper; import android.view.View; @@ -25,9 +28,36 @@ public class ReVancedUtils { @SuppressLint("StaticFieldLeak") public static Context context; + private static String versionName; + private ReVancedUtils() { } // utility class + public static String getVersionName() { + if (versionName != null) return versionName; + + PackageInfo packageInfo; + try { + final var packageName = Objects.requireNonNull(getContext()).getPackageName(); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) + packageInfo = context.getPackageManager().getPackageInfo( + packageName, + PackageManager.PackageInfoFlags.of(0) + ); + else + packageInfo = context.getPackageManager().getPackageInfo( + packageName, + 0 + ); + } catch (PackageManager.NameNotFoundException e) { + LogHelper.printException(() -> "Failed to get package info", e); + return null; + } + + return versionName = packageInfo.versionName; + } + /** * Hide a view by setting its layout height and width to 1dp. * From eeb87092d5ef8dd81465328d5d304c60a599068d Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Fri, 20 Oct 2023 03:01:42 +0200 Subject: [PATCH 10/10] fix(YouTube - Announcements): Check for null properly --- .../integrations/patches/announcements/AnnouncementsPatch.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/app/revanced/integrations/patches/announcements/AnnouncementsPatch.java b/app/src/main/java/app/revanced/integrations/patches/announcements/AnnouncementsPatch.java index 6e723ee575..e68d10c174 100644 --- a/app/src/main/java/app/revanced/integrations/patches/announcements/AnnouncementsPatch.java +++ b/app/src/main/java/app/revanced/integrations/patches/announcements/AnnouncementsPatch.java @@ -72,7 +72,7 @@ public static void showAnnouncement(final Activity context) { title = announcement.getString("title"); message = announcement.getJSONObject("content").getString("message"); - if (announcement.has("level")) level = Level.fromInt(announcement.getInt("level")); + if (!announcement.isNull("level")) level = Level.fromInt(announcement.getInt("level")); } catch (Throwable ex) { LogHelper.printException(() -> "Failed to parse announcement. Fall-backing to raw string", ex);