Merge "cf arm64 uses root-canal in the host as well"
diff --git a/common/libs/device_config/Android.bp b/common/libs/device_config/Android.bp
index 6cc5f6d..7e87dca 100644
--- a/common/libs/device_config/Android.bp
+++ b/common/libs/device_config/Android.bp
@@ -29,6 +29,7 @@
     name: "libcuttlefish_device_config",
     srcs: [
         "device_config.cpp",
+        "device_config_shared.cpp",
     ],
     shared_libs: [
         "libbase",
@@ -59,5 +60,6 @@
             ],
         },
     },
+    export_include_dirs: ["."],
     defaults: ["cuttlefish_host"],
 }
diff --git a/common/libs/device_config/device_config_shared.cpp b/common/libs/device_config/device_config_shared.cpp
new file mode 100644
index 0000000..ac4f8b4
--- /dev/null
+++ b/common/libs/device_config/device_config_shared.cpp
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "device_config.h"
+
+namespace cuttlefish {
+
+DeviceConfig GetDeviceConfig() {
+  const auto device_config_helper = cuttlefish::DeviceConfigHelper::Get();
+  return device_config_helper->GetDeviceConfig();
+}
+
+}  // namespace cuttlefish
\ No newline at end of file
diff --git a/common/libs/device_config/device_config_shared.h b/common/libs/device_config/device_config_shared.h
new file mode 100644
index 0000000..3176917
--- /dev/null
+++ b/common/libs/device_config/device_config_shared.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "device/google/cuttlefish/common/libs/device_config/device_config.pb.h"
+
+namespace cuttlefish {
+
+// Minimal version to share with Goldfish which doesn't include additional
+// Cuttlefish headers.
+//
+// TODO(natsu): switch ranchu hwcomposer to drm for display discovery.
+DeviceConfig GetDeviceConfig();
+
+}  // namespace cuttlefish
\ No newline at end of file
diff --git a/host/commands/assemble_cvd/disk_flags.cc b/host/commands/assemble_cvd/disk_flags.cc
index daa744c..eccd021 100644
--- a/host/commands/assemble_cvd/disk_flags.cc
+++ b/host/commands/assemble_cvd/disk_flags.cc
@@ -355,11 +355,16 @@
 
 static bool IsBootconfigSupported(const std::string& kernel_image_path,
                                   const std::string& build_dir) {
-  const std::string vmlinux_path = build_dir + "/vmlinux";
+  std::string vmlinux_path = build_dir + "/vmlinux";
   const std::string ikconfig_path = build_dir + "/ikconfig";
 
-  CHECK(DecompressKernel(kernel_image_path, vmlinux_path))
-      << "Failed to decompress kernel";
+  // Kernel is always uncompressed on aaarch64
+  if (HostArch() == "aarch64") {
+    vmlinux_path = kernel_image_path;
+  } else {
+    CHECK(DecompressKernel(kernel_image_path, vmlinux_path))
+        << "Failed to decompress kernel";
+  }
 
   Command ikconfig_cmd(HostBinaryPath("extract-ikconfig"));
   ikconfig_cmd.AddParameter(vmlinux_path);
diff --git a/host/commands/secure_env/tpm_key_blob_maker.cpp b/host/commands/secure_env/tpm_key_blob_maker.cpp
index abd6910..64f344a 100644
--- a/host/commands/secure_env/tpm_key_blob_maker.cpp
+++ b/host/commands/secure_env/tpm_key_blob_maker.cpp
@@ -110,6 +110,7 @@
   };
   for (auto tag : protected_tags) {
     if (key_description.Contains(tag)) {
+      LOG(ERROR) << "Invalid tag " << tag;
       return KM_ERROR_INVALID_TAG;
     }
   }
@@ -124,10 +125,19 @@
   hw_enforced->push_back(keymaster::TAG_OS_VERSION, os_version_);
   hw_enforced->push_back(keymaster::TAG_OS_PATCHLEVEL, os_patchlevel_);
 
+  return UnvalidatedCreateKeyBlob(key_material, *hw_enforced, *sw_enforced,
+                                  blob);
+}
+
+keymaster_error_t TpmKeyBlobMaker::UnvalidatedCreateKeyBlob(
+    const KeymasterKeyBlob& key_material, const AuthorizationSet& hw_enforced,
+    const AuthorizationSet& sw_enforced, KeymasterKeyBlob* blob) const {
   keymaster::Buffer key_material_buffer(
       key_material.key_material, key_material.key_material_size);
+  AuthorizationSet hw_enforced_mutable = hw_enforced;
+  AuthorizationSet sw_enforced_mutable = sw_enforced;
   CompositeSerializable sensitive_material(
-      {&key_material_buffer, hw_enforced, sw_enforced});
+      {&key_material_buffer, &hw_enforced_mutable, &sw_enforced_mutable});
   auto parent_key_fn = ParentKeyCreator(kUniqueKey);
   EncryptedSerializable encryption(
       resource_manager_, parent_key_fn, sensitive_material);
diff --git a/host/commands/secure_env/tpm_key_blob_maker.h b/host/commands/secure_env/tpm_key_blob_maker.h
index ddb694b..a0483b4 100644
--- a/host/commands/secure_env/tpm_key_blob_maker.h
+++ b/host/commands/secure_env/tpm_key_blob_maker.h
@@ -39,6 +39,12 @@
       keymaster::AuthorizationSet* hw_enforced,
       keymaster::AuthorizationSet* sw_enforced) const override;
 
+  keymaster_error_t UnvalidatedCreateKeyBlob(
+      const keymaster::KeymasterKeyBlob& key_material,
+      const keymaster::AuthorizationSet& hw_enforced,
+      const keymaster::AuthorizationSet& sw_enforced,
+      keymaster::KeymasterKeyBlob* blob) const;
+
   /**
    * Intermediate function between KeymasterContext::ParseKeyBlob and
    * KeyFactory::LoadKey, The inputs of this function match the outputs of
diff --git a/host/commands/secure_env/tpm_keymaster_context.cpp b/host/commands/secure_env/tpm_keymaster_context.cpp
index b8ec9de..850d48b 100644
--- a/host/commands/secure_env/tpm_keymaster_context.cpp
+++ b/host/commands/secure_env/tpm_keymaster_context.cpp
@@ -146,6 +146,7 @@
   keymaster::UniquePtr<keymaster::Key> key;
   auto error = ParseKeyBlob(blob_to_upgrade, upgrade_params, &key);
   if (error != KM_ERROR_OK) {
+    LOG(ERROR) << "Failed to parse key blob";
     return error;
   }
 
@@ -156,30 +157,26 @@
     // from proper numbered releases to unnumbered development and preview
     // releases.
 
-    int key_os_version_pos = key->sw_enforced().find(keymaster::TAG_OS_VERSION);
+    int key_os_version_pos = key->hw_enforced().find(keymaster::TAG_OS_VERSION);
     if (key_os_version_pos != -1) {
-      uint32_t key_os_version = key->sw_enforced()[key_os_version_pos].integer;
+      uint32_t key_os_version = key->hw_enforced()[key_os_version_pos].integer;
       if (key_os_version != 0) {
-        key->sw_enforced()[key_os_version_pos].integer = os_version_;
+        key->hw_enforced()[key_os_version_pos].integer = os_version_;
         set_changed = true;
       }
     }
   }
 
-  auto update_os = UpgradeIntegerTag(
-      keymaster::TAG_OS_VERSION,
-      os_version_,
-      &key->sw_enforced(),
-      &set_changed);
+  auto update_os = UpgradeIntegerTag(keymaster::TAG_OS_VERSION, os_version_,
+                                     &key->hw_enforced(), &set_changed);
 
-  auto update_patchlevel = UpgradeIntegerTag(
-      keymaster::TAG_OS_PATCHLEVEL,
-      os_patchlevel_,
-      &key->sw_enforced(),
-      &set_changed);
+  auto update_patchlevel =
+      UpgradeIntegerTag(keymaster::TAG_OS_PATCHLEVEL, os_patchlevel_,
+                        &key->hw_enforced(), &set_changed);
 
   if (!update_os || !update_patchlevel) {
-    // One of the version fields would have been a downgrade. Not allowed.
+    LOG(ERROR) << "One of the version fields would have been a downgrade. "
+               << "Not allowed.";
     return KM_ERROR_INVALID_ARGUMENT;
   }
 
@@ -188,25 +185,9 @@
     return KM_ERROR_OK;
   }
 
-  AuthorizationSet combined_authorization;
-  combined_authorization.Union(key->hw_enforced());
-  combined_authorization.Union(key->sw_enforced());
-
-  keymaster_key_origin_t origin = KM_ORIGIN_UNKNOWN;
-  if (!combined_authorization.GetTagValue(keymaster::TAG_ORIGIN, &origin)) {
-    LOG(WARNING) << "Key converted with unknown origin";
-  }
-
-  AuthorizationSet output_hw_enforced;
-  AuthorizationSet output_sw_enforced;
-
-  return key_blob_maker_->CreateKeyBlob(
-      combined_authorization,
-      origin,
-      key->key_material(),
-      upgraded_key,
-      &output_hw_enforced,
-      &output_sw_enforced);
+  return key_blob_maker_->UnvalidatedCreateKeyBlob(
+      key->key_material(), key->hw_enforced(), key->sw_enforced(),
+      upgraded_key);
 }
 
 keymaster_error_t TpmKeymasterContext::ParseKeyBlob(
diff --git a/host/frontend/webrtc/connection_observer.cpp b/host/frontend/webrtc/connection_observer.cpp
index e6444c4..c769f9b 100644
--- a/host/frontend/webrtc/connection_observer.cpp
+++ b/host/frontend/webrtc/connection_observer.cpp
@@ -21,6 +21,7 @@
 #include <linux/input.h>
 
 #include <map>
+#include <set>
 #include <thread>
 #include <vector>
 
@@ -138,8 +139,6 @@
   void OnMultiTouchEvent(const std::string & /*display_label*/, Json::Value id,
                          Json::Value slot, Json::Value x, Json::Value y,
                          bool down, int size) override {
-    static bool button_touch = false;
-    static bool finger = false;
 
     auto buffer = GetEventBuffer();
     if (!buffer) {
@@ -147,42 +146,39 @@
       return;
     }
 
-    if (!finger) {
-      buffer->AddEvent(EV_KEY, BTN_TOOL_FINGER, 1);
-      finger = true;
-    }
-
     for (int i=0; i<size; i++) {
-      buffer->AddEvent(EV_ABS, ABS_MT_SLOT, slot[i].asInt());
-
-      auto thisId = id[i].asInt();
-      if (thisId < 0 || down) {
-        buffer->AddEvent(EV_ABS, ABS_MT_TRACKING_ID, thisId);
-      }
-
-      if (thisId >= 0) {
-        // ABS_MT_POSITION_X: Reports the X coordinate of the tool.
-        // ABS_MT_POSITION_Y: Reports the Y coordinate of the tool.
-        buffer->AddEvent(EV_ABS, ABS_MT_POSITION_X, x[i].asInt());
-        buffer->AddEvent(EV_ABS, ABS_MT_POSITION_Y, y[i].asInt());
-        // ABS_{X,Y} must be reported with the location of the touch.
-        buffer->AddEvent(EV_ABS, ABS_X, x[i].asInt());
-        buffer->AddEvent(EV_ABS, ABS_Y, y[i].asInt());
-      }
-
-      if ((!button_touch && down) || (button_touch && !down)) {
-        // BTN_TOUCH must be used to report when a touch is active on the screen.
-        // BTN_TOUCH: Indicates whether the tool is touching the device.
-        buffer->AddEvent(EV_KEY, BTN_TOUCH, down);
-        LOG(VERBOSE) << "BTN_TOUCH " << down;
-        button_touch = !button_touch;
+      auto this_slot = slot[i].asInt();
+      auto this_id = id[i].asInt();
+      auto this_x = x[i].asInt();
+      auto this_y = y[i].asInt();
+      buffer->AddEvent(EV_ABS, ABS_MT_SLOT, this_slot);
+      if (down) {
+        bool is_new = active_touch_slots_.insert(this_slot).second;
+        if (is_new) {
+          buffer->AddEvent(EV_ABS, ABS_MT_TRACKING_ID, this_id);
+          if (active_touch_slots_.size() == 1) {
+            buffer->AddEvent(EV_KEY, BTN_TOUCH, 1);
+          }
+        }
+        buffer->AddEvent(EV_ABS, ABS_MT_POSITION_X, this_x);
+        buffer->AddEvent(EV_ABS, ABS_MT_POSITION_Y, this_y);
+        // send ABS_X and ABS_Y for single-touch compatibility
+        buffer->AddEvent(EV_ABS, ABS_X, this_x);
+        buffer->AddEvent(EV_ABS, ABS_Y, this_y);
+      } else {
+        // released touch
+        buffer->AddEvent(EV_ABS, ABS_MT_TRACKING_ID, this_id);
+        active_touch_slots_.erase(this_slot);
+        if (active_touch_slots_.empty()) {
+          buffer->AddEvent(EV_KEY, BTN_TOUCH, 0);
+        }
       }
     }
 
     buffer->AddEvent(EV_SYN, SYN_REPORT, 0);
     cuttlefish::WriteAll(input_sockets_.touch_client,
-    reinterpret_cast<const char *>(buffer->data()),
-    buffer->size());
+                         reinterpret_cast<const char *>(buffer->data()),
+                         buffer->size());
   }
 
   void OnKeyboardEvent(uint16_t code, bool down) override {
@@ -273,6 +269,7 @@
   std::shared_ptr<cuttlefish::webrtc_streaming::KernelLogEventsHandler> kernel_log_events_handler_;
   std::map<std::string, cuttlefish::SharedFD> commands_to_custom_action_servers_;
   std::weak_ptr<DisplayHandler> weak_display_handler_;
+  std::set<int32_t> active_touch_slots_;
 };
 
 CfConnectionObserverFactory::CfConnectionObserverFactory(
diff --git a/host/frontend/webrtc/main.cpp b/host/frontend/webrtc/main.cpp
index b824045..eadff20 100644
--- a/host/frontend/webrtc/main.cpp
+++ b/host/frontend/webrtc/main.cpp
@@ -48,7 +48,7 @@
 DEFINE_string(action_servers, "",
               "A comma-separated list of server_name:fd pairs, "
               "where each entry corresponds to one custom action server.");
-DEFINE_bool(write_virtio_input, false,
+DEFINE_bool(write_virtio_input, true,
             "Whether to send input events in virtio format.");
 DEFINE_int32(audio_server_fd, -1, "An fd to listen on for audio frames");
 
diff --git a/host/frontend/webrtc_operator/assets/js/app.js b/host/frontend/webrtc_operator/assets/js/app.js
index 2432501..b95bf21 100644
--- a/host/frontend/webrtc_operator/assets/js/app.js
+++ b/host/frontend/webrtc_operator/assets/js/app.js
@@ -476,7 +476,6 @@
     var idArr = [];
     var slotArr = [];
 
-    console.log('e.type: ' + e.type);
     if (eventType == "mouse" || eventType == "point") {
       xArr.push(e.offsetX);
       yArr.push(e.offsetY);
@@ -497,7 +496,6 @@
       for (var i=0; i < changes.length; i++) {
         xArr.push(changes[i].pageX - rect.left);
         yArr.push(changes[i].pageY - rect.top);
-        idArr.push(changes[i].identifier);
         if (touchIdSlotMap.has(changes[i].identifier)) {
           let slot = touchIdSlotMap.get(changes[i].identifier);
 
diff --git a/host/libs/vm_manager/crosvm_manager.cpp b/host/libs/vm_manager/crosvm_manager.cpp
index 8739b75..4b57575 100644
--- a/host/libs/vm_manager/crosvm_manager.cpp
+++ b/host/libs/vm_manager/crosvm_manager.cpp
@@ -252,9 +252,11 @@
   crosvm_cmd.AddParameter("--socket=", GetControlSocketPath(config));
 
   if (config.enable_vnc_server() || config.enable_webrtc()) {
-    crosvm_cmd.AddParameter("--single-touch=", instance.touch_socket_path(),
-                            ":", display_config.width,
-                            ":", display_config.height);
+    auto touch_type_parameter =
+        config.enable_webrtc() ? "--multi-touch=" : "--single-touch=";
+    crosvm_cmd.AddParameter(touch_type_parameter, instance.touch_socket_path(),
+                            ":", display_config.width, ":",
+                            display_config.height);
     crosvm_cmd.AddParameter("--keyboard=", instance.keyboard_socket_path());
   }
 
diff --git a/host/libs/vm_manager/qemu_manager.cpp b/host/libs/vm_manager/qemu_manager.cpp
index 2a5744a..1fe29ee 100644
--- a/host/libs/vm_manager/qemu_manager.cpp
+++ b/host/libs/vm_manager/qemu_manager.cpp
@@ -211,7 +211,7 @@
   auto access_kregistry_size_bytes = 0;
   if (FileExists(instance.access_kregistry_path())) {
     access_kregistry_size_bytes = FileSize(instance.access_kregistry_path());
-    CHECK(access_kregistry_size_bytes & (1024 * 1024 - 1))
+    CHECK((access_kregistry_size_bytes & (1024 * 1024 - 1)) == 0)
         << instance.access_kregistry_path() <<  " file size ("
         << access_kregistry_size_bytes << ") not a multiple of 1MB";
   }
@@ -219,7 +219,7 @@
   auto pstore_size_bytes = 0;
   if (FileExists(instance.pstore_path())) {
     pstore_size_bytes = FileSize(instance.pstore_path());
-    CHECK(pstore_size_bytes & (1024 * 1024 - 1))
+    CHECK((pstore_size_bytes & (1024 * 1024 - 1)) == 0)
         << instance.pstore_path() <<  " file size ("
         << pstore_size_bytes << ") not a multiple of 1MB";
   }
diff --git a/tests/graphics/Android.bp b/tests/graphics/Android.bp
new file mode 100644
index 0000000..cd9a61c
--- /dev/null
+++ b/tests/graphics/Android.bp
@@ -0,0 +1,29 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+java_test_host {
+    name: "GfxstreamEnabledTest",
+    srcs: [
+        "src/**/*.java",
+    ],
+    test_options: {
+        unit_test: false,
+    },
+    test_suites: [
+        "device-tests",
+    ],
+    libs: [
+        "tradefed",
+    ],
+}
\ No newline at end of file
diff --git a/tests/graphics/src/com/android/cuttlefish/tests/GfxstreamEnabledTest.java b/tests/graphics/src/com/android/cuttlefish/tests/GfxstreamEnabledTest.java
new file mode 100644
index 0000000..c3400a0
--- /dev/null
+++ b/tests/graphics/src/com/android/cuttlefish/tests/GfxstreamEnabledTest.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cuttlefish.tests;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.android.tradefed.device.cloud.RemoteAndroidVirtualDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests that Gfxstream was enabled as the virtual device's OpenGL and Vulkan driver.
+ */
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class GfxstreamEnabledTest extends BaseHostJUnit4Test {
+
+    @Test
+    public void testGfxstreamEnabled() throws Exception {
+        if (!(getDevice() instanceof RemoteAndroidVirtualDevice)) {
+            return;
+        }
+
+        assertThat(getDevice().getProperty("ro.hardware.egl")).isEqualTo("emulation");
+        assertThat(getDevice().getProperty("ro.hardware.vulkan")).isEqualTo("ranchu");
+    }
+}
\ No newline at end of file
diff --git a/vsoc_arm64/phone/aosp_cf.mk b/vsoc_arm64/phone/aosp_cf.mk
index d113c89..b33e523 100644
--- a/vsoc_arm64/phone/aosp_cf.mk
+++ b/vsoc_arm64/phone/aosp_cf.mk
@@ -39,13 +39,7 @@
 $(call inherit-product, device/google/cuttlefish/shared/phone/device_vendor.mk)
 
 # Nested virtualization support
-PRODUCT_PACKAGES += crosvm
-$(call inherit-product, external/crosvm/seccomp/crosvm_seccomp_policy_product_packages.mk)
-PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST += \
-    system/bin/crosvm \
-    system/lib64/libfdt.so \
-    system/lib64/libgfxstream_backend.so \
-    system/lib64/%.dylib.so \
+$(call inherit-product, packages/modules/Virtualization/apex/product_packages.mk)
 
 #
 # Special settings for the target
diff --git a/vsoc_arm64_only/phone/aosp_cf.mk b/vsoc_arm64_only/phone/aosp_cf.mk
index df8a801..6de27b6 100644
--- a/vsoc_arm64_only/phone/aosp_cf.mk
+++ b/vsoc_arm64_only/phone/aosp_cf.mk
@@ -40,13 +40,7 @@
 $(call inherit-product, device/google/cuttlefish/shared/phone/device_vendor.mk)
 
 # Nested virtualization support
-PRODUCT_PACKAGES += crosvm
-$(call inherit-product, external/crosvm/seccomp/crosvm_seccomp_policy_product_packages.mk)
-PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST += \
-    system/bin/crosvm \
-    system/lib64/libfdt.so \
-    system/lib64/libgfxstream_backend.so \
-    system/lib64/%.dylib.so \
+$(call inherit-product, packages/modules/Virtualization/apex/product_packages.mk)
 
 #
 # Special settings for the target
diff --git a/vsoc_x86_64/phone/aosp_cf.mk b/vsoc_x86_64/phone/aosp_cf.mk
index b96c7d1..478452f 100644
--- a/vsoc_x86_64/phone/aosp_cf.mk
+++ b/vsoc_x86_64/phone/aosp_cf.mk
@@ -39,13 +39,7 @@
 $(call inherit-product, device/google/cuttlefish/shared/phone/device_vendor.mk)
 
 # Nested virtualization support
-PRODUCT_PACKAGES += crosvm
-$(call inherit-product, external/crosvm/seccomp/crosvm_seccomp_policy_product_packages.mk)
-PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST += \
-    system/bin/crosvm \
-    system/lib64/libfdt.so \
-    system/lib64/libgfxstream_backend.so \
-    system/lib64/%.dylib.so \
+$(call inherit-product, packages/modules/Virtualization/apex/product_packages.mk)
 
 #
 # Special settings for the target
diff --git a/vsoc_x86_64_only/phone/aosp_cf.mk b/vsoc_x86_64_only/phone/aosp_cf.mk
index 267afb0..9596d5a 100644
--- a/vsoc_x86_64_only/phone/aosp_cf.mk
+++ b/vsoc_x86_64_only/phone/aosp_cf.mk
@@ -40,13 +40,7 @@
 $(call inherit-product, device/google/cuttlefish/shared/phone/device_vendor.mk)
 
 # Nested virtualization support
-PRODUCT_PACKAGES += crosvm
-$(call inherit-product, external/crosvm/seccomp/crosvm_seccomp_policy_product_packages.mk)
-PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST += \
-    system/bin/crosvm \
-    system/lib64/libfdt.so \
-    system/lib64/libgfxstream_backend.so \
-    system/lib64/%.dylib.so \
+$(call inherit-product, packages/modules/Virtualization/apex/product_packages.mk)
 
 #
 # Special settings for the target