Merge "Fix failure in outputIsNotRedirectedToLogcatIfNotDebuggable"
diff --git a/tests/helper/src/java/com/android/microdroid/test/device/MicrodroidDeviceTestBase.java b/tests/helper/src/java/com/android/microdroid/test/device/MicrodroidDeviceTestBase.java
index 2d568d0..b877a77 100644
--- a/tests/helper/src/java/com/android/microdroid/test/device/MicrodroidDeviceTestBase.java
+++ b/tests/helper/src/java/com/android/microdroid/test/device/MicrodroidDeviceTestBase.java
@@ -53,12 +53,17 @@
import java.util.concurrent.TimeUnit;
public abstract class MicrodroidDeviceTestBase {
+ private static final String TAG = "MicrodroidDeviceTestBase";
private final String MAX_PERFORMANCE_TASK_PROFILE = "CPUSET_SP_TOP_APP";
public static boolean isCuttlefish() {
return DeviceProperties.create(SystemProperties::get).isCuttlefish();
}
+ public static boolean isUserBuild() {
+ return DeviceProperties.create(SystemProperties::get).isUserBuild();
+ }
+
public static String getMetricPrefix() {
return MetricsProcessor.getMetricPrefix(
DeviceProperties.create(SystemProperties::get).getMetricsTag());
@@ -82,13 +87,22 @@
Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
UiAutomation uiAutomation = instrumentation.getUiAutomation();
String cmd = "settaskprofile " + Os.gettid() + " " + MAX_PERFORMANCE_TASK_PROFILE;
- String out = runInShell("MicrodroidDeviceTestBase", uiAutomation, cmd).trim();
+ String out = runInShell(TAG, uiAutomation, cmd).trim();
String expect = "Profile " + MAX_PERFORMANCE_TASK_PROFILE + " is applied successfully!";
if (!expect.equals(out)) {
throw new IOException("Could not apply max performance task profile: " + out);
}
}
+ public final boolean getDebugPolicyBoolean(String debugPolicy) throws IOException {
+ Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+ UiAutomation uiAutomation = instrumentation.getUiAutomation();
+ String debugPolicyFilePath = "/proc/device-tree" + debugPolicy;
+ String cmd = "su root xxd -p " + debugPolicyFilePath;
+ String dp = runInShell(TAG, uiAutomation, cmd).trim();
+ return "00000001".equals(dp);
+ }
+
private Context mCtx;
private boolean mProtectedVm;
diff --git a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
index e0abe98..d05d9b3 100644
--- a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
+++ b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
@@ -28,6 +28,7 @@
import static com.google.common.truth.Truth.assertWithMessage;
import static com.google.common.truth.TruthJUnit.assume;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
+import static org.junit.Assume.assumeFalse;
import static org.junit.Assert.assertThrows;
import com.google.common.base.Strings;
@@ -52,6 +53,7 @@
import android.system.virtualmachine.VirtualMachineDescriptor;
import android.system.virtualmachine.VirtualMachineException;
import android.system.virtualmachine.VirtualMachineManager;
+import android.util.Log;
import com.android.compatibility.common.util.CddTest;
import com.android.microdroid.test.device.MicrodroidDeviceTestBase;
@@ -1518,6 +1520,22 @@
}
}
+ private boolean isConsoleOutputEnabledByDebugPolicy() {
+ if (isUserBuild()) {
+ Log.i(
+ TAG,
+ "Debug policy is inaccessible in userd build. Assumes that console output is"
+ + " disabled");
+ return false;
+ }
+ try {
+ return getDebugPolicyBoolean("/avf/guest/common/log");
+ } catch (IOException e) {
+ Log.i(TAG, "Fail to read debug policy. Assumes false", e);
+ return false;
+ }
+ }
+
private boolean checkVmOutputIsRedirectedToLogcat(boolean debuggable) throws Exception {
String time =
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"));
@@ -1551,6 +1569,9 @@
@Test
public void outputIsRedirectedToLogcatIfNotCaptured() throws Exception {
assumeSupportedKernel();
+ assumeFalse(
+ "Debug policy would turn on console output. Perhapse userdebug build?",
+ isConsoleOutputEnabledByDebugPolicy());
assertThat(checkVmOutputIsRedirectedToLogcat(true)).isTrue();
}
@@ -1558,6 +1579,9 @@
@Test
public void outputIsNotRedirectedToLogcatIfNotDebuggable() throws Exception {
assumeSupportedKernel();
+ assumeFalse(
+ "Debug policy would turn on console output. Perhapse userdebug build?",
+ isConsoleOutputEnabledByDebugPolicy());
assertThat(checkVmOutputIsRedirectedToLogcat(false)).isFalse();
}
diff --git a/virtualizationmanager/src/aidl.rs b/virtualizationmanager/src/aidl.rs
index 5cd523d..48e2431 100644
--- a/virtualizationmanager/src/aidl.rs
+++ b/virtualizationmanager/src/aidl.rs
@@ -325,6 +325,11 @@
None
};
+ let debug_level = match config {
+ VirtualMachineConfig::AppConfig(app_config) => app_config.debugLevel,
+ _ => DebugLevel::NONE,
+ };
+
let state = &mut *self.state.lock().unwrap();
let console_fd =
clone_or_prepare_logger_fd(config, console_fd, format!("Console({})", cid))?;
@@ -425,6 +430,7 @@
disks,
params: config.params.to_owned(),
protected: *is_protected,
+ debug_level,
memory_mib: config.memoryMib.try_into().ok().and_then(NonZeroU32::new),
cpus,
host_cpu_topology,
diff --git a/virtualizationmanager/src/crosvm.rs b/virtualizationmanager/src/crosvm.rs
index 942e69a..9db0971 100644
--- a/virtualizationmanager/src/crosvm.rs
+++ b/virtualizationmanager/src/crosvm.rs
@@ -16,6 +16,7 @@
use crate::aidl::{remove_temporary_files, Cid, VirtualMachineCallbacks};
use crate::atom::{get_num_cpus, write_vm_exited_stats};
+use crate::debug_config::should_prepare_console_output;
use anyhow::{anyhow, bail, Context, Error, Result};
use command_fds::CommandFdExt;
use lazy_static::lazy_static;
@@ -41,7 +42,10 @@
use std::time::{Duration, SystemTime};
use std::thread::{self, JoinHandle};
use android_system_virtualizationcommon::aidl::android::system::virtualizationcommon::DeathReason::DeathReason;
-use android_system_virtualizationservice::aidl::android::system::virtualizationservice::MemoryTrimLevel::MemoryTrimLevel;
+use android_system_virtualizationservice::aidl::android::system::virtualizationservice::{
+ MemoryTrimLevel::MemoryTrimLevel,
+ VirtualMachineAppConfig::DebugLevel::DebugLevel
+};
use android_system_virtualizationservice_internal::aidl::android::system::virtualizationservice_internal::IGlobalVmContext::IGlobalVmContext;
use binder::Strong;
use android_system_virtualmachineservice::aidl::android::system::virtualmachineservice::IVirtualMachineService::IVirtualMachineService;
@@ -97,6 +101,7 @@
pub disks: Vec<DiskFile>,
pub params: Option<String>,
pub protected: bool,
+ pub debug_level: DebugLevel,
pub memory_mib: Option<NonZeroU32>,
pub cpus: Option<NonZeroU32>,
pub host_cpu_topology: bool,
@@ -723,8 +728,18 @@
let ramdump_reserve = RAMDUMP_RESERVED_MIB + swiotlb_size_mib;
command.arg("--params").arg(format!("crashkernel={ramdump_reserve}M"));
}
- } else if config.ramdump.is_some() {
- command.arg("--params").arg(format!("crashkernel={RAMDUMP_RESERVED_MIB}M"));
+ } else {
+ if config.ramdump.is_some() {
+ command.arg("--params").arg(format!("crashkernel={RAMDUMP_RESERVED_MIB}M"));
+ }
+ if config.debug_level == DebugLevel::NONE
+ && should_prepare_console_output(config.debug_level)
+ {
+ // bootconfig.normal will be used, but we need log.
+ // pvmfw will add following commands by itself, but non-protected VM should do so here.
+ command.arg("--params").arg("printk.devkmsg=on");
+ command.arg("--params").arg("console=hvc0");
+ }
}
if let Some(memory_mib) = config.memory_mib {