אפליקציה שתואמת ל-AVF מורכבת משני חלקים: החלק של האפליקציה שפועל במערכת ההפעלה המארחת של Android, והחלק של האפליקציה שפועל ב-Microdroid בתוך pVM.
החלק של האפליקציה שפועל ב-Android מטמיע את ממשק המשתמש, את הלוגיקה העסקית הלא סודית ויוצר ומנהל את מחזור החיים של pVM.
החלק של האפליקציה שפועל ב-Microdroid, בתוך pVM, אחראי לביצוע כל המשימות שצריך לבצע בצורה מאובטחת.
כדי להפעיל את החלק של pVM באפליקציה ולתקשר איתו, אפליקציית המארח יוצרת pVM ומריצה ספרייה משותפת של Native בתוך ה-pVM. הספרייה הזו מטמיעה שירות Binder שחלק המארח של האפליקציה משתמש בו כדי לתקשר עם החלק של האפליקציה בתוך pVM. איור 1 מציג את שני החלקים של האפליקציה ואת ערוץ התקשורת של ה-binder:
הגדרת קובץ התצורה
בקובץ vm_config.json
צריך להיות רשומה של מערכת ההפעלה של ה-pVM ושל הספרייה המשותפת. קובץ assets/vm_config.json
הבא מציג רשומות של קובץ תצורה עבור Microdroid וספרייה מקומית משותפת:
{
"os": {
"name": "microdroid"
},
"task": {
"type": "microdroid_launcher",
"command": "MicrodroidTestNativeLib.so"
}
}
הטמעה של שירות ה-binder
בספרייה המשותפת, מטמיעים שירות של קלסר. לדוגמה:
extern "C"
int android_native_main(int, char**) {
// Implement your binder service here
}
יצירת קוד אפליקציה
בחלק המארח של האפליקציה, יוצרים קוד שמכין את קובץ ההגדרות, טוען (או יוצר) נקודת אחיזה ל-VM ומריץ את ה-VM. לדוגמה:
// Prepare the configuration file
VirtualMachineConfig config = new VirtualMachineConfig
.Builder(getApplication(), "assets/vm_config.json")
.build();
// Load (or create) the handle to a VM
VirtualMachine vm = VirtualMachineManager
.getInstance(getApplication())
.getOrCreate("my_vm", config);
// Run the VM
vm.run();
תקשורת עם החלק של המכונה הווירטואלית באפליקציה
כדי לתקשר עם החלק של מכונת ה-VM באפליקציה, קודם צריך לרשום קריאה חוזרת כדי לקבל הודעה כשהשירות של ה-Binder במכונת ה-VM מוכן. כשמקבלים הודעה, מתחברים לשרת Binder ואז מתקשרים עם השרת באמצעות ממשק AIDL מותאם אישית. לדוגמה:
// Register the callback
vm.setCallback(Executors.newSingleThreadExecutor(),
new VirtualmachineCallback() {
@Override
public void onPayloadReady(VirtualMachine vm) {
// Connect to the binder server
IBinder binder = vm.connectToVsockServer(PORT).get();
IMyService svc = IMyService.Stub.asInterface(binder);
// Talk with server using custom AIDL interface
Result res = svc.doSomething();
}
}); //exception handling & proper threading omitted
vm.run();
כדי להוריד קוד מקור של אפליקציית הדגמה שמציגה את השלבים שמתוארים במסמך הזה, אפשר לעיין ב-MicrodroidDemo.