Unlock remote host goldfish by modifying VerifiedBootParams.textproto

A goldfish device must be unlocked when its system or system_dlkm is
replaced. The old solution was to add a parameter to the kernel
command line. It does not pass VtsBootconfigTest. This commit moves
the parameter to VerifiedBootParams.textproto.

Test: acloud-dev create -vv --avd-type goldfish \
      --emulator-zip ~/sdk-repo-linux-emulator.zip \
      --local-image $ANDROID_PRODUCT_OUT/emu-extra-linux-system-images.zip \
      --local-system-image $ANDROID_BUILD_TOP/out/target/product/generic_x86_64/system.img \
      --host 192.168.9.2 --host-user vsoc-01 \
      --host-ssh-private-key-path ~/id_rsa
Bug: 307432651
Change-Id: I0fc0a58916dcb320d8ace14f6eed8eaacbd75fe2
diff --git a/internal/lib/goldfish_utils.py b/internal/lib/goldfish_utils.py
index 3cecfe1..e5eefae 100644
--- a/internal/lib/goldfish_utils.py
+++ b/internal/lib/goldfish_utils.py
@@ -31,6 +31,7 @@
 _UNPACKED_RAMDISK_IMAGE_NAME = "ramdisk"
 # File names in a build environment or an SDK repository.
 SYSTEM_QEMU_IMAGE_NAME = "system-qemu.img"
+VERIFIED_BOOT_PARAMS_FILE_NAME = "VerifiedBootParams.textproto"
 _SDK_REPO_SYSTEM_IMAGE_NAME = "system.img"
 _MISC_INFO_FILE_NAME = "misc_info.txt"
 _SYSTEM_QEMU_CONFIG_FILE_NAME = "system-qemu-config.txt"
diff --git a/public/actions/remote_host_gf_device_factory.py b/public/actions/remote_host_gf_device_factory.py
index 643abbe..a55fd30 100644
--- a/public/actions/remote_host_gf_device_factory.py
+++ b/public/actions/remote_host_gf_device_factory.py
@@ -646,6 +646,17 @@
                 remote_image_dir, goldfish_utils.SYSTEM_QEMU_IMAGE_NAME)
             self._ssh.ScpPushFile(mixed_image, remote_disk_image_path)
 
+        # Adding the parameter to remote VerifiedBootParams.textproto unlocks
+        # the device so that the disabled vbmeta takes effect. An alternative
+        # is to append the parameter to the kernel command line by
+        # `emulator -qemu -append`, but that does not pass the compliance test.
+        remote_params_path = remote_path.join(
+            remote_image_dir, goldfish_utils.VERIFIED_BOOT_PARAMS_FILE_NAME)
+        # \\n is interpreted by shell and echo. \" is interpreted by shell.
+        param = r'\\nparam: \"androidboot.verifiedbootstate=orange\"'
+        self._ssh.Run(f"'test -f {remote_params_path} && "
+                      f"echo -e {param} >> {remote_params_path}'")
+
         return remote_disk_image_path
 
     def _MixAndUploadKernelImages(self, image_dir, boot_image_path, ota):
@@ -714,12 +725,6 @@
 
         cmd.extend(goldfish_utils.ConvertAvdSpecToArgs(self._avd_spec))
 
-        # Unlock the device so that the disabled vbmeta takes effect.
-        # These arguments must be at the end of the command line.
-        if self._ShouldMixDiskImage():
-            cmd.extend(("-qemu", "-append",
-                        "androidboot.verifiedbootstate=orange"))
-
         # Emulator does not support -stdouterr-file on macOS.
         self._ssh.Run(
             "'export {env} ; {cmd} 1> {stdout} 2> {stderr} &'".format(
diff --git a/public/actions/remote_host_gf_device_factory_test.py b/public/actions/remote_host_gf_device_factory_test.py
index 9fd54b0..09a25e1 100644
--- a/public/actions/remote_host_gf_device_factory_test.py
+++ b/public/actions/remote_host_gf_device_factory_test.py
@@ -77,6 +77,11 @@
     _LOGS = [{"path": "acloud_gf_1/instance/kernel.log", "type": "KERNEL_LOG"},
              {"path": "acloud_gf_1/instance/emu_stderr.txt", "type": "TEXT"},
              {"path": "acloud_gf_1/instance/logcat.txt", "type": "LOGCAT"}]
+    _VERIFIED_BOOT_PARAMS_COMMAND = (
+        "'test -f acloud_gf_1/image/x86_64/VerifiedBootParams.textproto && "
+        r'echo -e \\nparam: \"androidboot.verifiedbootstate=orange\" >> '
+        "acloud_gf_1/image/x86_64/VerifiedBootParams.textproto'"
+    )
     _SSH_COMMAND = (
         "'export ANDROID_PRODUCT_OUT=~/acloud_gf_1/image/x86_64 "
         "ANDROID_TMP=~/acloud_gf_1/instance "
@@ -240,6 +245,8 @@
         mock_gf_utils.ConvertAvdSpecToArgs.return_value = ["-gpu", "auto"]
         mock_gf_utils.MixDiskImage.return_value = "/mixed/disk"
         mock_gf_utils.SYSTEM_QEMU_IMAGE_NAME = "system-qemu.img"
+        mock_gf_utils.VERIFIED_BOOT_PARAMS_FILE_NAME = (
+            "VerifiedBootParams.textproto")
 
         factory = gf_factory.RemoteHostGoldfishDeviceFactory(
             self._mock_avd_spec)
@@ -260,6 +267,7 @@
         mock_gf_utils.MixDiskImage.assert_called_once()
         self._mock_ssh.ScpPushFile.assert_called_with(
             "/mixed/disk", "acloud_gf_1/image/x86_64/system-qemu.img")
+        self._mock_ssh.Run.assert_any_call(self._VERIFIED_BOOT_PARAMS_COMMAND)
 
         mock_gf_utils.FormatRemoteHostInstanceName.assert_called()
         self.assertEqual(self._X86_64_BUILD_INFO, factory.GetBuildInfoDict())