fix(YouTube - Miniplayer): Patched app crashes after first launch or clearing data

This commit is contained in:
inotia00 2024-12-31 20:47:37 +09:00
parent 8d045bc618
commit 74d39ff034

View File

@ -12,6 +12,8 @@ import static app.revanced.extension.youtube.utils.ExtendedUtils.IS_19_26_OR_GRE
import static app.revanced.extension.youtube.utils.ExtendedUtils.IS_19_29_OR_GREATER; import static app.revanced.extension.youtube.utils.ExtendedUtils.IS_19_29_OR_GREATER;
import static app.revanced.extension.youtube.utils.ExtendedUtils.validateValue; import static app.revanced.extension.youtube.utils.ExtendedUtils.validateValue;
import android.content.Context;
import android.content.res.Resources;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -82,49 +84,56 @@ public final class MiniplayerPatch {
} }
} }
private static final int MINIPLAYER_SIZE; private static int MINIPLAYER_SIZE = 0;
static { static {
// YT appears to use the device screen dip width, plus an unknown fixed horizontal padding size. setMiniPlayerSize();
DisplayMetrics displayMetrics = Utils.getContext().getResources().getDisplayMetrics(); }
final int deviceDipWidth = (int) (displayMetrics.widthPixels / displayMetrics.density);
// YT seems to use a minimum height to calculate the minimum miniplayer width based on the video. private static void setMiniPlayerSize() {
// 170 seems to be the smallest that can be used and using less makes no difference. try {
final int WIDTH_DIP_MIN = 170; // Seems to be the smallest that works. Context context = Utils.getContext();
final int HORIZONTAL_PADDING_DIP = 15; // Estimated padding. if (context == null) {
// Round down to the nearest 5 pixels, to keep any error toasts easier to read. return;
final int estimatedWidthDipMax = 5 * ((deviceDipWidth - HORIZONTAL_PADDING_DIP) / 5); }
// On some ultra low end devices the pixel width and density are the same number, Resources resources = context.getResources();
// which causes the estimate to always give a value of 1. if (resources == null) {
// Fix this by using a fixed size of double the min width. return;
final int WIDTH_DIP_MAX = estimatedWidthDipMax <= WIDTH_DIP_MIN }
? 2 * WIDTH_DIP_MIN // YT appears to use the device screen dip width, plus an unknown fixed horizontal padding size.
: estimatedWidthDipMax; DisplayMetrics displayMetrics = resources.getDisplayMetrics();
Logger.printDebug(() -> "Screen dip width: " + deviceDipWidth + " maxWidth: " + WIDTH_DIP_MAX); final int deviceDipWidth = (int) (displayMetrics.widthPixels / displayMetrics.density);
int dipWidth = Settings.MINIPLAYER_WIDTH_DIP.get(); // YT seems to use a minimum height to calculate the minimum miniplayer width based on the video.
// 170 seems to be the smallest that can be used and using less makes no difference.
final int WIDTH_DIP_MIN = 170; // Seems to be the smallest that works.
final int HORIZONTAL_PADDING_DIP = 15; // Estimated padding.
// Round down to the nearest 5 pixels, to keep any error toasts easier to read.
final int estimatedWidthDipMax = 5 * ((deviceDipWidth - HORIZONTAL_PADDING_DIP) / 5);
// On some ultra low end devices the pixel width and density are the same number,
// which causes the estimate to always give a value of 1.
// Fix this by using a fixed size of double the min width.
final int WIDTH_DIP_MAX = estimatedWidthDipMax <= WIDTH_DIP_MIN
? 2 * WIDTH_DIP_MIN
: estimatedWidthDipMax;
Logger.printDebug(() -> "Screen dip width: " + deviceDipWidth + " maxWidth: " + WIDTH_DIP_MAX);
if (dipWidth < WIDTH_DIP_MIN || dipWidth > WIDTH_DIP_MAX) { int dipWidth = Settings.MINIPLAYER_WIDTH_DIP.get();
Utils.showToastShort(str("revanced_miniplayer_width_dip_invalid_toast",
WIDTH_DIP_MIN, WIDTH_DIP_MAX));
Utils.showToastShort(str("revanced_extended_reset_to_default_toast"));
// Instead of resetting, clamp the size at the bounds. if (dipWidth < WIDTH_DIP_MIN || dipWidth > WIDTH_DIP_MAX) {
dipWidth = Math.max(WIDTH_DIP_MIN, Math.min(dipWidth, WIDTH_DIP_MAX)); Utils.showToastShort(str("revanced_miniplayer_width_dip_invalid_toast",
Settings.MINIPLAYER_WIDTH_DIP.save(dipWidth); WIDTH_DIP_MIN, WIDTH_DIP_MAX));
Utils.showToastShort(str("revanced_extended_reset_to_default_toast"));
// Instead of resetting, clamp the size at the bounds.
dipWidth = Math.max(WIDTH_DIP_MIN, Math.min(dipWidth, WIDTH_DIP_MAX));
Settings.MINIPLAYER_WIDTH_DIP.save(dipWidth);
}
MINIPLAYER_SIZE = dipWidth;
} catch (Exception ex) {
Logger.printException(() -> "setMiniPlayerSize failure", ex);
} }
MINIPLAYER_SIZE = dipWidth;
final int opacity = validateValue(
Settings.MINIPLAYER_OPACITY,
0,
100,
"revanced_miniplayer_opacity_invalid_toast"
);
OPACITY_LEVEL = (opacity * 255) / 100;
} }
/** /**
@ -175,6 +184,17 @@ public final class MiniplayerPatch {
private static final int OPACITY_LEVEL; private static final int OPACITY_LEVEL;
static {
final int opacity = validateValue(
Settings.MINIPLAYER_OPACITY,
0,
100,
"revanced_miniplayer_opacity_invalid_toast"
);
OPACITY_LEVEL = (opacity * 255) / 100;
}
public static final class MiniplayerHorizontalDragAvailability implements Setting.Availability { public static final class MiniplayerHorizontalDragAvailability implements Setting.Availability {
@Override @Override
public boolean isAvailable() { public boolean isAvailable() {
@ -293,7 +313,12 @@ public final class MiniplayerPatch {
*/ */
public static int setMiniplayerDefaultSize(int original) { public static int setMiniplayerDefaultSize(int original) {
if (CURRENT_TYPE.isModern()) { if (CURRENT_TYPE.isModern()) {
return MINIPLAYER_SIZE; if (MINIPLAYER_SIZE == 0) {
setMiniPlayerSize();
}
if (MINIPLAYER_SIZE != 0) {
return MINIPLAYER_SIZE;
}
} }
return original; return original;