Skip to content

Commit

Permalink
Youtube:
Browse files Browse the repository at this point in the history
- VideoAds
- BackgroundPlayback
- RemoveTrackingQueryParameter
- HideAds
- LithoFilter
  • Loading branch information
chsbuffer committed Jul 28, 2024
1 parent c90067c commit 0158c5b
Show file tree
Hide file tree
Showing 20 changed files with 2,214 additions and 68 deletions.
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Compatibility & Patches

## Youtube Music
Youtube Music tested version: 7.11.50
Patches:
- HideMusicVideoAds
- MinimizedPlayback
- RemoveUpgradeButton
- HideGetPremium
- EnableExclusiveAudioPlayback

## Youtube
Youtube tested version: 19.29.37
Patches:
- VideoAds
- BackgroundPlayback
- RemoveTrackingQueryParameter
- HideAds
- LithoFilter

# Credit

[DexKit](https://github.com/LuckyPray/DexKit)
[ReVanced Integrations](https://github.com/ReVanced/revanced-integrations)
[Revanced Patcher](https://github.com/ReVanced/revanced-patcher)
[Revanced Patches](https://github.com/ReVanced/revanced-patches)
1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,6 @@ android {

dependencies {
implementation(libs.dexkit)
implementation(libs.annotation)
compileOnly(libs.xposed)
}
157 changes: 157 additions & 0 deletions app/src/main/java/app/revanced/integrations/shared/Logger.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
package app.revanced.integrations.shared;

import static app.revanced.integrations.shared.settings.BaseSettings.DEBUG;
import static app.revanced.integrations.shared.settings.BaseSettings.DEBUG_STACKTRACE;
import static app.revanced.integrations.shared.settings.BaseSettings.DEBUG_TOAST_ON_ERROR;

import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.io.PrintWriter;
import java.io.StringWriter;

import app.revanced.integrations.shared.settings.BaseSettings;

public class Logger {

/**
* Log messages using lambdas.
*/
public interface LogMessage {
@NonNull
String buildMessageString();

/**
* @return For outer classes, this returns {@link Class#getSimpleName()}.
* For static, inner, or anonymous classes, this returns the simple name of the enclosing class.
* <br>
* For example, each of these classes return 'SomethingView':
* <code>
* com.company.SomethingView
* com.company.SomethingView$StaticClass
* com.company.SomethingView$1
* </code>
*/
private String findOuterClassSimpleName() {
var selfClass = this.getClass();

String fullClassName = selfClass.getName();
final int dollarSignIndex = fullClassName.indexOf('$');
if (dollarSignIndex < 0) {
return selfClass.getSimpleName(); // Already an outer class.
}

// Class is inner, static, or anonymous.
// Parse the simple name full name.
// A class with no package returns index of -1, but incrementing gives index zero which is correct.
final int simpleClassNameStartIndex = fullClassName.lastIndexOf('.') + 1;
return fullClassName.substring(simpleClassNameStartIndex, dollarSignIndex);
}
}

private static final String REVANCED_LOG_PREFIX = "revanced: ";

/**
* Logs debug messages under the outer class name of the code calling this method.
* Whenever possible, the log string should be constructed entirely inside {@link LogMessage#buildMessageString()}
* so the performance cost of building strings is paid only if {@link BaseSettings#DEBUG} is enabled.
*/
public static void printDebug(@NonNull LogMessage message) {
if (DEBUG.get()) {
var messageString = message.buildMessageString();

if (DEBUG_STACKTRACE.get()) {
var builder = new StringBuilder(messageString);
var sw = new StringWriter();
new Throwable().printStackTrace(new PrintWriter(sw));

builder.append('\n').append(sw);
messageString = builder.toString();
}

Log.d(REVANCED_LOG_PREFIX + message.findOuterClassSimpleName(), messageString);
}
}

/**
* Logs information messages using the outer class name of the code calling this method.
*/
public static void printInfo(@NonNull LogMessage message) {
printInfo(message, null);
}

/**
* Logs information messages using the outer class name of the code calling this method.
*/
public static void printInfo(@NonNull LogMessage message, @Nullable Exception ex) {
String logTag = REVANCED_LOG_PREFIX + message.findOuterClassSimpleName();
String logMessage = message.buildMessageString();
if (ex == null) {
Log.i(logTag, logMessage);
} else {
Log.i(logTag, logMessage, ex);
}
}

/**
* Logs exceptions under the outer class name of the code calling this method.
*/
public static void printException(@NonNull LogMessage message) {
printException(message, null, null);
}

/**
* Logs exceptions under the outer class name of the code calling this method.
*/
public static void printException(@NonNull LogMessage message, @Nullable Throwable ex) {
printException(message, ex, null);
}

/**
* Logs exceptions under the outer class name of the code calling this method.
* <p>
* If the calling code is showing it's own error toast,
* instead use {@link #printInfo(LogMessage, Exception)}
*
* @param message log message
* @param ex exception (optional)
* @param userToastMessage user specific toast message to show instead of the log message (optional)
*/
public static void printException(@NonNull LogMessage message, @Nullable Throwable ex,
@Nullable String userToastMessage) {
String messageString = message.buildMessageString();
String outerClassSimpleName = message.findOuterClassSimpleName();
String logMessage = REVANCED_LOG_PREFIX + outerClassSimpleName;
if (ex == null) {
Log.e(logMessage, messageString);
} else {
Log.e(logMessage, messageString, ex);
}
if (DEBUG_TOAST_ON_ERROR.get()) {
String toastMessageToDisplay = (userToastMessage != null)
? userToastMessage
: outerClassSimpleName + ": " + messageString;
Utils.showToastLong(toastMessageToDisplay);
}
}

/**
* Logging to use if {@link BaseSettings#DEBUG} or {@link Utils#getContext()} may not be initialized.
* Normally this method should not be used.
*/
public static void initializationInfo(@NonNull Class<?> callingClass, @NonNull String message) {
Log.i(REVANCED_LOG_PREFIX + callingClass.getSimpleName(), message);
}

/**
* Logging to use if {@link BaseSettings#DEBUG} or {@link Utils#getContext()} may not be initialized.
* Normally this method should not be used.
*/
public static void initializationException(@NonNull Class<?> callingClass, @NonNull String message,
@Nullable Exception ex) {
Log.e(REVANCED_LOG_PREFIX + callingClass.getSimpleName(), message, ex);
}

}
193 changes: 193 additions & 0 deletions app/src/main/java/app/revanced/integrations/shared/Utils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
package app.revanced.integrations.shared;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
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.preference.Preference;
import android.preference.PreferenceGroup;
import android.preference.PreferenceScreen;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.Toast;
import android.widget.Toolbar;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.text.Bidi;
import java.util.*;
import java.util.regex.Pattern;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class Utils {

@SuppressLint("StaticFieldLeak")
private static Context context;

public static void setContext(Context appContext) {
context = appContext;
}

public static Context getContext() {
return context;
}

/**
* General purpose pool for network calls and other background tasks.
* All tasks run at max thread priority.
*/
private static final ThreadPoolExecutor backgroundThreadPool = new ThreadPoolExecutor(
3, // 3 threads always ready to go
Integer.MAX_VALUE,
10, // For any threads over the minimum, keep them alive 10 seconds after they go idle
TimeUnit.SECONDS,
new SynchronousQueue<>(),
r -> { // ThreadFactory
Thread t = new Thread(r);
t.setPriority(Thread.MAX_PRIORITY); // run at max priority
return t;
});

public static void runOnBackgroundThread(@NonNull Runnable task) {
backgroundThreadPool.execute(task);
}

@NonNull
public static <T> Future<T> submitOnBackgroundThread(@NonNull Callable<T> call) {
return backgroundThreadPool.submit(call);
}


/**
* Safe to call from any thread
*/
public static void showToastShort(@NonNull String messageToToast) {
showToast(messageToToast, Toast.LENGTH_SHORT);
}

/**
* Safe to call from any thread
*/
public static void showToastLong(@NonNull String messageToToast) {
showToast(messageToToast, Toast.LENGTH_LONG);
}

private static void showToast(@NonNull String messageToToast, int toastDuration) {
Objects.requireNonNull(messageToToast);
runOnMainThreadNowOrLater(() -> {
if (context == null) {
Logger.initializationException(Utils.class, "Cannot show toast (context is null): " + messageToToast, null);
} else {
Logger.printDebug(() -> "Showing toast: " + messageToToast);
Toast.makeText(context, messageToToast, toastDuration).show();
}
}
);
}

/**
* Automatically logs any exceptions the runnable throws.
*
* @see #runOnMainThreadNowOrLater(Runnable)
*/
public static void runOnMainThread(@NonNull Runnable runnable) {
runOnMainThreadDelayed(runnable, 0);
}

/**
* Automatically logs any exceptions the runnable throws
*/
public static void runOnMainThreadDelayed(@NonNull Runnable runnable, long delayMillis) {
Runnable loggingRunnable = () -> {
try {
runnable.run();
} catch (Exception ex) {
Logger.printException(() -> runnable.getClass().getSimpleName() + ": " + ex.getMessage(), ex);
}
};
new Handler(Looper.getMainLooper()).postDelayed(loggingRunnable, delayMillis);
}

/**
* If called from the main thread, the code is run immediately.<p>
* If called off the main thread, this is the same as {@link #runOnMainThread(Runnable)}.
*/
public static void runOnMainThreadNowOrLater(@NonNull Runnable runnable) {
if (isCurrentlyOnMainThread()) {
runnable.run();
} else {
runOnMainThread(runnable);
}
}

/**
* @return if the calling thread is on the main thread
*/
public static boolean isCurrentlyOnMainThread() {
return Looper.getMainLooper().isCurrentThread();
}

/**
* @throws IllegalStateException if the calling thread is _off_ the main thread
*/
public static void verifyOnMainThread() throws IllegalStateException {
if (!isCurrentlyOnMainThread()) {
throw new IllegalStateException("Must call _on_ the main thread");
}
}

/**
* @throws IllegalStateException if the calling thread is _on_ the main thread
*/
public static void verifyOffMainThread() throws IllegalStateException {
if (isCurrentlyOnMainThread()) {
throw new IllegalStateException("Must call _off_ the main thread");
}
}


/**
* Hide a view by setting its layout params to 0x0
* @param view The view to hide.
*/
public static void hideViewByLayoutParams(View view) {
if (view instanceof LinearLayout) {
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(0, 0);
view.setLayoutParams(layoutParams);
} else if (view instanceof FrameLayout) {
FrameLayout.LayoutParams layoutParams2 = new FrameLayout.LayoutParams(0, 0);
view.setLayoutParams(layoutParams2);
} else if (view instanceof RelativeLayout) {
RelativeLayout.LayoutParams layoutParams3 = new RelativeLayout.LayoutParams(0, 0);
view.setLayoutParams(layoutParams3);
} else if (view instanceof Toolbar) {
Toolbar.LayoutParams layoutParams4 = new Toolbar.LayoutParams(0, 0);
view.setLayoutParams(layoutParams4);
} else if (view instanceof ViewGroup) {
ViewGroup.LayoutParams layoutParams5 = new ViewGroup.LayoutParams(0, 0);
view.setLayoutParams(layoutParams5);
} else {
ViewGroup.LayoutParams params = view.getLayoutParams();
params.width = 0;
params.height = 0;
view.setLayoutParams(params);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package app.revanced.integrations.shared.settings;

import static java.lang.Boolean.FALSE;
import static java.lang.Boolean.TRUE;

public class BaseSettings {
public static final BooleanSetting DEBUG = new BooleanSetting("revanced_debug", FALSE);
public static final BooleanSetting DEBUG_STACKTRACE = new BooleanSetting("revanced_debug_stacktrace", FALSE/*, parent(DEBUG)*/);
public static final BooleanSetting DEBUG_TOAST_ON_ERROR = new BooleanSetting("revanced_debug_toast_on_error", TRUE, "revanced_debug_toast_on_error_user_dialog_message");
public static final BooleanSetting DEBUG_PROTOBUFFER = new BooleanSetting("revanced_debug_protobuffer", FALSE/*, parent(DEBUG)*/);
}
Loading

0 comments on commit 0158c5b

Please sign in to comment.