Merge "Clean up stale network connections on snapshot load" into emu-master-dev
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 23d6d61..81e0fa0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -413,7 +413,7 @@
                                "-Wno-tautological-compare"
                                "-Wno-tautological-pointer-compare"
                                "-Wno-unused-variable")
-android_target_link_libraries(android-qemu-deps linux-x86_64 INTERFACE "${TCMALLOC_LIBRARIES} -lpulse -lutil")
+android_target_link_libraries(android-qemu-deps linux-x86_64 INTERFACE "${TCMALLOC_LIBRARIES} -lutil")
 android_target_link_libraries(android-qemu-deps darwin-x86_64 INTERFACE "-framework CoreAudio")
 android_target_link_libraries(android-qemu-deps windows_msvc-x86_64 INTERFACE msvc-posix-compat)
 
@@ -432,6 +432,17 @@
 target_compile_definitions(qemu2-common PRIVATE "-DPOISON_CONFIG_ANDROID")
 target_link_libraries(qemu2-common PUBLIC android-qemu-deps)
 
+# Not allowed to have libraries without source files.
+set(headless-paaudio_src audio/paaudio-headless-impl-placeholder.c)
+set(headless-paaudio_linux-x86_64_src audio/paaudio-headless-impl.c)
+android_add_library(headless-paaudio)
+
+android_add_interface(android-qemu-deps-headful)
+android_target_link_libraries(android-qemu-deps-headful linux-x86_64 INTERFACE "-lpulse")
+
+android_add_interface(android-qemu-deps-headless)
+android_target_link_libraries(android-qemu-deps-headless linux-x86_64 INTERFACE headless-paaudio)
+
 set(libqemu2-util_src ${libqemuutil_sources} ${libqemuutil_generated_sources})
 if(ANDROID_TARGET_TAG STREQUAL "windows_msvc-x86_64")
   # So we have some linker issues on MSVC debug (b/122598666) where clang places things in the .pdata sections which the
diff --git a/android/android-emu/android-libui.cmake b/android/android-emu/android-libui.cmake
index 7df086c..6466b72 100644
--- a/android/android-emu/android-libui.cmake
+++ b/android/android-emu/android-libui.cmake
@@ -86,7 +86,6 @@
     android/skin/qt/extended-pages/car-data-emulation/car-property-table.cpp
     android/skin/qt/extended-pages/car-data-emulation/car-property-utils.cpp
     android/skin/qt/extended-pages/car-data-emulation/car-sensor-data.cpp
-    android/skin/qt/extended-pages/car-data-emulation/checkbox-dialog.cpp
     android/skin/qt/extended-pages/car-data-page.cpp
     android/skin/qt/extended-pages/cellular-page.cpp
     android/skin/qt/extended-pages/dpad-page.cpp
diff --git a/android/android-emu/android/skin/qt/extended-pages/car-data-emulation/car-property-table.cpp b/android/android-emu/android/skin/qt/extended-pages/car-data-emulation/car-property-table.cpp
index fa58093..92c4c5a 100644
--- a/android/android-emu/android/skin/qt/extended-pages/car-data-emulation/car-property-table.cpp
+++ b/android/android-emu/android/skin/qt/extended-pages/car-data-emulation/car-property-table.cpp
@@ -13,7 +13,6 @@
 #include "android/skin/qt/qt-settings.h"
 #include "android/utils/debug.h"
 #include "android/skin/qt/extended-pages/car-data-emulation/vehicle_constants_generated.h"
-#include "android/skin/qt/extended-pages/car-data-emulation/checkbox-dialog.h"
 
 #include <cfloat>
 
@@ -24,7 +23,6 @@
 
 using std::string;
 using std::map;
-using std::vector;
 
 using emulator::EmulatorMessage;
 using emulator::MsgType;
@@ -44,41 +42,10 @@
 static constexpr int AREA_ID_COLUMN = 5;
 static constexpr int TYPE_COLUMN = 6;
 
-static constexpr int REFRESH_START = 1;
-static constexpr int REFRESH_STOP = 2;
-static constexpr int REFRESH_PUASE = 3;
-
-static constexpr int64_t REFRESH_INTERVEL = 1000000LL;
-
 static map<QString, int> tableIndex;
 
 CarPropertyTable::CarPropertyTable(QWidget* parent)
-    : QWidget(parent),
-      mUi(new Ui::CarPropertyTable),
-      mCarPropertyTableRefreshThread([this] {
-          while (true) {
-              int msg;
-              mRefreshMsg.tryReceive(&msg);
-              if (msg == REFRESH_STOP) {
-                  break;
-              }
-              android::base::AutoLock lock(mCarPropertyTableRefreshLock);
-              switch (msg) {
-                  case REFRESH_START:
-                      if (mSendEmulatorMsg != nullptr) {
-                          sendGetAllPropertiesRequest();
-                      }
-                      mCarPropertyTableRefreshCV.timedWait(
-                              &mCarPropertyTableRefreshLock,
-                              nextRefreshAbsolute());
-                      break;
-                  case REFRESH_PUASE:
-                      mCarPropertyTableRefreshCV.wait(
-                              &mCarPropertyTableRefreshLock);
-                      break;
-              }
-          }
-      }) {
+    : QWidget(parent), mUi(new Ui::CarPropertyTable) {
     mUi->setupUi(this);
 
     QStringList colHeaders;
@@ -96,15 +63,8 @@
     connect(this, SIGNAL(setRowCount(int)), this, SLOT(changeRowCount(int)), Qt::QueuedConnection);
     connect(mUi->table->horizontalHeader(), SIGNAL(sectionClicked(int)),
              this, SLOT(sortTable(int)), Qt::QueuedConnection);
-
-    mRefreshMsg.trySend(REFRESH_START);
-    mCarPropertyTableRefreshThread.start();
 };
 
-CarPropertyTable::~CarPropertyTable() {
-    stopCarPropertyTableRefreshThread();
-}
-
 QString CarPropertyTable::getLabel(int row) {
     return mUi->table->item(row, LABEL_COLUMN)->text();
 }
@@ -187,15 +147,16 @@
         for (int valIndex = 0; valIndex < emulatorMsg.value_size(); valIndex++) {
             VehiclePropValue val = emulatorMsg.value(valIndex);
             if (!propMap.count(val.prop())) {
-                // Some received constants are vendor id and aren't on the list.
-                // so if constants is vendor id, transfer raw value to hex and
-                // build as vender label like Vendor(id: XXX) where XXX is hex
+                // Some received constants are vendor id and aren't on the list. 
+                // so if constants is vendor id, transfer raw value to hex and 
+                // build as vender label like Vendor(id: XXX) where XXX is hex 
                 // representation of the property. If not, show raw value.
                 if (carpropertyutils::isVendor(val.prop())) {
                     propMap[val.prop()] = { carpropertyutils::vendorIdToString(val.prop()) };
                 } else {
                     propMap[val.prop()] = { QString::number(val.prop()) };
                 }
+                
             }
             PropertyDescription propDesc = propMap[val.prop()];
 
@@ -245,7 +206,6 @@
     bool pressedOk;
     int32_t int32Value;
     float floatValue;
-    vector<int32_t> *int32VecValue;
 
     EmulatorMessage writeMsg;
     string writeLog;
@@ -282,15 +242,6 @@
             writeLog = "Setting value for " + getLabel(row).toStdString();
             mSendEmulatorMsg(writeMsg, writeLog);
             break;
-        case (int32_t) VehiclePropertyType::INT32_VEC :
-            int32VecValue = getUserInt32VecValue(propDesc, row, &pressedOk);
-            if (!pressedOk) {
-                return;
-            }
-            writeMsg = makeSetPropMsgInt32Vec(prop, int32VecValue, areaId);
-            writeLog = "Setting value for " + getLabel(row).toStdString();
-            mSendEmulatorMsg(writeMsg, writeLog);
-            break;
     }
 
     mSendEmulatorMsg(writeMsg, writeLog);
@@ -304,7 +255,7 @@
     QString oldValueString = getValueText(row);
     QStringList items;
     items << tr("True") << tr("False");
-    QString item = QInputDialog::getItem(this, propDesc.label, nullptr,
+    QString item = QInputDialog::getItem(this, QString(), propDesc.label,
                                           items, items.indexOf(oldValueString), false, pressedOk);
     return (item == "True") ? 1 : 0;
 }
@@ -318,7 +269,7 @@
         for (const auto &detail : *(propDesc.lookupTable)) {
             items << detail.second;
         }
-        QString item = QInputDialog::getItem(this, propDesc.label, nullptr, items,
+        QString item = QInputDialog::getItem(this, QString(), propDesc.label, items,
                                               items.indexOf(oldValueString), false, pressedOk);
         for (const auto &detail : *(propDesc.lookupTable)) {
             if (item == detail.second) {
@@ -328,38 +279,17 @@
         }
     } else {
         int32_t oldValue = getValueText(row).toInt();
-        value = QInputDialog::getInt(this, propDesc.label, nullptr, oldValue,
+        value = QInputDialog::getInt(this, QString(), propDesc.label, oldValue,
                                       INT_MIN, INT_MAX, 1, pressedOk);
     }
     return value;
 }
 
-vector<int32_t>* CarPropertyTable::getUserInt32VecValue(
-        carpropertyutils::PropertyDescription propDesc,
-        int row,
-        bool* pressedOk) {
-    QString oldValueString = getValueText(row);
-    QStringList valueStringList= oldValueString.split("; ");
-    QSet<QString> oldStringSet = QSet<QString>::fromList(valueStringList);
-
-    vector<int32_t>* values;
-    if (propDesc.lookupTable != nullptr) {
-        CheckboxDialog checkboxDialog(this, propDesc.lookupTable, &oldStringSet, propDesc.label);
-        if(checkboxDialog.exec() == QDialog::Accepted) {
-            values = checkboxDialog.getVec();
-            *pressedOk = true;
-        } else {
-            *pressedOk = false;
-        }
-    }
-    return values;
-}
-
 float CarPropertyTable::getUserFloatValue(PropertyDescription propDesc, int row,
                                            bool* pressedOk) {
     // No property interprets floats with table, so we only deal with raw numbers.
     double oldValue = getValueText(row).toDouble();
-    double value = QInputDialog::getDouble(this, propDesc.label, nullptr, oldValue,
+    double value = QInputDialog::getDouble(this, QString(), propDesc.label, oldValue,
                                             FLT_MIN, FLT_MAX, 3, pressedOk);
     return value;
 }
@@ -390,17 +320,6 @@
     return emulatorMsg;
 }
 
-EmulatorMessage CarPropertyTable::makeSetPropMsgInt32Vec(int32_t propId,
-                                                          vector<int32_t>* vals,
-                                                          int areaId) {
-    VehiclePropValue* value;
-    EmulatorMessage emulatorMsg = makeSetPropMsg(propId, &value, areaId);
-    for(int32_t val : *vals){
-        value->add_int32_values(val);
-    }
-    return emulatorMsg;
-}
-
 EmulatorMessage CarPropertyTable::makeGetPropMsg(int32_t prop, int areaId) {
     EmulatorMessage emulatorMsg;
     emulatorMsg.set_msg_type(MsgType::GET_PROPERTY_CMD);
@@ -420,34 +339,10 @@
 }
 
 void CarPropertyTable::showEvent(QShowEvent*) {
-    // start asking data
-    setCarPropertyTableRefreshThread();
-}
-
-void CarPropertyTable::hideEvent(QHideEvent*) {
-    // stop asking data
-    pauseCarPropertyTableRefreshThread();
+    // Update data when we open the tab
+    if (mSendEmulatorMsg != nullptr) { sendGetAllPropertiesRequest(); }
 }
 
 void CarPropertyTable::setSendEmulatorMsgCallback(CarSensorData::EmulatorMsgCallback&& func) {
     mSendEmulatorMsg = std::move(func);
 }
-
-android::base::System::Duration CarPropertyTable::nextRefreshAbsolute() {
-    return android::base::System::get()->getUnixTimeUs() + REFRESH_INTERVEL;
-}
-
-void CarPropertyTable::setCarPropertyTableRefreshThread(){
-    mRefreshMsg.trySend(REFRESH_START);
-    mCarPropertyTableRefreshCV.signal();
-}
-
-void CarPropertyTable::stopCarPropertyTableRefreshThread(){
-    mRefreshMsg.trySend(REFRESH_STOP);
-    mCarPropertyTableRefreshCV.signal();
-    mCarPropertyTableRefreshThread.wait();
-}
-
-void CarPropertyTable::pauseCarPropertyTableRefreshThread(){
-    mRefreshMsg.trySend(REFRESH_PUASE);
-}
diff --git a/android/android-emu/android/skin/qt/extended-pages/car-data-emulation/car-property-table.h b/android/android-emu/android/skin/qt/extended-pages/car-data-emulation/car-property-table.h
index ccb5c89..9c14b94 100644
--- a/android/android-emu/android/skin/qt/extended-pages/car-data-emulation/car-property-table.h
+++ b/android/android-emu/android/skin/qt/extended-pages/car-data-emulation/car-property-table.h
@@ -10,11 +10,6 @@
 // GNU General Public License for more details.
 #pragma once
 
-#include "android/base/synchronization/ConditionVariable.h"
-#include "android/base/synchronization/Lock.h"
-#include "android/base/synchronization/MessageChannel.h"
-#include "android/base/system/System.h"
-#include "android/base/threads/FunctorThread.h"
 #include "ui_car-property-table.h"
 
 // TODO: (b/120444474) rename ERROR_INVALID_OPERATION & remove this undef
@@ -26,15 +21,6 @@
 #include <map>
 #include <vector>
 
-#ifdef _MSC_VER
-#include "msvc-posix.h"
-#else
-#include <sys/time.h>
-#endif
-
-using android::base::System;
-using android::base::FunctorThread;
-
 namespace carpropertyutils {
     struct PropertyDescription {
         QString label;
@@ -75,7 +61,6 @@
 
 public:
     explicit CarPropertyTable(QWidget* parent = nullptr);
-    ~CarPropertyTable();
     void processMsg(emulator::EmulatorMessage emulatorMsg);
     void setSendEmulatorMsgCallback(CarSensorData::EmulatorMsgCallback&&);
 
@@ -86,7 +71,6 @@
 
 protected:
     void showEvent(QShowEvent* event);
-    void hideEvent(QHideEvent* event);
 
 private slots:
     void updateTable(int row, int col, QTableWidgetItem* info);
@@ -106,15 +90,6 @@
     int getAreaId(int row);
     int getType(int row);
 
-    FunctorThread mCarPropertyTableRefreshThread;
-    android::base::MessageChannel<int, 2> mRefreshMsg;
-    android::base::ConditionVariable mCarPropertyTableRefreshCV;
-    android::base::Lock mCarPropertyTableRefreshLock;
-    android::base::System::Duration nextRefreshAbsolute();
-    void setCarPropertyTableRefreshThread();
-    void stopCarPropertyTableRefreshThread();
-    void pauseCarPropertyTableRefreshThread();
-
     QTableWidgetItem* createTableTextItem(QString info);
     QTableWidgetItem* createTableBoolItem(bool val);
 
@@ -127,9 +102,6 @@
                                               int areaId);
     emulator::EmulatorMessage makeSetPropMsgInt32(int32_t propId, int val, int areaId);
     emulator::EmulatorMessage makeSetPropMsgFloat(int32_t propId, float val, int areaId);
-    emulator::EmulatorMessage makeSetPropMsgInt32Vec(int32_t propId,
-                                                      std::vector<int32_t>* val,
-                                                      int areaId);
 
     int32_t getUserBoolValue(carpropertyutils::PropertyDescription propDesc,
                               int row, bool* pressedOk);
@@ -137,7 +109,4 @@
                              int row, bool* pressedOk);
     int32_t getUserInt32Value(carpropertyutils::PropertyDescription propDesc,
                                int row, bool* pressedOk);
-    std::vector<int32_t>* getUserInt32VecValue(carpropertyutils::PropertyDescription propDesc,
-                             int row, bool* pressedOk);
-
 };
diff --git a/android/android-emu/android/skin/qt/extended-pages/car-data-emulation/car-property-utils.cpp b/android/android-emu/android/skin/qt/extended-pages/car-data-emulation/car-property-utils.cpp
index 43f5ff7..c7d55f2 100644
--- a/android/android-emu/android/skin/qt/extended-pages/car-data-emulation/car-property-utils.cpp
+++ b/android/android-emu/android/skin/qt/extended-pages/car-data-emulation/car-property-utils.cpp
@@ -247,16 +247,16 @@
     { 286261506, { QObject::tr("Model"), false } },
     { 289407235, { QObject::tr("Model year"), false } },
     { 291504388, { QObject::tr("Fuel capacity (mL)"), false } },
-    { 289472773, { QObject::tr("Usable fuels"), true, &fuelTypeMap } },
+    { 289472773, { QObject::tr("Usable fuels"), false, &fuelTypeMap } },
     { 291504390, { QObject::tr("Battery capacity (Wh)"), false } },
-    { 289472775, { QObject::tr("Usable connectors (EV)"), true, &evConnectorTypeMap } },
+    { 289472775, { QObject::tr("Usable connectors (EV)"), false, &evConnectorTypeMap } },
     { 289407240, { QObject::tr("Fuel door location"), false } },
-    { 289407241, { QObject::tr("EV port location"), true, &portLocationMap } },
-    { 356516106, { QObject::tr("Driver seat location"), true, &seatMap } },
+    { 289407241, { QObject::tr("EV port location"), false, &portLocationMap } },
+    { 356516106, { QObject::tr("Driver seat location"), false, &seatMap } },
     { 291504644, { QObject::tr("Odometer value (km)"), false } },
     { 291504647, { QObject::tr("Speed (m/s)"), false } },
     { 291504897, { QObject::tr("Engine coolant temperature (°C)"), false } },
-    { 289407747, { QObject::tr("Engine oil level"), true, &oilLevelMap } },
+    { 289407747, { QObject::tr("Engine oil level"), false, &oilLevelMap } },
     { 291504900, { QObject::tr("Engine oil temperature (°C)"), false } },
     { 291504901, { QObject::tr("Engine RPM"), false } },
     { 290521862, { QObject::tr("Wheel ticks"), false } },
@@ -269,7 +269,7 @@
     { 291504904, { QObject::tr("Range remaining (m)"), false } },
     { 392168201, { QObject::tr("Tire pressure (kPa)"), false } },
     { 289408000, { QObject::tr("Selected gear"), true, &gearMap } },
-    { 289408001, { QObject::tr("Current gear"), true, &gearMap } },
+    { 289408001, { QObject::tr("Current gear"), false, &gearMap } },
     { 287310850, { QObject::tr("Parking brake on"), true } },
     { 287310851, { QObject::tr("Parking brake auto apply on"), true } },
     { 287310853, { QObject::tr("Fuel level low"), false } },
@@ -279,7 +279,7 @@
     { 287310858, { QObject::tr("ABS active"), false } },
     { 287310859, { QObject::tr("Traction control active"), false } },
     { 356517120, { QObject::tr("Fan speed"), true } },
-    { 356517121, { QObject::tr("Fan direction"), true, &fanDirectionMap, fanDirectionToString } },
+    { 356517121, { QObject::tr("Fan direction"), false, &fanDirectionMap, fanDirectionToString } },
     { 358614274, { QObject::tr("Current temperature (°C)"), true } },
     { 358614275, { QObject::tr("Target temperature set (°C)"), true } },
     { 320865540, { QObject::tr("Defroster on"), true } },
@@ -293,10 +293,10 @@
     { 339739916, { QObject::tr("Side mirror heat"), false } },
     { 289408269, { QObject::tr("Steering wheel heating/cooling"), true,
             nullptr, heatingCoolingToString} },
-    { 289408270, { QObject::tr("User display temperature units"), true, &tempUnitsMap } },
+    { 289408270, { QObject::tr("User display temperature units"), false, &tempUnitsMap } },
     { 356517135, { QObject::tr("Actual fan speed"), false } },
     { 354419984, { QObject::tr("Global power state"), false } },
-    { 356582673, { QObject::tr("Available fan positions"), true, &fanDirectionMap, fanDirectionToString } },
+    { 356582673, { QObject::tr("Available fan positions"), false, &fanDirectionMap, fanDirectionToString } },
     { 354419986, { QObject::tr("Automatic recirculation on"), true } },
     { 356517139, { QObject::tr("Seat ventilation"), true, nullptr, heatingCoolingToString } },
     { 291505923, { QObject::tr("Outside temperature (°C)"), false } },
diff --git a/android/android-emu/android/skin/qt/extended-pages/car-data-emulation/checkbox-dialog.cpp b/android/android-emu/android/skin/qt/extended-pages/car-data-emulation/checkbox-dialog.cpp
deleted file mode 100644
index a38e2bc..0000000
--- a/android/android-emu/android/skin/qt/extended-pages/car-data-emulation/checkbox-dialog.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// This software is licensed under the terms of the GNU General Public
-// License version 2, as published by the Free Software Foundation, and
-// may be copied, distributed, and modified under those terms.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-#include "checkbox-dialog.h"
-
-CheckboxDialog::CheckboxDialog(QWidget* parent,
-                               std::map<int32_t, QString>* lookupTable,
-                               QSet<QString>* checkedTitleSet,
-                               const QString& label)
-    : QDialog(parent) {
-
-    for(const auto &detail : *lookupTable){
-        QCheckBox *newcheckbox = new QCheckBox(detail.second);
-        if (checkedTitleSet->contains(detail.second)) {
-            newcheckbox->setCheckState(Qt::CheckState::Checked);
-        }
-        mCheckboxsVec.append(new QPair<QCheckBox*, int32_t>(newcheckbox, detail.first));
-    }
-    mButtonBox = new QDialogButtonBox(QDialogButtonBox::Ok
-                                     |QDialogButtonBox::Cancel);
-    connect(mButtonBox, &QDialogButtonBox::accepted, this, &CheckboxDialog::confirm);
-    connect(mButtonBox, &QDialogButtonBox::rejected, this, &CheckboxDialog::reject);
-
-    QGridLayout *checkboxDialogLayout = new QGridLayout;
-    int loc = -1;
-    for(auto &checkbox : mCheckboxsVec){
-        checkboxDialogLayout->addWidget(checkbox->first, ++loc, 0);
-    }
-    checkboxDialogLayout->addWidget(mButtonBox, ++loc, 0);
-    setLayout(checkboxDialogLayout);
-    setWindowTitle(label);
-}
-
-std::vector<int32_t>* CheckboxDialog::getVec(){
-    return mCheckedValues;
-}
-
-
-void CheckboxDialog::confirm(){
-    mCheckedValues = new std::vector<int32_t>();
-    for(auto &checkbox : mCheckboxsVec){
-        if(checkbox->first->isChecked()) {
-            mCheckedValues->push_back(checkbox->second);
-        }
-    }
-    accept();
-}
\ No newline at end of file
diff --git a/android/android-emu/android/skin/qt/extended-pages/car-data-emulation/checkbox-dialog.h b/android/android-emu/android/skin/qt/extended-pages/car-data-emulation/checkbox-dialog.h
deleted file mode 100644
index 01c598b..0000000
--- a/android/android-emu/android/skin/qt/extended-pages/car-data-emulation/checkbox-dialog.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// This software is licensed under the terms of the GNU General Public
-// License version 2, as published by the Free Software Foundation, and
-// may be copied, distributed, and modified under those terms.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-#pragma once
-
-#include <QDialog>
-#include <QSet>
-#include <QVector>
-#include <QPair>
-#include <QtWidgets>
-
-class QCheckBox;
-class QDialogButtonBox;
-
-// This CheckboxDialog is for user input for VHAL property whose type is
-// VehiclePropertyType:INT32_VEC, like INFO_FUEL_TYPE and INFO_EV_CONNECTOR_TYPE
-class CheckboxDialog : public QDialog
-{
-    Q_OBJECT
-public:
-    CheckboxDialog(QWidget* parent = 0,
-                   std::map<int32_t, QString>* lookupTable = 0,
-                   QSet<QString>* checkedTitleSet = 0,
-                   const QString& label = "null");
-    std::vector<int32_t>* getVec();
-
-public slots:
-    void confirm();
-
-private:
-
-    QVector<QPair<QCheckBox*, int32_t>*> mCheckboxsVec;
-    std::vector<int32_t> *mCheckedValues;
-    QDialogButtonBox *mButtonBox;
-};
\ No newline at end of file
diff --git a/android/android-emugl/host/libs/libOpenglRender/vulkan-registry/xml/cereal/functable.py b/android/android-emugl/host/libs/libOpenglRender/vulkan-registry/xml/cereal/functable.py
index 7e18e80..539a532 100644
--- a/android/android-emugl/host/libs/libOpenglRender/vulkan-registry/xml/cereal/functable.py
+++ b/android/android-emugl/host/libs/libOpenglRender/vulkan-registry/xml/cereal/functable.py
@@ -41,6 +41,8 @@
     "vkCreateSamplerYcbcrConversion",
     "vkCreateSamplerYcbcrConversionKHR",
     "vkUpdateDescriptorSetWithTemplate",
+    "vkGetPhysicalDeviceImageFormatProperties2",
+    "vkGetPhysicalDeviceImageFormatProperties2KHR",
 ]
 
 SUCCESS_VAL = {
diff --git a/android/android-emugl/host/libs/libOpenglRender/vulkan/VkDecoderGlobalState.cpp b/android/android-emugl/host/libs/libOpenglRender/vulkan/VkDecoderGlobalState.cpp
index 5306be8..b342c4a 100644
--- a/android/android-emugl/host/libs/libOpenglRender/vulkan/VkDecoderGlobalState.cpp
+++ b/android/android-emugl/host/libs/libOpenglRender/vulkan/VkDecoderGlobalState.cpp
@@ -55,8 +55,8 @@
 kEmulatedExtensions[] = {
     "VK_ANDROID_native_buffer",
     "VK_ANDROID_external_memory_android_hardware_buffer",
-    "VK_KHR_external_memory_fuchsia",
-    "VK_KHR_external_semaphore_fuchsia",
+    "VK_FUCHSIA_external_memory",
+    "VK_FUCHSIA_external_semaphore",
     "VK_KHR_external_semaphore_fd",
     "VK_FUCHSIA_buffer_collection",
 };
diff --git a/android/build/cmake/android.cmake b/android/build/cmake/android.cmake
index 60d843f..ff74754 100644
--- a/android/build/cmake/android.cmake
+++ b/android/build/cmake/android.cmake
@@ -616,7 +616,8 @@
                                          emulator-libui
                                          android-emu
                                          OpenGLESDispatch
-                                         android-qemu-deps)
+                                         android-qemu-deps
+                                         android-qemu-deps-headful)
 endfunction()
 
 
@@ -639,7 +640,8 @@
                                         android-emu
                                         emulator-libui-headless
                                         OpenGLESDispatch
-                                        android-qemu-deps)
+                                        android-qemu-deps
+                                        android-qemu-deps-headless)
 endfunction()
 
 
@@ -658,7 +660,8 @@
                                          libqemu2-util
                                          android-emu
                                          SDL2::SDL2
-                                         android-qemu-deps)
+                                         android-qemu-deps
+                                         android-qemu-deps-headful)
 endfunction()
 
 
diff --git a/audio/paaudio-headless-impl-placeholder.c b/audio/paaudio-headless-impl-placeholder.c
new file mode 100644
index 0000000..69b6bf0
--- /dev/null
+++ b/audio/paaudio-headless-impl-placeholder.c
@@ -0,0 +1,2 @@
+// Placeholder source file (libraries have to have at least one)
+// pulse audio is only for linux, and we need this to build for windows/mac
diff --git a/audio/paaudio-headless-impl.c b/audio/paaudio-headless-impl.c
new file mode 100644
index 0000000..52d4fe7
--- /dev/null
+++ b/audio/paaudio-headless-impl.c
@@ -0,0 +1,166 @@
+/* public domain */
+
+#include <pulse/pulseaudio.h>
+#include <errno.h>
+
+int pa_context_connect(pa_context* c, const char* server, pa_context_flags_t flags, const pa_spawn_api* api) {
+    return -1;
+}
+
+void pa_context_disconnect(pa_context* c) { }
+
+int pa_context_errno(pa_context* c) { return ENODEV; }
+
+pa_context_state_t pa_context_get_state(pa_context* c) { return PA_CONTEXT_FAILED; }
+
+pa_context* pa_context_new(pa_mainloop_api* api, const char* name) { return NULL; }
+
+pa_operation* pa_context_set_sink_input_mute(
+    pa_context* c,
+    uint32_t idx,
+    int mute,
+    pa_context_success_cb_t cb,
+    void* userdata) {
+    return NULL;
+}
+
+pa_operation* pa_context_set_sink_input_volume(
+    pa_context* c,
+    uint32_t idx,
+    const pa_cvolume* vol,
+    pa_context_success_cb_t cb,
+    void* userdata) {
+    return NULL;
+}
+
+pa_operation* pa_context_set_source_mute_by_index(
+    pa_context* c,
+    uint32_t idx,
+    int mute,
+    pa_context_success_cb_t cb,
+    void* userdata) {
+    return NULL;
+}
+
+pa_operation* pa_context_set_source_volume_by_index(
+    pa_context* c,
+    uint32_t idx,
+    const pa_cvolume* volume,
+    pa_context_success_cb_t cb,
+    void* userdata) {
+    return NULL;
+}
+
+
+void pa_context_set_state_callback(
+   pa_context* c,
+   pa_context_notify_cb_t cb,
+   void* userdata) { } 
+
+void pa_context_unref(pa_context *c) { }
+
+pa_cvolume* pa_cvolume_init(pa_cvolume *a) { return NULL; }
+
+void pa_operation_unref (pa_operation* o) { }
+
+int pa_stream_connect_playback(
+    pa_stream* s,
+    const char* dev,
+    const pa_buffer_attr* attr,
+    pa_stream_flags_t flags,
+    const pa_cvolume* volume,
+    pa_stream* sync_stream) { return -1; }
+
+int pa_stream_connect_record(
+    pa_stream* s,
+    const char* dev,
+    const pa_buffer_attr* attr,
+    pa_stream_flags_t   flags) { return -1; }
+
+pa_operation* pa_stream_cork(
+    pa_stream* s,
+    int b,
+    pa_stream_success_cb_t cb,
+    void* userdata) { return NULL; }
+
+int pa_stream_drop(pa_stream *p) { return -1; }
+
+uint32_t pa_stream_get_device_index(pa_stream* s) { return PA_INVALID_INDEX; }
+
+uint32_t pa_stream_get_index(pa_stream* s) { return PA_INVALID_INDEX; }
+
+pa_stream_state_t pa_stream_get_state(pa_stream* p) { return PA_STREAM_FAILED; }
+
+int pa_stream_is_corked(pa_stream *s) { return -1; }
+
+pa_stream* pa_stream_new(
+    pa_context* c,
+    const char* name,
+    const pa_sample_spec* ss,
+    const pa_channel_map* map) {
+    return NULL;
+}
+
+int pa_stream_peek(
+    pa_stream* p,
+    const void** data,
+    size_t* nbytes) {
+    return -1;
+}
+
+
+void pa_stream_set_read_callback(
+    pa_stream* p,
+    pa_stream_request_cb_t cb,
+    void* userdata) { }
+
+
+void pa_stream_set_state_callback(
+    pa_stream* s,
+    pa_stream_notify_cb_t cb,
+    void* userdata) { }
+
+void pa_stream_set_write_callback(
+    pa_stream* p,
+    pa_stream_request_cb_t cb,
+    void* userdata) { }
+
+void pa_stream_unref(pa_stream* s) { }
+
+size_t pa_stream_writable_size(pa_stream* p) { return 0; }
+
+int pa_stream_write(
+    pa_stream* p,
+    const void* data,
+    size_t nbytes,
+    pa_free_cb_t free_cb,
+    int64_t offset,
+    pa_seek_mode_t seek) {
+    return -1;
+}
+
+const char* pa_strerror(int error) { return "Using headless implementation"; }
+
+void pa_threaded_mainloop_free(pa_threaded_mainloop* m) { }
+
+pa_mainloop_api* pa_threaded_mainloop_get_api(pa_threaded_mainloop *m) { return NULL; }
+
+void pa_threaded_mainloop_lock(pa_threaded_mainloop *m) { }
+
+pa_threaded_mainloop* pa_threaded_mainloop_new(void) { return NULL; }
+
+void pa_threaded_mainloop_signal(pa_threaded_mainloop *m, int wait_for_accept) { }
+
+int pa_threaded_mainloop_start(pa_threaded_mainloop *m) { return -1; }
+
+void pa_threaded_mainloop_stop(pa_threaded_mainloop *m) { }
+
+void pa_threaded_mainloop_unlock(pa_threaded_mainloop *m) { }
+
+void pa_threaded_mainloop_wait(pa_threaded_mainloop *m) { }
+
+size_t pa_usec_to_bytes(pa_usec_t t, const pa_sample_spec *spec) { return 1; }
+
+
+
+
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 26184bc..adf2f31 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -1045,6 +1045,26 @@
     kernel_size = arm_load_elf(info, &elf_entry, &elf_low_addr,
                                &elf_high_addr, elf_machine, as);
     if (kernel_size > 0 && have_dtb(info)) {
+        if (info->initrd_filename) {
+            initrd_size = load_ramdisk(info->initrd_filename,
+                                       info->initrd_start,
+                                       info->ram_size -
+                                       info->initrd_start);
+            if (initrd_size < 0) {
+                initrd_size = load_image_targphys(info->initrd_filename,
+                                                  info->initrd_start,
+                                                  info->ram_size -
+                                                  info->initrd_start);
+            }
+            if (initrd_size < 0) {
+                fprintf(stderr, "qemu: could not load initrd '%s'\n",
+                        info->initrd_filename);
+                exit(1);
+            }
+        } else {
+            initrd_size = 0;
+        }
+        info->initrd_size = initrd_size;
         /* If there is still some room left at the base of RAM, try and put
          * the DTB there like we do for images loaded with -bios or -pflash.
          */
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 94dcb12..48bdff5 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1382,6 +1382,14 @@
 
     create_pcie(vms, pic);
 
+    if (machine_usb(machine)) {
+        PCIBus *pci_bus = (PCIBus*)object_resolve_path_type("", TYPE_PCI_BUS, NULL);
+        if (!pci_bus)
+            error_report("No PCI bus available to add USB OHCI controller to.");
+        else
+            pci_create_simple(pci_bus, -1, "pci-ohci");
+    }
+
     create_gpio(vms, pic);
 
     /* Create mmio transports, so the user can create virtio backends
diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c
index 52d91e4..7774be1 100644
--- a/hw/audio/intel-hda.c
+++ b/hw/audio/intel-hda.c
@@ -486,6 +486,16 @@
     st->bp    = 0;
 }
 
+static void intel_hda_reset_bdl(IntelHDAState *d, IntelHDAStream *st)
+{
+    g_free(st->bpl);
+    st->bpl      = NULL;
+    st->bentries = 0;
+    st->bsize    = 0;
+    st->be       = 0;
+    st->bp       = 0;
+}
+
 static void intel_hda_notify_codecs(IntelHDAState *d, uint32_t stream, bool running, bool output)
 {
     BusChild *kid;
@@ -575,27 +585,55 @@
     bool output = reg->stream >= 4;
     IntelHDAStream *st = d->st + reg->stream;
 
-    if (st->ctl & 0x01) {
-        /* reset */
-        dprint(d, 1, "st #%d: reset\n", reg->stream);
-        st->ctl = SD_STS_FIFO_READY << 24;
-    }
-    if ((st->ctl & 0x02) != (old & 0x02)) {
-        uint32_t stnr = (st->ctl >> 20) & 0x0f;
-        /* run bit flipped */
-        if (st->ctl & 0x02) {
-            /* start */
-            dprint(d, 1, "st #%d: start %d (ring buf %d bytes)\n",
-                   reg->stream, stnr, st->cbl);
-            intel_hda_parse_bdl(d, st);
-            intel_hda_notify_codecs(d, stnr, true, output);
-        } else {
-            /* stop */
-            dprint(d, 1, "st #%d: stop %d\n", reg->stream, stnr);
-            intel_hda_notify_codecs(d, stnr, false, output);
+    if ((st->ctl & 0x01) && (old & 0x01)) {
+        /* If the stream descriptor was in the reset state, and this update did
+         * not clear the reset bit, ignore the register write */
+        st->ctl = old;
+    } else {
+        if (st->ctl & 0x01) {
+            /* reset */
+            dprint(d, 1, "st #%d: reset\n", reg->stream);
+
+            /* Reset all writable register bits to their power on defaults.
+             * Mark the SRST bit as being set in the CTL register */
+            uint32_t stnr  = (st->ctl >> 20) & 0x0f;
+            st->ctl        = (SD_STS_FIFO_READY << 24) | 0x01;
+            st->lpib       = 0;
+            st->cbl        = 0;
+            st->lvi        = 0;
+            st->fmt        = 0;
+            st->bdlp_lbase = 0;
+            st->bdlp_ubase = 0;
+
+            /* In theory, no one should place the stream into reset while the
+             * RUN bit is set.  Docs say "The RUN bit must be cleared before
+             * SRST is asserted".  Behavior in this situation is undefined.
+             * QEMU's implementation chooses to 'magicically' stop all streams.
+             * */
+            if (old & 0x02) {
+                dprint(d, 1, "st #%d: WARNING SRST asserted while RUN set\n", reg->stream);
+                intel_hda_notify_codecs(d, stnr, false, output);
+                intel_hda_reset_bdl(d, st);
+            }
+        } else if ((st->ctl & 0x02) != (old & 0x02)) {
+            uint32_t stnr = (st->ctl >> 20) & 0x0f;
+            /* run bit flipped */
+            if (st->ctl & 0x02) {
+                /* start */
+                dprint(d, 1, "st #%d: start %d (ring buf %d bytes)\n",
+                       reg->stream, stnr, st->cbl);
+                intel_hda_parse_bdl(d, st);
+                intel_hda_notify_codecs(d, stnr, true, output);
+            } else {
+                /* stop */
+                dprint(d, 1, "st #%d: stop %d\n", reg->stream, stnr);
+                intel_hda_notify_codecs(d, stnr, false, output);
+                intel_hda_reset_bdl(d, st);
+            }
         }
+
+        intel_hda_update_irq(d);
     }
-    intel_hda_update_irq(d);
 }
 
 /* --------------------------------------------------------------------- */
@@ -812,6 +850,7 @@
         .name     = _t stringify(_i) " CTL",                          \
         .size     = 4,                                                \
         .wmask    = 0x1cff001f,                                       \
+        .wclear   = 0x1c000000,                                       \
         .offset   = offsetof(IntelHDAState, st[_i].ctl),              \
         .whandler = intel_hda_set_st_ctl,                             \
     },                                                                \
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index 85d2406..ef798f2 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -27,6 +27,7 @@
 #include "qemu/osdep.h"
 #include "hw/block/block.h"
 #include "hw/hw.h"
+#include "hw/pci/msi.h"
 #include "hw/pci/msix.h"
 #include "hw/pci/pci.h"
 #include "sysemu/sysemu.h"
@@ -106,7 +107,9 @@
 static void nvme_irq_assert(NvmeCtrl *n, NvmeCQueue *cq)
 {
     if (cq->irq_enabled) {
-        if (msix_enabled(&(n->parent_obj))) {
+        if (msi_enabled(&(n->parent_obj))) {
+            msi_notify(&(n->parent_obj), cq->vector);
+        } else if (msix_enabled(&(n->parent_obj))) {
             trace_nvme_irq_msix(cq->vector);
             msix_notify(&(n->parent_obj), cq->vector);
         } else {
@@ -1232,7 +1235,7 @@
     pcie_endpoint_cap_init(&n->parent_obj, 0x80);
 
     n->num_namespaces = 1;
-    n->num_queues = 64;
+    n->num_queues = 32;
     n->reg_size = pow2ceil(0x1004 + 2 * (n->num_queues + 1) * 4);
     n->ns_size = bs_size / (uint64_t)n->num_namespaces;
 
@@ -1246,6 +1249,7 @@
         PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64,
         &n->iomem);
     msix_init_exclusive_bar(&n->parent_obj, n->num_queues, 4, NULL);
+    msi_init(&n->parent_obj, 0, n->num_queues, true, false, NULL);
 
     id->vid = cpu_to_le16(pci_get_word(pci_conf + PCI_VENDOR_ID));
     id->ssvid = cpu_to_le16(pci_get_word(pci_conf + PCI_SUBSYSTEM_VENDOR_ID));
@@ -1335,6 +1339,7 @@
     }
 
     msix_uninit_exclusive_bar(pci_dev);
+    msi_uninit(&n->parent_obj);
 }
 
 static Property nvme_props[] = {
diff --git a/slirp/misc.c b/slirp/misc.c
index 260187b..c6ad76d 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -189,7 +189,10 @@
                     so->s = accept(s, (struct sockaddr *)&addr, &addrlen);
                 } while (so->s < 0 && errno == EINTR);
                 closesocket(s);
-                socket_set_fast_reuse(so->s);
+                /*
+                 * Do not call socket_set_fast_reuse() on a connected socket.
+                 * Some kernels disallow it.
+                 */
                 opt = 1;
                 qemu_setsockopt(so->s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
 		qemu_set_nonblock(so->s);
diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index 740415d..331a3b2 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -534,7 +534,10 @@
         return;
     }
     qemu_set_nonblock(s);
-    socket_set_fast_reuse(s);
+    /*
+     * Do not call socket_set_fast_reuse() on a connected socket.
+     * Some kernels disallow it.
+     */
     opt = 1;
     qemu_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
     socket_set_nodelay(s);
diff --git a/slirp/udp.c b/slirp/udp.c
index 8910be4..3654418 100644
--- a/slirp/udp.c
+++ b/slirp/udp.c
@@ -382,11 +382,16 @@
 	addr.sin_addr.s_addr = haddr;
 	addr.sin_port = hport;
 
+	/*
+	 * SO_REUSEADDR has to be set before binding the socket.
+	 * Some kernels disallow doing this on a connected/bound socket.
+	 */
+	socket_set_fast_reuse(so->s);
+
 	if (bind(so->s,(struct sockaddr *)&addr, addrlen) < 0) {
 		udp_detach(so);
 		return NULL;
 	}
-	socket_set_fast_reuse(so->s);
 
 	getsockname(so->s,(struct sockaddr *)&addr,&addrlen);
 	so->fhost.sin = addr;