-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- VideoAds - BackgroundPlayback - RemoveTrackingQueryParameter - HideAds - LithoFilter
- Loading branch information
Showing
20 changed files
with
2,214 additions
and
68 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -51,5 +51,6 @@ android { | |
|
||
dependencies { | ||
implementation(libs.dexkit) | ||
implementation(libs.annotation) | ||
compileOnly(libs.xposed) | ||
} |
157 changes: 157 additions & 0 deletions
157
app/src/main/java/app/revanced/integrations/shared/Logger.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
193
app/src/main/java/app/revanced/integrations/shared/Utils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
app/src/main/java/app/revanced/integrations/shared/settings/BaseSettings.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)*/); | ||
} |
Oops, something went wrong.