Replacing Xposed with a Gradle Plugin for Automated Android Privacy Checks

This article compares the traditional Xposed‑based dynamic privacy checker with a new Gradle‑plugin instrumentation approach, explains the design and implementation of the Transform API‑driven solution, shows performance metrics, provides usage instructions, and outlines automated testing and future improvements for Android apps.

Sohu Tech Products
Sohu Tech Products
Sohu Tech Products
Replacing Xposed with a Gradle Plugin for Automated Android Privacy Checks

Background

Privacy protection is critical in mobile app development. The original solution relied on the Xposed framework to intercept method calls at runtime, but it required specific phone models, complex installation steps, and could not be integrated into automated test pipelines.

Comparison of Two Solutions

2.1 Xposed Implementation

High device‑model dependency; only works on phones that support Xposed.

Complex setup involving multiple apps and configurations.

Incompatible with automated testing environments.

2.2 Instrumentation (Gradle Plugin) Implementation

Device‑agnostic; works on any Android phone.

Simple integration—no extra software installation required.

Can be incorporated into CI/CD pipelines for automated testing.

Solution Implementation

3.1 Overview

The new approach uses the Gradle TransformApi to scan all class files, locate privacy‑related methods with the ASM library, and inject code that records stack traces. When the user consents to the privacy policy, the collected data is written to a result.json file for further analysis.

3.2 Design Details

The implementation consists of two modules: gradle_plugin: a custom Gradle plugin that processes class files during the build. privacy_check: defines the code to be injected.

Key classes include:

PrivacyPlugin : registers the PrivacyClassVisitorFactory for each variant.

val androidComponents = project.extensions.getByType(ApplicationAndroidComponentsExtension::class.java)
val extension = project.extensions.create("privacyCheck", PrivacyExtension::class.java)
androidComponents.onVariants { variant ->
    if (!extension.enable) {
        println("privacyCheck disable")
        return@onVariants
    }
    variant.instrumentation.transformClassesWith(
        PrivacyClassVisitorFactory::class.java,
        InstrumentationScope.ALL
    ) {}
    variant.instrumentation.setAsmFramesComputationMode(FramesComputationMode.COMPUTE_FRAMES_FOR_INSTRUMENTED_METHODS)
}

PrivacyClassVisitorFactory : extends AsmClassVisitorFactory, creates a PrivacyClassVisitor for each class and skips irrelevant classes.

override fun createClassVisitor(classContext: ClassContext, nextClassVisitor: ClassVisitor): ClassVisitor {
    return PrivacyClassVisotor(instrumentationContext.apiVersion.get(), nextClassVisitor)
}
override fun isInstrumentable(classData: ClassData): Boolean {
    return !PrivacyPluginUtil.ignoreClass(classData.className)
}

PrivacyClassVisitor : visits each method, uses PrivacyMethodVisitor (which extends ASM AdviceAdapter) to insert calls to PrivacyCollectUtil.appendData whenever a privacy method is detected.

override fun visitMethodInsn(opcodeAndSource: Int, owner: String?, nameInsn: String?, descriptor: String?, isInterface: Boolean) {
    privacyMethodList.forEach { classMethod ->
        if (owner == classMethod.className && nameInsn == classMethod.methodName) {
            mv.visitLdcInsn("${className}#${name}")
            mv.visitLdcInsn("${owner.replace("/", ".")}#${nameInsn}")
            mv.visitMethodInsn(INVOKESTATIC, "com/xx/privacycheck/PrivacyCollectUtil", "appendData",
                "(Ljava/lang/String;Ljava/lang/String;)V", false)
        }
    }
    super.visitMethodInsn(opcodeAndSource, owner, nameInsn, descriptor, isInterface)
}

3.3 Plugin Performance

Using the plugin, a full compilation of the sample project takes about 5 seconds. After modifying a single class and layout, incremental compilation drops to 2.2 seconds, demonstrating the low overhead of the instrumentation.

Full compile time chart
Full compile time chart
Incremental compile time chart
Incremental compile time chart

Plugin Usage

To enable the plugin, add the following to app/build.gradle.kts and set enable = true. The plugin should only be activated in test builds to avoid affecting end‑users.

plugins {
    id("com.xx.privacycheck")
}
android {
    privacyCheck {
        enable = true
    }
}

During runtime, the privacy check runs only in debug builds:

if (BuildConfig.DEBUG) {
    PrivacyCollectUtil.stopCollect(this@PreProcessingActivity)
}

Automated Testing

A Python script using uiautomator2 drives the device: it installs the APK, clicks the consent button, and extracts the generated JSON file. The script also uploads the data to the APM backend for further analysis.

if __name__ == '__main__':
    # parse arguments, install APK, start check, load JSON
    installApk()
    startCheck()
    loadJson()

Result Processing

By examining the stack traces in the JSON output, developers can locate privacy‑method calls and move them behind the user‑consent point, reducing unnecessary access before permission is granted.

Conclusion and Outlook

The presented Gradle‑plugin solution provides a flexible, device‑independent way to perform dynamic privacy checks, outperforming the previous Xposed method in compatibility and extensibility. Future work includes adding a whitelist to skip certain modules, further speeding up instrumentation, and expanding support for additional privacy‑related APIs.

Future improvements diagram
Future improvements diagram
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

InstrumentationAndroidprivacyGradle PluginASMDynamic analysis
Sohu Tech Products
Written by

Sohu Tech Products

A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.