Merge "Change Terminal app's image tag to SDK_INT_FULL" into main
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/MainActivity.kt b/android/TerminalApp/java/com/android/virtualization/terminal/MainActivity.kt
index 662fef5..35c5570 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/MainActivity.kt
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/MainActivity.kt
@@ -29,7 +29,6 @@
import android.os.ConditionVariable
import android.os.Environment
import android.os.SystemProperties
-import android.os.Trace
import android.provider.Settings
import android.util.DisplayMetrics
import android.util.Log
@@ -328,7 +327,7 @@
val stopIntent = Intent()
stopIntent.setClass(this, VmLauncherService::class.java)
- stopIntent.setAction(VmLauncherService.ACTION_STOP_VM_LAUNCHER_SERVICE)
+ stopIntent.setAction(VmLauncherService.ACTION_SHUTDOWN_VM)
val stopPendingIntent =
PendingIntent.getService(
this,
@@ -363,7 +362,6 @@
)
.build()
- Trace.beginAsyncSection("executeTerminal", 0)
run(this, this, notification, getDisplayInfo())
}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/TerminalTabFragment.kt b/android/TerminalApp/java/com/android/virtualization/terminal/TerminalTabFragment.kt
index 5c01ead..7e78235 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/TerminalTabFragment.kt
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/TerminalTabFragment.kt
@@ -19,7 +19,6 @@
import android.graphics.Bitmap
import android.net.http.SslError
import android.os.Bundle
-import android.os.Trace
import android.util.Log
import android.view.LayoutInflater
import android.view.View
@@ -145,7 +144,6 @@
object : WebView.VisualStateCallback() {
override fun onComplete(completedRequestId: Long) {
if (completedRequestId == requestId) {
- Trace.endAsyncSection("executeTerminal", 0)
bootProgressView.visibility = View.GONE
terminalView.visibility = View.VISIBLE
terminalView.mapTouchToMouseEvent()
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.kt b/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.kt
index 345e8dd..2d7468d 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.kt
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.kt
@@ -31,7 +31,7 @@
import android.os.Parcel
import android.os.Parcelable
import android.os.ResultReceiver
-import android.os.Trace
+import android.os.SystemProperties
import android.system.virtualmachine.VirtualMachine
import android.system.virtualmachine.VirtualMachineCustomImageConfig
import android.system.virtualmachine.VirtualMachineCustomImageConfig.AudioConfig
@@ -63,6 +63,7 @@
import java.util.concurrent.CompletableFuture
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
+import java.util.concurrent.TimeUnit
class VmLauncherService : Service() {
inner class VmLauncherServiceBinder : android.os.Binder() {
@@ -71,8 +72,9 @@
private val binder = VmLauncherServiceBinder()
+ private lateinit var executorService: ExecutorService
+
// TODO: using lateinit for some fields to avoid null
- private var executorService: ExecutorService? = null
private var virtualMachine: VirtualMachine? = null
private var resultReceiver: ResultReceiver? = null
private var server: Server? = null
@@ -167,8 +169,13 @@
}
}
+ override fun onCreate() {
+ super.onCreate()
+ executorService = Executors.newCachedThreadPool(TerminalThreadFactory(applicationContext))
+ }
+
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
- if (intent.action == ACTION_STOP_VM_LAUNCHER_SERVICE) {
+ if (intent.action == ACTION_SHUTDOWN_VM) {
if (debianService != null && debianService!!.shutdownDebian()) {
// During shutdown, change the notification content to indicate that it's closing
val notification = createNotificationForTerminalClose()
@@ -184,7 +191,6 @@
Log.d(TAG, "VM instance is already started")
return START_NOT_STICKY
}
- executorService = Executors.newCachedThreadPool(TerminalThreadFactory(applicationContext))
val image = InstalledImage.getDefault(this)
val json = ConfigJson.from(this, image.configPath)
@@ -200,15 +206,12 @@
}
val config = configBuilder.build()
- Trace.beginSection("vmCreate")
val runner: Runner =
try {
create(this, config)
} catch (e: VirtualMachineException) {
throw RuntimeException("cannot create runner", e)
}
- Trace.endSection()
- Trace.beginAsyncSection("debianBoot", 0)
virtualMachine = runner.vm
resultReceiver =
@@ -222,7 +225,7 @@
stopSelf()
}
val logDir = getFileStreamPath(virtualMachine!!.name + ".log").toPath()
- Logger.setup(virtualMachine!!, logDir, executorService!!)
+ Logger.setup(virtualMachine!!, logDir, executorService)
val notification =
intent.getParcelableExtra<Notification?>(EXTRA_NOTIFICATION, Notification::class.java)
@@ -246,6 +249,15 @@
},
executorService,
)
+ .exceptionallyAsync(
+ { e ->
+ Log.e(TAG, "Failed to start VM", e)
+ resultReceiver!!.send(RESULT_ERROR, null)
+ stopSelf()
+ null
+ },
+ executorService,
+ )
return START_NOT_STICKY
}
@@ -282,13 +294,15 @@
}
},
)
+
+ resolvedInfo.orTimeout(VM_BOOT_TIMEOUT_SECONDS.toLong(), TimeUnit.SECONDS)
return resolvedInfo
}
private fun createNotificationForTerminalClose(): Notification {
val stopIntent = Intent()
stopIntent.setClass(this, VmLauncherService::class.java)
- stopIntent.setAction(ACTION_STOP_VM_LAUNCHER_SERVICE)
+ stopIntent.setAction(ACTION_SHUTDOWN_VM)
val stopPendingIntent =
PendingIntent.getService(
this,
@@ -411,7 +425,7 @@
return
}
- executorService!!.execute(
+ executorService.execute(
Runnable {
// TODO(b/373533555): we can use mDNS for that.
val debianServicePortFile = File(filesDir, "debian_service_port")
@@ -439,10 +453,9 @@
Log.e(TAG, "failed to stop a VM instance", e)
}
}
- executorService?.shutdownNow()
- executorService = null
virtualMachine = null
}
+ executorService.shutdownNow()
super.onDestroy()
}
@@ -456,8 +469,7 @@
private const val ACTION_START_VM_LAUNCHER_SERVICE =
"android.virtualization.START_VM_LAUNCHER_SERVICE"
const val EXTRA_DISPLAY_INFO = "EXTRA_DISPLAY_INFO"
- const val ACTION_STOP_VM_LAUNCHER_SERVICE: String =
- "android.virtualization.STOP_VM_LAUNCHER_SERVICE"
+ const val ACTION_SHUTDOWN_VM: String = "android.virtualization.ACTION_SHUTDOWN_VM"
private const val RESULT_START = 0
private const val RESULT_STOP = 1
@@ -467,6 +479,19 @@
private const val KEY_TERMINAL_IPADDRESS = "address"
private const val KEY_TERMINAL_PORT = "port"
+ private val VM_BOOT_TIMEOUT_SECONDS: Int =
+ {
+ val deviceName = SystemProperties.get("ro.product.vendor.device", "")
+ val cuttlefish = deviceName.startsWith("vsoc_")
+ val goldfish = deviceName.startsWith("emu64")
+
+ if (cuttlefish || goldfish) {
+ 3 * 60
+ } else {
+ 30
+ }
+ }()
+
private const val INITIAL_MEM_BALLOON_PERCENT = 10
private const val MAX_MEM_BALLOON_PERCENT = 50
private const val MEM_BALLOON_INFLATE_INTERVAL_MILLIS = 60000L
@@ -516,7 +541,7 @@
fun stop(context: Context) {
val i = getMyIntent(context)
- i.setAction(ACTION_STOP_VM_LAUNCHER_SERVICE)
+ i.setAction(ACTION_SHUTDOWN_VM)
context.startService(i)
}
}
diff --git a/guest/pvmfw/src/main.rs b/guest/pvmfw/src/main.rs
index 9afbcc3..30624cd 100644
--- a/guest/pvmfw/src/main.rs
+++ b/guest/pvmfw/src/main.rs
@@ -41,7 +41,6 @@
use alloc::boxed::Box;
use bssl_avf::Digester;
use diced_open_dice::{bcc_handover_parse, DiceArtifacts, DiceContext, Hidden, VM_KEY_ALGORITHM};
-use hypervisor_backends::get_mem_sharer;
use libfdt::Fdt;
use log::{debug, error, info, trace, warn};
use pvmfw_avb::verify_payload;
@@ -99,15 +98,7 @@
}
let guest_page_size = verified_boot_data.page_size.unwrap_or(SIZE_4KB);
- // TODO(ptosi): Cache the (single?) granule once, in vmbase.
- let hyp_page_size = if let Some(mem_sharer) = get_mem_sharer() {
- Some(mem_sharer.granule().map_err(|e| {
- error!("Failed to get granule size: {e}");
- RebootReason::InternalError
- })?)
- } else {
- None
- };
+ let hyp_page_size = hypervisor_backends::get_granule_size();
let _ =
sanitize_device_tree(untrusted_fdt, vm_dtbo, vm_ref_dt, guest_page_size, hyp_page_size)?;
let fdt = untrusted_fdt; // DT has now been sanitized.
diff --git a/libs/libhypervisor_backends/src/hypervisor.rs b/libs/libhypervisor_backends/src/hypervisor.rs
index aa65133..7c274f5 100644
--- a/libs/libhypervisor_backends/src/hypervisor.rs
+++ b/libs/libhypervisor_backends/src/hypervisor.rs
@@ -152,3 +152,8 @@
pub fn get_device_assigner() -> Option<&'static dyn DeviceAssigningHypervisor> {
get_hypervisor().as_device_assigner()
}
+
+/// Gets the unique hypervisor granule size, if any.
+pub fn get_granule_size() -> Option<usize> {
+ get_hypervisor().get_granule_size()
+}
diff --git a/libs/libhypervisor_backends/src/hypervisor/common.rs b/libs/libhypervisor_backends/src/hypervisor/common.rs
index bfe638f..f229e14 100644
--- a/libs/libhypervisor_backends/src/hypervisor/common.rs
+++ b/libs/libhypervisor_backends/src/hypervisor/common.rs
@@ -32,6 +32,13 @@
fn as_device_assigner(&self) -> Option<&dyn DeviceAssigningHypervisor> {
None
}
+
+ /// Returns the granule used by all APIs (MEM_SHARE, MMIO_GUARD, device assignment, ...).
+ ///
+ /// If no such API is supported or if they support different granule sizes, returns None.
+ fn get_granule_size(&self) -> Option<usize> {
+ None
+ }
}
pub trait MmioGuardedHypervisor {
diff --git a/libs/libhypervisor_backends/src/hypervisor/geniezone.rs b/libs/libhypervisor_backends/src/hypervisor/geniezone.rs
index 76e010b..0913ff3 100644
--- a/libs/libhypervisor_backends/src/hypervisor/geniezone.rs
+++ b/libs/libhypervisor_backends/src/hypervisor/geniezone.rs
@@ -84,6 +84,10 @@
fn as_mem_sharer(&self) -> Option<&dyn MemSharingHypervisor> {
Some(self)
}
+
+ fn get_granule_size(&self) -> Option<usize> {
+ <Self as MemSharingHypervisor>::granule(self).ok()
+ }
}
impl MmioGuardedHypervisor for GeniezoneHypervisor {
diff --git a/libs/libhypervisor_backends/src/hypervisor/kvm_aarch64.rs b/libs/libhypervisor_backends/src/hypervisor/kvm_aarch64.rs
index 233097b..f183107 100644
--- a/libs/libhypervisor_backends/src/hypervisor/kvm_aarch64.rs
+++ b/libs/libhypervisor_backends/src/hypervisor/kvm_aarch64.rs
@@ -90,6 +90,10 @@
fn as_device_assigner(&self) -> Option<&dyn DeviceAssigningHypervisor> {
Some(self)
}
+
+ fn get_granule_size(&self) -> Option<usize> {
+ <Self as MemSharingHypervisor>::granule(self).ok()
+ }
}
impl MmioGuardedHypervisor for ProtectedKvmHypervisor {
diff --git a/libs/libhypervisor_backends/src/hypervisor/kvm_x86.rs b/libs/libhypervisor_backends/src/hypervisor/kvm_x86.rs
index 7f9ea4d..d72f788 100644
--- a/libs/libhypervisor_backends/src/hypervisor/kvm_x86.rs
+++ b/libs/libhypervisor_backends/src/hypervisor/kvm_x86.rs
@@ -84,6 +84,10 @@
fn as_mem_sharer(&self) -> Option<&dyn MemSharingHypervisor> {
Some(self)
}
+
+ fn get_granule_size(&self) -> Option<usize> {
+ <Self as MemSharingHypervisor>::granule(self).ok()
+ }
}
macro_rules! vmcall {
diff --git a/libs/libhypervisor_backends/src/lib.rs b/libs/libhypervisor_backends/src/lib.rs
index 33dc5ad..3c81ac8 100644
--- a/libs/libhypervisor_backends/src/lib.rs
+++ b/libs/libhypervisor_backends/src/lib.rs
@@ -24,5 +24,6 @@
pub use error::{Error, Result};
pub use hypervisor::{
- get_device_assigner, get_mem_sharer, get_mmio_guard, DeviceAssigningHypervisor, KvmError,
+ get_device_assigner, get_granule_size, get_mem_sharer, get_mmio_guard,
+ DeviceAssigningHypervisor, KvmError,
};