Merge "Refactor clipboard handling into a separate class" into main
diff --git a/android/FerrochromeApp/AndroidManifest.xml b/android/FerrochromeApp/AndroidManifest.xml
index d640c4a..f6d3f6a 100644
--- a/android/FerrochromeApp/AndroidManifest.xml
+++ b/android/FerrochromeApp/AndroidManifest.xml
@@ -12,6 +12,9 @@
<intent>
<action android:name="android.virtualization.VM_LAUNCHER" />
</intent>
+ <intent>
+ <action android:name="android.virtualization.FERROCHROME_DOWNLOADER" />
+ </intent>
</queries>
<application
android:label="Ferrochrome">
diff --git a/android/FerrochromeApp/custom_vm_setup.sh b/android/FerrochromeApp/custom_vm_setup.sh
index a5480ff..4dce0c7 100644
--- a/android/FerrochromeApp/custom_vm_setup.sh
+++ b/android/FerrochromeApp/custom_vm_setup.sh
@@ -7,13 +7,13 @@
}
function install() {
- user=$(cmd user get-main-user)
- src_dir=/data/media/${user}/ferrochrome/
+ src_dir=$(getprop debug.custom_vm_setup.path)
+ src_dir=${src_dir/#\/storage\/emulated\//\/data\/media\/}
dst_dir=/data/local/tmp/
cat $(find ${src_dir} -name "images.tar.gz*" | sort) | tar xz -C ${dst_dir}
- cp -u ${src_dir}vm_config.json ${dst_dir}
- chmod 666 ${dst_dir}*
+ cp -u ${src_dir}/vm_config.json ${dst_dir}
+ chmod 666 ${dst_dir}/*
# increase the size of state.img to the multiple of 4096
num_blocks=$(du -b -K ${dst_dir}state.img | cut -f 1)
@@ -21,8 +21,8 @@
additional_blocks=$((( ${required_num_blocks} - ${num_blocks} )))
dd if=/dev/zero bs=512 count=${additional_blocks} >> ${dst_dir}state.img
- rm ${src_dir}images.tar.gz*
- rm ${src_dir}vm_config.json
+ rm ${src_dir}/images.tar.gz*
+ rm ${src_dir}/vm_config.json
}
setprop debug.custom_vm_setup.done false
diff --git a/android/FerrochromeApp/java/com/android/virtualization/ferrochrome/FerrochromeActivity.java b/android/FerrochromeApp/java/com/android/virtualization/ferrochrome/FerrochromeActivity.java
index 2df5cab..dba0078 100644
--- a/android/FerrochromeApp/java/com/android/virtualization/ferrochrome/FerrochromeActivity.java
+++ b/android/FerrochromeApp/java/com/android/virtualization/ferrochrome/FerrochromeActivity.java
@@ -16,14 +16,17 @@
package com.android.virtualization.ferrochrome;
+import android.annotation.WorkerThread;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.Intent;
+import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.os.Environment;
import android.os.SystemProperties;
+import android.text.TextUtils;
import android.util.Log;
import android.view.WindowManager;
import android.widget.TextView;
@@ -43,12 +46,20 @@
public class FerrochromeActivity extends Activity {
private static final String TAG = FerrochromeActivity.class.getName();
private static final String ACTION_VM_LAUNCHER = "android.virtualization.VM_LAUNCHER";
+ private static final String ACTION_FERROCHROME_DOWNLOAD =
+ "android.virtualization.FERROCHROME_DOWNLOADER";
+ private static final String EXTRA_FERROCHROME_DEST_DIR = "dest_dir";
+ private static final String EXTRA_FERROCHROME_UPDATE_NEEDED = "update_needed";
private static final Path DEST_DIR =
Path.of(Environment.getExternalStorageDirectory().getPath(), "ferrochrome");
+ private static final String ASSET_DIR = "ferrochrome";
private static final Path VERSION_FILE = Path.of(DEST_DIR.toString(), "version");
private static final int REQUEST_CODE_VMLAUNCHER = 1;
+ private static final int REQUEST_CODE_FERROCHROME_DOWNLOADER = 2;
+
+ private ResolvedActivity mVmLauncher;
ExecutorService executorService = Executors.newSingleThreadExecutor();
@@ -66,25 +77,28 @@
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
// Find VM Launcher
- Intent intent = new Intent(ACTION_VM_LAUNCHER).setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
- PackageManager pm = getPackageManager();
- List<ResolveInfo> resolveInfos =
- pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
- if (resolveInfos == null || resolveInfos.size() != 1) {
+ mVmLauncher = ResolvedActivity.resolve(getPackageManager(), ACTION_VM_LAUNCHER);
+ if (mVmLauncher == null) {
updateStatus("Failed to resolve VM Launcher");
return;
}
// Clean up the existing vm launcher process if there is
ActivityManager am = getSystemService(ActivityManager.class);
- am.killBackgroundProcesses(resolveInfos.get(0).activityInfo.packageName);
+ am.killBackgroundProcesses(mVmLauncher.activityInfo.packageName);
executorService.execute(
() -> {
- if (updateImageIfNeeded()) {
- updateStatus("Starting Ferrochrome...");
- runOnUiThread(
- () -> startActivityForResult(intent, REQUEST_CODE_VMLAUNCHER));
+ if (hasLocalAssets()) {
+ if (updateImageIfNeeded()) {
+ updateStatus("Starting Ferrochrome...");
+ runOnUiThread(
+ () ->
+ startActivityForResult(
+ mVmLauncher.intent, REQUEST_CODE_VMLAUNCHER));
+ }
+ } else {
+ tryLaunchDownloader();
}
});
}
@@ -93,9 +107,55 @@
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_VMLAUNCHER) {
finishAndRemoveTask();
+ } else if (requestCode == REQUEST_CODE_FERROCHROME_DOWNLOADER) {
+ String destDir = data.getStringExtra(EXTRA_FERROCHROME_DEST_DIR);
+ boolean updateNeeded =
+ data.getBooleanExtra(EXTRA_FERROCHROME_UPDATE_NEEDED, /* default= */ true);
+
+ if (resultCode != RESULT_OK || TextUtils.isEmpty(destDir)) {
+ Log.w(
+ TAG,
+ "Ferrochrome downloader returned error, code="
+ + resultCode
+ + ", dest="
+ + destDir);
+ updateStatus("User didn't accepted ferrochrome download..");
+ return;
+ }
+
+ Log.w(TAG, "Ferrochrome downloader returned OK");
+
+ if (!updateNeeded) {
+ updateStatus("Starting Ferrochrome...");
+ startActivityForResult(mVmLauncher.intent, REQUEST_CODE_VMLAUNCHER);
+ }
+
+ executorService.execute(
+ () -> {
+ if (!extractImages(destDir)) {
+ updateStatus("Images from downloader looks bad..");
+ return;
+ }
+ updateStatus("Starting Ferrochrome...");
+ runOnUiThread(
+ () ->
+ startActivityForResult(
+ mVmLauncher.intent, REQUEST_CODE_VMLAUNCHER));
+ });
}
}
+ @WorkerThread
+ private boolean hasLocalAssets() {
+ try {
+ String[] files = getAssets().list(ASSET_DIR);
+ return files != null && files.length > 0;
+ } catch (IOException e) {
+ return false;
+ }
+ }
+
+ @WorkerThread
private boolean updateImageIfNeeded() {
if (!isUpdateNeeded()) {
Log.d(TAG, "No update needed.");
@@ -107,13 +167,8 @@
Files.createDirectory(DEST_DIR);
}
- String[] files = getAssets().list("ferrochrome");
- if (files == null || files.length == 0) {
- updateStatus("ChromeOS image not found. Please go/try-ferrochrome");
- return false;
- }
-
updateStatus("Copying images...");
+ String[] files = getAssets().list("ferrochrome");
for (String file : files) {
updateStatus(file);
Path dst = Path.of(DEST_DIR.toString(), file);
@@ -126,7 +181,38 @@
}
updateStatus("Done.");
+ return extractImages(DEST_DIR.toAbsolutePath().toString());
+ }
+
+ @WorkerThread
+ private void tryLaunchDownloader() {
+ // TODO(jaewan): Add safeguard to check whether ferrochrome downloader is valid.
+ Log.w(TAG, "No built-in assets found. Try again with ferrochrome downloader");
+
+ ResolvedActivity downloader =
+ ResolvedActivity.resolve(getPackageManager(), ACTION_FERROCHROME_DOWNLOAD);
+ if (downloader == null) {
+ Log.d(TAG, "Ferrochrome downloader doesn't exist");
+ updateStatus("ChromeOS image not found. Please go/try-ferrochrome");
+ return;
+ }
+ String pkgName = downloader.activityInfo.packageName;
+ Log.d(TAG, "Resolved Ferrochrome Downloader, pkgName=" + pkgName);
+ updateStatus("Launching Ferrochrome downloader for update");
+
+ // onActivityResult() will handle downloader result.
+ startActivityForResult(downloader.intent, REQUEST_CODE_FERROCHROME_DOWNLOADER);
+ }
+
+ @WorkerThread
+ private boolean extractImages(String destDir) {
updateStatus("Extracting images...");
+
+ if (TextUtils.isEmpty(destDir)) {
+ throw new RuntimeException("Internal error: destDir shouldn't be null");
+ }
+
+ SystemProperties.set("debug.custom_vm_setup.path", destDir);
SystemProperties.set("debug.custom_vm_setup.done", "false");
SystemProperties.set("debug.custom_vm_setup.start", "true");
while (!SystemProperties.getBoolean("debug.custom_vm_setup.done", false)) {
@@ -143,6 +229,7 @@
return true;
}
+ @WorkerThread
private boolean isUpdateNeeded() {
Path[] pathsToCheck = {DEST_DIR, VERSION_FILE};
for (Path p : pathsToCheck) {
@@ -188,4 +275,33 @@
statusView.append(line + "\n");
});
}
+
+ private static final class ResolvedActivity {
+ public final ActivityInfo activityInfo;
+ public final Intent intent;
+
+ private ResolvedActivity(ActivityInfo activityInfo, Intent intent) {
+ this.activityInfo = activityInfo;
+ this.intent = intent;
+ }
+
+ /* synthetic access */
+ static ResolvedActivity resolve(PackageManager pm, String action) {
+ Intent intent = new Intent(action).setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
+ List<ResolveInfo> resolveInfos =
+ pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
+ if (resolveInfos == null || resolveInfos.size() != 1) {
+ Log.w(
+ TAG,
+ "Failed to resolve activity, action="
+ + action
+ + ", resolved="
+ + resolveInfos);
+ return null;
+ }
+ ActivityInfo activityInfo = resolveInfos.get(0).activityInfo;
+ intent.setClassName(activityInfo.packageName, activityInfo.name);
+ return new ResolvedActivity(activityInfo, intent);
+ }
+ }
}
diff --git a/android/VmLauncherApp/java/com/android/virtualization/vmlauncher/Logger.java b/android/VmLauncherApp/java/com/android/virtualization/vmlauncher/Logger.java
index ccfff95..e1cb285 100644
--- a/android/VmLauncherApp/java/com/android/virtualization/vmlauncher/Logger.java
+++ b/android/VmLauncherApp/java/com/android/virtualization/vmlauncher/Logger.java
@@ -41,7 +41,7 @@
private Logger() {}
static void setup(VirtualMachine vm, Path path, ExecutorService executor) {
- if (vm.getConfig().getDebugLevel() == VirtualMachineConfig.DEBUG_LEVEL_FULL) {
+ if (vm.getConfig().getDebugLevel() != VirtualMachineConfig.DEBUG_LEVEL_FULL) {
return;
}
diff --git a/docs/custom_vm.md b/docs/custom_vm.md
index e4b374f..6a1cc00 100644
--- a/docs/custom_vm.md
+++ b/docs/custom_vm.md
@@ -53,7 +53,7 @@
"name": "debian",
"disks": [
{
- "image": "/data/local/tmp/debian.img
+ "image": "/data/local/tmp/debian.img",
"partitions": [],
"writable": true
}
@@ -306,15 +306,15 @@
```
To see console logs only, check
-`/data/data/com{,.google}.android.virtualization.vmlauncher/files/console.log`
+`/data/data/com{,.google}.android.virtualization.vmlauncher/files/${vm_name}.log`
For HSUM enabled devices,
-`/data/user/${current_user_id}/com{,.google}.android.virtualization.vmlauncher/files/console.log`
+`/data/user/${current_user_id}/com{,.google}.android.virtualization.vmlauncher/files/${vm_name}.log`
You can monitor console out as follows
```shell
-$ adb shell 'su root tail +0 -F /data/user/$(am get-current-user)/com{,.google}.android.virtualization.vmlauncher/files/console.log'
+$ adb shell 'su root tail +0 -F /data/user/$(am get-current-user)/com{,.google}.android.virtualization.vmlauncher/files/${vm_name}.log'
```
For ChromiumOS, you can enter to the console via SSH connection. Check your IP
diff --git a/guest/pvmfw/image.ld b/guest/pvmfw/image.ld
index 18bb3ba..fb26806 100644
--- a/guest/pvmfw/image.ld
+++ b/guest/pvmfw/image.ld
@@ -18,5 +18,4 @@
{
image : ORIGIN = 0x7fc00000, LENGTH = 2M
writable_data : ORIGIN = 0x7fe00000, LENGTH = 2M
- dtb_region : ORIGIN = 0x80000000, LENGTH = 2M
}
diff --git a/guest/pvmfw/src/dice.rs b/guest/pvmfw/src/dice.rs
index 8be73a4..470711f 100644
--- a/guest/pvmfw/src/dice.rs
+++ b/guest/pvmfw/src/dice.rs
@@ -36,8 +36,10 @@
#[derive(Debug)]
pub enum Error {
/// Error in CBOR operations
+ #[allow(dead_code)]
CborError(ciborium::value::Error),
/// Error in DICE operations
+ #[allow(dead_code)]
DiceError(diced_open_dice::DiceError),
}
diff --git a/guest/rialto/image.ld b/guest/rialto/image.ld
index 368acbb..95ffdf8 100644
--- a/guest/rialto/image.ld
+++ b/guest/rialto/image.ld
@@ -16,7 +16,6 @@
MEMORY
{
- dtb_region : ORIGIN = 0x80000000, LENGTH = 2M
image : ORIGIN = 0x80200000, LENGTH = 2M
writable_data : ORIGIN = 0x80400000, LENGTH = 2M
}
diff --git a/libs/dice/open_dice/Android.bp b/libs/dice/open_dice/Android.bp
index 62504d1..efe350f 100644
--- a/libs/dice/open_dice/Android.bp
+++ b/libs/dice/open_dice/Android.bp
@@ -92,6 +92,9 @@
"--ctypes-prefix=core::ffi",
"--raw-line=#![no_std]",
],
+ dylib: {
+ enabled: false,
+ },
no_stdlibs: true,
prefer_rlib: true,
stdlibs: [
diff --git a/libs/libfdt/Android.bp b/libs/libfdt/Android.bp
index 7dc9e64..b2e7b2b 100644
--- a/libs/libfdt/Android.bp
+++ b/libs/libfdt/Android.bp
@@ -16,6 +16,9 @@
"--raw-line=#![no_std]",
"--ctypes-prefix=core::ffi",
],
+ dylib: {
+ enabled: false,
+ },
static_libs: [
"libfdt",
],
diff --git a/libs/libvmbase/example/image.ld b/libs/libvmbase/example/image.ld
index 368acbb..95ffdf8 100644
--- a/libs/libvmbase/example/image.ld
+++ b/libs/libvmbase/example/image.ld
@@ -16,7 +16,6 @@
MEMORY
{
- dtb_region : ORIGIN = 0x80000000, LENGTH = 2M
image : ORIGIN = 0x80200000, LENGTH = 2M
writable_data : ORIGIN = 0x80400000, LENGTH = 2M
}
diff --git a/libs/libvmbase/example/src/layout.rs b/libs/libvmbase/example/src/layout.rs
index fc578bc..49e4aa7 100644
--- a/libs/libvmbase/example/src/layout.rs
+++ b/libs/libvmbase/example/src/layout.rs
@@ -29,8 +29,6 @@
}
pub fn print_addresses() {
- let dtb = layout::dtb_range();
- info!("dtb: {}..{} ({} bytes)", dtb.start, dtb.end, dtb.end - dtb.start);
let text = layout::text_range();
info!("text: {}..{} ({} bytes)", text.start, text.end, text.end - text.start);
let rodata = layout::rodata_range();
diff --git a/libs/libvmbase/example/src/main.rs b/libs/libvmbase/example/src/main.rs
index da82b17..a01f619 100644
--- a/libs/libvmbase/example/src/main.rs
+++ b/libs/libvmbase/example/src/main.rs
@@ -26,6 +26,7 @@
use crate::layout::{boot_stack_range, print_addresses, DEVICE_REGION};
use crate::pci::{check_pci, get_bar_region};
use aarch64_paging::paging::MemoryRegion;
+use aarch64_paging::paging::VirtualAddress;
use aarch64_paging::MapError;
use alloc::{vec, vec::Vec};
use core::ptr::addr_of_mut;
@@ -35,7 +36,10 @@
use log::{debug, error, info, trace, warn, LevelFilter};
use vmbase::{
bionic, configure_heap,
- layout::{dtb_range, rodata_range, scratch_range, text_range},
+ layout::{
+ crosvm::{FDT_MAX_SIZE, MEM_START},
+ rodata_range, scratch_range, text_range,
+ },
linker, logger, main,
memory::{PageTable, SIZE_64KB},
};
@@ -47,7 +51,7 @@
main!(main);
configure_heap!(SIZE_64KB);
-fn init_page_table(pci_bar_range: &MemoryRegion) -> Result<(), MapError> {
+fn init_page_table(dtb: &MemoryRegion, pci_bar_range: &MemoryRegion) -> Result<(), MapError> {
let mut page_table = PageTable::default();
page_table.map_device(&DEVICE_REGION)?;
@@ -55,7 +59,7 @@
page_table.map_rodata(&rodata_range().into())?;
page_table.map_data(&scratch_range().into())?;
page_table.map_data(&boot_stack_range().into())?;
- page_table.map_rodata(&dtb_range().into())?;
+ page_table.map_rodata(dtb)?;
page_table.map_device(pci_bar_range)?;
info!("Activating IdMap...");
@@ -76,15 +80,16 @@
info!("Hello world");
info!("x0={:#018x}, x1={:#018x}, x2={:#018x}, x3={:#018x}", arg0, arg1, arg2, arg3);
print_addresses();
- assert_eq!(arg0, dtb_range().start.0 as u64);
check_data();
check_stack_guard();
info!("Checking FDT...");
- let fdt = dtb_range();
- let fdt_size = fdt.end.0 - fdt.start.0;
+ let fdt_addr = usize::try_from(arg0).unwrap();
+ // We are about to access the region so check that it matches our page tables in idmap.S.
+ assert_eq!(fdt_addr, MEM_START);
// SAFETY: The DTB range is valid, writable memory, and we don't construct any aliases to it.
- let fdt = unsafe { core::slice::from_raw_parts_mut(fdt.start.0 as *mut u8, fdt_size) };
+ let fdt = unsafe { core::slice::from_raw_parts_mut(fdt_addr as *mut u8, FDT_MAX_SIZE) };
+ let fdt_region = (VirtualAddress(fdt_addr)..VirtualAddress(fdt_addr + fdt.len())).into();
let fdt = Fdt::from_mut_slice(fdt).unwrap();
info!("FDT passed verification.");
check_fdt(fdt);
@@ -96,7 +101,7 @@
check_alloc();
- init_page_table(&get_bar_region(&pci_info)).unwrap();
+ init_page_table(&fdt_region, &get_bar_region(&pci_info)).unwrap();
check_data();
check_dice();
diff --git a/libs/libvmbase/sections.ld b/libs/libvmbase/sections.ld
index c7ef0ec..01b7e39 100644
--- a/libs/libvmbase/sections.ld
+++ b/libs/libvmbase/sections.ld
@@ -29,12 +29,6 @@
SECTIONS
{
- .dtb (NOLOAD) : {
- dtb_begin = .;
- . += LENGTH(dtb_region);
- dtb_end = .;
- } >dtb_region
-
/*
* Collect together the code. This is page aligned so it can be mapped
* as executable-only.
diff --git a/libs/libvmbase/src/layout.rs b/libs/libvmbase/src/layout.rs
index 5ac435f..adcb2fa 100644
--- a/libs/libvmbase/src/layout.rs
+++ b/libs/libvmbase/src/layout.rs
@@ -60,11 +60,6 @@
}};
}
-/// Memory reserved for the DTB.
-pub fn dtb_range() -> Range<VirtualAddress> {
- linker_region!(dtb_begin, dtb_end)
-}
-
/// Executable code.
pub fn text_range() -> Range<VirtualAddress> {
linker_region!(text_begin, text_end)
diff --git a/tests/ferrochrome/AndroidTest.xml b/tests/ferrochrome/AndroidTest.xml
index 9eaaed3..6c975be 100644
--- a/tests/ferrochrome/AndroidTest.xml
+++ b/tests/ferrochrome/AndroidTest.xml
@@ -35,13 +35,19 @@
<option name="run-command" value="mkdir /data/local/tmp" />
<option name="teardown-command" value="pkill vmlauncher" />
<option name="teardown-command" value="rm /data/local/tmp/chromiumos_base_image.bin" />
+ <option name="teardown-command" value="rm -rf /data/local/tmp/ferrochrome_screenshots" />
</target_preparer>
- <test class="com.android.tradefed.testtype.binary.ExecutableHostTest" >
+ <test class="com.android.tradefed.testtype.binary.ExecutableHostTest">
<option name="binary" value="ferrochrome-tests" />
<option name="relative-path-execution" value="true" />
<option name="runtime-hint" value="10m" />
<option name="per-binary-timeout" value="20m" />
</test>
+
+ <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
+ <option name="directory-keys" value="/data/local/tmp/ferrochrome_screenshots" />
+ <option name="collect-on-run-ended-only" value="true" />
+ </metrics_collector>
</configuration>
diff --git a/tests/ferrochrome/ferrochrome.sh b/tests/ferrochrome/ferrochrome.sh
index 683b82e..b9b9fbc 100755
--- a/tests/ferrochrome/ferrochrome.sh
+++ b/tests/ferrochrome/ferrochrome.sh
@@ -21,12 +21,13 @@
FECR_GS_URL="https://storage.googleapis.com/chromiumos-image-archive/ferrochrome-public"
FECR_DEFAULT_VERSION="R128-15958.0.0"
+FECR_DEFAULT_SCREENSHOT_DIR="/data/local/tmp/ferrochrome_screenshots" # Hardcoded at AndroidTest.xml
FECR_TEST_IMAGE="chromiumos_test_image"
FECR_BASE_IMAGE="chromiumos_base_image"
FECR_DEVICE_DIR="/data/local/tmp"
FECR_IMAGE_VM_CONFIG_JSON="chromiumos_base_image.bin" # hardcoded at vm_config.json
FECR_CONFIG_PATH="/data/local/tmp/vm_config.json" # hardcoded at VmLauncherApp
-FECR_CONSOLE_LOG_PATH="/data/data/\${pkg_name}/files/console.log"
+FECR_CONSOLE_LOG_PATH="files/cros.log" # log file name is ${vm_name}.log
FECR_TEST_IMAGE_BOOT_COMPLETED_LOG="Have fun and send patches!"
FECR_BASE_IMAGE_BOOT_COMPLETED_LOG="Chrome started, our work is done, exiting"
FECR_BOOT_TIMEOUT="300" # 5 minutes (300 seconds)
@@ -74,6 +75,7 @@
fecr_verbose=""
fecr_image="${FECR_DEFAULT_IMAGE}"
fecr_boot_completed_log="${FECR_DEFAULT_BOOT_COMPLETED_LOG}"
+fecr_screenshot_dir="${FECR_DEFAULT_SCREENSHOT_DIR}"
# Parse parameters
while (( "${#}" )); do
@@ -153,18 +155,20 @@
adb shell svc power stayon true
adb shell wm dismiss-keyguard
+echo "Granting runtime permissions to ensure VmLauncher is focused"
+adb shell pm grant ${pkg_name} android.permission.RECORD_AUDIO
+
echo "Starting ferrochrome"
adb shell am start-activity -a ${ACTION_NAME} > /dev/null
-if [[ $(adb shell getprop ro.fw.mu.headless_system_user) == "true" ]]; then
- current_user=$(adb shell am get-current-user)
- log_path="/data/user/${current_user}/${pkg_name}/files/console.log"
-else
- log_path="/data/data/${pkg_name}/files/console.log"
-fi
+# HSUM aware log path
+current_user=$(adb shell am get-current-user)
+log_path="/data/user/${current_user}/${pkg_name}/${FECR_CONSOLE_LOG_PATH}"
fecr_start_time=${EPOCHSECONDS}
+adb shell mkdir -p "${fecr_screenshot_dir}"
while [[ $((EPOCHSECONDS - fecr_start_time)) -lt ${FECR_BOOT_TIMEOUT} ]]; do
+ adb shell screencap -a -p "${fecr_screenshot_dir}/screenshot-${EPOCHSECONDS}.png"
adb shell grep -soF \""${fecr_boot_completed_log}"\" "${log_path}" && exit 0 || true
sleep 10
done