Merge "Add the skeleton for the client-side API"
diff --git a/microdroid/sepolicy/system/private/hwservice_contexts b/microdroid/sepolicy/system/private/hwservice_contexts
index f4583e2..9b47b06 100644
--- a/microdroid/sepolicy/system/private/hwservice_contexts
+++ b/microdroid/sepolicy/system/private/hwservice_contexts
@@ -1,3 +1,4 @@
+android.hardware.keymaster::IKeymasterDevice u:object_r:hal_keymaster_hwservice:s0
android.hidl.allocator::IAllocator u:object_r:hidl_allocator_hwservice:s0
android.hidl.base::IBase u:object_r:hidl_base_hwservice:s0
android.hidl.manager::IServiceManager u:object_r:hidl_manager_hwservice:s0
diff --git a/microdroid/sepolicy/system/private/service_contexts b/microdroid/sepolicy/system/private/service_contexts
index 965b688..150c89a 100644
--- a/microdroid/sepolicy/system/private/service_contexts
+++ b/microdroid/sepolicy/system/private/service_contexts
@@ -10,8 +10,8 @@
android.security.compat u:object_r:keystore_compat_hal_service:s0
android.security.identity u:object_r:credstore_service:s0
android.security.keystore u:object_r:keystore_service:s0
+android.security.legacykeystore u:object_r:legacykeystore_service:s0
android.security.maintenance u:object_r:keystore_maintenance_service:s0
android.security.remoteprovisioning u:object_r:remoteprovisioning_service:s0
-android.security.vpnprofilestore u:object_r:vpnprofilestore_service:s0
apexservice u:object_r:apex_service:s0
* u:object_r:default_android_service:s0
diff --git a/microdroid/sepolicy/system/public/domain.te b/microdroid/sepolicy/system/public/domain.te
index d84abf1..799a2f1 100644
--- a/microdroid/sepolicy/system/public/domain.te
+++ b/microdroid/sepolicy/system/public/domain.te
@@ -677,6 +677,7 @@
-credstore_service
-keystore_maintenance_service
-keystore_service
+ -legacykeystore_service
-mediadrmserver_service
-mediaextractor_service
-mediametrics_service
@@ -684,7 +685,6 @@
-nfc_service
-radio_service
-virtual_touchpad_service
- -vpnprofilestore_service
-vr_hwc_service
-vr_manager_service
userdebug_or_eng(`-hal_face_service')
diff --git a/microdroid/sepolicy/system/public/keystore.te b/microdroid/sepolicy/system/public/keystore.te
index 155322c..43ee28d 100644
--- a/microdroid/sepolicy/system/public/keystore.te
+++ b/microdroid/sepolicy/system/public/keystore.te
@@ -20,7 +20,7 @@
add_service(keystore, keystore_compat_hal_service)
add_service(keystore, authorization_service)
add_service(keystore, keystore_maintenance_service)
-add_service(keystore, vpnprofilestore_service)
+add_service(keystore, legacykeystore_service)
# Check SELinux permissions.
selinux_check_access(keystore)
diff --git a/microdroid/sepolicy/system/public/service.te b/microdroid/sepolicy/system/public/service.te
index 74dc104..365515a 100644
--- a/microdroid/sepolicy/system/public/service.te
+++ b/microdroid/sepolicy/system/public/service.te
@@ -22,6 +22,7 @@
type keystore_compat_hal_service, service_manager_type;
type keystore_maintenance_service, service_manager_type;
type keystore_service, service_manager_type;
+type legacykeystore_service, service_manager_type;
type lpdump_service, service_manager_type;
type mediaserver_service, service_manager_type;
type mediametrics_service, service_manager_type;
@@ -44,7 +45,6 @@
type virtualization_service, service_manager_type;
type virtual_touchpad_service, service_manager_type;
type vold_service, service_manager_type;
-type vpnprofilestore_service, service_manager_type;
type vr_hwc_service, service_manager_type;
type vrflinger_vsync_service, service_manager_type;
diff --git a/microdroid/sepolicy/system/public/te_macros b/microdroid/sepolicy/system/public/te_macros
index 8d15d47..7dc5062 100644
--- a/microdroid/sepolicy/system/public/te_macros
+++ b/microdroid/sepolicy/system/public/te_macros
@@ -635,7 +635,7 @@
allow keystore $1:process getattr;
allow $1 apc_service:service_manager find;
allow $1 keystore_service:service_manager find;
- allow $1 vpnprofilestore_service:service_manager find;
+ allow $1 legacykeystore_service:service_manager find;
binder_call($1, keystore)
binder_call(keystore, $1)
')
diff --git a/virtualizationservice/Android.bp b/virtualizationservice/Android.bp
index a941742..c209f10 100644
--- a/virtualizationservice/Android.bp
+++ b/virtualizationservice/Android.bp
@@ -31,6 +31,7 @@
"libmicrodroid_payload_config",
"libprotobuf",
"libprotos",
+ "libregex",
"libserde_json",
"libserde",
"libshared_child",
diff --git a/virtualizationservice/src/aidl.rs b/virtualizationservice/src/aidl.rs
index b841ad0..5c0c3b8 100644
--- a/virtualizationservice/src/aidl.rs
+++ b/virtualizationservice/src/aidl.rs
@@ -16,7 +16,7 @@
use crate::composite::make_composite_image;
use crate::crosvm::{CrosvmConfig, DiskFile, VmInstance};
-use crate::payload;
+use crate::payload::{make_payload_disk, ApexInfoList};
use crate::{Cid, FIRST_GUEST_CID};
use android_system_virtualizationservice::aidl::android::system::virtualizationservice::IVirtualizationService::IVirtualizationService;
@@ -62,9 +62,19 @@
["com.android.adbd", "com.android.i18n", "com.android.os.statsd", "com.android.sdkext"];
/// Implementation of `IVirtualizationService`, the entry point of the AIDL service.
-#[derive(Debug, Default)]
+#[derive(Debug)]
pub struct VirtualizationService {
state: Mutex<State>,
+ apex_info_list: ApexInfoList,
+}
+
+impl VirtualizationService {
+ pub fn new() -> Result<VirtualizationService> {
+ Ok(VirtualizationService {
+ state: Default::default(),
+ apex_info_list: ApexInfoList::load()?,
+ })
+ }
}
impl Interface for VirtualizationService {}
@@ -109,13 +119,15 @@
let config = match config {
VirtualMachineConfig::AppConfig(config) => BorrowedOrOwned::Owned(
- load_app_config(config, &temporary_directory).map_err(|e| {
- error!("Failed to load app config from {}: {}", &config.configPath, e);
- new_binder_exception(
- ExceptionCode::SERVICE_SPECIFIC,
- format!("Failed to load app config from {}: {}", &config.configPath, e),
- )
- })?,
+ load_app_config(&self.apex_info_list, config, &temporary_directory).map_err(
+ |e| {
+ error!("Failed to load app config from {}: {}", &config.configPath, e);
+ new_binder_exception(
+ ExceptionCode::SERVICE_SPECIFIC,
+ format!("Failed to load app config from {}: {}", &config.configPath, e),
+ )
+ },
+ )?,
),
VirtualMachineConfig::RawConfig(config) => BorrowedOrOwned::Borrowed(config),
};
@@ -286,6 +298,7 @@
}
fn load_app_config(
+ apex_info_list: &ApexInfoList,
config: &VirtualMachineAppConfig,
temporary_directory: &Path,
) -> Result<VirtualMachineRawConfig> {
@@ -314,7 +327,8 @@
);
apexes.dedup_by(|a, b| a.name == b.name);
- vm_config.disks.push(payload::make_disk_image(
+ vm_config.disks.push(make_payload_disk(
+ apex_info_list,
format!("/proc/self/fd/{}", apk_file.as_raw_fd()).into(),
format!("/proc/self/fd/{}", idsig_file.as_raw_fd()).into(),
config_path,
diff --git a/virtualizationservice/src/main.rs b/virtualizationservice/src/main.rs
index 658203b..3f2e99c 100644
--- a/virtualizationservice/src/main.rs
+++ b/virtualizationservice/src/main.rs
@@ -39,7 +39,7 @@
android_logger::Config::default().with_tag(LOG_TAG).with_min_level(Level::Trace),
);
- let service = VirtualizationService::default();
+ let service = VirtualizationService::new().unwrap();
let service = BnVirtualizationService::new_binder(
service,
BinderFeatures { set_requesting_sid: true, ..BinderFeatures::default() },
diff --git a/virtualizationservice/src/payload.rs b/virtualizationservice/src/payload.rs
index b6e9c04..d3dc289 100644
--- a/virtualizationservice/src/payload.rs
+++ b/virtualizationservice/src/payload.rs
@@ -16,21 +16,66 @@
use crate::composite::align_to_partition_size;
-use anyhow::Result;
+use anyhow::{anyhow, Result};
use microdroid_metadata::{ApexPayload, ApkPayload, Metadata};
use microdroid_payload_config::ApexConfig;
+use regex::Regex;
use std::fs;
use std::fs::OpenOptions;
-use std::io::{Seek, SeekFrom, Write};
+use std::io::{BufRead, BufReader, Seek, SeekFrom, Write};
use std::path::{Path, PathBuf};
use std::process::Command;
use vmconfig::{DiskImage, Partition};
-// TODO(b/191601801): look up /apex/apex-info-list.xml
-fn get_path(package_name: &str) -> Result<PathBuf> {
- let output = Command::new("pm").arg("path").arg(package_name).output()?;
- let output = String::from_utf8(output.stdout)?;
- Ok(PathBuf::from(output.strip_prefix("package:").unwrap().trim()))
+/// Represents the list of APEXes
+#[derive(Debug)]
+pub struct ApexInfoList {
+ list: Vec<ApexInfo>,
+}
+
+#[derive(Debug)]
+struct ApexInfo {
+ name: String,
+ path: PathBuf,
+}
+
+impl ApexInfoList {
+ /// Loads ApexInfoList
+ pub fn load() -> Result<ApexInfoList> {
+ // TODO(b/191601801): look up /apex/apex-info-list.xml instead of apexservice
+ // Each APEX prints the line:
+ // Module: <...> Version: <...> VersionName: <...> Path: <...> IsActive: <...> IsFactory: <...>
+ // We only care about "Module:" and "Path:" tagged values for now.
+ let info_pattern = Regex::new(r"^Module: (?P<name>[^ ]*) .* Path: (?P<path>[^ ]*) .*$")?;
+ let output = Command::new("cmd")
+ .arg("-w")
+ .arg("apexservice")
+ .arg("getActivePackages")
+ .output()
+ .expect("failed to execute apexservice cmd");
+ let list = BufReader::new(output.stdout.as_slice())
+ .lines()
+ .map(|line| -> Result<ApexInfo> {
+ let line = line?;
+ let captures =
+ info_pattern.captures(&line).ok_or_else(|| anyhow!("can't parse: {}", line))?;
+ let name = captures.name("name").unwrap();
+ let path = captures.name("path").unwrap();
+ Ok(ApexInfo { name: name.as_str().to_owned(), path: path.as_str().into() })
+ })
+ .collect::<Result<Vec<ApexInfo>>>()?;
+ Ok(ApexInfoList { list })
+ }
+
+ fn get_path_for(&self, apex_name: &str) -> Result<PathBuf> {
+ Ok(self
+ .list
+ .iter()
+ .find(|apex| apex.name == apex_name)
+ .ok_or_else(|| anyhow!("{} not found.", apex_name))?
+ .path
+ .clone())
+ }
}
/// When passing a host APEX file as a block device in a payload disk image,
@@ -74,7 +119,8 @@
/// ..
/// microdroid-apk: [apk, zero filler]
/// microdroid-apk-idsig: idsig
-pub fn make_disk_image(
+pub fn make_payload_disk(
+ apex_info_list: &ApexInfoList,
apk_file: PathBuf,
idsig_file: PathBuf,
config_path: &str,
@@ -113,7 +159,7 @@
for (i, apex) in apexes.iter().enumerate() {
partitions.push(make_partition(
format!("microdroid-apex-{}", i),
- get_path(&apex.name)?,
+ apex_info_list.get_path_for(&apex.name)?,
temporary_directory,
&mut filler_count,
&make_size_filler,