Skip to content
This repository has been archived by the owner on Dec 8, 2024. It is now read-only.

feat(YouTube Music): add support version 6.20.51 #57

Merged
merged 7 commits into from
Sep 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package app.revanced.integrations.music.patches.account;

import static app.revanced.integrations.shared.utils.StringRef.str;
import static app.revanced.integrations.shared.utils.Utils.isSDKAbove;

import android.view.View;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

import app.revanced.integrations.music.settings.Settings;
Expand All @@ -18,9 +21,15 @@ public class AccountPatch {
static {
accountMenuBlockList = Settings.HIDE_ACCOUNT_MENU_FILTER_STRINGS.get().split("\\n");
// Some settings should not be hidden.
accountMenuBlockList = Arrays.stream(accountMenuBlockList)
.filter(item -> !Objects.equals(item, str("settings")))
.toArray(String[]::new);
if (isSDKAbove(24)) {
accountMenuBlockList = Arrays.stream(accountMenuBlockList)
.filter(item -> !Objects.equals(item, str("settings")))
.toArray(String[]::new);
} else {
List<String> tmp = new ArrayList<>(Arrays.asList(accountMenuBlockList));
tmp.remove(str("settings")); // "Settings" should appear only once in the account menu
accountMenuBlockList = tmp.toArray(new String[0]);
}
}

public static void hideAccountMenu(CharSequence charSequence, View view) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static app.revanced.integrations.shared.utils.Utils.hideViewByRemovingFromParentUnderCondition;
import static app.revanced.integrations.shared.utils.Utils.hideViewUnderCondition;
import static app.revanced.integrations.shared.utils.Utils.isSDKAbove;

import android.annotation.SuppressLint;
import android.graphics.Color;
Expand All @@ -13,7 +14,7 @@
import app.revanced.integrations.music.settings.Settings;
import app.revanced.integrations.music.shared.VideoType;

@SuppressWarnings("unused")
@SuppressWarnings({"unused", "ResultOfMethodCallIgnored"})
public class PlayerPatch {
private static final int MUSIC_VIDEO_GREY_BACKGROUND_COLOR = -12566464;
private static final int MUSIC_VIDEO_ORIGINAL_BACKGROUND_COLOR = -16579837;
Expand Down Expand Up @@ -132,7 +133,7 @@ public static void hideAudioVideoSwitchToggle(View view) {
return;

if (view.getParent() instanceof ViewGroup viewGroup) {
viewGroup.removeView(view);
viewGroup.setVisibility(View.INVISIBLE);
inotia00 marked this conversation as resolved.
Show resolved Hide resolved
}
}

Expand Down Expand Up @@ -173,6 +174,13 @@ public static boolean restoreOldPlayerBackground(boolean original) {
if (!Settings.SETTINGS_INITIALIZED.get()) {
return original;
}
if (!isSDKAbove(23)) {
// Disable this patch on Android 5.0 / 5.1 to fix a black play button.
// Android 5.x have a different design for play button,
// and if the new background is applied forcibly, the play button turns black.
// 6.20.51 uses the old background from the beginning, so there is no impact.
return original;
}
return !Settings.RESTORE_OLD_PLAYER_BACKGROUND.get();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package app.revanced.integrations.music.returnyoutubedislike;

import static app.revanced.integrations.shared.returnyoutubedislike.ReturnYouTubeDislike.Vote;
import static app.revanced.integrations.shared.utils.Utils.isSDKAbove;

import android.graphics.Canvas;
import android.graphics.Paint;
Expand All @@ -25,6 +26,7 @@

import java.text.NumberFormat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
Expand Down Expand Up @@ -251,40 +253,40 @@ private static SpannableString newSpanUsingStylingOfAnotherSpan(@NonNull Spanned
return destination;
}

/**
* @noinspection deprecation
*/
private static String formatDislikeCount(long dislikeCount) {
synchronized (ReturnYouTubeDislike.class) { // number formatter is not thread safe, must synchronize
if (isSDKAbove(24)) {
if (dislikeCountFormatter == null) {
// Note: Java number formatters will use the locale specific number characters.
// such as Arabic which formats "1.234" into "۱,۲۳٤"
// But YouTube disregards locale specific number characters
// and instead shows english number characters everywhere.
Locale locale = Objects.requireNonNull(Utils.getContext()).getResources().getConfiguration().locale;
Locale locale = Objects.requireNonNull(Utils.getContext()).getResources().getConfiguration().getLocales().get(0);
Logger.printDebug(() -> "Locale: " + locale);
dislikeCountFormatter = CompactDecimalFormat.getInstance(locale, CompactDecimalFormat.CompactStyle.SHORT);
}
return dislikeCountFormatter.format(dislikeCount);
} else {
return String.valueOf(dislikeCount);
}
}

/**
* @noinspection deprecation
*/
private static String formatDislikePercentage(float dislikePercentage) {
synchronized (ReturnYouTubeDislike.class) { // number formatter is not thread safe, must synchronize
if (dislikePercentageFormatter == null) {
Locale locale = Objects.requireNonNull(Utils.getContext()).getResources().getConfiguration().locale;
Logger.printDebug(() -> "Locale: " + locale);
dislikePercentageFormatter = NumberFormat.getPercentInstance(locale);
}
if (dislikePercentage >= 0.01) { // at least 1%
dislikePercentageFormatter.setMaximumFractionDigits(0); // show only whole percentage points
} else {
dislikePercentageFormatter.setMaximumFractionDigits(1); // show up to 1 digit precision
if (isSDKAbove(24)) {
synchronized (ReturnYouTubeDislike.class) { // number formatter is not thread safe, must synchronize
if (dislikePercentageFormatter == null) {
Locale locale = Objects.requireNonNull(Utils.getContext()).getResources().getConfiguration().getLocales().get(0);
Logger.printDebug(() -> "Locale: " + locale);
dislikePercentageFormatter = NumberFormat.getPercentInstance(locale);
}
if (dislikePercentage >= 0.01) { // at least 1%
dislikePercentageFormatter.setMaximumFractionDigits(0); // show only whole percentage points
} else {
dislikePercentageFormatter.setMaximumFractionDigits(1); // show up to 1 digit precision
}
return dislikePercentageFormatter.format(dislikePercentage);
}
return dislikePercentageFormatter.format(dislikePercentage);
} else {
return String.valueOf((int) (dislikePercentage * 100));
}
}

Expand All @@ -294,12 +296,23 @@ public static ReturnYouTubeDislike getFetchForVideoId(@Nullable String videoId)
synchronized (fetchCache) {
// Remove any expired entries.
final long now = System.currentTimeMillis();
fetchCache.values().removeIf(value -> {
final boolean expired = value.isExpired(now);
if (expired)
Logger.printDebug(() -> "Removing expired fetch: " + value.videoId);
return expired;
});
if (isSDKAbove(24)) {
fetchCache.values().removeIf(value -> {
final boolean expired = value.isExpired(now);
if (expired)
Logger.printDebug(() -> "Removing expired fetch: " + value.videoId);
return expired;
});
} else {
final Iterator<Map.Entry<String, ReturnYouTubeDislike>> itr = fetchCache.entrySet().iterator();
while (itr.hasNext()) {
final Map.Entry<String, ReturnYouTubeDislike> entry = itr.next();
if (entry.getValue().isExpired(now)) {
Logger.printDebug(() -> "Removing expired fetch: " + entry.getValue().videoId);
itr.remove();
}
}
}

ReturnYouTubeDislike fetch = fetchCache.get(videoId);
if (fetch == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import static app.revanced.integrations.shared.settings.Setting.getSettingFromPath;
import static app.revanced.integrations.shared.utils.ResourceUtils.getStringArray;
import static app.revanced.integrations.shared.utils.StringRef.str;
import static app.revanced.integrations.shared.utils.Utils.isSDKAbove;
import static app.revanced.integrations.shared.utils.Utils.showToastShort;

import android.annotation.SuppressLint;
Expand All @@ -25,7 +26,6 @@
import android.content.Intent;
import android.icu.text.SimpleDateFormat;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceFragment;
import android.text.InputType;
Expand Down Expand Up @@ -239,7 +239,7 @@ private void exportActivity() {
private void importActivity() {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType(Build.VERSION.SDK_INT <= 28 ? "*/*" : "text/plain");
intent.setType(isSDKAbove(29) ? "text/plain" : "*/*");
startActivityForResult(intent, READ_REQUEST_CODE);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,12 @@ private static int dpToPx(float dp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics());
}

@SuppressWarnings("deprecation")
public static AlertDialog.Builder getDialogBuilder(@NonNull Context context) {
return new AlertDialog.Builder(context, android.R.style.Theme_DeviceDefault_Dialog_Alert);
return new AlertDialog.Builder(context, isSDKAbove(22)
? android.R.style.Theme_DeviceDefault_Dialog_Alert
: AlertDialog.THEME_DEVICE_DEFAULT_DARK
inotia00 marked this conversation as resolved.
Show resolved Hide resolved
);
}

public static FrameLayout.LayoutParams getLayoutParams() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import android.widget.Button;

import java.lang.ref.WeakReference;
import java.util.Arrays;

import app.revanced.integrations.shared.settings.BaseSettings;
import app.revanced.integrations.shared.utils.Logger;
Expand Down Expand Up @@ -81,10 +80,10 @@ private enum DialogType {
}

private static DialogType getDialogType(int code) {
return Arrays.stream(values())
.filter(val -> code == val.code)
.findFirst()
.orElse(DialogType.NULL);
for (DialogType val : values())
if (code == val.code) return val;

return DialogType.NULL;
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package app.revanced.integrations.shared.patches;

import static app.revanced.integrations.shared.utils.StringRef.str;
import static app.revanced.integrations.shared.utils.Utils.isSDKAbove;

import android.annotation.SuppressLint;
import android.app.Activity;
Expand Down Expand Up @@ -131,16 +132,30 @@ public static void checkGmsCore(Activity mActivity) {
/**
* @return If GmsCore is not running in the background.
*/
@SuppressWarnings("deprecation")
private static boolean contentProviderClientUnAvailable(Context context) {
// Check if GmsCore is running in the background.
// Do this check before the battery optimization check.
try (ContentProviderClient client = context.getContentResolver().acquireContentProviderClient(GMS_CORE_PROVIDER)) {
return client == null;
if (isSDKAbove(24)) {
try (ContentProviderClient client = context.getContentResolver().acquireContentProviderClient(GMS_CORE_PROVIDER)) {
return client == null;
}
} else {
ContentProviderClient client = null;
try {
//noinspection resource
client = context.getContentResolver()
.acquireContentProviderClient(GMS_CORE_PROVIDER);
return client == null;
} finally {
if (client != null) client.release();
}
}
}

@SuppressLint("BatteryLife") // Permission is part of GmsCore
private static void openGmsCoreDisableBatteryOptimizationsIntent(Activity mActivity) {
if (!isSDKAbove(23)) return;
Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.fromParts("package", GMS_CORE_PACKAGE_NAME, null));
mActivity.startActivityForResult(intent, 0);
Expand All @@ -150,7 +165,7 @@ private static void openGmsCoreDisableBatteryOptimizationsIntent(Activity mActiv
* @return If GmsCore is not whitelisted from battery optimizations.
*/
private static boolean batteryOptimizationsEnabled(Context context) {
if (context.getSystemService(Context.POWER_SERVICE) instanceof PowerManager powerManager) {
if (isSDKAbove(23) && context.getSystemService(Context.POWER_SERVICE) instanceof PowerManager powerManager) {
return !powerManager.isIgnoringBatteryOptimizations(GMS_CORE_PACKAGE_NAME);
}
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@

import static app.revanced.integrations.shared.utils.StringRef.str;
import static app.revanced.integrations.shared.utils.Utils.hideViewGroupByMarginLayoutParams;
import static app.revanced.integrations.shared.utils.Utils.isSDKAbove;

import android.support.v7.widget.RecyclerView;
import android.view.ViewGroup;
import android.widget.TextView;

import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import app.revanced.integrations.shared.settings.BaseSettings;
import app.revanced.integrations.shared.utils.Logger;
Expand All @@ -21,9 +24,15 @@ public final class SettingsMenuPatch {
static {
settingsMenuBlockList = BaseSettings.HIDE_SETTINGS_MENU_FILTER_STRINGS.get().split("\\n");
// Some settings should not be hidden.
settingsMenuBlockList = Arrays.stream(settingsMenuBlockList)
.filter(item -> !StringUtils.equalsAny(item, str("revanced_hide_settings_menu_title"), str("revanced_extended_settings_title")))
.toArray(String[]::new);
if (isSDKAbove(24)) {
settingsMenuBlockList = Arrays.stream(settingsMenuBlockList)
.filter(item -> !StringUtils.equalsAny(item, str("revanced_hide_settings_menu_title"), str("revanced_extended_settings_title")))
.toArray(String[]::new);
} else {
final List<String> tmpList = new ArrayList<>(Arrays.asList(settingsMenuBlockList));
tmpList.removeAll(Arrays.asList(str("revanced_hide_settings_menu_title"), str("revanced_extended_settings_title")));
settingsMenuBlockList = tmpList.toArray(new String[0]);
}
}

public static void hideSettingsMenu(RecyclerView recyclerView) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package app.revanced.integrations.shared.patches.components;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;

import java.util.ArrayList;
import java.util.Arrays;
Expand Down Expand Up @@ -44,11 +45,13 @@ public Iterator<T> iterator() {
return filterGroups.iterator();
}

@RequiresApi(24)
@Override
public void forEach(@NonNull Consumer<? super T> action) {
filterGroups.forEach(action);
}

@RequiresApi(24)
@NonNull
@Override
public Spliterator<T> spliterator() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package app.revanced.integrations.shared.settings;

import static app.revanced.integrations.shared.utils.StringRef.str;
import static app.revanced.integrations.shared.utils.Utils.isSDKAbove;

import android.content.Context;
import android.os.Build;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
Expand Down Expand Up @@ -107,7 +109,12 @@ public static List<Setting<?>> allLoadedSettings() {
*/
@NonNull
private static List<Setting<?>> allLoadedSettingsSorted() {
SETTINGS.sort(Comparator.comparing((Setting<?> o) -> o.key));
if (isSDKAbove(24)) {
SETTINGS.sort(Comparator.comparing((Setting<?> o) -> o.key));
} else {
//noinspection ComparatorCombinators
Collections.sort(SETTINGS, (o1, o2) -> o1.key.compareTo(o2.key));
}
return allLoadedSettings();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
if (setting.userDialogMessage != null && ((SwitchPreference) pref).isChecked() != (Boolean) setting.defaultValue) {
showSettingUserDialogConfirmation((SwitchPreference) pref, (BooleanSetting) setting);
} else if (setting.rebootApp) {
showRestartDialog(getContext());
showRestartDialog(getActivity());
}
}

Expand All @@ -97,7 +97,7 @@ protected void initialize() {
private void showSettingUserDialogConfirmation(SwitchPreference switchPref, BooleanSetting setting) {
Utils.verifyOnMainThread();

final var context = getContext();
final var context = getActivity();
showingUserDialogMessage = true;
assert setting.userDialogMessage != null;
new AlertDialog.Builder(context)
Expand Down
Loading