A Gradle plugin that improves the experience when developing Android apps, especially system tools, that use hidden APIs.

Related tags

Database android
Overview

HiddenApiRefinePlugin

A Gradle plugin that improves the experience when developing Android apps, especially system tools, that use hidden APIs.

Background

When developing system tools, it's impossible inevitable to use hidden APIs. There are two ways to use hidden APIs, the reflection way and the linking way. For some types of system tools, a large amount of hidden APIs is required, the reflection way is too inconvenient. So the linking way is commonly used in those projects.

In short, the linking way is to create Java-only modules with stub classes and then compileOnly them in the main Android modules. This is the same as what Android SDK's android.jar does.

However the linking way, or "the stub way", have some problems:

  1. "Bridge classes" is required if only some members of the class are hidden.
  2. Kotlin will try to link public classes from the stub module, implementation a second Java-only which compileOnly the stub module can workaround the problem.
  3. Interface implementation will be removed by R8 if the stub module is not compileOnly directly from the main module, however doing this will bring back problem 2.

This plugin is to solve these problems.

What do this plugin do

This plugin uses the Transform API of the Android Gradle Plugin to create a transform that removes specific prefixes from class names. So we can add a special prefix (e.g., '$') to stub classes, and all the problems will be gone and the stub module does not need to be a Java-only module.

The idea is from @Kr328.

Usage

Root project

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'dev.rikka.tools:hidden-api-refine:1.0.0'
    }
}

Module

plugins {
    id('dev.rikka.tools.hidden-api-refine')
}

hiddenApiRefine {
    // Prefix to remove, default is ['$']
    refinePrefix = ['$']
    // Print log, default is true
    log = true
}

Note, the plugin is to remove the prefix of the package name, not the class name. For example, the $ in com.example.$Example will not be removed.

Use "hidden" classes with public classes

Sometimes we need to use "hidden" classes with public classes.

For example, use the hidden android.os.UserHandle#of method to create an instance of UserHandle.

package $android.os;

public class UserHandle {
    public static UserHandle ALL;

    public static UserHandle of(int userId) {
        throw new RuntimeException();
    }
}
$android.os.UserHandle userHandle = $android.os.UserHandle.of(userId);

However, this UserHandle cannot be passed to other public APIs that accepts UserHandle. This is because this UserHandle is actually $android.os.UserHandle rather than android.os.UserHandle.

This can be simply solved with this "trick".

public class Unsafe {
    @SuppressWarnings("unchecked")
    public static <T> T unsafeCast(Object object) {
        return (T) object;
    }
}
UserHandle userHandle = Unsafe.unsafeCast($android.os.UserHandle.of(userId));

After R8, this "cast" will be "removed" or "inlined". This line will be identical to a normal method call.

UserHandle userHandle = android.os.UserHandle.of(userId);
Comments
  • [Ask for help]ApplicationPackageManager cannot be cast to android.view.SurfaceControl

    [Ask for help]ApplicationPackageManager cannot be cast to android.view.SurfaceControl

    I want to call a hidden api in android.view.SurfaceControl. So I call this in my app module.

    Refine.unsafeCast<SurfaceControlHidden>(context.packageManager).internalDisplayToken
    

    And my "hidden-api" module is like

    package android.view;
    
    import dev.rikka.tools.refine.RefineAs;
    
    @RefineAs(SurfaceControl.class)
    public class SurfaceControlHidden {
    
        private native long[] nativeGetPhysicalDisplayIds();
        private native IBinder nativeGetPhysicalDisplayToken(long physicalDisplayId);
    
        public long[] getPhysicalDisplayIds() {
            return nativeGetPhysicalDisplayIds();
        }
    
        public IBinder getPhysicalDisplayToken(long physicalDisplayId) {
            return nativeGetPhysicalDisplayToken(physicalDisplayId);
        }
    
        public IBinder getInternalDisplayToken() {
            final long[] physicalDisplayIds = getPhysicalDisplayIds();
            if (physicalDisplayIds.length == 0) {
                return null;
            }
            return getPhysicalDisplayToken(physicalDisplayIds[0]);
        }
    
    }
    

    But when the app actually call the hidden api, it causes

    java.lang.ClassCastException: android.app.ApplicationPackageManager cannot be cast to android.view.SurfaceControl
    

    Did I make a mistake somewhere? Please help point it out. Thank you very much.

    opened by Moderpach 6
  • Handle duplicate entries

    Handle duplicate entries

    > Task :app:transformClassesWithHiddenApiRefineForDebug FAILED
    java.util.zip.ZipException: duplicate entry: org/bouncycastle/jcajce/provider/asymmetric/edec/KeyFactorySpi$X448.class
    	at java.util.zip.ZipOutputStream.putNextEntry(ZipOutputStream.java:232)
    	at java.util.jar.JarOutputStream.putNextEntry(JarOutputStream.java:109)
    	at dev.rikka.tools.HiddenApiRefineTransform.doTransform(HiddenApiRefineTransform.java:104)
    	at dev.rikka.tools.HiddenApiRefineTransform.transform(HiddenApiRefineTransform.java:186)
    	at com.android.build.gradle.internal.pipeline.TransformTask$2.call(TransformTask.java:281)
    	at com.android.build.gradle.internal.pipeline.TransformTask$2.call(TransformTask.java:244)
    	at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:106)
    	at com.android.build.gradle.internal.pipeline.TransformTask.transform(TransformTask.java:239)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.lang.reflect.Method.invoke(Method.java:498)
    	at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:104)
    	at org.gradle.api.internal.project.taskfactory.IncrementalTaskInputsTaskAction.doExecute(IncrementalTaskInputsTaskAction.java:47)
    	at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:51)
    	at org.gradle.api.internal.project.taskfactory.AbstractIncrementalTaskAction.execute(AbstractIncrementalTaskAction.java:25)
    	at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:29)
    	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$3.run(ExecuteActionsTaskExecuter.java:555)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:56)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$run$1(DefaultBuildOperationExecutor.java:71)
    	at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.runWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:45)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:71)
    	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:540)
    	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:523)
    	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.access$300(ExecuteActionsTaskExecuter.java:108)
    	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution.executeWithPreviousOutputFiles(ExecuteActionsTaskExecuter.java:271)
    	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution.execute(ExecuteActionsTaskExecuter.java:260)
    	at org.gradle.internal.execution.steps.ExecuteStep.lambda$execute$0(ExecuteStep.java:33)
    	at java.util.Optional.map(Optional.java:215)
    	at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:33)
    	at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:26)
    	at org.gradle.internal.execution.steps.CleanupOutputsStep.execute(CleanupOutputsStep.java:67)
    	at org.gradle.internal.execution.steps.CleanupOutputsStep.execute(CleanupOutputsStep.java:36)
    	at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:49)
    	at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:34)
    	at org.gradle.internal.execution.steps.CancelExecutionStep.execute(CancelExecutionStep.java:43)
    	at org.gradle.internal.execution.steps.TimeoutStep.executeWithoutTimeout(TimeoutStep.java:73)
    	at org.gradle.internal.execution.steps.TimeoutStep.execute(TimeoutStep.java:54)
    	at org.gradle.internal.execution.steps.CreateOutputsStep.execute(CreateOutputsStep.java:44)
    	at org.gradle.internal.execution.steps.SnapshotOutputsStep.execute(SnapshotOutputsStep.java:54)
    	at org.gradle.internal.execution.steps.SnapshotOutputsStep.execute(SnapshotOutputsStep.java:38)
    	at org.gradle.internal.execution.steps.BroadcastChangingOutputsStep.execute(BroadcastChangingOutputsStep.java:42)
    	at org.gradle.internal.execution.steps.CacheStep.executeWithoutCache(CacheStep.java:159)
    	at org.gradle.internal.execution.steps.CacheStep.execute(CacheStep.java:72)
    	at org.gradle.internal.execution.steps.CacheStep.execute(CacheStep.java:43)
    	at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:44)
    	at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:33)
    	at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:38)
    	at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:24)
    	at org.gradle.internal.execution.steps.SkipUpToDateStep.executeBecause(SkipUpToDateStep.java:92)
    	at org.gradle.internal.execution.steps.SkipUpToDateStep.lambda$execute$0(SkipUpToDateStep.java:85)
    	at java.util.Optional.map(Optional.java:215)
    	at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:55)
    	at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:39)
    	at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:76)
    	at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:37)
    	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:36)
    	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:26)
    	at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:94)
    	at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:49)
    	at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:79)
    	at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:53)
    	at org.gradle.internal.execution.steps.ValidateStep.execute(ValidateStep.java:74)
    	at org.gradle.internal.execution.steps.SkipEmptyWorkStep.lambda$execute$2(SkipEmptyWorkStep.java:78)
    	at java.util.Optional.orElseGet(Optional.java:267)
    	at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:78)
    	at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:34)
    	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsStartedStep.execute(MarkSnapshottingInputsStartedStep.java:39)
    	at org.gradle.internal.execution.steps.LoadExecutionStateStep.execute(LoadExecutionStateStep.java:40)
    	at org.gradle.internal.execution.steps.LoadExecutionStateStep.execute(LoadExecutionStateStep.java:28)
    	at org.gradle.internal.execution.impl.DefaultWorkExecutor.execute(DefaultWorkExecutor.java:33)
    	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:187)
    	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:179)
    	at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:109)
    	at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
    	at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:62)
    	at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
    	at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:56)
    	at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
    	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77)
    	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
    	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:200)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:195)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
    	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:62)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$call$2(DefaultBuildOperationExecutor.java:76)
    	at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.callWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:54)
    	at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:76)
    	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
    	at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:41)
    	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:372)
    	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:359)
    	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:352)
    	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:338)
    	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.lambda$run$0(DefaultPlanExecutor.java:127)
    	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:191)
    	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.executeNextNode(DefaultPlanExecutor.java:182)
    	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:124)
    	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
    	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
    	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
    	at java.lang.Thread.run(Thread.java:748)
    
    Execution failed for task ':app:transformClassesWithHiddenApiRefineForDebug'.
    > java.util.zip.ZipException: duplicate entry: org/bouncycastle/jcajce/provider/asymmetric/edec/KeyFactorySpi$X448.class
    
    help wanted 
    opened by MuntashirAkon 3
  • Feature: use annotation processor

    Feature: use annotation processor

    新变化

    对于 hidden api 模块

    dependencies {
        annotationProcessor("dev.rikka.tools.refine:annotation-processor:3.0.0") // or kapt
    
        compileOnly("dev.rikka.tools.refine:annotation:3.0.0")
    }
    

    对于使用 hidden api 的模块

    plugins {
        id("dev.rikka.tools.refine.gradle-plugin")
    }
    
    dependencies {
        implementation("dev.rikka.tools.refine:runtime:3.0.0") // optional
    }
    

    使用

    @RefineAs(PackageManager.class)
    public class PackageManagerHidden {
        public interface OnPermissionsChangedListener {
            void onPermissionsChanged(int uid);
        }
    
        public void addOnPermissionsChangeListener(OnPermissionsChangedListener listener) {}
        public void removeOnPermissionsChangeListener(OnPermissionsChangedListener listener) {}
    }
    
    opened by Kr328 0
  • Use annotation instead of hardcode prefix

    Use annotation instead of hardcode prefix

    用法

    导入 annotation 到 hideapi 子项目

    dependencies {
        implementation("dev.rikka.tools.refine:annotation:2.0.0")
    }
    

    为隐藏 API 标记需要重定义的目标类

    package android.app;
    
    import dev.rikka.tools.refine.RefineAs;
    import utils.Utils;
    
    @RefineAs(ActivityManager.class) // 将 ActivityManagerHidden 定义为 ActivityManager
    public class ActivityManagerHidden {
        public void forceStopPackageAsUser(String packageName, int userId) {
            Utils.throwStub();
        }
    }
    

    导入 gradle 插件

    buildscript {
        dependencies {
            classpath("dev.rikka.tools.refine:gradle-plugin:2.0.0")
        }
    }
    

    应用插件

    plugins {
        id("dev.rikka.tools.refine.gradle-plugin")
    }
    

    使用与原方法一致

    fun ActivityManager.forceStopPackageAsUser(packageName: String, userId: Int) {
        this.unsafeCast<ActivityManagerHidden>().forceStopPackageAsUser(packageName, userId)
    }
    
    opened by Kr328 0
  • AGP 8.0 isn't supported: Stop using Transform API

    AGP 8.0 isn't supported: Stop using Transform API

    As seen in https://github.com/RikkaApps/HiddenApiRefinePlugin/issues/14#issuecomment-1334663554:

    WARNING:API 'android.registerTransform' is obsolete.
    It will be removed in version 8.0 of the Android Gradle plugin.
    The Transform API is removed to improve build performance. Projects that use the
    Transform API force the Android Gradle plugin to use a less optimized flow for the
    build that can result in large regressions in build times. It’s also difficult to
    use the Transform API and combine it with other Gradle features; the replacement
    APIs aim to make it easier to extend the build without introducing performance or
    correctness issues.
    
    There is no single replacement for the Transform API—there are new, targeted
    APIs for each use case. All the replacement APIs are in the
    `androidComponents {}` block.
    
    The Transform API uses incremental APIs deprecated since Gradle 7.5. Please add
    `android.experimental.legacyTransform.forceNonIncremental=true` to
    `gradle.properties` to fix this issue. Note that this will run transforms
    non-incrementally and may have a build performance impact.
    For more information, see https://developer.android.com/studio/releases/gradle-plugin-api-updates#transform-api.
    To determine what is calling android.registerTransform, use -Pandroid.debug.obsoleteApi=true on the command line to display more information.
    
    opened by bddckr 0
  • [FR] Make annotation processor incremental

    [FR] Make annotation processor incremental

    When running assembleDebug, I'm getting the following warning:

    > Task :hidden-apis:kaptDebugKotlin [WARN] Incremental annotation processing requested, but support is disabled because the following processors are not incremental: dev.rikka.tools.refine.RefineProcessor (DYNAMIC).

    opened by bddckr 0
  • Needs to build two time if a new package directory is added

    Needs to build two time if a new package directory is added

    Steps to reproduce

    1. In an already existing project, add a new package from New > Package in IntelliJ/Android Studio
    2. Run ./gradlew assembleDebug (or ./gradlew assembleRelease)
    3. Get the error below. (Running the above command second time works)
    > Task :app:transformClassesWithHiddenApiRefineForRelease FAILED
    java.io.FileNotFoundException: /Users/muntashir/Documents/Projects/AppManager/app/build/intermediates/javac/release/classes/io/github/muntashirakon/AppManager/docs (Is a directory)
            at java.base/java.io.FileInputStream.open0(Native Method)
            at java.base/java.io.FileInputStream.open(FileInputStream.java:212)
            at java.base/java.io.FileInputStream.<init>(FileInputStream.java:154)
            at dev.rikka.tools.refine.RefineTransform.doTransform(RefineTransform.java:207)
            at dev.rikka.tools.refine.RefineTransform.transform(RefineTransform.java:224)
            at com.android.build.gradle.internal.pipeline.TransformTask$2.call(TransformTask.java:284)
            at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:69)
            at com.android.build.gradle.internal.profile.AnalyticsResourceManager.recordBlockAtExecution(AnalyticsResourceManager.kt:226)
            at com.android.build.gradle.internal.profile.AnalyticsService.recordBlock(AnalyticsService.kt:151)
            at com.android.build.gradle.internal.pipeline.TransformTask.transform(TransformTask.java:242)
            at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
            at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            at java.base/java.lang.reflect.Method.invoke(Method.java:564)
            at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:104)
            at org.gradle.api.internal.project.taskfactory.IncrementalTaskInputsTaskAction.doExecute(IncrementalTaskInputsTaskAction.java:47)
            at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:51)
            at org.gradle.api.internal.project.taskfactory.AbstractIncrementalTaskAction.execute(AbstractIncrementalTaskAction.java:25)
            at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:29)
            at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$2.run(ExecuteActionsTaskExecuter.java:506)
            at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
            at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
            at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
            at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
            at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
            at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
            at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:56)
            at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$run$1(DefaultBuildOperationExecutor.java:74)
            at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.runWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:45)
            at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:74)
            at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:491)
            at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:474)
            at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.access$300(ExecuteActionsTaskExecuter.java:106)
            at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution.executeWithPreviousOutputFiles(ExecuteActionsTaskExecuter.java:271)
            at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution.execute(ExecuteActionsTaskExecuter.java:249)
            at org.gradle.internal.execution.steps.ExecuteStep.executeInternal(ExecuteStep.java:83)
            at org.gradle.internal.execution.steps.ExecuteStep.access$000(ExecuteStep.java:37)
            at org.gradle.internal.execution.steps.ExecuteStep$1.call(ExecuteStep.java:50)
            at org.gradle.internal.execution.steps.ExecuteStep$1.call(ExecuteStep.java:47)
            at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:200)
            at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:195)
            at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
            at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
            at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
            at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
            at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:62)
            at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$call$2(DefaultBuildOperationExecutor.java:79)
            at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.callWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:54)
            at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:79)
            at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:47)
            at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:37)
            at org.gradle.internal.execution.steps.RemovePreviousOutputsStep.execute(RemovePreviousOutputsStep.java:68)
            at org.gradle.internal.execution.steps.RemovePreviousOutputsStep.execute(RemovePreviousOutputsStep.java:38)
            at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:50)
            at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:36)
            at org.gradle.internal.execution.steps.CancelExecutionStep.execute(CancelExecutionStep.java:41)
            at org.gradle.internal.execution.steps.TimeoutStep.executeWithoutTimeout(TimeoutStep.java:74)
            at org.gradle.internal.execution.steps.TimeoutStep.execute(TimeoutStep.java:55)
            at org.gradle.internal.execution.steps.CreateOutputsStep.execute(CreateOutputsStep.java:51)
            at org.gradle.internal.execution.steps.CreateOutputsStep.execute(CreateOutputsStep.java:29)
            at org.gradle.internal.execution.steps.CaptureStateAfterExecutionStep.execute(CaptureStateAfterExecutionStep.java:54)
            at org.gradle.internal.execution.steps.CaptureStateAfterExecutionStep.execute(CaptureStateAfterExecutionStep.java:35)
            at org.gradle.internal.execution.steps.BroadcastChangingOutputsStep.execute(BroadcastChangingOutputsStep.java:60)
            at org.gradle.internal.execution.steps.BroadcastChangingOutputsStep.execute(BroadcastChangingOutputsStep.java:27)
            at org.gradle.internal.execution.steps.BuildCacheStep.executeWithoutCache(BuildCacheStep.java:174)
            at org.gradle.internal.execution.steps.BuildCacheStep.execute(BuildCacheStep.java:74)
            at org.gradle.internal.execution.steps.BuildCacheStep.execute(BuildCacheStep.java:45)
            at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:40)
            at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:29)
            at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:36)
            at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:22)
            at org.gradle.internal.execution.steps.SkipUpToDateStep.executeBecause(SkipUpToDateStep.java:99)
            at org.gradle.internal.execution.steps.SkipUpToDateStep.lambda$execute$0(SkipUpToDateStep.java:92)
            at java.base/java.util.Optional.map(Optional.java:258)
            at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:52)
            at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:36)
            at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:85)
            at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:42)
            at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:37)
            at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:27)
            at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:91)
            at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:49)
            at org.gradle.internal.execution.steps.ValidateStep.execute(ValidateStep.java:106)
            at org.gradle.internal.execution.steps.ValidateStep.execute(ValidateStep.java:51)
            at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:72)
            at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:46)
            at org.gradle.internal.execution.steps.SkipEmptyWorkStep.lambda$execute$2(SkipEmptyWorkStep.java:86)
            at java.base/java.util.Optional.orElseGet(Optional.java:362)
            at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:86)
            at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:32)
            at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsStartedStep.execute(MarkSnapshottingInputsStartedStep.java:38)
            at org.gradle.internal.execution.steps.LoadExecutionStateStep.execute(LoadExecutionStateStep.java:43)
            at org.gradle.internal.execution.steps.LoadExecutionStateStep.execute(LoadExecutionStateStep.java:31)
            at org.gradle.internal.execution.steps.AssignWorkspaceStep.lambda$execute$0(AssignWorkspaceStep.java:40)
            at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution$2.withWorkspace(ExecuteActionsTaskExecuter.java:284)
            at org.gradle.internal.execution.steps.AssignWorkspaceStep.execute(AssignWorkspaceStep.java:40)
            at org.gradle.internal.execution.steps.AssignWorkspaceStep.execute(AssignWorkspaceStep.java:30)
            at org.gradle.internal.execution.steps.IdentityCacheStep.execute(IdentityCacheStep.java:37)
            at org.gradle.internal.execution.steps.IdentityCacheStep.execute(IdentityCacheStep.java:27)
            at org.gradle.internal.execution.steps.IdentifyStep.execute(IdentifyStep.java:44)
            at org.gradle.internal.execution.steps.IdentifyStep.execute(IdentifyStep.java:33)
            at org.gradle.internal.execution.impl.DefaultExecutionEngine$1.execute(DefaultExecutionEngine.java:76)
            at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:185)
            at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:174)
            at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:109)
            at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
            at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:51)
            at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
            at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:56)
            at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
            at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77)
            at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
            at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
            at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:200)
            at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:195)
            at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
            at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
            at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
            at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
            at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:62)
            at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$call$2(DefaultBuildOperationExecutor.java:79)
            at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.callWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:54)
            at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:79)
            at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
            at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:74)
            at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:408)
            at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:395)
            at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:388)
            at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:374)
            at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.lambda$run$0(DefaultPlanExecutor.java:127)
            at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:191)
            at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.executeNextNode(DefaultPlanExecutor.java:182)
            at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:124)
            at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
            at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
            at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
            at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
            at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
            at java.base/java.lang.Thread.run(Thread.java:832)
    
    opened by MuntashirAkon 2
  • [FR] Support Gradle's configuration cache

    [FR] Support Gradle's configuration cache

    https://docs.gradle.org/7.4/userguide/configuration_cache.html

    * What went wrong:
    Configuration cache state could not be cached: input property '$3' of ':app:transformClassesWithHiddenApiRefineForRelease': error writing value of type 'org.gradle.api.internal.file.FilteredFileTree'
    > Querying the mapped value of provider(interface java.util.Set) before task ':app:compileReleaseKotlin' has completed is not supported
    
    Could not create task ':app::app:transformClassesWithHiddenApiRefineForDebug'.
    > The task name ':app:transformClassesWithHiddenApiRefineForDebug' must not contain any of the following characters: [/, \, :, <, >, ", ?, *, |].
    
    help wanted 
    opened by zhaobozhen 1
  • [BUG] Subclasses of the hidden class are not renamed

    [BUG] Subclasses of the hidden class are not renamed

    NOTE: This could be a documentation issue.

    Consider the following example:

    AppOpsManagerHidden.java

    @RefineAs(AppOpsManager.class)
    public class AppOpsManagerHidden {
        public static class PackageOps implements Parcelable {
            @NonNull
            public String getPackageName() {
                throw new UnsupportedOperationException();
            }
    
            public int getUid() {
                throw new UnsupportedOperationException();
            }
    
            @NonNull
            public List<Parcelable> getOps() {
                throw new UnsupportedOperationException();
            }
        }
    
        public static class OpEntry implements Parcelable {
            public int getOp() {
                throw new UnsupportedOperationException();
            }
    
            public int getMode() {
                throw new UnsupportedOperationException();
            }
        }
    }
    

    TestClass.java

    public class TestClass {
        // Corresponding class file still has AppOpsManagerHidden.PackageOps signature instead of AppOpsManager.PackageOps
        AppOpsManagerHidden.PackageOps packageOps;
    
        public TestClass(Parcelable obj) {
            this.packageOps = Refine.unsafeCast(obj);
        }
    }
    

    According to the documentation, this should've worked.

    WORKAROUND

    There's a workaround: Annotating AppOpsManagerHidden.PackageOps (with @Refine(AppOpsManager.PackageOps.class)) and AppOpsManagerHidden.OpEntry (with @Refine(AppOpsManager.OpEntry.class)) fixes the issue.

    help wanted 
    opened by MuntashirAkon 4
Releases(v3.0.3)
Owner
Rikka apps
Rikka apps
SceneView is a 3D/AR Android View with ARCore and Google Filament. This is the newest way to make your Android 3D/AR app.

SceneView is a 3D/AR Android View with ARCore and Google Filament This is Sceneform replacement Features Use SceneView for 3D only or ArSceneView for

SceneView Open Community 235 Jan 4, 2023
MapDB provides concurrent Maps, Sets and Queues backed by disk storage or off-heap-memory. It is a fast and easy to use embedded Java database engine.

MapDB: database engine MapDB combines embedded database engine and Java collections. It is free under Apache 2 license. MapDB is flexible and can be u

Jan Kotek 4.6k Dec 30, 2022
MapDB provides concurrent Maps, Sets and Queues backed by disk storage or off-heap-memory. It is a fast and easy to use embedded Java database engine.

MapDB: database engine MapDB combines embedded database engine and Java collections. It is free under Apache 2 license. MapDB is flexible and can be u

Jan Kotek 4.6k Jan 1, 2023
A tool based on mysql-connector to simplify the use of databases, tables & columns

Description A tool based on mysql-connector to simplify the use of databases, tables & columns. This tool automatically creates the databases & tables

nz 6 Nov 17, 2022
Easy-es - easy use for elastich search

Born To Simplify Development What is Easy-Es? Easy-Es is a powerfully enhanced toolkit of RestHighLevelClient for simplify development. This toolkit p

null 777 Jan 6, 2023
BenDB - An fastest, qualified & easy to use multi database library

BenDB - An fastest, qualified & easy to use multi database library

Fitchle 2 May 3, 2022
A simple-to-use storage ORM supporting several databases for Java.

Storage Handler This is a library based off of my old storage handler within my queue revamp. It's for easy storage handling for multiple platforms. N

NV6 7 Jun 22, 2022
A Java library designed to make making decisions based on the current operating system easier.

Java OS Independence ...or JOSI for short, is a simple and lightweight Java library designed to make making decisions based on the current operating s

null 38 Dec 30, 2022
IoTDB (Internet of Things Database) is a data management system for time series data

English | 中文 IoTDB Overview IoTDB (Internet of Things Database) is a data management system for time series data, which can provide users specific ser

The Apache Software Foundation 3k Jan 1, 2023
Student Result Management System - This is a CLI based software where the Software is capable of maintaining and generating Student's Result at the end of a semester after the teacher's have provided the respective marks.

Student Result Management System This is a CLI based software where the Software is capable of maintaining and generating Student's Result at the end

Abir Bhattacharya 3 Aug 27, 2022
The Prometheus monitoring system and time series database.

Prometheus Visit prometheus.io for the full documentation, examples and guides. Prometheus, a Cloud Native Computing Foundation project, is a systems

Prometheus 46.3k Jan 10, 2023
A simple Database management system

总览 在开始 simpledb 旅途之前, 我们先从整体上来看看 SimpleDb 是一个 DBMS 数据库管理系统, 包含存储, 算子, 优化, 事务, 索引 等, 全方位介绍了如何从0实现一个 DBMS, 可以说, 这门课是学习 TIDB 等其他分布式数据库的前提.

null 66 Dec 28, 2022
Online Quiz system - JDBC, JSP

Online-Quiz-System-in-Java Online Quiz system - JDBC, JSP Java Project based on JDBC, JSP, Java Servlet and Server Deployment Project Aim Develop web

Muhammad Asad 6 Oct 14, 2022
requery - modern SQL based query & persistence for Java / Kotlin / Android

A light but powerful object mapping and SQL generator for Java/Kotlin/Android with RxJava and Java 8 support. Easily map to or create databases, perfo

requery 3.1k Jan 5, 2023
A RatingBar library for android, you can customize size, spacing, color and image easily, and support right to left.

AndRatingBar A RatingBar library for android, you can customize size, spacing, color and image easily, and support right to left. 安卓RatingBar终极方案,继承自原

dqq 271 Aug 14, 2021
The application is a PoC that helps in identifying modern bankers, potentially malicious and remote controlling applications abusing Android AccessibilityService.

Motivation Project aims to help in: identifying keyloggers and events hijacking malicious applications such as Anubis/TeaBot, identifying a "fake bank

Krzysztof Pranczk 33 Dec 9, 2022
Sample Android App for WebRTC with Firebase as backend

Android WebRTC Firebase Simple Demo App for Android WebRTC video call using Firebase Realtime Database as Signalling server. Prerequisites Firebase Ac

Devesh Chaudhari 19 Dec 17, 2022
Realtime SOS Android Application. Location (GPS + Cellular Network) tracing application by alerting guardians of the User.

WomenSaftey Women Safety Android Application: Realtime SOS Android Application. Designed a Location (GPS + Cellular Network) tracing application by al

jatin kasera 6 Nov 19, 2022