Merge "Use the default SAP interface name in VtsHalWifiHostapdV1_2TargetTest." into udc-dev
diff --git a/automotive/can/1.0/tools/configurator/canhalconfigurator.rc b/automotive/can/1.0/tools/configurator/canhalconfigurator.rc
index ff0efd7..8ae7cb2 100644
--- a/automotive/can/1.0/tools/configurator/canhalconfigurator.rc
+++ b/automotive/can/1.0/tools/configurator/canhalconfigurator.rc
@@ -1,3 +1,4 @@
 service canhalconfigurator /system_ext/bin/canhalconfigurator
   class core
+  user root
   oneshot
diff --git a/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json b/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json
index ae36290..84edeed 100644
--- a/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json
+++ b/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json
@@ -3705,7 +3705,19 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::MIRROR_DRIVER_LEFT_RIGHT",
+                    "areaId": "VehicleAreaMirror::DRIVER_LEFT",
+                    "supportedEnumValues": [
+                        "ErrorState::NOT_AVAILABLE_SAFETY",
+                        "ErrorState::NOT_AVAILABLE_POOR_VISIBILITY",
+                        "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
+                        "ErrorState::NOT_AVAILABLE_SPEED_LOW",
+                        "ErrorState::NOT_AVAILABLE_DISABLED",
+                        "BlindSpotWarningState::NO_WARNING",
+                        "BlindSpotWarningState::WARNING"
+                    ]
+                },
+                {
+                    "areaId": "VehicleAreaMirror::DRIVER_RIGHT",
                     "supportedEnumValues": [
                         "ErrorState::NOT_AVAILABLE_SAFETY",
                         "ErrorState::NOT_AVAILABLE_POOR_VISIBILITY",
diff --git a/automotive/vehicle/aidl/impl/grpc/Android.bp b/automotive/vehicle/aidl/impl/grpc/Android.bp
new file mode 100644
index 0000000..e8f0970
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/grpc/Android.bp
@@ -0,0 +1,102 @@
+// Copyright (C) 2023 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 {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+genrule {
+    name: "VehicleServerProtoStub_h@default-grpc",
+    tools: [
+        "aprotoc",
+        "protoc-gen-grpc-cpp-plugin",
+    ],
+    cmd: "$(location aprotoc) -I$$(dirname $(in)) -Ihardware/interfaces/automotive/vehicle/aidl/impl/proto -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-cpp-plugin) $(in) --grpc_out=$(genDir) --cpp_out=$(genDir)",
+    srcs: [
+        "proto/VehicleServer.proto",
+    ],
+    out: [
+        "VehicleServer.pb.h",
+        "VehicleServer.grpc.pb.h",
+    ],
+    visibility: ["//visibility:private"],
+}
+
+genrule {
+    name: "VehicleServerProtoStub_cc@default-grpc",
+    tools: [
+        "aprotoc",
+        "protoc-gen-grpc-cpp-plugin",
+    ],
+    cmd: "$(location aprotoc) -I$$(dirname $(in)) -Ihardware/interfaces/automotive/vehicle/aidl/impl/proto -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-cpp-plugin) $(in) --grpc_out=$(genDir) --cpp_out=$(genDir)",
+    srcs: [
+        "proto/VehicleServer.proto",
+    ],
+    out: [
+        "VehicleServer.pb.cc",
+        "VehicleServer.grpc.pb.cc",
+    ],
+    visibility: ["//visibility:private"],
+}
+
+cc_library_static {
+    name: "android.hardware.automotive.vehicle@default-grpc-libgrpc",
+    vendor: true,
+    host_supported: true,
+    include_dirs: [
+        "external/protobuf/src",
+    ],
+    generated_headers: [
+        "VehicleServerProtoStub_h@default-grpc",
+    ],
+    export_generated_headers: [
+        "VehicleServerProtoStub_h@default-grpc",
+    ],
+    generated_sources: [
+        "VehicleServerProtoStub_cc@default-grpc",
+    ],
+    whole_static_libs: [
+        "VehicleHalProtos",
+    ],
+    shared_libs: [
+        "libgrpc++",
+    ],
+    cflags: [
+        "-Wno-unused-parameter",
+    ],
+}
+
+cc_library_static {
+    name: "android.hardware.automotive.vehicle@default-grpc-hardware-lib",
+    defaults: ["VehicleHalDefaults"],
+    vendor: true,
+    srcs: [
+        "GRPCVehicleHardware.cpp",
+    ],
+    whole_static_libs: [
+        "android.hardware.automotive.vehicle@default-grpc-libgrpc",
+        "VehicleHalProtoMessageConverter",
+    ],
+    header_libs: [
+        "IVehicleHardware",
+    ],
+    shared_libs: [
+        "libgrpc++",
+        "libprotobuf-cpp-full",
+    ],
+    export_include_dirs: ["."],
+    cflags: [
+        "-Wno-unused-parameter",
+    ],
+}
diff --git a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.cpp b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.cpp
new file mode 100644
index 0000000..015157d
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.cpp
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2023 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 <GRPCVehicleHardware.h>
+
+#include "ProtoMessageConverter.h"
+
+#include <android-base/logging.h>
+#include <grpc++/grpc++.h>
+
+#include <cstdlib>
+#include <mutex>
+#include <shared_mutex>
+#include <utility>
+
+namespace android::hardware::automotive::vehicle::virtualization {
+
+static std::shared_ptr<::grpc::ChannelCredentials> getChannelCredentials() {
+    // TODO(chenhaosjtuacm): get secured credentials here
+    return ::grpc::InsecureChannelCredentials();
+}
+
+GRPCVehicleHardware::GRPCVehicleHardware(std::string service_addr)
+    : mServiceAddr(std::move(service_addr)),
+      mGrpcChannel(::grpc::CreateChannel(mServiceAddr, getChannelCredentials())),
+      mGrpcStub(proto::VehicleServer::NewStub(mGrpcChannel)),
+      mValuePollingThread([this] { ValuePollingLoop(); }) {}
+
+GRPCVehicleHardware::~GRPCVehicleHardware() {
+    {
+        std::lock_guard lck(mShutdownMutex);
+        mShuttingDownFlag.store(true);
+    }
+    mShutdownCV.notify_all();
+    mValuePollingThread.join();
+}
+
+std::vector<aidlvhal::VehiclePropConfig> GRPCVehicleHardware::getAllPropertyConfigs() const {
+    std::vector<aidlvhal::VehiclePropConfig> configs;
+    ::grpc::ClientContext context;
+    auto config_stream = mGrpcStub->GetAllPropertyConfig(&context, ::google::protobuf::Empty());
+    proto::VehiclePropConfig protoConfig;
+    while (config_stream->Read(&protoConfig)) {
+        aidlvhal::VehiclePropConfig config;
+        proto_msg_converter::protoToAidl(protoConfig, &config);
+        configs.push_back(std::move(config));
+    }
+    auto grpc_status = config_stream->Finish();
+    if (!grpc_status.ok()) {
+        LOG(ERROR) << __func__
+                   << ": GRPC GetAllPropertyConfig Failed: " << grpc_status.error_message();
+    }
+    return configs;
+}
+
+aidlvhal::StatusCode GRPCVehicleHardware::setValues(
+        std::shared_ptr<const SetValuesCallback> callback,
+        const std::vector<aidlvhal::SetValueRequest>& requests) {
+    ::grpc::ClientContext context;
+    proto::VehiclePropValueRequests protoRequests;
+    proto::SetValueResults protoResults;
+    for (const auto& request : requests) {
+        auto& protoRequest = *protoRequests.add_requests();
+        protoRequest.set_request_id(request.requestId);
+        proto_msg_converter::aidlToProto(request.value, protoRequest.mutable_value());
+    }
+    // TODO(chenhaosjtuacm): Make it Async.
+    auto grpc_status = mGrpcStub->SetValues(&context, protoRequests, &protoResults);
+    if (!grpc_status.ok()) {
+        LOG(ERROR) << __func__ << ": GRPC SetValues Failed: " << grpc_status.error_message();
+        {
+            std::shared_lock lck(mCallbackMutex);
+            // TODO(chenhaosjtuacm): call on-set-error callback.
+        }
+        return aidlvhal::StatusCode::INTERNAL_ERROR;
+    }
+    std::vector<aidlvhal::SetValueResult> results;
+    for (const auto& protoResult : protoResults.results()) {
+        auto& result = results.emplace_back();
+        result.requestId = protoResult.request_id();
+        result.status = static_cast<aidlvhal::StatusCode>(protoResult.status());
+        // TODO(chenhaosjtuacm): call on-set-error callback.
+    }
+    (*callback)(std::move(results));
+
+    return aidlvhal::StatusCode::OK;
+}
+
+aidlvhal::StatusCode GRPCVehicleHardware::getValues(
+        std::shared_ptr<const GetValuesCallback> callback,
+        const std::vector<aidlvhal::GetValueRequest>& requests) const {
+    ::grpc::ClientContext context;
+    proto::VehiclePropValueRequests protoRequests;
+    proto::GetValueResults protoResults;
+    for (const auto& request : requests) {
+        auto& protoRequest = *protoRequests.add_requests();
+        protoRequest.set_request_id(request.requestId);
+        proto_msg_converter::aidlToProto(request.prop, protoRequest.mutable_value());
+    }
+    // TODO(chenhaosjtuacm): Make it Async.
+    auto grpc_status = mGrpcStub->GetValues(&context, protoRequests, &protoResults);
+    if (!grpc_status.ok()) {
+        LOG(ERROR) << __func__ << ": GRPC GetValues Failed: " << grpc_status.error_message();
+        return aidlvhal::StatusCode::INTERNAL_ERROR;
+    }
+    std::vector<aidlvhal::GetValueResult> results;
+    for (const auto& protoResult : protoResults.results()) {
+        auto& result = results.emplace_back();
+        result.requestId = protoResult.request_id();
+        result.status = static_cast<aidlvhal::StatusCode>(protoResult.status());
+        if (protoResult.has_value()) {
+            aidlvhal::VehiclePropValue value;
+            proto_msg_converter::protoToAidl(protoResult.value(), &value);
+            result.prop = std::move(value);
+        }
+    }
+    (*callback)(std::move(results));
+
+    return aidlvhal::StatusCode::OK;
+}
+
+void GRPCVehicleHardware::registerOnPropertyChangeEvent(
+        std::unique_ptr<const PropertyChangeCallback> callback) {
+    std::lock_guard lck(mCallbackMutex);
+    if (mOnPropChange) {
+        LOG(ERROR) << __func__ << " must only be called once.";
+        return;
+    }
+    mOnPropChange = std::move(callback);
+}
+
+void GRPCVehicleHardware::registerOnPropertySetErrorEvent(
+        std::unique_ptr<const PropertySetErrorCallback> callback) {
+    std::lock_guard lck(mCallbackMutex);
+    if (mOnSetErr) {
+        LOG(ERROR) << __func__ << " must only be called once.";
+        return;
+    }
+    mOnSetErr = std::move(callback);
+}
+
+DumpResult GRPCVehicleHardware::dump(const std::vector<std::string>& /* options */) {
+    // TODO(chenhaosjtuacm): To be implemented.
+    return {};
+}
+
+aidlvhal::StatusCode GRPCVehicleHardware::checkHealth() {
+    // TODO(chenhaosjtuacm): To be implemented.
+    return aidlvhal::StatusCode::OK;
+}
+
+aidlvhal::StatusCode GRPCVehicleHardware::updateSampleRate(int32_t /* propId */,
+                                                           int32_t /* areaId */,
+                                                           float /* sampleRate */) {
+    // TODO(chenhaosjtuacm): To be implemented.
+    return aidlvhal::StatusCode::OK;
+}
+
+bool GRPCVehicleHardware::waitForConnected(std::chrono::milliseconds waitTime) {
+    return mGrpcChannel->WaitForConnected(gpr_time_add(
+            gpr_now(GPR_CLOCK_MONOTONIC), gpr_time_from_millis(waitTime.count(), GPR_TIMESPAN)));
+}
+
+void GRPCVehicleHardware::ValuePollingLoop() {
+    while (!mShuttingDownFlag.load()) {
+        ::grpc::ClientContext context;
+
+        bool rpc_stopped{false};
+        std::thread shuttingdown_watcher([this, &rpc_stopped, &context]() {
+            std::unique_lock<std::mutex> lck(mShutdownMutex);
+            mShutdownCV.wait(lck, [this, &rpc_stopped]() {
+                return rpc_stopped || mShuttingDownFlag.load();
+            });
+            context.TryCancel();
+        });
+
+        auto value_stream =
+                mGrpcStub->StartPropertyValuesStream(&context, ::google::protobuf::Empty());
+        LOG(INFO) << __func__ << ": GRPC Value Streaming Started";
+        proto::VehiclePropValues protoValues;
+        while (!mShuttingDownFlag.load() && value_stream->Read(&protoValues)) {
+            std::vector<aidlvhal::VehiclePropValue> values;
+            for (const auto protoValue : protoValues.values()) {
+                values.push_back(aidlvhal::VehiclePropValue());
+                proto_msg_converter::protoToAidl(protoValue, &values.back());
+            }
+            std::shared_lock lck(mCallbackMutex);
+            if (mOnPropChange) {
+                (*mOnPropChange)(values);
+            }
+        }
+
+        {
+            std::lock_guard lck(mShutdownMutex);
+            rpc_stopped = true;
+        }
+        mShutdownCV.notify_all();
+        shuttingdown_watcher.join();
+
+        auto grpc_status = value_stream->Finish();
+        // never reach here until connection lost
+        LOG(ERROR) << __func__ << ": GRPC Value Streaming Failed: " << grpc_status.error_message();
+
+        // try to reconnect
+    }
+}
+
+}  // namespace android::hardware::automotive::vehicle::virtualization
diff --git a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.h b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.h
new file mode 100644
index 0000000..90588aa
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2023 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 <IVehicleHardware.h>
+#include <VehicleHalTypes.h>
+#include <VehicleUtils.h>
+#include <android-base/result.h>
+
+#include "VehicleServer.grpc.pb.h"
+#include "VehicleServer.pb.h"
+
+#include <atomic>
+#include <chrono>
+#include <condition_variable>
+#include <memory>
+#include <shared_mutex>
+#include <string>
+#include <thread>
+#include <vector>
+
+namespace android::hardware::automotive::vehicle::virtualization {
+
+namespace aidlvhal = ::aidl::android::hardware::automotive::vehicle;
+
+class GRPCVehicleHardware : public IVehicleHardware {
+  public:
+    explicit GRPCVehicleHardware(std::string service_addr);
+
+    ~GRPCVehicleHardware();
+
+    // Get all the property configs.
+    std::vector<aidlvhal::VehiclePropConfig> getAllPropertyConfigs() const override;
+
+    // Set property values asynchronously. Server could return before the property set requests
+    // are sent to vehicle bus or before property set confirmation is received. The callback is
+    // safe to be called after the function returns and is safe to be called in a different thread.
+    aidlvhal::StatusCode setValues(std::shared_ptr<const SetValuesCallback> callback,
+                                   const std::vector<aidlvhal::SetValueRequest>& requests) override;
+
+    // Get property values asynchronously. Server could return before the property values are ready.
+    // The callback is safe to be called after the function returns and is safe to be called in a
+    // different thread.
+    aidlvhal::StatusCode getValues(
+            std::shared_ptr<const GetValuesCallback> callback,
+            const std::vector<aidlvhal::GetValueRequest>& requests) const override;
+
+    // Dump debug information in the server.
+    DumpResult dump(const std::vector<std::string>& options) override;
+
+    // Check whether the system is healthy, return {@code StatusCode::OK} for healthy.
+    aidlvhal::StatusCode checkHealth() override;
+
+    // Register a callback that would be called when there is a property change event from vehicle.
+    void registerOnPropertyChangeEvent(
+            std::unique_ptr<const PropertyChangeCallback> callback) override;
+
+    // Register a callback that would be called when there is a property set error event from
+    // vehicle.
+    void registerOnPropertySetErrorEvent(
+            std::unique_ptr<const PropertySetErrorCallback> callback) override;
+
+    // Update the sample rate for the [propId, areaId] pair.
+    aidlvhal::StatusCode updateSampleRate(int32_t propId, int32_t areaId,
+                                          float sampleRate) override;
+
+    bool waitForConnected(std::chrono::milliseconds waitTime);
+
+  private:
+    void ValuePollingLoop();
+
+    std::string mServiceAddr;
+    std::shared_ptr<::grpc::Channel> mGrpcChannel;
+    std::unique_ptr<proto::VehicleServer::Stub> mGrpcStub;
+    std::thread mValuePollingThread;
+
+    std::shared_mutex mCallbackMutex;
+    std::unique_ptr<const PropertyChangeCallback> mOnPropChange;
+    std::unique_ptr<const PropertySetErrorCallback> mOnSetErr;
+
+    std::mutex mShutdownMutex;
+    std::condition_variable mShutdownCV;
+    std::atomic<bool> mShuttingDownFlag{false};
+};
+
+}  // namespace android::hardware::automotive::vehicle::virtualization
diff --git a/automotive/vehicle/aidl/impl/grpc/OWNERS b/automotive/vehicle/aidl/impl/grpc/OWNERS
new file mode 100644
index 0000000..7a96f23
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/grpc/OWNERS
@@ -0,0 +1,3 @@
+shanyu@google.com
+chenhaosjtuacm@google.com
+egranata@google.com
diff --git a/automotive/vehicle/aidl/impl/grpc/proto/VehicleServer.proto b/automotive/vehicle/aidl/impl/grpc/proto/VehicleServer.proto
new file mode 100644
index 0000000..3490195
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/grpc/proto/VehicleServer.proto
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+syntax = "proto3";
+
+package android.hardware.automotive.vehicle.proto;
+
+import "android/hardware/automotive/vehicle/StatusCode.proto";
+import "android/hardware/automotive/vehicle/VehiclePropConfig.proto";
+import "android/hardware/automotive/vehicle/VehiclePropValue.proto";
+import "android/hardware/automotive/vehicle/VehiclePropValueRequest.proto";
+import "google/protobuf/empty.proto";
+
+message VehicleHalCallStatus {
+    StatusCode status_code = 1;
+}
+
+message VehiclePropValues {
+    repeated VehiclePropValue values = 1;
+}
+
+service VehicleServer {
+    rpc GetAllPropertyConfig(google.protobuf.Empty) returns (stream VehiclePropConfig) {}
+
+    rpc SetValues(VehiclePropValueRequests) returns (SetValueResults) {}
+
+    rpc GetValues(VehiclePropValueRequests) returns (GetValueResults) {}
+
+    rpc StartPropertyValuesStream(google.protobuf.Empty) returns (stream VehiclePropValues) {}
+}
diff --git a/automotive/vehicle/aidl/impl/grpc/test/Android.bp b/automotive/vehicle/aidl/impl/grpc/test/Android.bp
new file mode 100644
index 0000000..efdf4ca
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/grpc/test/Android.bp
@@ -0,0 +1,46 @@
+// Copyright (C) 2023 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 {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_test {
+    name: "GRPCVehicleHardwareUnitTest",
+    vendor: true,
+    srcs: ["GRPCVehicleHardwareUnitTest.cpp"],
+    whole_static_libs: [
+        "android.hardware.automotive.vehicle@default-grpc-hardware-lib",
+    ],
+    header_libs: [
+        "IVehicleHardware",
+    ],
+    static_libs: [
+        "libgtest",
+        "libgmock",
+    ],
+    shared_libs: [
+        "libgrpc++",
+        "libprotobuf-cpp-full",
+    ],
+    // libgrpc++.so is installed as root, require root to access it.
+    require_root: true,
+    defaults: [
+        "VehicleHalDefaults",
+    ],
+    cflags: [
+        "-Wno-unused-parameter",
+    ],
+    test_suites: ["device-tests"],
+}
diff --git a/automotive/vehicle/aidl/impl/grpc/test/GRPCVehicleHardwareUnitTest.cpp b/automotive/vehicle/aidl/impl/grpc/test/GRPCVehicleHardwareUnitTest.cpp
new file mode 100644
index 0000000..f578021
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/grpc/test/GRPCVehicleHardwareUnitTest.cpp
@@ -0,0 +1,94 @@
+// Copyright (C) 2023 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 "GRPCVehicleHardware.h"
+#include "VehicleServer.grpc.pb.h"
+#include "VehicleServer.pb.h"
+
+#include <gmock/gmock.h>
+#include <grpc++/grpc++.h>
+#include <gtest/gtest.h>
+
+#include <chrono>
+#include <memory>
+#include <string>
+
+namespace android::hardware::automotive::vehicle::virtualization {
+
+const std::string kFakeServerAddr = "0.0.0.0:54321";
+
+class FakeVehicleServer : public proto::VehicleServer::Service {
+  public:
+    ::grpc::Status StartPropertyValuesStream(
+            ::grpc::ServerContext* context, const ::google::protobuf::Empty* request,
+            ::grpc::ServerWriter<proto::VehiclePropValues>* stream) override {
+        stream->Write(proto::VehiclePropValues());
+        // A fake disconnection.
+        return ::grpc::Status(::grpc::StatusCode::ABORTED, "Connection lost.");
+    }
+
+    // Functions that we do not care.
+    ::grpc::Status GetAllPropertyConfig(
+            ::grpc::ServerContext* context, const ::google::protobuf::Empty* request,
+            ::grpc::ServerWriter<proto::VehiclePropConfig>* stream) override {
+        return ::grpc::Status::OK;
+    }
+
+    ::grpc::Status SetValues(::grpc::ServerContext* context,
+                             const proto::VehiclePropValueRequests* requests,
+                             proto::SetValueResults* results) override {
+        return ::grpc::Status::OK;
+    }
+
+    ::grpc::Status GetValues(::grpc::ServerContext* context,
+                             const proto::VehiclePropValueRequests* requests,
+                             proto::GetValueResults* results) override {
+        return ::grpc::Status::OK;
+    }
+};
+
+TEST(GRPCVehicleHardwareUnitTest, Reconnect) {
+    auto receivedUpdate = std::make_shared<std::atomic<int>>(0);
+    auto vehicleHardware = std::make_unique<GRPCVehicleHardware>(kFakeServerAddr);
+    vehicleHardware->registerOnPropertyChangeEvent(
+            std::make_unique<const IVehicleHardware::PropertyChangeCallback>(
+                    [receivedUpdate](const auto&) { receivedUpdate->fetch_add(1); }));
+
+    constexpr size_t kServerRestartTimes = 5;
+    for (size_t serverStart = 0; serverStart < kServerRestartTimes; ++serverStart) {
+        EXPECT_EQ(receivedUpdate->load(), 0);
+        auto fakeServer = std::make_unique<FakeVehicleServer>();
+        ::grpc::ServerBuilder builder;
+        builder.RegisterService(fakeServer.get());
+        builder.AddListeningPort(kFakeServerAddr, ::grpc::InsecureServerCredentials());
+        auto grpcServer = builder.BuildAndStart();
+
+        // Wait until the vehicle hardware received the second update (after one fake
+        // disconnection).
+        constexpr auto kMaxWaitTime = std::chrono::seconds(5);
+        auto startTime = std::chrono::steady_clock::now();
+        while (receivedUpdate->load() <= 1 &&
+               std::chrono::steady_clock::now() - startTime < kMaxWaitTime)
+            ;
+
+        grpcServer->Shutdown();
+        grpcServer->Wait();
+        EXPECT_GT(receivedUpdate->load(), 1);
+
+        // Reset for the next round.
+        receivedUpdate->store(0);
+    }
+}
+
+}  // namespace android::hardware::automotive::vehicle::virtualization
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl
index a92b366..2be76cb 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl
@@ -178,6 +178,8 @@
      *   2) A face is rejected, and ISessionCallback#onAuthenticationFailed is invoked.
      *   3) Any non-recoverable error occurs (such as lockout). See the full list of
      *      authentication-specific errors in the Error enum.
+     *   4) ISessionCallback#onLockoutPermanent is invoked.
+     *   5) ISessionCallback#onLockoutTimed is invoked.
      *
      * Note that upon successful authentication, the lockout counter for this (sensorId, userId)
      * pair must be cleared.
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl
index b3c348d..9eb575c 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl
@@ -119,6 +119,8 @@
      * lockout, and authentication can be restarted after a period of time. See
      * ISession#resetLockout.
      *
+     * This ends the authentication lifecycle.
+     *
      * @param sensorId Sensor for which the user is locked out.
      * @param userId User for which the sensor is locked out.
      * @param durationMillis Remaining duration of the lockout.
@@ -131,6 +133,8 @@
      * Authentication is disabled until the user unlocks with their device credential
      * (PIN/Pattern/Password). See ISession#resetLockout.
      *
+     * This ends the authentication lifecycle.
+     *
      * @param sensorId Sensor for which the user is locked out.
      * @param userId User for which the sensor is locked out.
      */
diff --git a/compatibility_matrices/Android.bp b/compatibility_matrices/Android.bp
index 622835e..93b5380 100644
--- a/compatibility_matrices/Android.bp
+++ b/compatibility_matrices/Android.bp
@@ -78,7 +78,7 @@
         "compatibility_matrix.8.xml",
     ],
     kernel_configs: [
-        "kernel_config_current_5.15",
-        "kernel_config_current_6.1",
+        "kernel_config_u_5.15",
+        "kernel_config_u_6.1",
     ],
 }
diff --git a/compatibility_matrices/compatibility_matrix.9.xml b/compatibility_matrices/compatibility_matrix.9.xml
new file mode 100644
index 0000000..188746d
--- /dev/null
+++ b/compatibility_matrices/compatibility_matrix.9.xml
@@ -0,0 +1,730 @@
+<!-- WARNING: This file is unused in the Android 14 branch. -->
+<compatibility-matrix version="1.0" type="framework" level="9">
+    <hal format="hidl" optional="true">
+        <name>android.hardware.audio</name>
+        <version>6.0</version>
+        <version>7.0-1</version>
+        <interface>
+            <name>IDevicesFactory</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.audio.effect</name>
+        <version>6.0</version>
+        <version>7.0</version>
+        <interface>
+            <name>IEffectsFactory</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.audio.core</name>
+        <version>1</version>
+        <interface>
+            <name>IModule</name>
+            <instance>default</instance>
+            <instance>a2dp</instance>
+            <instance>bluetooth</instance>
+            <instance>hearing_aid</instance>
+            <instance>msd</instance>
+            <instance>r_submix</instance>
+            <instance>stub</instance>
+            <instance>usb</instance>
+        </interface>
+        <interface>
+            <name>IConfig</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.audio.effect</name>
+        <version>1</version>
+        <interface>
+            <name>IFactory</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.audio.sounddose</name>
+        <version>1</version>
+        <interface>
+            <name>ISoundDoseFactory</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+         <name>android.hardware.authsecret</name>
+         <version>1</version>
+         <interface>
+             <name>IAuthSecret</name>
+             <instance>default</instance>
+         </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.automotive.audiocontrol</name>
+        <version>2-3</version>
+        <interface>
+            <name>IAudioControl</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.automotive.can</name>
+        <version>1</version>
+        <interface>
+            <name>ICanController</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.automotive.evs</name>
+        <version>1-2</version>
+        <interface>
+            <name>IEvsEnumerator</name>
+            <regex-instance>[a-z]+/[0-9]+</regex-instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.automotive.occupant_awareness</name>
+        <version>1</version>
+        <interface>
+            <name>IOccupantAwareness</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.automotive.vehicle</name>
+        <version>1-2</version>
+        <interface>
+            <name>IVehicle</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.automotive.remoteaccess</name>
+        <interface>
+            <name>IRemoteAccess</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.automotive.ivn</name>
+        <interface>
+            <name>IIvnAndroidDevice</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.biometrics.face</name>
+        <version>3</version>
+        <interface>
+            <name>IFace</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.biometrics.fingerprint</name>
+        <version>3</version>
+        <interface>
+            <name>IFingerprint</name>
+            <instance>default</instance>
+            <instance>virtual</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.bluetooth</name>
+        <version>1.0-1</version>
+        <interface>
+            <name>IBluetoothHci</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.bluetooth</name>
+        <interface>
+            <name>IBluetoothHci</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.bluetooth.audio</name>
+        <version>3</version>
+        <interface>
+            <name>IBluetoothAudioProviderFactory</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.boot</name>
+        <interface>
+            <name>IBootControl</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.broadcastradio</name>
+        <interface>
+            <name>IBroadcastRadio</name>
+            <regex-instance>.*</regex-instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true" updatable-via-apex="true">
+        <name>android.hardware.camera.provider</name>
+        <version>1-2</version>
+        <interface>
+            <name>ICameraProvider</name>
+            <regex-instance>[^/]+/[0-9]+</regex-instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.cas</name>
+        <interface>
+            <name>IMediaCasService</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.confirmationui</name>
+        <version>1</version>
+        <interface>
+            <name>IConfirmationUI</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.contexthub</name>
+        <version>2</version>
+        <interface>
+            <name>IContextHub</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true" updatable-via-apex="true">
+        <name>android.hardware.drm</name>
+        <version>1</version>
+        <interface>
+            <name>IDrmFactory</name>
+            <regex-instance>.*</regex-instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.dumpstate</name>
+        <interface>
+            <name>IDumpstateDevice</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.gatekeeper</name>
+        <version>1</version>
+        <interface>
+            <name>IGatekeeper</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.gnss</name>
+        <version>2-3</version>
+        <interface>
+            <name>IGnss</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.gnss.visibility_control</name>
+        <version>1</version>
+        <interface>
+            <name>IGnssVisibilityControl</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.gnss.measurement_corrections</name>
+        <version>1</version>
+        <interface>
+            <name>IMeasurementCorrectionsInterface</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.graphics.allocator</name>
+        <version>1-2</version>
+        <interface>
+            <name>IAllocator</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.graphics.composer3</name>
+        <version>2</version>
+        <interface>
+            <name>IComposer</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <!-- Either the native or the HIDL mapper HAL must exist on the device -->
+    <hal format="hidl" optional="true">
+        <name>android.hardware.graphics.mapper</name>
+        <!-- New, non-Go devices should use 4.0, tested in vts_treble_vintf_vendor_test -->
+        <version>2.1</version>
+        <version>3.0</version>
+        <version>4.0</version>
+        <interface>
+            <name>IMapper</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.health</name>
+        <version>1-2</version>
+        <interface>
+            <name>IHealth</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.health.storage</name>
+        <version>1</version>
+        <interface>
+            <name>IStorage</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.identity</name>
+        <version>1-5</version>
+        <interface>
+            <name>IIdentityCredentialStore</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.net.nlinterceptor</name>
+        <interface>
+            <name>IInterceptor</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.oemlock</name>
+        <version>1</version>
+        <interface>
+            <name>IOemLock</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.ir</name>
+        <version>1</version>
+        <interface>
+            <name>IConsumerIr</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.input.processor</name>
+        <version>1</version>
+        <interface>
+            <name>IInputProcessor</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.security.keymint</name>
+        <version>1-3</version>
+        <interface>
+            <name>IKeyMintDevice</name>
+            <instance>default</instance>
+            <instance>strongbox</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.security.keymint</name>
+        <version>1-3</version>
+        <interface>
+            <name>IRemotelyProvisionedComponent</name>
+            <instance>default</instance>
+            <instance>strongbox</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.light</name>
+        <version>2</version>
+        <interface>
+            <name>ILights</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.media.c2</name>
+        <version>1.0-2</version>
+        <interface>
+            <name>IComponentStore</name>
+            <regex-instance>default[0-9]*</regex-instance>
+            <regex-instance>vendor[0-9]*_software</regex-instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.memtrack</name>
+        <version>1</version>
+        <interface>
+            <name>IMemtrack</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.neuralnetworks</name>
+        <version>1-4</version>
+        <interface>
+            <name>IDevice</name>
+            <regex-instance>.*</regex-instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.nfc</name>
+        <interface>
+            <name>INfc</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.power</name>
+        <version>4</version>
+        <interface>
+            <name>IPower</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.power.stats</name>
+        <version>2</version>
+        <interface>
+            <name>IPowerStats</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.config</name>
+        <version>2</version>
+        <interface>
+            <name>IRadioConfig</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.data</name>
+        <version>2</version>
+        <interface>
+            <name>IRadioData</name>
+            <instance>slot1</instance>
+            <instance>slot2</instance>
+            <instance>slot3</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.messaging</name>
+        <version>2</version>
+        <interface>
+            <name>IRadioMessaging</name>
+            <instance>slot1</instance>
+            <instance>slot2</instance>
+            <instance>slot3</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.modem</name>
+        <version>2</version>
+        <interface>
+            <name>IRadioModem</name>
+            <instance>slot1</instance>
+            <instance>slot2</instance>
+            <instance>slot3</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.network</name>
+        <version>2</version>
+        <interface>
+            <name>IRadioNetwork</name>
+            <instance>slot1</instance>
+            <instance>slot2</instance>
+            <instance>slot3</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.sim</name>
+        <version>2</version>
+        <interface>
+            <name>IRadioSim</name>
+            <instance>slot1</instance>
+            <instance>slot2</instance>
+            <instance>slot3</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.sap</name>
+        <version>1</version>
+        <interface>
+            <name>ISap</name>
+            <instance>slot1</instance>
+            <instance>slot2</instance>
+            <instance>slot3</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.voice</name>
+        <version>2</version>
+        <interface>
+            <name>IRadioVoice</name>
+            <instance>slot1</instance>
+            <instance>slot2</instance>
+            <instance>slot3</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.ims</name>
+        <version>1</version>
+        <interface>
+            <name>IRadioIms</name>
+            <instance>slot1</instance>
+            <instance>slot2</instance>
+            <instance>slot3</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.satellite</name>
+        <version>1</version>
+        <interface>
+            <name>IRadioSatellite</name>
+            <instance>slot1</instance>
+            <instance>slot2</instance>
+            <instance>slot3</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.ims.media</name>
+        <version>1</version>
+        <interface>
+            <name>IImsMedia</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.renderscript</name>
+        <version>1.0</version>
+        <interface>
+            <name>IDevice</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.rebootescrow</name>
+        <version>1</version>
+        <interface>
+            <name>IRebootEscrow</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.secure_element</name>
+        <version>1</version>
+        <interface>
+            <name>ISecureElement</name>
+            <regex-instance>eSE[1-9][0-9]*</regex-instance>
+            <regex-instance>SIM[1-9][0-9]*</regex-instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.security.secureclock</name>
+        <version>1</version>
+        <interface>
+            <name>ISecureClock</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.security.sharedsecret</name>
+        <version>1</version>
+        <interface>
+            <name>ISharedSecret</name>
+            <instance>default</instance>
+            <instance>strongbox</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.sensors</name>
+        <version>2</version>
+        <interface>
+            <name>ISensors</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.soundtrigger</name>
+        <version>2.3</version>
+        <interface>
+            <name>ISoundTriggerHw</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+         <name>android.hardware.soundtrigger3</name>
+         <version>1</version>
+         <interface>
+             <name>ISoundTriggerHw</name>
+             <instance>default</instance>
+         </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.tetheroffload.config</name>
+        <version>1.0</version>
+        <interface>
+            <name>IOffloadConfig</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.tetheroffload.control</name>
+        <version>1.1</version>
+        <interface>
+            <name>IOffloadControl</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.tetheroffload</name>
+        <version>1</version>
+        <interface>
+            <name>IOffload</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.thermal</name>
+        <version>1</version>
+        <interface>
+            <name>IThermal</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.tv.hdmi.cec</name>
+        <version>1</version>
+        <interface>
+            <name>IHdmiCec</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.tv.hdmi.earc</name>
+        <version>1</version>
+        <interface>
+            <name>IEArc</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.tv.hdmi.connection</name>
+        <version>1</version>
+        <interface>
+            <name>IHdmiConnection</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.tv.tuner</name>
+        <version>1-2</version>
+        <interface>
+            <name>ITuner</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.tv.input</name>
+        <version>1</version>
+        <interface>
+            <name>ITvInput</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.usb</name>
+        <version>1-2</version>
+        <interface>
+            <name>IUsb</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.usb.gadget</name>
+        <interface>
+            <name>IUsbGadget</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.vibrator</name>
+        <version>1-2</version>
+        <interface>
+            <name>IVibrator</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.vibrator</name>
+        <version>1-2</version>
+        <interface>
+            <name>IVibratorManager</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.weaver</name>
+        <version>2</version>
+        <interface>
+            <name>IWeaver</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true" updatable-via-apex="true">
+        <name>android.hardware.wifi</name>
+        <version>1</version>
+        <interface>
+            <name>IWifi</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.uwb</name>
+        <version>1</version>
+        <interface>
+            <name>IUwb</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.wifi.hostapd</name>
+        <version>1</version>
+        <interface>
+            <name>IHostapd</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.wifi.supplicant</name>
+        <version>2</version>
+        <interface>
+            <name>ISupplicant</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <!-- Either the native or the HIDL mapper HAL must exist on the device -->
+    <hal format="native" optional="true">
+        <name>mapper</name>
+        <version>5.0</version>
+        <interface>
+            <regex-instance>.*</regex-instance>
+        </interface>
+    </hal>
+</compatibility-matrix>
diff --git a/radio/aidl/vts/radio_modem_test.cpp b/radio/aidl/vts/radio_modem_test.cpp
index c00b238..3454f33 100644
--- a/radio/aidl/vts/radio_modem_test.cpp
+++ b/radio/aidl/vts/radio_modem_test.cpp
@@ -191,6 +191,13 @@
  * Test IRadioModem.getImei() for the response returned.
  */
 TEST_P(RadioModemTest, getImei) {
+    int32_t aidl_version;
+    ndk::ScopedAStatus aidl_status = radio_modem->getInterfaceVersion(&aidl_version);
+    ASSERT_OK(aidl_status);
+    if (aidl_version < 2) {
+        ALOGI("Skipped the test since getImei is not supported on version < 2");
+        GTEST_SKIP();
+    }
     LOG(DEBUG) << "getImei";
     serial = GetRandomSerialNumber();
 
diff --git a/radio/aidl/vts/radio_sim_test.cpp b/radio/aidl/vts/radio_sim_test.cpp
index 44be258..f657142 100644
--- a/radio/aidl/vts/radio_sim_test.cpp
+++ b/radio/aidl/vts/radio_sim_test.cpp
@@ -765,6 +765,14 @@
  * Test IRadioSim.iccCloseLogicalChannelWithSessionInfo() for the response returned.
  */
 TEST_P(RadioSimTest, iccCloseLogicalChannelWithSessionInfo) {
+    int32_t aidl_version;
+    ndk::ScopedAStatus aidl_status = radio_sim->getInterfaceVersion(&aidl_version);
+    ASSERT_OK(aidl_status);
+    if (aidl_version < 2) {
+        ALOGI("Skipped the test since"
+              " iccCloseLogicalChannelWithSessionInfo is not supported on version < 2");
+        GTEST_SKIP();
+    }
     LOG(DEBUG) << "iccCloseLogicalChannelWithSessionInfo";
     serial = GetRandomSerialNumber();
     SessionInfo info;
diff --git a/security/keymint/aidl/vts/functional/Android.bp b/security/keymint/aidl/vts/functional/Android.bp
index ed3ca74..7a4359d 100644
--- a/security/keymint/aidl/vts/functional/Android.bp
+++ b/security/keymint/aidl/vts/functional/Android.bp
@@ -63,6 +63,7 @@
     srcs: [
         "AttestKeyTest.cpp",
         "AuthTest.cpp",
+        "BootloaderStateTest.cpp",
         "DeviceUniqueAttestationTest.cpp",
         "KeyBlobUpgradeTest.cpp",
         "KeyMintTest.cpp",
diff --git a/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp b/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp
new file mode 100644
index 0000000..fdadad4
--- /dev/null
+++ b/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+#define LOG_TAG "keymint_1_bootloader_test"
+
+#include <memory>
+#include <optional>
+#include <string>
+#include <vector>
+
+#include <android/binder_manager.h>
+#include <remote_prov/remote_prov_utils.h>
+
+#include "KeyMintAidlTestBase.h"
+
+namespace aidl::android::hardware::security::keymint::test {
+
+using ::android::getAidlHalInstanceNames;
+using ::std::string;
+using ::std::vector;
+
+// Since this test needs to talk to KeyMint HAL, it can only run as root. Thus,
+// bootloader can not be locked.
+class BootloaderStateTest : public testing::TestWithParam<std::string> {
+  public:
+    virtual void SetUp() override {
+        ::ndk::SpAIBinder binder(AServiceManager_waitForService(GetParam().c_str()));
+        keyMint_ = IKeyMintDevice::fromBinder(binder);
+        ASSERT_TRUE(keyMint_) << "Failed to get KM device";
+    }
+
+    std::shared_ptr<IKeyMintDevice> keyMint_;
+};
+
+// Check that attested bootloader state is set to unlocked.
+TEST_P(BootloaderStateTest, IsUnlocked) {
+    // Generate a key with attestation.
+    AuthorizationSet keyDesc = AuthorizationSetBuilder()
+                                       .Authorization(TAG_NO_AUTH_REQUIRED)
+                                       .EcdsaSigningKey(EcCurve::P_256)
+                                       .AttestationChallenge("foo")
+                                       .AttestationApplicationId("bar")
+                                       .Digest(Digest::NONE)
+                                       .SetDefaultValidity();
+    KeyCreationResult creationResult;
+    auto kmStatus = keyMint_->generateKey(keyDesc.vector_data(), std::nullopt, &creationResult);
+    ASSERT_TRUE(kmStatus.isOk());
+
+    vector<Certificate> key_cert_chain = std::move(creationResult.certificateChain);
+
+    // Parse attested AVB values.
+    const auto& attestation_cert = key_cert_chain[0].encodedCertificate;
+    X509_Ptr cert(parse_cert_blob(attestation_cert));
+    ASSERT_TRUE(cert.get());
+
+    ASN1_OCTET_STRING* attest_rec = get_attestation_record(cert.get());
+    ASSERT_TRUE(attest_rec);
+
+    vector<uint8_t> key;
+    VerifiedBoot attestedVbState;
+    bool attestedBootloaderState;
+    vector<uint8_t> attestedVbmetaDigest;
+    auto error = parse_root_of_trust(attest_rec->data, attest_rec->length, &key, &attestedVbState,
+                                     &attestedBootloaderState, &attestedVbmetaDigest);
+    ASSERT_EQ(error, ErrorCode::OK);
+    ASSERT_FALSE(attestedBootloaderState) << "This test runs as root. Bootloader must be unlocked.";
+}
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, BootloaderStateTest,
+                         testing::ValuesIn(getAidlHalInstanceNames(IKeyMintDevice::descriptor)),
+                         ::android::PrintInstanceNameToString);
+
+}  // namespace aidl::android::hardware::security::keymint::test
diff --git a/wifi/aidl/android/hardware/wifi/IWifiStaIface.aidl b/wifi/aidl/android/hardware/wifi/IWifiStaIface.aidl
index 2c81984..6d6afaf 100644
--- a/wifi/aidl/android/hardware/wifi/IWifiStaIface.aidl
+++ b/wifi/aidl/android/hardware/wifi/IWifiStaIface.aidl
@@ -534,14 +534,18 @@
     void stopSendingKeepAlivePackets(in int cmdId);
 
     /**
-     * Set DTIM multiplier used when the system is in the suspended mode.
+     * Set maximum acceptable DTIM multiplier to hardware driver.
+     * Any multiplier larger than this maximum value must not be accepted since it will cause
+     * packet loss higher than what the system can accept, which will cause unexpected behavior
+     * for apps, and may interrupt the network connection.
+     *
      * When STA is in the power saving mode and system is suspended,
      * the wake up interval will be set to:
      *              1) multiplier * DTIM period if multiplier > 0.
      *              2) the driver default value if multiplier <= 0.
      * Some implementations may apply an additional cap to wake up interval in the case of 1).
      *
-     * @param multiplier integer DTIM multiplier value to set.
+     * @param multiplier integer maximum DTIM multiplier value to set.
      * @throws ServiceSpecificException with one of the following values:
      *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
      *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
diff --git a/wifi/aidl/default/wifi.cpp b/wifi/aidl/default/wifi.cpp
index e30c38a..d6a85da 100644
--- a/wifi/aidl/default/wifi.cpp
+++ b/wifi/aidl/default/wifi.cpp
@@ -19,6 +19,7 @@
 #include <android-base/logging.h>
 
 #include "aidl_return_util.h"
+#include "aidl_sync_util.h"
 #include "wifi_status_util.h"
 
 namespace {
@@ -32,6 +33,7 @@
 namespace wifi {
 using aidl_return_util::validateAndCall;
 using aidl_return_util::validateAndCallWithLock;
+using aidl_sync_util::acquireGlobalLock;
 
 Wifi::Wifi(const std::shared_ptr<::android::wifi_system::InterfaceTool> iface_tool,
            const std::shared_ptr<legacy_hal::WifiLegacyHalFactory> legacy_hal_factory,
@@ -78,6 +80,7 @@
 }
 
 binder_status_t Wifi::dump(int fd, const char** args, uint32_t numArgs) {
+    const auto lock = acquireGlobalLock();
     LOG(INFO) << "-----------Debug was called----------------";
     if (chips_.size() == 0) {
         LOG(INFO) << "No chips to display.";