2
Arsitektur Repository
Repository ini terbagi menjadi tiga bagian dengan peran yang berbeda. cli/ memuat skrip hiddenjar beserta tool Java yang merakit android.jar kustom; resources-helper/ adalah library Android yang dipublikasikan; sample/ adalah aplikasi contoh yang memakai library tersebut. Gradle hanya mengenal dua bagian terakhir, karena settings.gradle hanya menyertakan :resources-helper dan :sample (settings.gradle:1-91). Direktori cli/ berada di luar model modul Gradle dan dijangkau lewat task Exec di root project (build.gradle:111-1302).
graph TD
SDK["SDK platforms/android-XX/android.jar"] --> BUILDJAR
DEV["emulator atau device via adb"] --> HIDDENJAR
GRADLE["buildHiddenJar / hiddenJarDoctor / restoreHiddenJar"] --> HIDDENJAR
HIDDENJAR["cli/hiddenjar dan cli/hiddenjar.ps1"] --> TOOLS["BuildJar + Stubifier + ClosureVerify"]
TOOLS --> BUILDJAR["BuildJar --base --out"]
BUILDJAR --> JAR["android.jar kustom"]
JAR --> RH["resources-helper"]
RH --> SAMPLE["sample"]
style SDK fill:#336791,color:#fff
style JAR fill:#8b5cf6,color:#fff
style GRADLE fill:#f59e0b,color:#000
style RH fill:#2d7d46,color:#fff
style SAMPLE fill:#2d7d46,color:#fff
%% fig: Peta tiga bagian repository dan ketergantungannya pada android.jar kustom
%% desc: CLI merakit android.jar kustom dari SDK dan device, lalu library resources-helper dan aplikasi sample dibangun di atasnya.Tiga bagian dan perannya
| Bagian | Path | Plugin Gradle | Isi utama |
|---|---|---|---|
| CLI | cli/ | tidak ada, dipanggil lewat task Exec | hiddenjar, hiddenjar.ps1, BuildJar.java, Stubifier.java, ClosureVerify.java |
| Library | resources-helper/ | com.android.library + com.vanniktech.maven.publish | InternalAccessor, ResourcesHolder |
| Aplikasi contoh | sample/ | com.android.application | MainActivity, Receiver, Adapter |
Seluruh plugin dideklarasikan sekali di root build dengan apply false, sehingga versinya dipatok dari satu tempat (build.gradle:3-113). Nilai versinya berasal dari version catalog: agp = "9.2.1", kotlin = "2.3.21", dokka = "2.2.0", vanniktechPublish = "0.37.0" (gradle/libs.versions.toml:1-104). Rincian tiap blok plugins dan android dibahas di Konfigurasi Build Gradle.
Modul library menerapkan plugin com.android.library dan maven.publish, menetapkan group = 'com.anggrayudi' serta namespace = 'com.anggrayudi.hiddenapi' (resources-helper/build.gradle:1-225). Modul aplikasi menerapkan plugin com.android.application dan memakai namespace = 'com.anggrayudi.hiddenapi.sample' (sample/build.gradle:1-66). Aplikasi contoh mendeklarasikan flavorDimensions = ["librarySource"] dengan dua product flavor, local dan maven; flavor local ditandai getIsDefault().set(true) (sample/build.gradle:33-467).
Bagian CLI di luar model modul
Root build menyimpan dua path skrip sebagai ext.hiddenJarBashScript dan ext.hiddenJarPsScript, lalu hiddenJarInvoke memilih powershell saat os.name mengandung windows dan bash pada sistem lain (build.gradle:85-958). Skrip bash menetapkan VERSION="1.0.0", DEX_TOOLS_VERSION="2.4.37", CACHE_DIR="${HOME}/.cache/hiddenjar", serta tiga path sumber tool: STUBIFIER_SRC, CLOSURE_SRC, dan BUILDJAR_SRC (cli/hiddenjar:15-25).
Ketiga tool Java itu bukan dependensi Gradle. Fungsi ensure_java_tools mengompilasinya sekali dengan javac ke ${WORK_DIR}/cli-out dan menyimpan classpath di JAVA_TOOLS_CP (cli/hiddenjar:205-222). Fungsi assemble_jar kemudian menjalankan BuildJar --base ... --out ..., dengan flag opsional --keep-bodies dan --keep-dangling (cli/hiddenjar:227-236). BuildJar merakit jar seluruhnya di memori dan hanya menyalin namespace android/, com/android/internal/, dan dalvik/ dari boot jar device di atas base jar SDK (cli/BuildJar.java:45-489). Alur perintahnya dijelaskan di Panduan CLI hiddenjar dan urutan tahapnya di Pipeline Build hiddenjar; detail perakitan ada di Perakitan Jar: BuildJar dan Stubifier.
Ketergantungan pada android.jar kustom
Saat cmd_build berjalan, base jar diambil dari resolve_platform_dir lalu ditetapkan base_jar="${platform_dir}/android.jar" (cli/hiddenjar:256-264). Keluaran perakitan inilah yang dipasang menggantikan android.jar di SDK, sehingga modul yang dikompilasi melihat simbol hidden API. Pemasangannya dijelaskan di Memasang Custom android.jar ke SDK.
⚠️ Jar kustom hanya membuka jalan pada tahap kompilasi. Pada runtime, Android 9+ (API 28+) tetap menegakkan blocklist non-SDK untuk aplikasi non-system (README.md:99-10010). Batas tersebut dirinci di Batasan Runtime dan Cakupan Hidden API.
Konfigurasi yang dibagi antar modul
Blok subprojects menerapkan setelan yang sama ke setiap modul yang memakai plugin com.android.library atau com.android.application: compileSdkVersion 37, minSdkVersion 23, targetSdkVersion 37, sourceCompatibility/targetCompatibility JavaVersion.VERSION_11, buildConfig = true, dan dependensi libs.kotlin.stdlib.jdk8 (build.gradle:21-6111). Identitas publikasi diambil dari gradle.properties: GROUP=com.anggrayudi, POM_ARTIFACT_ID=android-hidden-api, VERSION_NAME=35.0-SNAPSHOT (gradle.properties:21-2412). Modul library menambahkan androidx.appcompat dan androidx.localbroadcastmanager sebagai implementation (resources-helper/build.gradle:24-3013).
Ketergantungan antar bagian
Satu-satunya ketergantungan antarmodul adalah dari aplikasi contoh ke library: implementation project(':resources-helper') (sample/build.gradle:5714). Bagian CLI tidak menjadi dependensi modul mana pun. Library justru tidak memerlukan android.jar kustom untuk membaca resource internal, karena getResourceId memakai Resources.getSystem().getIdentifier(resName, clas, "android") pada runtime (resources-helper/src/main/java/com/anggrayudi/hiddenapi/InternalAccessor.java:105-11115). Mekanisme itu diuraikan di InternalAccessor: Membaca Resource com.android.internal, sedangkan penyimpanan hasilnya di ResourcesHolder dan Pengiriman via Broadcast.