Merge "WebRTC: Add option to include arbitrary http headers"
diff --git a/AndroidProducts.mk b/AndroidProducts.mk
index d0424b5..dd082d6 100644
--- a/AndroidProducts.mk
+++ b/AndroidProducts.mk
@@ -25,6 +25,7 @@
 	aosp_cf_x86_pasan:$(LOCAL_DIR)/vsoc_x86/pasan/aosp_cf.mk \
 	aosp_cf_x86_phone:$(LOCAL_DIR)/vsoc_x86/phone/aosp_cf.mk \
 	aosp_cf_x86_phone_noapex:$(LOCAL_DIR)/vsoc_x86_noapex/aosp_cf_noapex.mk \
+	aosp_cf_x86_only_phone:$(LOCAL_DIR)/vsoc_x86_only/phone/aosp_cf.mk \
 	aosp_cf_x86_go_phone:$(LOCAL_DIR)/vsoc_x86/go_phone/device.mk \
 	aosp_cf_x86_go_512_phone:$(LOCAL_DIR)/vsoc_x86/go_512_phone/device.mk \
 	aosp_cf_x86_tv:$(LOCAL_DIR)/vsoc_x86/tv/device.mk
diff --git a/host/commands/assemble_cvd/flags.cc b/host/commands/assemble_cvd/flags.cc
index 3fbf611..e934f11 100644
--- a/host/commands/assemble_cvd/flags.cc
+++ b/host/commands/assemble_cvd/flags.cc
@@ -32,6 +32,7 @@
 #include "host/libs/allocd/utils.h"
 #include "host/libs/config/data_image.h"
 #include "host/libs/config/fetcher_config.h"
+#include "host/libs/config/host_tools_version.h"
 #include "host/libs/graphics_detector/graphics_detector.h"
 #include "host/libs/vm_manager/crosvm_manager.h"
 #include "host/libs/vm_manager/qemu_manager.h"
@@ -359,13 +360,13 @@
   }
   tmp_config_obj.set_vm_manager(FLAGS_vm_manager);
 
+  const cuttlefish::GraphicsAvailability graphics_availability =
+    GetGraphicsAvailabilityWithSubprocessCheck();
+
+  LOG(VERBOSE) << GetGraphicsAvailabilityString(graphics_availability);
+
   tmp_config_obj.set_gpu_mode(FLAGS_gpu_mode);
   if (tmp_config_obj.gpu_mode() == cuttlefish::kGpuModeAuto) {
-    const cuttlefish::GraphicsAvailability graphics_availability =
-      GetGraphicsAvailabilityWithSubprocessCheck();
-
-    LOG(VERBOSE) << GetGraphicsAvailabilityString(graphics_availability);
-
     if (ShouldEnableAcceleratedRendering(graphics_availability)) {
         LOG(INFO) << "GPU auto mode: detected prerequisites for accelerated "
                      "rendering support.";
@@ -382,6 +383,16 @@
                    "--gpu_mode=guest_swiftshader.";
       tmp_config_obj.set_gpu_mode(cuttlefish::kGpuModeGuestSwiftshader);
     }
+  } else if (tmp_config_obj.gpu_mode() == cuttlefish::kGpuModeGfxStream ||
+             tmp_config_obj.gpu_mode() == cuttlefish::kGpuModeDrmVirgl) {
+    if (!ShouldEnableAcceleratedRendering(graphics_availability)) {
+      LOG(ERROR) << "--gpu_mode="
+                 << tmp_config_obj.gpu_mode()
+                 << " was requested but the prerequisites for accelerated "
+                    "rendering were not detected so the device may not "
+                    "function correctly. Please consider switching to "
+                    "--gpu_mode=auto or --gpu_mode=guest_swiftshader.";
+    }
   }
   // Sepolicy rules need to be updated to support gpu mode. Temporarily disable
   // auto-enabling sandbox when gpu is enabled (b/152323505).
@@ -563,6 +574,8 @@
     }
   }
 
+  tmp_config_obj.set_host_tools_version(cuttlefish::HostToolsCrc());
+
   tmp_config_obj.set_deprecated_boot_completed(FLAGS_deprecated_boot_completed);
 
   tmp_config_obj.set_qemu_binary(FLAGS_qemu_binary);
@@ -764,20 +777,20 @@
   // for now, we don't set non-default options for QEMU
   if (FLAGS_gpu_mode == cuttlefish::kGpuModeGuestSwiftshader &&
       NumStreamers() == 0) {
-    // This makes the vnc server the default streamer unless the user requests
+    // This makes WebRTC the default streamer unless the user requests
     // another via a --star_<streamer> flag, while at the same time it's
-    // possible to run without any streamer by setting --start_vnc_server=false.
-    SetCommandLineOptionWithMode("start_vnc_server", "true",
+    // possible to run without any streamer by setting --start_webrtc=false.
+    SetCommandLineOptionWithMode("start_webrtc", "true",
                                  google::FlagSettingMode::SET_FLAGS_DEFAULT);
   }
 }
 
 void SetDefaultFlagsForCrosvm() {
   if (NumStreamers() == 0) {
-    // This makes the vnc server the default streamer unless the user requests
+    // This makes WebRTC the default streamer unless the user requests
     // another via a --star_<streamer> flag, while at the same time it's
-    // possible to run without any streamer by setting --start_vnc_server=false.
-    SetCommandLineOptionWithMode("start_vnc_server", "true",
+    // possible to run without any streamer by setting --start_webrtc=false.
+    SetCommandLineOptionWithMode("start_webrtc", "true",
                                  google::FlagSettingMode::SET_FLAGS_DEFAULT);
   }
 
diff --git a/host/commands/launch/Android.bp b/host/commands/launch/Android.bp
index a755f7c..ec6b6fd 100644
--- a/host/commands/launch/Android.bp
+++ b/host/commands/launch/Android.bp
@@ -27,6 +27,7 @@
         "libjsoncpp",
         "libnl",
         "libxml2",
+        "libz",
     ],
     static_libs: [
         "libcuttlefish_host_config",
diff --git a/host/commands/launch/launch_cvd.cc b/host/commands/launch/launch_cvd.cc
index 1833bb9..c081065 100644
--- a/host/commands/launch/launch_cvd.cc
+++ b/host/commands/launch/launch_cvd.cc
@@ -25,6 +25,7 @@
 #include "common/libs/utils/subprocess.h"
 #include "host/commands/launch/filesystem_explorer.h"
 #include "host/libs/config/cuttlefish_config.h"
+#include "host/libs/config/host_tools_version.h"
 #include "host/libs/config/fetcher_config.h"
 
 #include "flag_forwarder.h"
@@ -140,6 +141,19 @@
   }
   return "";
 }
+
+bool HostToolsUpdated() {
+  if (cuttlefish::CuttlefishConfig::ConfigExists()) {
+    auto config = cuttlefish::CuttlefishConfig::Get();
+    if (config) {
+      auto current_tools = cuttlefish::HostToolsCrc();
+      auto last_tools = config->host_tools_version();
+      return current_tools != last_tools;
+    }
+  }
+  return true;
+}
+
 } // namespace
 
 int main(int argc, char** argv) {
@@ -158,6 +172,9 @@
   auto use_metrics = FLAGS_report_anonymous_usage_stats;
   FLAGS_report_anonymous_usage_stats = ValidateMetricsConfirmation(use_metrics);
 
+  // TODO(b/159068082) Make decisions based on this value in assemble_cvd
+  LOG(INFO) << "Host changed from last run: " << HostToolsUpdated();
+
   cuttlefish::SharedFD assembler_stdout, assembler_stdout_capture;
   cuttlefish::SharedFD::Pipe(&assembler_stdout_capture, &assembler_stdout);
 
diff --git a/host/frontend/webrtc_operator/assets/js/app.js b/host/frontend/webrtc_operator/assets/js/app.js
index 1e942a6..e79de71 100644
--- a/host/frontend/webrtc_operator/assets/js/app.js
+++ b/host/frontend/webrtc_operator/assets/js/app.js
@@ -270,11 +270,16 @@
   let ul = document.getElementById('device_list');
   ul.innerHTML = "";
   let count = 1;
+  let device_to_button_map = {};
   for (const dev_id of device_ids) {
     const button_id = 'connect_' + count++;
     ul.innerHTML += ('<li class="device_entry" title="Connect to ' + dev_id
                      + '">' + dev_id + '<button id="' + button_id
                      + '" >Connect</button></li>');
+    device_to_button_map[dev_id] = button_id;
+  }
+
+  for (const [dev_id, button_id] of Object.entries(device_to_button_map)) {
     document.getElementById(button_id).addEventListener(
         'click', evt => ConnectDeviceCb(dev_id));
   }
diff --git a/host/libs/config/Android.bp b/host/libs/config/Android.bp
index 7be049f..53db489 100644
--- a/host/libs/config/Android.bp
+++ b/host/libs/config/Android.bp
@@ -20,6 +20,7 @@
         "cuttlefish_config_instance.cpp",
         "data_image.cpp",
         "fetcher_config.cpp",
+        "host_tools_version.cpp",
         "kernel_args.cpp",
         "known_paths.cpp",
         "logging.cpp",
@@ -31,6 +32,7 @@
         "libgflags",
         "libjsoncpp",
         "libxml2",
+        "libz",
     ],
     defaults: ["cuttlefish_host_and_guest"],
 }
diff --git a/host/libs/config/cuttlefish_config.cpp b/host/libs/config/cuttlefish_config.cpp
index d52ee16..d40ad01 100644
--- a/host/libs/config/cuttlefish_config.cpp
+++ b/host/libs/config/cuttlefish_config.cpp
@@ -163,6 +163,8 @@
 
 const char* kConsole = "console";
 
+const char* kHostToolsVersion = "host_tools_version";
+
 }  // namespace
 
 namespace cuttlefish {
@@ -638,6 +640,27 @@
   return (*dictionary_)[kModemSimulatorSimType].asInt();
 }
 
+void CuttlefishConfig::set_host_tools_version(
+    const std::map<std::string, uint32_t>& versions) {
+  Json::Value json(Json::objectValue);
+  for (const auto& [key, value] : versions) {
+    json[key] = value;
+  }
+  (*dictionary_)[kHostToolsVersion] = json;
+}
+
+std::map<std::string, uint32_t> CuttlefishConfig::host_tools_version() const {
+  if (!dictionary_->isMember(kHostToolsVersion)) {
+    return {};
+  }
+  std::map<std::string, uint32_t> versions;
+  const auto& elem = (*dictionary_)[kHostToolsVersion];
+  for (auto it = elem.begin(); it != elem.end(); it++) {
+    versions[it.key().asString()] = it->asUInt();
+  }
+  return versions;
+}
+
 void CuttlefishConfig::set_guest_enforce_security(bool guest_enforce_security) {
   (*dictionary_)[kGuestEnforceSecurity] = guest_enforce_security;
 }
diff --git a/host/libs/config/cuttlefish_config.h b/host/libs/config/cuttlefish_config.h
index e5cf705..f84ab9a 100644
--- a/host/libs/config/cuttlefish_config.h
+++ b/host/libs/config/cuttlefish_config.h
@@ -18,6 +18,7 @@
 #include <sys/types.h>
 #include <array>
 #include <cstdint>
+#include <map>
 #include <memory>
 #include <string>
 #include <set>
@@ -308,6 +309,9 @@
   void set_modem_simulator_sim_type(int sim_type);
   int modem_simulator_sim_type() const;
 
+  void set_host_tools_version(const std::map<std::string, uint32_t>&);
+  std::map<std::string, uint32_t> host_tools_version() const;
+
   class InstanceSpecific;
   class MutableInstanceSpecific;
 
diff --git a/host/libs/config/host_tools_version.cpp b/host/libs/config/host_tools_version.cpp
new file mode 100644
index 0000000..58f0657
--- /dev/null
+++ b/host/libs/config/host_tools_version.cpp
@@ -0,0 +1,82 @@
+//
+// Copyright (C) 2020 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 "host/libs/config/host_tools_version.h"
+
+#include <algorithm>
+#include <fstream>
+#include <future>
+#include <vector>
+
+#include <zlib.h>
+
+#include "common/libs/utils/files.h"
+#include "host/libs/config/cuttlefish_config.h"
+
+using std::uint32_t;
+
+namespace cuttlefish {
+
+static uint32_t FileCrc(const std::string& path) {
+  uint32_t crc = crc32(0, (unsigned char*) path.c_str(), path.size());
+  std::ifstream file_stream(path, std::ifstream::binary);
+  std::vector<char> data(1024, 0);
+  while (file_stream) {
+    file_stream.read(data.data(), data.size());
+    crc = crc32(crc, (unsigned char*) data.data(), file_stream.gcount());
+  }
+  return crc;
+}
+
+static std::map<std::string, uint32_t> DirectoryCrc(const std::string& path) {
+  auto full_path = DefaultHostArtifactsPath(path);
+  if (!DirectoryExists(full_path)) {
+    return {};
+  }
+  std::vector<std::string> files = DirectoryContents(full_path);
+  for (auto it = files.begin(); it != files.end();) {
+    if (*it == "." || *it == "..") {
+      it = files.erase(it);
+    } else {
+      it++;
+    }
+  }
+  std::vector<std::future<uint32_t>> calculations;
+  for (auto& file : files) {
+    file = path + "/" + file; // mutate in place in files vector
+    calculations.emplace_back(
+        std::async(FileCrc, DefaultHostArtifactsPath(file)));
+  }
+  std::map<std::string, uint32_t> crcs;
+  for (int i = 0; i < files.size(); i++) {
+    crcs[files[i]] = calculations[i].get();
+  }
+  return crcs;
+}
+
+std::map<std::string, uint32_t> HostToolsCrc() {
+  auto bin_future = std::async(DirectoryCrc, "bin");
+  auto lib_future = std::async(DirectoryCrc, "lib64");
+  std::map<std::string, uint32_t> all_crcs;
+  for (auto const& [file, crc] : bin_future.get()) {
+    all_crcs[file] = crc;
+  }
+  for (auto const& [file, crc] : lib_future.get()) {
+    all_crcs[file] = crc;
+  }
+  return all_crcs;
+}
+
+} // namespace cuttlefish
diff --git a/host/libs/config/host_tools_version.h b/host/libs/config/host_tools_version.h
new file mode 100644
index 0000000..06b075e
--- /dev/null
+++ b/host/libs/config/host_tools_version.h
@@ -0,0 +1,26 @@
+//
+// Copyright (C) 2020 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 <cstdint>
+#include <map>
+#include <string>
+
+namespace cuttlefish {
+
+std::map<std::string, uint32_t> HostToolsCrc();
+
+} // namespace cuttlefish
diff --git a/host/libs/vm_manager/crosvm_manager.cpp b/host/libs/vm_manager/crosvm_manager.cpp
index 96239a4..7da3898 100644
--- a/host/libs/vm_manager/crosvm_manager.cpp
+++ b/host/libs/vm_manager/crosvm_manager.cpp
@@ -105,14 +105,6 @@
     };
   }
 
-  // Try to load the Nvidia modeset kernel module. Running Crosvm with Nvidia's EGL library on a
-  // fresh machine after a boot will fail because the Nvidia EGL library will fork to run the
-  // nvidia-modprobe command and the main Crosvm process will abort after receiving the exit signal
-  // of the forked child which is interpreted as a failure.
-  cuttlefish::Command modprobe_cmd("/usr/bin/nvidia-modprobe");
-  modprobe_cmd.AddParameter("--modeset");
-  modprobe_cmd.Start().Wait();
-
   if (gpu_mode == cuttlefish::kGpuModeDrmVirgl) {
     return {
       "androidboot.hardware.gralloc=minigbm",
diff --git a/shared/sepolicy/vendor/google/hwservice.te b/shared/sepolicy/vendor/google/hwservice.te
index ca4766a..1c32f8f 100644
--- a/shared/sepolicy/vendor/google/hwservice.te
+++ b/shared/sepolicy/vendor/google/hwservice.te
@@ -1 +1 @@
-type hal_wlc_hwservice, hwservice_manager_type;
+type hal_wlc_hwservice, hwservice_manager_type, vendor_hwservice_type;
diff --git a/tools/upload_to_gce_and_run.py b/tools/upload_to_gce_and_run.py
index f9e796c..6a79c64 100755
--- a/tools/upload_to_gce_and_run.py
+++ b/tools/upload_to_gce_and_run.py
@@ -19,11 +19,14 @@
   dir = os.getcwd()
   try:
     os.chdir(args.image_dir)
-    images = glob.glob('*.img')
-    if len(images) == 0:
+    artifacts = []
+    artifact_patterns = ['*.img', 'bootloader']
+    for artifact_pattern in artifact_patterns:
+      artifacts.extend(glob.glob(artifact_pattern))
+    if len(artifacts) == 0:
       raise OSError('No images found in: %s' + args.image_dir)
     subprocess.check_call(
-        'tar -c -f - --lzop -S ' + ' '.join(images) +
+        'tar -c -f - --lzop -S ' + ' '.join(artifacts) +
         ' | ' +
         gcloud_ssh(args) + '-- tar -x -f - --lzop -S',
         shell=True)
diff --git a/vsoc_x86_only/BoardConfig.mk b/vsoc_x86_only/BoardConfig.mk
new file mode 100644
index 0000000..de482ef
--- /dev/null
+++ b/vsoc_x86_only/BoardConfig.mk
@@ -0,0 +1,31 @@
+#
+# Copyright 2020 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.
+#
+
+#
+# x86 (32-bit kernel) target for Cuttlefish
+#
+
+-include device/google/cuttlefish/shared/BoardConfig.mk
+
+TARGET_BOARD_PLATFORM := vsoc_x86
+TARGET_ARCH := x86
+TARGET_ARCH_VARIANT := x86
+TARGET_CPU_ABI := x86
+
+TARGET_NO_BOOTLOADER := false
+BOARD_PREBUILT_BOOTLOADER := device/google/cuttlefish_prebuilts/bootloader/crosvm_x86_64/u-boot.rom
+
+BOARD_VENDOR_RAMDISK_KERNEL_MODULES += $(wildcard device/google/cuttlefish_prebuilts/kernel/5.4-i686/*.ko)
diff --git a/vsoc_x86_only/kernel.mk b/vsoc_x86_only/kernel.mk
new file mode 100644
index 0000000..235f38b
--- /dev/null
+++ b/vsoc_x86_only/kernel.mk
@@ -0,0 +1,16 @@
+#
+# Copyright (C) 2020 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.
+
+PRODUCT_COPY_FILES += device/google/cuttlefish_prebuilts/kernel/5.4-i686/kernel:kernel
diff --git a/vsoc_x86_only/phone/aosp_cf.mk b/vsoc_x86_only/phone/aosp_cf.mk
new file mode 100644
index 0000000..b9a7d98
--- /dev/null
+++ b/vsoc_x86_only/phone/aosp_cf.mk
@@ -0,0 +1,48 @@
+#
+# Copyright (C) 2020 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.
+#
+
+#
+# All components inherited here go to system image (same as GSI system)
+#
+$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_system.mk)
+
+PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS := relaxed
+
+#
+# All components inherited here go to system_ext image (same as GSI system_ext)
+#
+$(call inherit-product, $(SRC_TARGET_DIR)/product/handheld_system_ext.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/telephony_system_ext.mk)
+
+#
+# All components inherited here go to product image (same as GSI product)
+#
+$(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_product.mk)
+PRODUCT_OTA_ENFORCE_VINTF_KERNEL_REQUIREMENTS := false
+
+#
+# All components inherited here go to vendor image
+#
+$(call inherit-product, device/google/cuttlefish/shared/phone/device_vendor.mk)
+
+#
+# Special settings for the target
+#
+$(call inherit-product, device/google/cuttlefish/vsoc_x86_only/kernel.mk)
+
+PRODUCT_NAME := aosp_cf_x86_only_phone
+PRODUCT_DEVICE := vsoc_x86_only
+PRODUCT_MODEL := Cuttlefish x86 phone (32-bit kernel)