diff --git a/app/src/main/java/app/revanced/integrations/shared/Utils.java b/app/src/main/java/app/revanced/integrations/shared/Utils.java index 1e94efdb..f440b253 100644 --- a/app/src/main/java/app/revanced/integrations/shared/Utils.java +++ b/app/src/main/java/app/revanced/integrations/shared/Utils.java @@ -249,6 +249,25 @@ public class Utils { return null; } + @Nullable + public static ViewParent getParentView(@NonNull View view, int nthParent) { + ViewParent parent = view.getParent(); + + int currentDepth = 0; + while (++currentDepth < nthParent && parent != null) { + parent = parent.getParent(); + } + + if (currentDepth == nthParent) { + return parent; + } + + final int currentDepthLog = currentDepth; + Logger.printDebug(() -> "Could not find parent view of depth: " + nthParent + + " and instead found at: " + currentDepthLog + " view: " + view); + return null; + } + public static void restartApp(@NonNull Context context) { String packageName = context.getPackageName(); Intent intent = context.getPackageManager().getLaunchIntentForPackage(packageName); diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/playback/quality/RestoreOldVideoQualityMenuPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/playback/quality/RestoreOldVideoQualityMenuPatch.java index 7d6f24ee..1cc65371 100644 --- a/app/src/main/java/app/revanced/integrations/youtube/patches/playback/quality/RestoreOldVideoQualityMenuPatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/playback/quality/RestoreOldVideoQualityMenuPatch.java @@ -3,9 +3,11 @@ package app.revanced.integrations.youtube.patches.playback.quality; import android.support.v7.widget.RecyclerView; import android.view.View; import android.view.ViewGroup; +import android.view.ViewParent; import android.widget.ListView; import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.Utils; import app.revanced.integrations.youtube.patches.components.VideoQualityMenuFilterPatch; import app.revanced.integrations.youtube.settings.Settings; @@ -26,23 +28,43 @@ public final class RestoreOldVideoQualityMenuPatch { recyclerView.getViewTreeObserver().addOnDrawListener(() -> { try { // Check if the current view is the quality menu. - if (VideoQualityMenuFilterPatch.isVideoQualityMenuVisible) { - VideoQualityMenuFilterPatch.isVideoQualityMenuVisible = false; - - ((ViewGroup) recyclerView.getParent().getParent().getParent()).setVisibility(View.GONE); - View advancedQualityView = ((ViewGroup) recyclerView.getChildAt(0)).getChildAt(3); - if (advancedQualityView != null) { - // Click the "Advanced" quality menu to show the "old" quality menu. - advancedQualityView.setSoundEffectsEnabled(false); - advancedQualityView.performClick(); - } + if (!VideoQualityMenuFilterPatch.isVideoQualityMenuVisible || recyclerView.getChildCount() == 0) { + return; } + VideoQualityMenuFilterPatch.isVideoQualityMenuVisible = false; + + ViewParent quickQualityViewParent = Utils.getParentView(recyclerView, 3); + if (!(quickQualityViewParent instanceof ViewGroup)) { + return; + } + + View firstChild = recyclerView.getChildAt(0); + if (!(firstChild instanceof ViewGroup)) { + return; + } + + ViewGroup advancedQualityParentView = (ViewGroup) firstChild; + if (advancedQualityParentView.getChildCount() < 4) { + return; + } + + View advancedQualityView = advancedQualityParentView.getChildAt(3); + if (advancedQualityView == null) { + return; + } + + ((ViewGroup) quickQualityViewParent).setVisibility(View.GONE); + + // Click the "Advanced" quality menu to show the "old" quality menu. + advancedQualityView.setSoundEffectsEnabled(false); + advancedQualityView.performClick(); } catch (Exception ex) { Logger.printException(() -> "onFlyoutMenuCreate failure", ex); } }); } + /** * Injection point. * diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/playback/speed/CustomPlaybackSpeedPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/playback/speed/CustomPlaybackSpeedPatch.java index e863f8fd..59d63bcb 100644 --- a/app/src/main/java/app/revanced/integrations/youtube/patches/playback/speed/CustomPlaybackSpeedPatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/playback/speed/CustomPlaybackSpeedPatch.java @@ -6,6 +6,8 @@ import android.preference.ListPreference; import android.support.v7.widget.RecyclerView; import android.view.View; import android.view.ViewGroup; +import android.view.ViewParent; + import androidx.annotation.NonNull; import app.revanced.integrations.youtube.patches.components.PlaybackSpeedMenuFilterPatch; @@ -115,24 +117,36 @@ public class CustomPlaybackSpeedPatch { if (!PlaybackSpeedMenuFilterPatch.isPlaybackSpeedMenuVisible || recyclerView.getChildCount() == 0) { return; } - ViewGroup PlaybackSpeedParentView = (ViewGroup) recyclerView.getChildAt(0); - if (PlaybackSpeedParentView == null || PlaybackSpeedParentView.getChildCount() != 8) { + + View firstChild = recyclerView.getChildAt(0); + if (!(firstChild instanceof ViewGroup)) { + return; + } + ViewGroup PlaybackSpeedParentView = (ViewGroup) firstChild; + if (PlaybackSpeedParentView.getChildCount() != 8) { return; } PlaybackSpeedMenuFilterPatch.isPlaybackSpeedMenuVisible = false; - ViewGroup parentView3rd = (ViewGroup) recyclerView.getParent().getParent().getParent(); - ViewGroup parentView4th = (ViewGroup) parentView3rd.getParent(); + + ViewParent parentView3rd = Utils.getParentView(recyclerView, 3); + if (!(parentView3rd instanceof ViewGroup)) { + return; + } + ViewParent parentView4th = parentView3rd.getParent(); + if (!(parentView4th instanceof ViewGroup)) { + return; + } // Dismiss View [R.id.touch_outside] is the 1st ChildView of the 4th ParentView. // This only shows in phone layout. - final var touchInsidedView = parentView4th.getChildAt(0); + final var touchInsidedView = ((ViewGroup) parentView4th).getChildAt(0); touchInsidedView.setSoundEffectsEnabled(false); touchInsidedView.performClick(); // In tablet layout there is no Dismiss View, instead we just hide all two parent views. - parentView3rd.setVisibility(View.GONE); - parentView4th.setVisibility(View.GONE); + ((ViewGroup) parentView3rd).setVisibility(View.GONE); + ((ViewGroup) parentView4th).setVisibility(View.GONE); // This works without issues for both tablet and phone layouts, // So no code is needed to check whether the current device is a tablet or phone.