Initial import of Brizzi HCE project
This commit is contained in:
BIN
.gradle/9.0.0/checksums/checksums.lock
Normal file
BIN
.gradle/9.0.0/checksums/checksums.lock
Normal file
Binary file not shown.
BIN
.gradle/9.0.0/checksums/md5-checksums.bin
Normal file
BIN
.gradle/9.0.0/checksums/md5-checksums.bin
Normal file
Binary file not shown.
BIN
.gradle/9.0.0/checksums/sha1-checksums.bin
Normal file
BIN
.gradle/9.0.0/checksums/sha1-checksums.bin
Normal file
Binary file not shown.
BIN
.gradle/9.0.0/executionHistory/executionHistory.bin
Normal file
BIN
.gradle/9.0.0/executionHistory/executionHistory.bin
Normal file
Binary file not shown.
BIN
.gradle/9.0.0/executionHistory/executionHistory.lock
Normal file
BIN
.gradle/9.0.0/executionHistory/executionHistory.lock
Normal file
Binary file not shown.
BIN
.gradle/9.0.0/fileChanges/last-build.bin
Normal file
BIN
.gradle/9.0.0/fileChanges/last-build.bin
Normal file
Binary file not shown.
BIN
.gradle/9.0.0/fileHashes/fileHashes.bin
Normal file
BIN
.gradle/9.0.0/fileHashes/fileHashes.bin
Normal file
Binary file not shown.
BIN
.gradle/9.0.0/fileHashes/fileHashes.lock
Normal file
BIN
.gradle/9.0.0/fileHashes/fileHashes.lock
Normal file
Binary file not shown.
BIN
.gradle/9.0.0/fileHashes/resourceHashesCache.bin
Normal file
BIN
.gradle/9.0.0/fileHashes/resourceHashesCache.bin
Normal file
Binary file not shown.
0
.gradle/9.0.0/gc.properties
Normal file
0
.gradle/9.0.0/gc.properties
Normal file
BIN
.gradle/9.5.0/checksums/checksums.lock
Normal file
BIN
.gradle/9.5.0/checksums/checksums.lock
Normal file
Binary file not shown.
BIN
.gradle/9.5.0/checksums/md5-checksums.bin
Normal file
BIN
.gradle/9.5.0/checksums/md5-checksums.bin
Normal file
Binary file not shown.
BIN
.gradle/9.5.0/checksums/sha1-checksums.bin
Normal file
BIN
.gradle/9.5.0/checksums/sha1-checksums.bin
Normal file
Binary file not shown.
BIN
.gradle/9.5.0/executionHistory/executionHistory.bin
Normal file
BIN
.gradle/9.5.0/executionHistory/executionHistory.bin
Normal file
Binary file not shown.
BIN
.gradle/9.5.0/executionHistory/executionHistory.lock
Normal file
BIN
.gradle/9.5.0/executionHistory/executionHistory.lock
Normal file
Binary file not shown.
BIN
.gradle/9.5.0/fileChanges/last-build.bin
Normal file
BIN
.gradle/9.5.0/fileChanges/last-build.bin
Normal file
Binary file not shown.
BIN
.gradle/9.5.0/fileHashes/fileHashes.bin
Normal file
BIN
.gradle/9.5.0/fileHashes/fileHashes.bin
Normal file
Binary file not shown.
BIN
.gradle/9.5.0/fileHashes/fileHashes.lock
Normal file
BIN
.gradle/9.5.0/fileHashes/fileHashes.lock
Normal file
Binary file not shown.
BIN
.gradle/9.5.0/fileHashes/resourceHashesCache.bin
Normal file
BIN
.gradle/9.5.0/fileHashes/resourceHashesCache.bin
Normal file
Binary file not shown.
0
.gradle/9.5.0/gc.properties
Normal file
0
.gradle/9.5.0/gc.properties
Normal file
Binary file not shown.
BIN
.gradle/buildOutputCleanup/buildOutputCleanup.lock
Normal file
BIN
.gradle/buildOutputCleanup/buildOutputCleanup.lock
Normal file
Binary file not shown.
2
.gradle/buildOutputCleanup/cache.properties
Normal file
2
.gradle/buildOutputCleanup/cache.properties
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#Sat May 02 10:25:41 WIB 2026
|
||||||
|
gradle.version=9.0.0
|
||||||
BIN
.gradle/buildOutputCleanup/outputFiles.bin
Normal file
BIN
.gradle/buildOutputCleanup/outputFiles.bin
Normal file
Binary file not shown.
2
.gradle/config.properties
Normal file
2
.gradle/config.properties
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#Sat May 02 10:14:21 WIB 2026
|
||||||
|
java.home=/Applications/Android Studio.app/Contents/jbr/Contents/Home
|
||||||
BIN
.gradle/file-system.probe
Normal file
BIN
.gradle/file-system.probe
Normal file
Binary file not shown.
0
.gradle/vcs-1/gc.properties
Normal file
0
.gradle/vcs-1/gc.properties
Normal file
3
.idea/.gitignore
generated
vendored
Normal file
3
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
6
.idea/AndroidProjectSystem.xml
generated
Normal file
6
.idea/AndroidProjectSystem.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="AndroidProjectSystem">
|
||||||
|
<option name="providerId" value="com.android.tools.idea.GradleProjectSystem" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
1724
.idea/caches/deviceStreaming.xml
generated
Normal file
1724
.idea/caches/deviceStreaming.xml
generated
Normal file
File diff suppressed because it is too large
Load Diff
6
.idea/compiler.xml
generated
Normal file
6
.idea/compiler.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="CompilerConfiguration">
|
||||||
|
<bytecodeTargetLevel target="21" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
11
.idea/deploymentTargetSelector.xml
generated
Normal file
11
.idea/deploymentTargetSelector.xml
generated
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="deploymentTargetSelector">
|
||||||
|
<selectionStates>
|
||||||
|
<SelectionState runConfigName="app">
|
||||||
|
<option name="selectionMode" value="DROPDOWN" />
|
||||||
|
<DialogSelection />
|
||||||
|
</SelectionState>
|
||||||
|
</selectionStates>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
19
.idea/gradle.xml
generated
Normal file
19
.idea/gradle.xml
generated
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||||
|
<component name="GradleSettings">
|
||||||
|
<option name="linkedExternalProjectsSettings">
|
||||||
|
<GradleProjectSettings>
|
||||||
|
<option name="testRunner" value="CHOOSE_PER_TEST" />
|
||||||
|
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
|
<option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
|
||||||
|
<option name="modules">
|
||||||
|
<set>
|
||||||
|
<option value="$PROJECT_DIR$" />
|
||||||
|
<option value="$PROJECT_DIR$/app" />
|
||||||
|
</set>
|
||||||
|
</option>
|
||||||
|
</GradleProjectSettings>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
10
.idea/migrations.xml
generated
Normal file
10
.idea/migrations.xml
generated
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectMigrations">
|
||||||
|
<option name="MigrateToGradleLocalJavaHome">
|
||||||
|
<set>
|
||||||
|
<option value="$PROJECT_DIR$" />
|
||||||
|
</set>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
9
.idea/misc.xml
generated
Normal file
9
.idea/misc.xml
generated
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<project version="4">
|
||||||
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
|
||||||
|
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectType">
|
||||||
|
<option name="id" value="Android" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
17
.idea/runConfigurations.xml
generated
Normal file
17
.idea/runConfigurations.xml
generated
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="RunConfigurationProducerService">
|
||||||
|
<option name="ignoredProducers">
|
||||||
|
<set>
|
||||||
|
<option value="com.intellij.execution.junit.AbstractAllInDirectoryConfigurationProducer" />
|
||||||
|
<option value="com.intellij.execution.junit.AllInPackageConfigurationProducer" />
|
||||||
|
<option value="com.intellij.execution.junit.PatternConfigurationProducer" />
|
||||||
|
<option value="com.intellij.execution.junit.TestInClassConfigurationProducer" />
|
||||||
|
<option value="com.intellij.execution.junit.UniqueIdConfigurationProducer" />
|
||||||
|
<option value="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.kotlin.idea.junit.KotlinJUnitRunConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.kotlin.idea.junit.KotlinPatternConfigurationProducer" />
|
||||||
|
</set>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
BIN
.pdfpages/page.png
Normal file
BIN
.pdfpages/page.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 82 KiB |
BIN
.qlpreview/Spesifikasi Emoney BRI new.pdf.png
Normal file
BIN
.qlpreview/Spesifikasi Emoney BRI new.pdf.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 256 KiB |
125
HCE_BRIZZI_SMOKE_TEST.md
Normal file
125
HCE_BRIZZI_SMOKE_TEST.md
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
# Uji Cepat Brizzi HCE (1x Smoke Test)
|
||||||
|
|
||||||
|
Tujuan:
|
||||||
|
- memastikan APK bisa dipasang,
|
||||||
|
- service HCE aktif,
|
||||||
|
- AID terpasang,
|
||||||
|
- lalu validasi interaksi dasar saat ditempel ke reader Brizzi.
|
||||||
|
|
||||||
|
> Path AID di app ini:
|
||||||
|
> - `F0010203040506`
|
||||||
|
> - `5A00000301000000`
|
||||||
|
> - `5A00000303000000`
|
||||||
|
|
||||||
|
## 0) Setup environment
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /Users/wirabasalamah/Documents/Codex/brizzi-hce
|
||||||
|
export ANDROID_SDK_ROOT=/opt/android-sdk
|
||||||
|
export JAVA_HOME=/Library/Java/JavaVirtualMachines/temurin-21.jdk/Contents/Home
|
||||||
|
```
|
||||||
|
|
||||||
|
## 1) Build & install ke device
|
||||||
|
|
||||||
|
```bash
|
||||||
|
"$JAVA_HOME"/bin/java -version >/dev/null 2>&1
|
||||||
|
./gradlew clean assembleDebug
|
||||||
|
adb devices -l
|
||||||
|
adb install -r app/build/outputs/apk/debug/app-debug.apk
|
||||||
|
```
|
||||||
|
|
||||||
|
Kalau install gagal karena versi mismatch:
|
||||||
|
- pastikan package belum terpasang versi lama: `adb uninstall com.korancrew.brizzi`
|
||||||
|
- lalu install ulang.
|
||||||
|
|
||||||
|
## 2) Pastikan app dan HCE service terpasang
|
||||||
|
|
||||||
|
```bash
|
||||||
|
adb shell pm list packages | rg com.korancrew.brizzi
|
||||||
|
adb shell dumpsys package com.korancrew.brizzi | rg -n "HostApduService|BrizziHostApduService|permission.BIND_NFC_SERVICE"
|
||||||
|
```
|
||||||
|
|
||||||
|
Jalankan app sekali untuk inisialisasi:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
adb shell am start -n com.korancrew.brizzi/.MainActivity
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3) Verifikasi file konfigurasi AID Service
|
||||||
|
|
||||||
|
```bash
|
||||||
|
adb shell cat /data/data/com.korancrew.brizzi/files/../shared_prefs/app_preferences.xml
|
||||||
|
```
|
||||||
|
> Catatan: isi ini tidak selalu menampilkan XML service AID secara langsung karena AID service ada di manifest/resource.
|
||||||
|
> Verifikasi cepat AID lewat:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
adb shell cmd package resolve-activity --brief com.korancrew.brizzi/.MainActivity
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4) Siapkan logcat khusus HCE sebelum nempel ke reader
|
||||||
|
|
||||||
|
```bash
|
||||||
|
adb logcat -c
|
||||||
|
adb logcat | rg -n "BrizziHce|HOST_APDU|processCommandApdu|BrizziHostApduService|BrizziSecurityMetrics"
|
||||||
|
```
|
||||||
|
|
||||||
|
Biarkan logging berjalan.
|
||||||
|
|
||||||
|
## 5) Tes interaksi manual dengan reader Brizzi
|
||||||
|
|
||||||
|
1. Pastikan Android **sudah unlock** (karena `requireDeviceUnlock="true"`).
|
||||||
|
2. Nyalakan NFC.
|
||||||
|
3. Nempelkan device ke reader Brizzi.
|
||||||
|
4. Pantau logcat:
|
||||||
|
- harus ada response terhadap APDU masuk dari `processCommandApdu`.
|
||||||
|
- kamu akan melihat event seperti:
|
||||||
|
- `ISO_SELECT_OK`
|
||||||
|
- `SELECT_AID1 / SELECT_AID3`
|
||||||
|
- `AUTH_SUCCESS` (kalau workflow auth dipakai)
|
||||||
|
- `GET_BALANCE`, `DEBIT_PREPARED`, `COMMIT_OK`, dll.
|
||||||
|
|
||||||
|
Jika perlu lihat ringkasan metrik setelah transaksi:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
adb shell am start -n com.korancrew.brizzi/.MainActivity -a com.korancrew.brizzi.ACTION_DUMP_METRICS
|
||||||
|
```
|
||||||
|
|
||||||
|
## 6) Skenario “minimal berhasil” yang harus terlihat
|
||||||
|
|
||||||
|
Urutan sehat ideal:
|
||||||
|
1. Reader kirim select AID (`AID1`/`AID3`) → app balas sukses (SW `9100`).
|
||||||
|
2. Pada AID3: key request + auth challenge → balasan valid.
|
||||||
|
3. `GET_BALANCE` → balasan sesuai saldo.
|
||||||
|
4. Jika ada debit/credit:
|
||||||
|
- command transaksi dipersiapkan,
|
||||||
|
- `COMMIT` menyimpan perubahan.
|
||||||
|
|
||||||
|
## 7) Skenario gagal yang harus muncul (normal saat kondisi salah)
|
||||||
|
|
||||||
|
- Reader kirim debit tanpa auth → `CONDITIONS_NOT_SATISFIED` (`6985`).
|
||||||
|
- Perintah salah format / malformed → `COMMAND_REJECTED_INVALID_SIZE` di log.
|
||||||
|
- Akses komando tidak diizinkan tanpa flow yang benar → event `AUTH_DENIED`/`*_DENIED`.
|
||||||
|
|
||||||
|
## 8) Reset metrik cepat (untuk pengujian ulang)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
adb shell am start -n com.korancrew.brizzi/.MainActivity -a com.korancrew.brizzi.ACTION_RESET_METRICS
|
||||||
|
adb shell logcat -c
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Penilaian akhir (hasil pass/fail)
|
||||||
|
|
||||||
|
Pass jika:
|
||||||
|
- app bisa install dan service aktif,
|
||||||
|
- logcat menangkap proses APDU saat reader nempel,
|
||||||
|
- reader melakukan response sesuai flow AID → auth → command,
|
||||||
|
- tidak terjadi crash setelah beberapa siklus tap.
|
||||||
|
|
||||||
|
Fail jika:
|
||||||
|
- tidak ada satu pun log `BrizziHce` saat transaksi,
|
||||||
|
- APK tidak menerima command sama sekali saat NFC dipakai,
|
||||||
|
- response selalu `6FFF`/`6700` secara permanen (kemungkinan AID/routing atau format APDU mismatch).
|
||||||
|
|
||||||
56
PRODUCTION_CHECKLIST.md
Normal file
56
PRODUCTION_CHECKLIST.md
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
# Brizzi HCE — Production Readiness (Langkah 1–6)
|
||||||
|
|
||||||
|
## 1) Hardening APDU & State Machine
|
||||||
|
- ✅ Structured APDU parser (`ApduParser`) sudah dipakai.
|
||||||
|
- ✅ Guard sesi/transaksi berbasis phase (`BrizziSession`).
|
||||||
|
- ✅ Validasi panjang APDU, timeout sesi, replay-duplicate, dan limit command-rate di service.
|
||||||
|
|
||||||
|
## 2) Command/Session Security (Sudah Dilakukan)
|
||||||
|
- ✅ Branching APDU terproteksi state (select → auth → command → commit/abort).
|
||||||
|
- ✅ Error SW dipisahkan untuk malformed, unsupported, rate-limit, dan security status.
|
||||||
|
|
||||||
|
## 3) Build & Obfuscation (Sudah Dilakukan)
|
||||||
|
- ✅ `release` tetap pakai R8 + shrink/resources.
|
||||||
|
- ✅ Baseline ProGuard rules untuk service/router/card classes.
|
||||||
|
- ✅ `debug` tetap non-minify agar troubleshooting.
|
||||||
|
|
||||||
|
## 4) Runtime & Platform Baseline (Baru)
|
||||||
|
- ✅ Tambah NFC permission di manifest.
|
||||||
|
- ✅ Nonaktifkan cleartext traffic (`usesCleartextTraffic=false`) + network security config.
|
||||||
|
- ✅ Tambah `FLAG_SECURE` di activity agar layar tidak bisa di-screen capture.
|
||||||
|
|
||||||
|
## 5) Monitoring & Incident Readiness (Wajib)
|
||||||
|
- Implement `audit log` terstruktur untuk event security (replay hit, rate-limit hit, auth fail).
|
||||||
|
- ✅ Menambahkan counter audit event di runtime:
|
||||||
|
- `BrizziSecurityMetrics` menyimpan jumlah event keamanan dan command-response.
|
||||||
|
- Batasi log production ke metadata minimum (tanpa card data raw/APDU body).
|
||||||
|
- ✅ Export statistik sudah aktif:
|
||||||
|
- success/fail command rate (`COMMAND_SUCCESS`, `COMMAND_FAIL`, `COMMAND_TOTAL`),
|
||||||
|
- timeout/rate-limit/replay statistik terpisah,
|
||||||
|
- incident threshold auto-alert (`COMMAND_RATE_LIMIT`, `REPLAY_DETECTED`, `APDU_PARSE_FAILED`, `AUTH_DENIED`, dll.).
|
||||||
|
- ✅ Incident report juga diekspor ke file lokal internal:
|
||||||
|
- `security_metrics_report.txt` ditulis saat command selesai dan saat deactivation.
|
||||||
|
|
||||||
|
### Perintah cepat (opsional)
|
||||||
|
- Dump metrik (debug-only):
|
||||||
|
- `adb shell am start -n com.korancrew.brizzi/.MainActivity -a com.korancrew.brizzi.ACTION_DUMP_METRICS`
|
||||||
|
- Reset metrik (debug-only):
|
||||||
|
- `adb shell am start -n com.korancrew.brizzi/.MainActivity -a com.korancrew.brizzi.ACTION_RESET_METRICS`
|
||||||
|
- Catatan:
|
||||||
|
- file log tambahan ada di:
|
||||||
|
- `/data/data/com.korancrew.brizzi/files/security_metrics_report.txt` (dengan `run-as` pada debug)
|
||||||
|
|
||||||
|
## 6) Release Operations (Wajib)
|
||||||
|
- Siapkan signing config release dan keystore aman.
|
||||||
|
- Smoke test HCE end-to-end di device fisik:
|
||||||
|
- select AID 1 & AID 3,
|
||||||
|
- auth success/fail,
|
||||||
|
- debit/credit + commit + abort,
|
||||||
|
- update log/last transaction + commit,
|
||||||
|
- replay/rate-limit handling.
|
||||||
|
- Lakukan QA dengan:
|
||||||
|
- command invalid / malformed,
|
||||||
|
- APDU burst,
|
||||||
|
- NFC deactivation/reactivation,
|
||||||
|
- timeout sesi.
|
||||||
|
- Pastikan Play Console/enterprise rollout memakai APK/AAB yang sudah ditandatangani.
|
||||||
209
README.md
Normal file
209
README.md
Normal file
@ -0,0 +1,209 @@
|
|||||||
|
# BRIZZI HCE (Android NFC Host Card Emulation)
|
||||||
|
|
||||||
|
Dokumen ini menjelaskan struktur project, alur eksekusi, dan cara membacanya supaya kamu bisa langsung maintance/debug proyek ini.
|
||||||
|
|
||||||
|
## 1) Gambaran Umum
|
||||||
|
|
||||||
|
Project ini adalah aplikasi Android HCE (Host Card Emulation) yang memproses APDU dari reader NFC (misalnya terminal).
|
||||||
|
Komponen utamanya:
|
||||||
|
- [BrizziHostApduService](/Users/wirabasalamah/Documents/Codex/brizzi-hce/app/src/main/java/com/korancrew/brizzi/hce/BrizziHostApduService.kt): service utama untuk menerima APDU.
|
||||||
|
- [BrizziApduRouter](/Users/wirabasalamah/Documents/Codex/brizzi-hce/app/src/main/java/com/korancrew/brizzi/hce/BrizziApduRouter.kt): pemroses perintah dan state machine transaksi.
|
||||||
|
- [BrizziSession](/Users/wirabasalamah/Documents/Codex/brizzi-hce/app/src/main/java/com/korancrew/brizzi/hce/BrizziSession.kt): menjaga kondisi sesi saat ini (AID, auth, transaksi pending).
|
||||||
|
- [BrizziCard / BrizziCardSnapshot](/Users/wirabasalamah/Documents/Codex/brizzi-hce/app/src/main/java/com/korancrew/brizzi/hce/BrizziCard.kt): model data kartu virtual.
|
||||||
|
- [BrizziSecureStorage](/Users/wirabasalamah/Documents/Codex/brizzi-hce/app/src/main/java/com/korancrew/brizzi/hce/BrizziSecureStorage.kt): persistensi kartu terenkripsi.
|
||||||
|
- [BrizziSecurityMetrics](/Users/wirabasalamah/Documents/Codex/brizzi-hce/app/src/main/java/com/korancrew/brizzi/hce/BrizziSecurityMetrics.kt): monitoring keamanan dan incident readiness.
|
||||||
|
|
||||||
|
## 2) Bagaimana alur request APDU
|
||||||
|
|
||||||
|
1. APDU masuk ke `processCommandApdu(...)` di `BrizziHostApduService`.
|
||||||
|
2. Service melakukan:
|
||||||
|
- validasi basic (null/size/rate limit),
|
||||||
|
- log/track metrik event,
|
||||||
|
- dispatch ke `BrizziApduRouter.handle()`.
|
||||||
|
3. Router:
|
||||||
|
- parse APDU via `ApduParser`,
|
||||||
|
- cek timeout sesi,
|
||||||
|
- cek replay untuk command sensitif,
|
||||||
|
- validasi state session (AID/auth/transaction),
|
||||||
|
- memetakan hasil ke SW response.
|
||||||
|
4. Response SW/konten dikirim ke terminal.
|
||||||
|
|
||||||
|
## 3) State machine yang penting
|
||||||
|
|
||||||
|
`BrizziSession` menyimpan dua level state:
|
||||||
|
- **SessionPhase**
|
||||||
|
- `NONE`
|
||||||
|
- `AID1_SELECTED`
|
||||||
|
- `AID3_SELECTED`
|
||||||
|
- `AID3_AUTHENTICATED`
|
||||||
|
- **TransactionPhase**
|
||||||
|
- `NONE`
|
||||||
|
- `DEBIT_PENDING`
|
||||||
|
- `CREDIT_PENDING`
|
||||||
|
- `LOG_PENDING`
|
||||||
|
- `LAST_TXN_PENDING`
|
||||||
|
|
||||||
|
`hasPendingTransactionState()` dipakai untuk mencegah abuse:
|
||||||
|
- command debit/credit tidak boleh overlapping,
|
||||||
|
- commit/abort (`C7`/`A7`) harus disinkron.
|
||||||
|
|
||||||
|
## 4) Security hardening yang sudah diterapkan
|
||||||
|
|
||||||
|
- Parsing APDU tidak lagi pakai regex string mentah sepenuhnya; gunakan `ApduParser` untuk parse CLA/INS/P1/P2/Lc/Data/Le.
|
||||||
|
- Validasi panjang dan malformed handling lebih ketat (`wrongLength`, `unsupportedInstruction`, `rateLimitExceeded`, dll.).
|
||||||
|
- Replay protection untuk command sensitif dalam window pendek.
|
||||||
|
- Rate limit:
|
||||||
|
- max 80 command / 1000ms,
|
||||||
|
- minimum gap antar command 30ms.
|
||||||
|
- Session timeout 120 detik.
|
||||||
|
- `FLAG_SECURE` di UI supaya tidak mudah di-screenshot.
|
||||||
|
- `usesCleartextTraffic=false` dan `networkSecurityConfig`.
|
||||||
|
- Logging produksi diarahkan ke metadata minimal (tidak menyimpan raw APDU).
|
||||||
|
|
||||||
|
## 5) Penyimpanan data (yang dipilih)
|
||||||
|
|
||||||
|
Sebelum ini data ada di RAM. Sekarang:
|
||||||
|
- `BrizziSecureStorage` menyimpan data kartu ke `EncryptedSharedPreferences`:
|
||||||
|
- `card_number`, `balance`, `logs`, `lastTransactionDate`, dsb.
|
||||||
|
- Kunci enkripsi berasal dari Android Keystore (`MasterKey`).
|
||||||
|
- Data dipersisten saat `commit` transaksi (`C7`) via callback `onCardUpdated`.
|
||||||
|
- Bila loading gagal, sistem fallback ke nilai default (`BrizziCard()`).
|
||||||
|
|
||||||
|
Catatan: ini aman untuk tingkat aplikasi, namun bukan secure element hardware.
|
||||||
|
|
||||||
|
## 6) Monitoring & Incident readiness (point 5 yang kamu minta)
|
||||||
|
|
||||||
|
`BrizziSecurityMetrics` menyimpan counter event:
|
||||||
|
- command total/sukses/gagal,
|
||||||
|
- timeout, rate limit, replay,
|
||||||
|
- auth denied, parse fail, dan lain-lain.
|
||||||
|
|
||||||
|
Mechanism:
|
||||||
|
- service memanggil `track(event)` untuk setiap event penting,
|
||||||
|
- bila ambang incident terlampaui (mis. `COMMAND_RATE_LIMIT`, `REPLAY_DETECTED`, `AUTH_DENIED`, dll), service log `security incidents` (throttled per menit),
|
||||||
|
- snapshot juga diekspor ke file internal:
|
||||||
|
- `app/files/security_metrics_report.txt`.
|
||||||
|
|
||||||
|
### Debug actions dari MainActivity
|
||||||
|
|
||||||
|
- Dump metrics (debug only):
|
||||||
|
- `adb shell am start -n com.korancrew.brizzi/.MainActivity -a com.korancrew.brizzi.ACTION_DUMP_METRICS`
|
||||||
|
- Reset metrics (debug only):
|
||||||
|
- `adb shell am start -n com.korancrew.brizzi/.MainActivity -a com.korancrew.brizzi.ACTION_RESET_METRICS`
|
||||||
|
- Lihat file log:
|
||||||
|
- `/data/data/com.korancrew.brizzi/files/security_metrics_report.txt`
|
||||||
|
|
||||||
|
## 7) Command support (high level)
|
||||||
|
|
||||||
|
Di router, mapping didasarkan pada helper:
|
||||||
|
- AID selector (1/3): `905A...0100...`, `905A...0300...`
|
||||||
|
- AID 1 info/status
|
||||||
|
- AID 3 auth & read balance/log/transaction
|
||||||
|
- debit/credit
|
||||||
|
- write log + update last transaction + commit/abort
|
||||||
|
- fallback: `unsupportedInstruction` (6D00)
|
||||||
|
|
||||||
|
Untuk daftar lengkap command literal, lihat:
|
||||||
|
- [BrizziCommandCatalog](/Users/wirabasalamah/Documents/Codex/brizzi-hce/app/src/main/java/com/korancrew/brizzi/hce/BrizziCommandCatalog.kt)
|
||||||
|
- implementasi detail di `handleParsed(...)`:
|
||||||
|
- [BrizziApduRouter.kt](/Users/wirabasalamah/Documents/Codex/brizzi-hce/app/src/main/java/com/korancrew/brizzi/hce/BrizziApduRouter.kt)
|
||||||
|
|
||||||
|
## 8) Cara memahami kode (urutan baca yang disarankan)
|
||||||
|
|
||||||
|
1. [BrizziHostApduService.kt](app/src/main/java/com/korancrew/brizzi/hce/BrizziHostApduService.kt) – masuknya data APDU, rate limit, metrik.
|
||||||
|
2. [BrizziApduRouter.kt](app/src/main/java/com/korancrew/brizzi/hce/BrizziApduRouter.kt) – policy/routing per command.
|
||||||
|
3. [BrizziSession.kt](app/src/main/java/com/korancrew/brizzi/hce/BrizziSession.kt) – state session/transaction.
|
||||||
|
4. [ApduParser.kt](app/src/main/java/com/korancrew/brizzi/hce/ApduParser.kt) – struktur parser.
|
||||||
|
5. [BrizziCard.kt](app/src/main/java/com/korancrew/brizzi/hce/BrizziCard.kt) + [BrizziSecureStorage.kt](app/src/main/java/com/korancrew/brizzi/hce/BrizziSecureStorage.kt).
|
||||||
|
6. [BrizziSecurityMetrics.kt](app/src/main/java/com/korancrew/brizzi/hce/BrizziSecurityMetrics.kt) – event/incident.
|
||||||
|
7. [BrizziResponse.kt](app/src/main/java/com/korancrew/brizzi/hce/BrizziResponse.kt) + [Hex.kt](app/src/main/java/com/korancrew/brizzi/hce/Hex.kt).
|
||||||
|
|
||||||
|
## 9) Build & release yang dipakai sekarang
|
||||||
|
|
||||||
|
- `debug`: non-minify (mudah debug).
|
||||||
|
- `release`: minify + shrink + ProGuard:
|
||||||
|
- [proguard-rules.pro](/Users/wirabasalamah/Documents/Codex/brizzi-hce/app/proguard-rules.pro)
|
||||||
|
- Signing release hanya aktif jika property gradle diisi (via CI keystore properties):
|
||||||
|
- `RELEASE_STORE_FILE`, `RELEASE_STORE_PASSWORD`, `RELEASE_KEY_ALIAS`, `RELEASE_KEY_PASSWORD`.
|
||||||
|
|
||||||
|
## 10) Known caveat (buat pembacaan objektif)
|
||||||
|
|
||||||
|
- Banyak SW command belum sepenuhnya di-convert ke parser berbasis field; saat ini tetap berbasis string matching untuk backward compatibility.
|
||||||
|
- Jika ini akan dipakai di production nyata (bukan simulasi/prototype), perlu hardening tambahan:
|
||||||
|
- enkripsi/rotasi kunci lebih ketat,
|
||||||
|
- secure policy distribusi dan integrity update,
|
||||||
|
- backend attestation/monitoring terpusat.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 11) Ringkas: arsitektur dalam satu kalimat
|
||||||
|
Ini adalah **stateful HCE emulator**: APDU masuk → rate-limit & parser → aturan fase sesi → update card/metrics → response status dengan persistensi terenkripsi + audit event.
|
||||||
|
|
||||||
|
## 12) Cara membaca kode (bisa dijadikan panduan debugging)
|
||||||
|
|
||||||
|
### 12.1 Alur end-to-end dalam 1 request
|
||||||
|
|
||||||
|
1. Terminal mengirim APDU ke `BrizziHostApduService`.
|
||||||
|
2. `processCommandApdu(...)` memvalidasi ukuran, null, dan rate-limit di service.
|
||||||
|
3. `BrizziHostApduService` menyerahkan APDU ke `BrizziApduRouter.handle(...)`.
|
||||||
|
4. Router memanggil `ApduParser.parse(...)` untuk decode field CLA/INS/P1/P2/Lc/Data/Le.
|
||||||
|
5. Router memvalidasi:
|
||||||
|
- sesi timeout (`SESSION_TIMEOUT_MS`),
|
||||||
|
- replay untuk perintah sensitif (`REPLAY_WINDOW_MS`),
|
||||||
|
- state/phase yang valid (`BrizziSession`),
|
||||||
|
- format payload (contoh: debit/credit/write log/last transaction).
|
||||||
|
6. Jika valid, router memproses rule per command dan memodifikasi `pending*` pada `session` serta `card` jika commit.
|
||||||
|
7. Response dibentuk dari `BrizziResponse` (`6700`, `6985`, `6FFF`, `9100`, dll).
|
||||||
|
8. Service mencatat event ke `BrizziSecurityMetrics`, menilai health, dan menulis snapshot ke `security_metrics_report.txt`.
|
||||||
|
|
||||||
|
### 12.2 Urutan file untuk dibaca dari atas ke bawah
|
||||||
|
|
||||||
|
1. [BrizziHostApduService.kt](/Users/wirabasalamah/Documents/Codex/brizzi-hce/app/src/main/java/com/korancrew/brizzi/hce/BrizziHostApduService.kt)
|
||||||
|
- Titik masuk APDU dari HCE.
|
||||||
|
- Juga memegang rate-limit, incident throttle log, dan ekpor metrik.
|
||||||
|
2. [BrizziApduRouter.kt](/Users/wirabasalamah/Documents/Codex/brizzi-hce/app/src/main/java/com/korancrew/brizzi/hce/BrizziApduRouter.kt)
|
||||||
|
- Aturan stateful command routing.
|
||||||
|
- Core logic transaksi debit/credit/log/last transaction/commit-abort.
|
||||||
|
3. [BrizziSession.kt](/Users/wirabasalamah/Documents/Codex/brizzi-hce/app/src/main/java/com/korancrew/brizzi/hce/BrizziSession.kt)
|
||||||
|
- Menjaga state sesi, fase autentikasi, fase transaksi, anti-replay, dan pending state.
|
||||||
|
4. [ApduParser.kt](/Users/wirabasalamah/Documents/Codex/brizzi-hce/app/src/main/java/com/korancrew/brizzi/hce/ApduParser.kt)
|
||||||
|
- Parsing protokol APDU (case-1..case-4).
|
||||||
|
5. [BrizziCard.kt](/Users/wirabasalamah/Documents/Codex/brizzi-hce/app/src/main/java/com/korancrew/brizzi/hce/BrizziCard.kt) + [BrizziSecureStorage.kt](/Users/wirabasalamah/Documents/Codex/brizzi-hce/app/src/main/java/com/korancrew/brizzi/hce/BrizziSecureStorage.kt)
|
||||||
|
- Struktur data card dan log transaksi; bagaimana data bertahan di penyimpanan terenkripsi.
|
||||||
|
6. [BrizziSecurityMetrics.kt](/Users/wirabasalamah/Documents/Codex/brizzi-hce/app/src/main/java/com/korancrew/brizzi/hce/BrizziSecurityMetrics.kt)
|
||||||
|
- Event tracking, incident threshold, snapshot/report.
|
||||||
|
|
||||||
|
### 12.3 Kontrak keamanan yang harus dipahami
|
||||||
|
|
||||||
|
- **Syarat autentikasi:** akses area saldo/log/last transaction hanya setelah fase `AID3_AUTHENTICATED`.
|
||||||
|
- **Syarat transaksi:** debit/credit harus dalam state siap transaksi, tidak boleh ada pending transaction lain.
|
||||||
|
- **Commit/Abort:** `C7`/`A7` adalah pembatas akhir lifecycle transaksi. Tanpa pending state, kedua command itu ditolak.
|
||||||
|
- **Logika rollback:** pending update hanya masuk ke state final saat `COMMIT`; `ABORT` membersihkan pending.
|
||||||
|
- **Replay guard:** command sensitif (debit/credit/commit/abort/write log/last tx) tidak boleh diulang dalam window pendek.
|
||||||
|
|
||||||
|
### 12.4 Checklist membaca log saat debugging
|
||||||
|
|
||||||
|
- Jika terjadi `CONDITIONS_NOT_SATISFIED` berulang: cek urutan select-aid-auth-send command.
|
||||||
|
- Jika `rateLimitExceeded` sering:
|
||||||
|
- periksa apakah device reader terlalu cepat kirim command (<30ms antar command).
|
||||||
|
- pastikan transaksi tidak melebihi 80 command/s.
|
||||||
|
- Jika `COMMAND_PARSE_FAILED` naik: cek command malformed (Lc/Le mismatch, trailing bytes, payload aneh).
|
||||||
|
- Ambil snapshot metrik:
|
||||||
|
- `adb shell am start -n com.korancrew.brizzi/.MainActivity -a com.korancrew.brizzi.ACTION_DUMP_METRICS`
|
||||||
|
- Hapus metrik jika perlu test ulang:
|
||||||
|
- `adb shell am start -n com.korancrew.brizzi/.MainActivity -a com.korancrew.brizzi.ACTION_RESET_METRICS`
|
||||||
|
|
||||||
|
## 13) Peta ancaman & mitigasi singkat (ringkas)
|
||||||
|
|
||||||
|
- **Replay** → dibatasi window 800ms di router + deteksi command sensitif.
|
||||||
|
- **Flood** → dibatasi 80 cmd/1000ms + minimum 30ms antar command di service.
|
||||||
|
- **Session theft/continuity** → timeout 120 detik, reset state saat deactivated.
|
||||||
|
- **Data disclosure** → `FLAG_SECURE`, cleartext dimatikan, keystore-backed storage untuk card state.
|
||||||
|
- **Silent fail di prod** → metrik tidak menyimpan APDU mentah, hanya metadata event.
|
||||||
|
|
||||||
|
## 14) Paket uji cepat (smoke test) untuk koneksi reader
|
||||||
|
|
||||||
|
- Gunakan [HCE_BRIZZI_SMOKE_TEST.md](/Users/wirabasalamah/Documents/Codex/brizzi-hce/HCE_BRIZZI_SMOKE_TEST.md) untuk menjalankan alur verifikasi:
|
||||||
|
- build/install,
|
||||||
|
- cek service + logcat,
|
||||||
|
- validasi interaksi AID/auth/transaksi ke reader.
|
||||||
65
app/build.gradle.kts
Normal file
65
app/build.gradle.kts
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
plugins {
|
||||||
|
id("com.android.application")
|
||||||
|
id("org.jetbrains.kotlin.android")
|
||||||
|
}
|
||||||
|
|
||||||
|
android {
|
||||||
|
namespace = "com.korancrew.brizzi"
|
||||||
|
compileSdk = 34
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
applicationId = "com.korancrew.brizzi"
|
||||||
|
minSdk = 26
|
||||||
|
targetSdk = 34
|
||||||
|
versionCode = 1
|
||||||
|
versionName = "1.0"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (project.hasProperty("RELEASE_STORE_FILE")) {
|
||||||
|
signingConfigs {
|
||||||
|
create("release") {
|
||||||
|
storeFile = file(project.property("RELEASE_STORE_FILE") as String)
|
||||||
|
storePassword = project.property("RELEASE_STORE_PASSWORD") as String
|
||||||
|
keyAlias = project.property("RELEASE_KEY_ALIAS") as String
|
||||||
|
keyPassword = project.property("RELEASE_KEY_PASSWORD") as String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buildTypes {
|
||||||
|
debug {
|
||||||
|
isMinifyEnabled = false
|
||||||
|
isShrinkResources = false
|
||||||
|
}
|
||||||
|
release {
|
||||||
|
isMinifyEnabled = true
|
||||||
|
isShrinkResources = true
|
||||||
|
if (project.findProperty("RELEASE_STORE_FILE") != null) {
|
||||||
|
signingConfig = signingConfigs.getByName("release")
|
||||||
|
}
|
||||||
|
proguardFiles(
|
||||||
|
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||||
|
"proguard-rules.pro",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility = JavaVersion.VERSION_17
|
||||||
|
targetCompatibility = JavaVersion.VERSION_17
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = "17"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation("androidx.core:core-ktx:1.13.1")
|
||||||
|
implementation("androidx.appcompat:appcompat:1.7.0")
|
||||||
|
implementation("com.google.android.material:material:1.12.0")
|
||||||
|
implementation("androidx.activity:activity-ktx:1.9.1")
|
||||||
|
implementation("androidx.security:security-crypto-ktx:1.1.0")
|
||||||
|
|
||||||
|
testImplementation("junit:junit:4.13.2")
|
||||||
|
}
|
||||||
1
app/build/20260502_1030065886705461100.compiler.options
Normal file
1
app/build/20260502_1030065886705461100.compiler.options
Normal file
File diff suppressed because one or more lines are too long
1
app/build/20260502_10441768603012048599.compiler.options
Normal file
1
app/build/20260502_10441768603012048599.compiler.options
Normal file
File diff suppressed because one or more lines are too long
1
app/build/20260502_11229470137753326535.compiler.options
Normal file
1
app/build/20260502_11229470137753326535.compiler.options
Normal file
File diff suppressed because one or more lines are too long
1
app/build/20260502_12847016678562219229.compiler.options
Normal file
1
app/build/20260502_12847016678562219229.compiler.options
Normal file
File diff suppressed because one or more lines are too long
1
app/build/20260502_12929062320326023968.compiler.options
Normal file
1
app/build/20260502_12929062320326023968.compiler.options
Normal file
File diff suppressed because one or more lines are too long
1
app/build/20260502_13545760743152707855.compiler.options
Normal file
1
app/build/20260502_13545760743152707855.compiler.options
Normal file
File diff suppressed because one or more lines are too long
1
app/build/20260502_14006553528600817580.compiler.options
Normal file
1
app/build/20260502_14006553528600817580.compiler.options
Normal file
File diff suppressed because one or more lines are too long
1
app/build/20260502_14119314172237048984.compiler.options
Normal file
1
app/build/20260502_14119314172237048984.compiler.options
Normal file
File diff suppressed because one or more lines are too long
1
app/build/20260502_16048052753253708905.compiler.options
Normal file
1
app/build/20260502_16048052753253708905.compiler.options
Normal file
File diff suppressed because one or more lines are too long
1
app/build/20260502_16448714221378634363.compiler.options
Normal file
1
app/build/20260502_16448714221378634363.compiler.options
Normal file
File diff suppressed because one or more lines are too long
1
app/build/20260502_1659645070981979515.compiler.options
Normal file
1
app/build/20260502_1659645070981979515.compiler.options
Normal file
File diff suppressed because one or more lines are too long
1
app/build/20260502_17583341153065590112.compiler.options
Normal file
1
app/build/20260502_17583341153065590112.compiler.options
Normal file
File diff suppressed because one or more lines are too long
1
app/build/20260502_1911321491867890971.compiler.options
Normal file
1
app/build/20260502_1911321491867890971.compiler.options
Normal file
File diff suppressed because one or more lines are too long
1
app/build/20260502_302000541545794375.compiler.options
Normal file
1
app/build/20260502_302000541545794375.compiler.options
Normal file
File diff suppressed because one or more lines are too long
1
app/build/20260502_3087422793227347210.compiler.options
Normal file
1
app/build/20260502_3087422793227347210.compiler.options
Normal file
File diff suppressed because one or more lines are too long
1
app/build/20260502_4093483830319087828.compiler.options
Normal file
1
app/build/20260502_4093483830319087828.compiler.options
Normal file
File diff suppressed because one or more lines are too long
1
app/build/20260502_4133832481298853240.compiler.options
Normal file
1
app/build/20260502_4133832481298853240.compiler.options
Normal file
File diff suppressed because one or more lines are too long
1
app/build/20260502_6697145872691256647.compiler.options
Normal file
1
app/build/20260502_6697145872691256647.compiler.options
Normal file
File diff suppressed because one or more lines are too long
1
app/build/20260502_6942646467784478520.compiler.options
Normal file
1
app/build/20260502_6942646467784478520.compiler.options
Normal file
File diff suppressed because one or more lines are too long
1
app/build/20260502_7022465596170032654.compiler.options
Normal file
1
app/build/20260502_7022465596170032654.compiler.options
Normal file
File diff suppressed because one or more lines are too long
@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
BIN
app/build/intermediates/apk/debug/app-debug.apk
Normal file
BIN
app/build/intermediates/apk/debug/app-debug.apk
Normal file
Binary file not shown.
21
app/build/intermediates/apk/debug/output-metadata.json
Normal file
21
app/build/intermediates/apk/debug/output-metadata.json
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"version": 3,
|
||||||
|
"artifactType": {
|
||||||
|
"type": "APK",
|
||||||
|
"kind": "Directory"
|
||||||
|
},
|
||||||
|
"applicationId": "com.korancrew.brizzi",
|
||||||
|
"variantName": "debug",
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"type": "SINGLE",
|
||||||
|
"filters": [],
|
||||||
|
"attributes": [],
|
||||||
|
"versionCode": 1,
|
||||||
|
"versionName": "1.0",
|
||||||
|
"outputFile": "app-debug.apk"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"elementType": "File",
|
||||||
|
"minSdkVersionForDexing": 26
|
||||||
|
}
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
#- File Locator -
|
||||||
|
listingFile=../../../apk/debug/output-metadata.json
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
appMetadataVersion=1.1
|
||||||
|
androidGradlePluginVersion=8.5.2
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"version": 3,
|
||||||
|
"artifactType": {
|
||||||
|
"type": "COMPATIBLE_SCREEN_MANIFEST",
|
||||||
|
"kind": "Directory"
|
||||||
|
},
|
||||||
|
"applicationId": "com.korancrew.brizzi",
|
||||||
|
"variantName": "debug",
|
||||||
|
"elements": []
|
||||||
|
}
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
app/build/intermediates/dex/debug/mergeExtDexDebug/classes.dex
Normal file
BIN
app/build/intermediates/dex/debug/mergeExtDexDebug/classes.dex
Normal file
Binary file not shown.
BIN
app/build/intermediates/dex/debug/mergeExtDexDebug/classes2.dex
Normal file
BIN
app/build/intermediates/dex/debug/mergeExtDexDebug/classes2.dex
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1 @@
|
|||||||
|
4
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user