fix(YouTube - Change form factor): Restore Automotive form factor watch history menu, channel pages, and community posts (#4541)

This commit is contained in:
LisoUseInAIKyrios
2025-03-06 08:26:09 +02:00
committed by GitHub
parent 5bd2e86afe
commit aa5c001968
6 changed files with 173 additions and 12 deletions

View File

@ -1,9 +1,17 @@
package app.revanced.extension.youtube.patches;
import static app.revanced.extension.youtube.shared.NavigationBar.NavigationButton;
import android.view.View;
import androidx.annotation.Nullable;
import app.revanced.extension.shared.Utils;
import java.util.Objects;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.youtube.settings.Settings;
import app.revanced.extension.youtube.shared.NavigationBar;
import app.revanced.extension.youtube.shared.PlayerType;
@SuppressWarnings("unused")
public class ChangeFormFactorPatch {
@ -41,14 +49,57 @@ public class ChangeFormFactorPatch {
@Nullable
private static final Integer FORM_FACTOR_TYPE = Settings.CHANGE_FORM_FACTOR.get().formFactorType;
private static final boolean USING_AUTOMOTIVE_TYPE = Objects.requireNonNull(
FormFactor.AUTOMOTIVE.formFactorType).equals(FORM_FACTOR_TYPE);
/**
* Injection point.
*/
public static int getFormFactor(int original) {
return FORM_FACTOR_TYPE == null
? original
: FORM_FACTOR_TYPE;
if (FORM_FACTOR_TYPE == null) return original;
if (USING_AUTOMOTIVE_TYPE) {
// Do not change if the player is opening or is opened,
// otherwise the video description cannot be opened.
PlayerType current = PlayerType.getCurrent();
if (current.isMaximizedOrFullscreen() || current == PlayerType.WATCH_WHILE_SLIDING_MINIMIZED_MAXIMIZED) {
Logger.printDebug(() -> "Using original form factor for player");
return original;
}
if (!NavigationBar.isSearchBarActive()) {
// Automotive type shows error 400 when opening a channel page and using some explore tab.
// This is a bug in unpatched YouTube that occurs on actual Android Automotive devices.
// Work around the issue by using the original form factor if not in search and the
// navigation back button is present.
if (NavigationBar.isBackButtonVisible()) {
Logger.printDebug(() -> "Using original form factor, as back button is visible without search present");
return original;
}
// Do not change library tab otherwise watch history is hidden.
// Do this check last since the current navigation button is required.
if (NavigationButton.getSelectedNavigationButton() == NavigationButton.LIBRARY) {
return original;
}
}
}
return FORM_FACTOR_TYPE;
}
/**
* Injection point.
*/
public static void navigationTabCreated(NavigationButton button, View tabView) {
// On first startup of the app the navigation buttons are fetched and updated.
// If the user immediately opens the 'You' or opens a video, then the call to
// update the navigtation buttons will use the non automotive form factor
// and the explore tab is missing.
// Fixing this is not so simple because of the concurrent calls for the player and You tab.
// For now, always hide the explore tab.
if (USING_AUTOMOTIVE_TYPE && button == NavigationButton.EXPLORE) {
tabView.setVisibility(View.GONE);
}
}
}

View File

@ -3,7 +3,9 @@ package app.revanced.extension.youtube.shared;
import static app.revanced.extension.youtube.shared.NavigationBar.NavigationButton.CREATE;
import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.widget.FrameLayout;
import androidx.annotation.Nullable;
@ -24,12 +26,22 @@ import app.revanced.extension.youtube.settings.Settings;
@SuppressWarnings("unused")
public final class NavigationBar {
/**
* Interface to call obfuscated methods in AppCompat Toolbar class.
*/
public interface AppCompatToolbarPatchInterface {
Drawable patch_getNavigationIcon();
}
//
// Search bar
// Search and toolbar.
//
private static volatile WeakReference<View> searchBarResultsRef = new WeakReference<>(null);
private static volatile WeakReference<AppCompatToolbarPatchInterface> toolbarResultsRef
= new WeakReference<>(null);
/**
* Injection point.
*/
@ -37,6 +49,22 @@ public final class NavigationBar {
searchBarResultsRef = new WeakReference<>(searchbarResults);
}
/**
* Injection point.
*/
public static void setToolbar(FrameLayout layout) {
AppCompatToolbarPatchInterface toolbar = Utils.getChildView(layout, false, (view) ->
view instanceof AppCompatToolbarPatchInterface
);
if (toolbar == null) {
Logger.printException(() -> "Could not find navigation toolbar");
return;
}
toolbarResultsRef = new WeakReference<>(toolbar);
}
/**
* @return If the search bar is on screen. This includes if the player
* is on screen and the search results are behind the player (and not visible).
@ -47,8 +75,13 @@ public final class NavigationBar {
return searchbarResults != null && searchbarResults.getParent() != null;
}
public static boolean isBackButtonVisible() {
AppCompatToolbarPatchInterface toolbar = toolbarResultsRef.get();
return toolbar != null && toolbar.patch_getNavigationIcon() != null;
}
//
// Navigation bar buttons
// Navigation bar buttons.
//
/**