Repository navigation
th AI AGENTS
Languages: English | العربية | Čeština | Deutsch | Español | فارسی | Français | हिन्दी | Bahasa Indonesia | Italiano | 日本語 | 한국어 | Nederlands | Polski | Português | Русский | Svenska | ไทย | Türkçe | Tiếng Việt | 中文
VDBackup ถูกสร้างขึ้นเพื่อให้ผู้ช่วย AI หรือ agent สามารถจัดการเนื้อหาและการกระทำ ทุกอย่าง ของโมดูลได้แบบ headless เช่นเดียวกับที่คนทำผ่าน WebUI WebUI เป็นเพียงไคลเอนต์หนึ่งของ JSON API ขนาดเล็ก agent ของคุณก็เป็นอีกไคลเอนต์หนึ่ง จงใช้ API อย่าขูด (scrape) WebUI
ทุกอย่างผ่านจุดเข้าเดียว รันเป็น root บนอุปกรณ์:
sh /data/adb/modules/vdbackup/scripts/helper.sh <verb> <base64(JSON-args)>
- อาร์กิวเมนต์เป็นอ็อบเจกต์ JSON เดียว เข้ารหัสแบบ base64 ส่งเป็น argv token เดียว
- คำสั่งจะพิมพ์ อ็อบเจกต์ JSON หนึ่งตัว ออกทาง stdout:
{"ok":true,...}หรือ{"ok":false,"code":"ERR_...","message":"..."}จง parse ค่านั้น อย่าขูดข้อความเด็ดขาด - การทำงานที่ใช้เวลานาน (
backup,restore,import) จะคืนค่า{"ok":true,"opid":"..."}ทันทีและรันแบบ แยกออก (detached) (ยังทำงานต่อแม้ผู้เรียก/WebUI จะหายไป) จง poll ความคืบหน้าของมัน งานยังไม่เสร็จเมื่อการเรียกคืนค่า -
progressและcancelรับ base64 ของสตริง opid ดิบ ไม่ใช่อ็อบเจกต์ JSON
ตัวช่วยเล็ก ๆ สำหรับ shell ของคุณ:
b64() { printf '%s' "$1" | base64 -w0; }
H=/data/adb/modules/vdbackup/scripts/helper.sh
sh "$H" backup "$(b64 '{"package":"com.example.app","mode":"full"}')"หากต้องการควบคุมจากเครื่องเวิร์กสเตชัน ให้รันคำสั่งนั้นผ่านช่องทาง root ปกติของคุณไปยังอุปกรณ์
(adb shell เป็น root หรือการตั้งค่า SSH-to-root) โมดูลมาพร้อมไบนารีที่ฝังมาให้แล้ว ดังนั้น
เมื่อติดตั้งแล้วจะ ไม่ต้องใช้อินเทอร์เน็ต สำหรับการ backup/restore ในเครื่อง มีเพียงปลายทาง
คลาวด์ (rclone/restic/ssh) เท่านั้นที่คุยกับเครือข่าย
| Verb | Args (JSON) | Returns |
|---|---|---|
ping |
{} |
{ok,version,abi} |
overview |
{user?} |
{ok:true,apps,instances,path_backups,jobs,backups_size,free,total} จำนวน (ขนาดเป็น bytes): แอปที่มี backup, จำนวน backup instance ทั้งหมด, path backup แบบเดี่ยว, งานที่ตั้งเวลา, ขนาด backup รวม และพื้นที่ว่าง/ทั้งหมดของระบบไฟล์ backup ไม่ detached, คืนค่าทันที; ใช้โดยภาพรวมหน้าแรกของ WebUI |
config-get |
{} |
{ok,config} |
config-set |
อ็อบเจกต์ config (หรือ {key,value}) |
{ok} |
keygen |
{} |
สร้างคู่กุญแจ age สำหรับการเข้ารหัส |
list-apps |
{user?} |
{ok,apps:[{package,label,system,versionCode}]} (dex, shell fallback) |
label |
{package,user?} |
{ok,label} (ชื่อแอปจริงที่แปลภาษาแล้ว ไม่ขึ้นกับบริบท) |
icon |
{package,user?,vc?} |
{ok,package,icon} (base64 PNG; แคชต่อ package+vc) |
backup |
ดูด้านล่าง |
{ok,opid} (detached) |
restore |
ดูด้านล่าง |
{ok,opid} (detached) |
import |
{from,ref,password,ssaid,user} |
{ok,opid} (detached) |
import-scan |
{from,path} |
{ok,backups:[...]} |
progress |
base64(opid) | ไฟล์ progress-<opid>.json แบบสด |
cancel |
base64(opid) | {ok,cancelled} |
list-ops |
{} |
{ok,ops:[...]} (เชื่อมต่อใหม่หลังรีคอนเนกต์) |
list-apps/icons
|
{user?} / {user?,items:[{package,vc}]}
|
รายการแอป / ไอคอน base64 แบบกลุ่ม |
list-backups |
{package?} |
{ok,backups:[{ref,package,label,versionName,versionCode,created_at,mode,items}]} |
list-users |
{} |
{ok,users:[{id,name}]} ผู้ใช้ Android ของอุปกรณ์ (หลายผู้ใช้). |
list-dirs |
{path} |
{ok,path,parent,dirs:[...]} ไดเรกทอรีย่อยของพาธ (ตัวเลือกโฟลเดอร์). |
path-list |
{user?} |
{ok,backups:[...]} การสำรองโฟลเดอร์/ไฟล์แบบเดี่ยว. |
provenance |
{} |
รายการตรวจสอบไบนารีที่มากับแอป (PROVENANCE.json). |
backup-info |
{ref} |
{ok,...} รายละเอียดครบของ backup หนึ่งชุด (เวอร์ชัน, แหล่งติดตั้ง, สถานะ, วันที่, mode, ขนาด, items, จำนวนสิทธิ์, อุปกรณ์) |
backup-icon |
{ref} |
{ok,icon} base64 PNG จาก manifest (ใช้ได้แม้แอปถูกถอนการติดตั้ง) |
delete-backup |
{ref} |
{ok,deleted} (ref ต้องอยู่ใต้ไดเรกทอรี backups) |
prune |
{package,user?,keep} |
{ok,pruned:[...]} เก็บ N ล่าสุดของ package |
log-read |
{limit?} |
{ok,entries:[...]} audit log, ใหม่สุดก่อน |
log-export |
{user?} |
{ok:true,path} (path สัมบูรณ์ของไฟล์ .txt ที่เขียนไว้ใต้ไดเรกทอรี backup) หรือ {ok:false,code:"ERR_LOG_EXPORT"} เขียน activity log (audit.jsonl) พร้อมส่วนหัว build/อุปกรณ์สั้น ๆ ลงในไฟล์ข้อความเดียวที่ผู้ใช้มองเห็นได้ เพื่อให้แนบไปกับรายงานบั๊กได้ ไม่ detached, คืนค่าทันที |
special-categories |
{} |
{ok,categories:[{id,available}]} (messages/contacts/wifi/bluetooth/calendar/wallpaper/dns/system_settings) |
special-backup |
{categories,compression?,password?,portable?} |
{ok,opid} การสำรองระดับทั้งระบบ (detached) |
special-restore |
{ref,confirm:true,categories?,password?} |
{ok,opid} (ต้องรีบูต; confirm เป็นตัวกั้น) |
special-list |
{} |
{ok,backups:[{ref,created_at,categories}]} |
path-backup |
{path,compression?,password?} |
{ok,opid} สำรองพาธสัมบูรณ์ใด ๆ เป็น tar.zst+manifest.json ใต้ .paths/ (detached) |
path-restore |
{ref,confirm:true,password?} |
{ok,opid} กู้คืนการสำรองพาธไปยังตำแหน่งเดิมของมัน (confirm เป็นตัวกั้น; detached) |
sysmount-status |
{} |
{ok,nomount,nm,ksu,live_capable} |
sysmount-add / sysmount-del / sysmount-list
|
{package,priv?} |
เมานต์แอปที่ติดตั้งให้เป็นแอประบบ (โมดูลย่อยแบบ systemless; มีผลทันทีผ่าน NoMount มิฉะนั้นเมื่อบูตครั้งถัดไป) |
companion-status / companion-install
|
{} |
สถานะ / การติดตั้งตามความต้องการของตัวเสริม Google Drive |
dests-list / dest-add / dest-test / dest-del
|
{id,type,...} |
การจัดการปลายทาง |
remote-add / remote-list / remote-del
|
{name,backend,params:{...}} |
การจัดการ rclone remote (สร้างรายการใน rclone.conf ที่ปลายทาง type:"rclone" ชี้ไป); backend เป็น rclone backend ใดก็ได้ ไม่มี whitelist |
remote-authorize |
{backend} |
{ok:true,url} (เอนจินได้เปิดเบราว์เซอร์ของโทรศัพท์ไปยัง URL ขอความยินยอมนั้นแล้วผ่าน Android VIEW intent) หรือ {ok:false,code:"ERR_AUTHORIZE"} รัน rclone authorize <backend> บน callback server ในเครื่อง (127.0.0.1:53682) เพื่อทำ OAuth บนอุปกรณ์ |
remote-authorize-poll |
{} |
{ok:true,done:false,url} ขณะกำลังรอ, {ok:true,done:true,token} เมื่อผู้ใช้ให้ความยินยอมแล้ว (token ที่จะส่งให้ remote-add), หรือ {ok:false,code:"ERR_AUTHORIZE"}
|
remote-authorize-cancel |
{} |
{ok:true,cancelled:true}; หยุดการอนุญาตที่ค้างอยู่ |
cloud-status |
{} |
{ok,rclone,restic,fetchable,size} (ไบนารี rclone/restic มีอยู่หรือไม่, รุ่น lite นี้ดึงมาได้หรือไม่, ขนาดดาวน์โหลดเป็นไบต์) |
cloud-fetch |
{} |
{ok,opid} (detached) ดาวน์โหลด+ตรวจสอบ+ติดตั้งส่วนเสริม rclone/restic บนรุ่น lite
|
schedule-set / schedule-list / schedule-delete
|
ดูด้านล่าง | งานที่ตั้งเวลาไว้ (การ backup หรือการกู้คืน; กำหนดเป้าหมายเป็นแอปเดียว ชุดของแอป หรือแอปทั้งหมด) |
scheduler-tick |
{} |
รันงานที่ถึงกำหนด + ใช้การเก็บรักษา (retention) + ตัวสังเกตการสำรองอัตโนมัติ (heartbeat ตอนบูตเรียกสิ่งนี้) |
update-check |
{} |
{ok,current_version,current_code,latest_version,latest_code,update_available,zipUrl,changelog,notes} (ไม่ detached; คืนค่าทันที; ERR_UPDATE_CHECK เมื่อล้มเหลว - ดูด้านล่าง) |
การ poll progress จะคืน progress-<opid>.json แบบสดของการดำเนินการนั้น ฟิลด์เหล่านี้
มีอยู่เสมอ:
| ฟิลด์ | ชนิด | ความหมาย |
|---|---|---|
opid |
string | id ของการดำเนินการ |
percent |
int | ความคืบหน้า 0-100 |
phase |
string | ป้ายเฟสปัจจุบัน |
item |
string | ชนิด item ที่กำลังประมวลผลอยู่ |
done |
bool | เป็น true เมื่อเขียนครั้งสุดท้าย (finish / dry-run / restore-test) |
การดำเนินการที่กำลังรันยังอาจมีฟิลด์สดแบบ ทางเลือก (optional) เหล่านี้ด้วย ฟิลด์เหล่านี้จะหายไป หรือว่างเมื่อไม่ทราบค่า และ ถูกละไว้เมื่อเขียนครั้งสุดท้าย (finish / dry-run / restore-test):
| ฟิลด์ | ชนิด | ความหมาย |
|---|---|---|
rate |
string | ความเร็วการถ่ายโอน เช่น "4.2 MiB/s" (ว่าง = ไม่ทราบ) |
eta |
string | เวลาที่เหลือโดยประมาณ เช่น "1m12s" (ว่าง = ไม่ทราบ) |
n |
int | ดัชนี item ปัจจุบัน (0 = ไม่ทราบ) |
of |
int | จำนวน item ทั้งหมด (0 = ไม่ทราบ) |
cur |
string | ชื่อ item ปัจจุบัน (ว่าง = ไม่มี) |
การถ่ายโอนแบบคลาวด์จะเติม rate/eta (percent มาจาก rclone) ส่วน backup แบบ Full ในเครื่องจะเติม
n/of/cur ป้ายเฟสมีเฟสการผนึก checksum คือ verified และสำหรับการถ่ายโอนแบบคลาวด์คือ
transfer และ mirror <item>
{
"package": "com.example.app",
"user": 0,
"mode": "full", // full | snapshot | mirror
"compression": "zstd:10", // none | lz4 | zstd[:N] | gzip
"items": ["apk","data","data_de","obb","external","media"],
"encrypt_data": false,
"encrypt_apk": false,
"dest": "local", // local | <destination id>
"verify": true, // re-hash each archive vs the manifest (default on for Full)
"dry_run": false, // true = report a size plan, write nothing
"ssaid": false, // OPT-IN, see below
"manual": false // true = single interactive backup, keeps these exact items;
// omit/false lets config.app_items (a per-app item map) override
// the set on bulk, auto and scheduled runs
}restore/import รับ {ref} (ไดเรกทอรี backup / scan ref) restore ยังรับ:
"items" (ชุดย่อยของประเภท item ในการสำรองที่จะกู้คืน; ละไว้เพื่อกู้คืนทั้งหมด), "test": true
(แตกไฟล์ไปยังไดเรกทอรีชั่วคราวและตรวจสอบ โดยไม่แตะแอปที่ใช้งานจริง), "mode" สำหรับ snapshot/mirror,
"password" สำหรับ backup ที่เข้ารหัส, "ssaid" (opt-in) และตัวเลือกแหล่งติดตั้ง
"spoof_installer" (ค่าเริ่มต้นจาก config, ตั้ง installer เป็น Play Store ตอนติดตั้ง) และ
"deep_spoof": true (ขั้นสูงแบบ opt-in; ยังปลอมแปลง initiating package และ package source ด้วย
การแก้ไขฐานข้อมูล package มีผลหลังรีบูต) ส่วน import รับ "from": "neo" | "databackup" และสำหรับ
Neo backup ที่เข้ารหัสไว้ จะรับ "password"
งานที่ตั้งเวลาจะเลือก หนึ่ง เป้าหมายและ การกระทำ หนึ่งอย่าง:
{
"id": "nightly-games",
"action": "backup", // "backup" (ค่าเริ่มต้น) | "restore"
"package": "com.example.app", // แอปเดียว - หรือ -
"packages": ["com.a","com.b"], // ชุดของแอป - หรือ -
"all": true, // แอปทั้งหมด ลบด้วยรายการแอปที่ยกเว้น
"cron": "daily", // hourly | daily | weekly
"at": "02:30", // HH:MM
"mode": "full",
"dest": "local",
"keep": 5,
"items": ["apk","data"],
"require_wifi": false, // เกต: รันเฉพาะเมื่ออยู่บน Wi-Fi
"require_charging": false, // เกต: รันเฉพาะขณะกำลังชาร์จ
"min_battery": 0, // เกต: รันเฉพาะเมื่อแบตเตอรี่ % นี้ขึ้นไป (0-100)
"days": [1,2,3,4,5] // เกต: รันเฉพาะวันเหล่านี้ (0=อาทิตย์)
}ระบุ package, packages หรือ all อย่างใดอย่างหนึ่ง เพียงหนึ่งเดียว สำหรับเป้าหมาย งาน backup
จะคง mode/dest/keep/items ตามปกติไว้ ส่วนงาน restore (action: "restore") จะกู้คืน backup
ล่าสุด ของแต่ละแอปเป้าหมาย (หรือ ref ที่ระบุชัดเจน) และ เขียนทับข้อมูลปัจจุบันของแอปทุกครั้งที่รัน -
สิ่งนี้เป็นไปโดยเจตนาและเป็นแบบ opt-in ดังนั้นจงตั้งค่ามันเฉพาะเมื่อผู้ใช้ร้องขอโดยตรงเท่านั้น
งานที่ตั้งเวลาอาจมี เงื่อนไขเกตแบบทางเลือก (gate conditions) ได้ เมื่อเกตของงานที่ถึงกำหนดไม่เป็นไปตามเงื่อนไข
งานนั้นจะ ถูกข้ามและลองใหม่ใน tick ถัดไป โดยไม่เลื่อนกำหนดการของมัน (last_run ของมันจะไม่ถูกประทับ
ดังนั้นมันจะเริ่มทำงานทันทีที่เงื่อนไขเป็นจริง):
| ฟิลด์ | ชนิด | เกต |
|---|---|---|
require_wifi |
bool | รันเฉพาะขณะอยู่บน Wi-Fi |
require_charging |
bool | รันเฉพาะขณะกำลังชาร์จ |
min_battery |
int (0-100) | รันเฉพาะเมื่อแบตเตอรี่อยู่ที่ระดับนี้ขึ้นไป |
days |
array of int (0-6, 0=อาทิตย์) | รันเฉพาะวันเหล่านี้ |
นอกเหนือจากนี้ จะมีการตรวจ ความปลอดภัยด้านความร้อน (thermal safety) ขั้นต่ำเสมอ: การดำเนินการที่ตั้งเวลา
จะถูกข้ามขณะที่อุปกรณ์ร้อนจัดจนอันตราย การข้ามด้วยเกตทุกครั้งจะถูกเขียนลง audit trail เป็น
op:"scheduler-gated" พร้อม reason อย่างใดอย่างหนึ่งใน wifi / charging / battery / days /
thermal
ปลายทางคลาวด์คือปลายทาง type:"rclone" ที่ระบุชื่อ rclone remote จงสร้าง remote นั้นก่อน
ด้วย remote-add ค่า backend เป็น rclone backend ใดก็ได้ - ไม่มี whitelist remote-add
รับชื่อ backend ใดก็ได้ (dropbox, onedrive, box, pcloud, mega, b2, s3, sftp,
smb, webdav, ftp, drive และอีก ~70 ตัวที่ rclone รองรับ) และ params จะถูกส่งต่อตรงไป
ยังคอนฟิก rclone เป็นคู่ key=value ช่องรหัสผ่านจะถูกเก็บแบบบดบัง (obscured) ไม่เคยเก็บแบบ
ข้อความเปล่า backend ที่พบบ่อยและ params ของมัน:
sftp : host, port, user, pass smb : host, port, user, pass
ftp : host, port, user, pass webdav: url, vendor, user, pass
s3 : provider, access_key_id, secret_access_key, endpoint, region
drive : token, scope (token = output of `rclone authorize "drive"`)
OAuth บนอุปกรณ์ (ไม่ต้องใช้พีซี) backend ที่ต้องการการลงชื่อเข้าใช้ผ่านเบราว์เซอร์ (Google Drive,
Dropbox, OneDrive, Box, pCloud) ไม่จำเป็นต้องใช้เดสก์ท็อปหรือการวาง token ด้วยมือ เรียก
remote-authorize ด้วย {backend}: เอนจินจะรัน rclone authorize <backend> กับ callback server
ในเครื่อง (127.0.0.1:53682) และเปิดเบราว์เซอร์ของโทรศัพท์เองไปยังหน้าขอความยินยอมของผู้ให้บริการ
ผ่าน Android VIEW intent โดยคืนค่า {ok:true,url} (หรือ {ok:false,code:"ERR_AUTHORIZE"}) แล้ว
poll remote-authorize-poll ({}): มันจะคืน {ok:true,done:false,url} ขณะกำลังรอ และ
{ok:true,done:true,token} เมื่อผู้ใช้อนุมัติ - ส่ง token นั้นให้ remote-add ส่วน
remote-authorize-cancel ({}) จะหยุดการอนุญาตที่ค้างอยู่ ({ok:true,cancelled:true})
การวางผลลัพธ์ของ rclone authorize "<backend>" จากคอมพิวเตอร์เครื่องใดก็ได้ด้วยมือยังคงรองรับเป็นทางเลือกสำรอง
Google Drive มีสองเส้นทาง: drive remote นี้ (ไม่ต้องใช้โปรเจกต์ Google Cloud ใช้ OAuth ของ
rclone เอง - อนุญาตบนอุปกรณ์ด้วย remote-authorize หรือรัน rclone authorize "drive" ครั้งเดียว
บนคอมพิวเตอร์เครื่องใดก็ได้แล้วส่ง token มา) หรือแอปคู่หู (companion) แบบ opt-in (OAuth client id
ของคุณเอง) ทั้งสองทางลงเอยเป็นปลายทางธรรมดา
ฟิลด์ config network_policy ควบคุมว่าการโอนย้ายไปคลาวด์จะใช้การเชื่อมต่อแบบใดได้:
any (ค่าเริ่มต้น), wifi, หรือ mobile ตั้งค่าด้วย config-set เมื่อเป็น wifi หรือ
mobile การโอนย้ายไปคลาวด์ทุกครั้ง (การอัปโหลด Full rclone/Drive, การ sync แบบ Mirror, การ
backup/restore snapshot restic ระยะไกล, การ restore แบบ Mirror) จะตรวจทรานสปอร์ตที่ใช้งานอยู่ก่อน
และยกเลิกด้วย ERR_NET_POLICY หากไม่ตรงกัน - ทั้งสำหรับงานที่ทำเองและงานที่ตั้งเวลา ปลายทางในเครื่อง
จะไม่ถูกจำกัดเลย
-
การผนึก checksum (คลาวด์) หลังจากการคัดลอกขึ้นคลาวด์สำเร็จ เอนจินจะรันการตรวจ checksum ระยะไกล
(
rclone check) หากไม่ตรงกันจะทำให้การดำเนินการล้มเหลวด้วยERR_VERIFYส่วนแบ็กเอนด์ที่ไม่มีแฮช ร่วมกับฝั่งในเครื่องจะถูกข้าม (ไม่ถือว่าล้มเหลว) -
การตรวจโควตา (คลาวด์, โหมด Full) ก่อนการอัปโหลดโหมด Full ไปยัง
rcloneremote เอนจินจะสอบถาม พื้นที่ว่างของ remote (rclone about --json) และปฏิเสธด้วยERR_QUOTAหาก backup จะใส่ไม่พอ remote ที่ไม่รายงานข้อมูลโควตาจะถูกข้าม โหมด Mirror เป็นการซิงก์แบบเดลตาจึงได้รับการยกเว้น
รุ่น full รวมไบนารีทั้งหมดไว้ในตัวและไม่ต้องใช้เครือข่ายเลย ส่วนรุ่น lite ละไว้สองตัวที่ใหญ่ที่สุดคือ
rclone และ restic และดึงมาแบบตามต้องการในครั้งแรกที่คุณรันการกระทำแบบคลาวด์หรือ snapshot
cloud-status รายงานว่ามีอยู่แล้วหรือไม่, รุ่นนี้ดึงมาได้หรือไม่, และขนาดดาวน์โหลดเป็นไบต์ cloud-fetch
ทำงานแบบ detached (ให้ poll progress ด้วย opid ของมัน): มันดาวน์โหลดส่วนเสริม
rclone+restic ตามสถาปัตยกรรม, ตรวจสอบกับ SHA-256 ที่ฝังไว้ในโมดูล, และติดตั้งลงในแคชรันไทม์
เฟสความคืบหน้าคือ downloading, verifying และ installing; รหัสสุดท้ายคือ ERR_NONE เมื่อสำเร็จ
หรือ ERR_FETCH (ดาวน์โหลดล้มเหลว) / ERR_FETCH_VERIFY (เช็กซัมไม่ตรง ถูกทิ้ง) เมื่อล้มเหลว
บนรุ่น full ไม่จำเป็นต้องใช้ การทำ backup/restore ไปยังปลายทางคลาวด์หรือ snapshot บนรุ่น lite
ก่อนที่ไบนารีจะมีอยู่ จะล้มเหลวด้วย ERR_CLOUD_FETCHABLE; ไคลเอนต์ควรเสนอให้รัน cloud-fetch
แล้วลองใหม่
special-categories รายงานว่าอุปกรณ์มีหมวดหมู่ระดับทั้งระบบใดบ้าง; special-backup จับหมวดที่คุณส่งใน
categories และ special-restore นำกลับมาใช้ใหม่ หมวดหมู่มีดังนี้:
| หมวดหมู่ | มันคืออะไร | ความหมายของการกู้คืน |
|---|---|---|
messages |
SMS/MMS | แทนที่ผ่าน provider (ล้าง + แตกไฟล์) |
contacts |
รายชื่อติดต่อและบันทึกการโทร | แทนที่ผ่าน provider (ล้าง + แตกไฟล์) |
wifi |
เครือข่าย Wi-Fi ที่บันทึกไว้ | แทนที่ผ่าน provider (ล้าง + แตกไฟล์) |
bluetooth |
การจับคู่ Bluetooth | แทนที่ผ่าน provider (ล้าง + แตกไฟล์) |
calendar |
provider ปฏิทิน (com.android.providers.calendar, แอป + ข้อมูล); ยังส่งออกแบบพกพาไปยัง calendar.json ด้วย |
แทนที่ผ่าน provider (ล้าง + แตกไฟล์) |
wallpaper |
วอลเปเปอร์หน้าจอหลักและหน้าจอล็อก พร้อม wallpaper_info.xml เก็บแบบดิบ (ไบนารี) |
แทนที่ไฟล์ |
dns |
โหมดและตัวระบุ DNS ส่วนตัว อ่านจากการตั้งค่า |
settings put แบบ idempotent |
system_settings |
ดัมป์การตั้งค่า system/global/secure แบบเต็ม |
opt-in, settings put แบบ idempotent, เขียนทับการตั้งค่าของอุปกรณ์ |
system_settings เป็น opt-in อย่างเคร่งครัดและทำลายข้อมูลเมื่อกู้คืน เช่นเดียวกับ ssaid มันเขียนทับ
การตั้งค่าระดับทั้งอุปกรณ์เมื่อถูกกู้คืน จึงถูกกั้นไว้หลังความยินยอมที่ชัดแจ้งของผู้ใช้และบันทึกลงใน audit trail
อย่าเลือกมันโดยค่าเริ่มต้นเด็ดขาด; เฉพาะเมื่อผู้ใช้ร้องขอโดยตรงและตั้งใจเท่านั้น
path-backup / path-restore สำรองและกู้คืน พาธสัมบูรณ์ใด ๆ - โฟลเดอร์หรือไฟล์เดี่ยว - บนที่จัดเก็บ
ที่แชร์หรือใต้ /data นอกโมเดลต่อแอป archive ถูกเขียนเป็น tar.zst บวก manifest.json ในรูปแบบของ
VDBackup เอง (ผนึกด้วย SHA-256 พร้อมชุด RECOVERY เมื่อเข้ารหัส) ใต้ .paths/ ในไดเรกทอรี backups
// path-backup
{ "path": "/sdcard/DCIM/Camera", "compression": "zstd:10", "password": "..." }
// path-restore
{ "ref": "<.paths ref>", "confirm": true, "password": "..." }- พาธต้นทางต้องเป็น สัมบูรณ์ และอยู่ใต้รากที่อนุญาตอย่างใดอย่างหนึ่ง:
/storage/emulated,/data/media,/sdcard,/dataพาธที่ไม่มีอยู่จะล้มเหลวด้วยERR_NO_PATH; พาธที่อยู่นอกรากที่อนุญาต หรือที่มี..จะล้มเหลวด้วยERR_BAD_PATH -
path-restoreเขียนกลับไปยังตำแหน่งเดิม จึงเป็นการทำลายข้อมูลและต้องการ"confirm": true- ตัวกั้นที่มีแรงเสียดทานสูง เช่นเดียวกับspecial-restorerefที่ไม่ใช่การสำรองพาธที่ถูกต้องจะล้มเหลวด้วยERR_BAD_REF - ทั้งคู่รันแบบ detached; poll
progressด้วยopidที่คืนมา
update-check รายงานว่ามีการเผยแพร่เวอร์ชันใหม่กว่าของโมดูลหรือไม่ เพื่อให้ agent (หรือ WebUI)
แสดงได้ มันเป็น read verb ที่คืนค่าทันที - มันไม่ใช่ detached จึงไม่มี opid ให้ poll
มันถูกเรียกเฉพาะจากการกระทำที่ชัดเจนของผู้ใช้ และดึง manifest การอัปเดตที่เผยแพร่ของโมดูล
(URL updateJson จาก module.prop) ด้วย curl ที่มาพร้อมกันผ่านคำขอ HTTP ฝั่ง root - สิ่งนี้
ทำงานนอก WebView จึงไม่อยู่ภายใต้ CSP ของ WebUI - แล้วเปรียบเทียบ versionCode ที่เผยแพร่กับที่
ติดตั้งอยู่ มันไม่รับอาร์กิวเมนต์ใด ๆ
เมื่อสำเร็จจะคืนค่า:
| ฟิลด์ | ชนิด | ความหมาย |
|---|---|---|
ok |
bool | true |
current_version |
string | versionName ที่ติดตั้ง |
current_code |
int | versionCode ที่ติดตั้ง |
latest_version |
string | versionName ที่เผยแพร่ |
latest_code |
int | versionCode ที่เผยแพร่ |
update_available |
bool |
true เมื่อ latest_code มากกว่า current_code
|
zipUrl |
string | URL ของ zip ที่เผยแพร่ |
changelog |
string | URL ของ changelog ที่เผยแพร่ |
notes |
string | บันทึกการเผยแพร่ |
หากไม่มี URL updateJson คำขอเครือข่ายล้มเหลว หรือ parse manifest ไม่ได้ มันจะคืนค่า
{"ok":false,"code":"ERR_UPDATE_CHECK"}
update-check เพียง รายงาน ความพร้อมใช้งานและบันทึกการเผยแพร่เท่านั้น ส่วนการอัปเดตจริงทำโดย
ตัวจัดการ root ของคุณ (KernelSU / APatch / Magisk) ผ่าน updateJson ของโมดูล ไม่ใช่โดย verb นี้
-
ssaidเป็น opt-in อย่างเคร่งครัด (ค่าเริ่มต้นปิด) มันสำรอง/กู้คืน ANDROID_ID ของอุปกรณ์ โดยการเขียนทับไฟล์ระบบ การ restore จะมีผลหลังรีบูตเท่านั้น และไฟล์เดิมจะถูกบันทึกไว้ก่อนเสมอ เพื่อการย้อนกลับ ส่ง"ssaid": trueเฉพาะเมื่อผู้ใช้ร้องขอโดยตรงและตั้งใจเท่านั้น - ไม่เคยทำโดยปริยาย -
การกระทำที่เปลี่ยนแปลงข้อมูล (restore, delete, import) เป็นการทำลายข้อมูล และถูกบันทึกลงใน
audit trail ในเครื่อง (
logs/audit.jsonl) การ restore เป็นไปอย่างซื่อตรง (ล้างแล้วจึงแตกไฟล์) จึงย้อนแอปกลับไปสู่สถานะที่ตรงเป๊ะของ backup นั้น จงยืนยันเจตนาก่อนเรียกใช้มัน -
system_settingsเป็น opt-in และทำลายข้อมูล เหมือนssaidทุกประการ การกู้คืนมันจะเขียนทับ การตั้งค่าระดับทั้งอุปกรณ์ จงส่งมันเฉพาะเมื่อผู้ใช้ร้องขอโดยตรง; มันถูกกั้นด้วยความยินยอมที่ชัดแจ้งและถูกบันทึกใน audit trail -
การกู้คืนเป็นแบบ idempotent การกู้คืน provider แบบดิบ (messages/contacts/wifi/bluetooth/
calendar) จะ แทนที่ แทนที่จะผสาน - ข้อมูล provider ถูกล้างและ archive ถูกแตกทับลงไป - ดังนั้น
การกู้คืน backup เดิมซ้ำจึงไม่สามารถสร้างแถวซ้ำได้ ส่วน
dnsและsystem_settingsถูกนำกลับมาใช้ด้วยsettings putแบบ idempotent -
การแตก archive มีการป้องกัน path traversal การ restore รันเป็น root ดังนั้นทุก archive (restore,
import, special-restore, path-restore) ถูกตรวจก่อนการเขียนใด ๆ: archive ที่สมาชิกใช้พาธสัมบูรณ์หรือมี
..จะถูกปฏิเสธตั้งแต่ต้นด้วยERR_UNSAFE_ARCHIVEก่อนที่จะมีการเขียนทำลายข้อมูลแม้แต่ครั้งเดียว (GNU tar ยังรันด้วย--no-absolute-names) archive ที่ถูกดัดแปลงไม่มีวันหลุดออกจากไดเรกทอรีเป้าหมายได้ -
ห้ามลดทอน การคงรักษา (SELinux/uid/gid/modes/xattr) หรือกฎของ APK (APK จะถูกบีบอัดเสมอ
ไม่เคยเข้ารหัสเว้นแต่ตั้ง
encrypt_apk) - จงถือเอาเอาต์พุต JSON เป็นแหล่งความจริง ตรวจ
ok/code, pollprogress, และแสดงรหัสERR_*ออกมาแทนที่จะเดา
ดู ARCHITECTURE.md และ FILE-STRUCTURE.md สำหรับรายละเอียดภายใน
เอกสารนี้สร้างขึ้นด้วย Claude (Anthropic) และดูแลโดย VD171 ยินดีรับการแก้ไขและปรับปรุง - ดู CONTRIBUTING.md