Merge "Add new OperandType TENSOR_QUANT16_ASYMM."
diff --git a/audio/5.0/config/api/current.txt b/audio/5.0/config/api/current.txt
index 4334172..bceedcc 100644
--- a/audio/5.0/config/api/current.txt
+++ b/audio/5.0/config/api/current.txt
@@ -194,6 +194,7 @@
   public static class DevicePorts.DevicePort {
     ctor public DevicePorts.DevicePort();
     method public java.lang.String getAddress();
+    method public java.util.List<audio.policy.configuration.V5_0.AudioFormat> getEncodedFormats();
     method public audio.policy.configuration.V5_0.Gains getGains();
     method public java.util.List<audio.policy.configuration.V5_0.Profile> getProfile();
     method public audio.policy.configuration.V5_0.Role getRole();
@@ -201,6 +202,7 @@
     method public java.lang.String getType();
     method public boolean get_default();
     method public void setAddress(java.lang.String);
+    method public void setEncodedFormats(java.util.List<audio.policy.configuration.V5_0.AudioFormat>);
     method public void setGains(audio.policy.configuration.V5_0.Gains);
     method public void setRole(audio.policy.configuration.V5_0.Role);
     method public void setTagName(java.lang.String);
diff --git a/audio/5.0/config/audio_policy_configuration.xsd b/audio/5.0/config/audio_policy_configuration.xsd
index b0927b2..efe93b3 100644
--- a/audio/5.0/config/audio_policy_configuration.xsd
+++ b/audio/5.0/config/audio_policy_configuration.xsd
@@ -461,6 +461,8 @@
                             </xs:documentation>
                         </xs:annotation>
                     </xs:attribute>
+                    <xs:attribute name="encodedFormats" type="audioFormatsList" use="optional"
+                                  default="" />
                 </xs:complexType>
                 <xs:unique name="devicePortProfileUniqueness">
                     <xs:selector xpath="profile"/>
@@ -595,7 +597,7 @@
             <xs:element name="formats" type="surroundFormats"/>
         </xs:sequence>
     </xs:complexType>
-    <xs:simpleType name="surroundFormatsList">
+    <xs:simpleType name="audioFormatsList">
         <xs:list itemType="audioFormat" />
     </xs:simpleType>
     <xs:complexType name="surroundFormats">
@@ -603,7 +605,7 @@
             <xs:element name="format" minOccurs="0" maxOccurs="unbounded">
                 <xs:complexType>
                     <xs:attribute name="name" type="audioFormat" use="required"/>
-                    <xs:attribute name="subformats" type="surroundFormatsList" />
+                    <xs:attribute name="subformats" type="audioFormatsList" />
                 </xs:complexType>
             </xs:element>
         </xs:sequence>
diff --git a/audio/common/all-versions/default/service/Android.mk b/audio/common/all-versions/default/service/Android.mk
index 32110ee..58987c7 100644
--- a/audio/common/all-versions/default/service/Android.mk
+++ b/audio/common/all-versions/default/service/Android.mk
@@ -50,7 +50,8 @@
     android.hardware.audio.effect@5.0 \
     android.hardware.bluetooth.a2dp@1.0 \
     android.hardware.soundtrigger@2.0 \
-    android.hardware.soundtrigger@2.1
+    android.hardware.soundtrigger@2.1 \
+    android.hardware.soundtrigger@2.2
 
 # Can not switch to Android.bp until AUDIOSERVER_MULTILIB
 # is deprecated as build config variable are not supported
diff --git a/audio/common/all-versions/default/service/service.cpp b/audio/common/all-versions/default/service/service.cpp
index 7b5da81..15ce5e0 100644
--- a/audio/common/all-versions/default/service/service.cpp
+++ b/audio/common/all-versions/default/service/service.cpp
@@ -25,6 +25,7 @@
 #include <android/hardware/bluetooth/a2dp/1.0/IBluetoothAudioOffload.h>
 #include <android/hardware/soundtrigger/2.0/ISoundTriggerHw.h>
 #include <android/hardware/soundtrigger/2.1/ISoundTriggerHw.h>
+#include <android/hardware/soundtrigger/2.2/ISoundTriggerHw.h>
 #include <binder/ProcessState.h>
 #include <cutils/properties.h>
 #include <hidl/HidlTransportSupport.h>
@@ -58,9 +59,10 @@
            registerPassthroughServiceImplementation<audio::effect::V2_0::IEffectsFactory>() != OK,
     LOG_ALWAYS_FATAL_IF(fail, "Could not register audio effect API 2, 4 nor 5");
 
-    fail = registerPassthroughServiceImplementation<soundtrigger::V2_1::ISoundTriggerHw>() != OK &&
+    fail = registerPassthroughServiceImplementation<soundtrigger::V2_2::ISoundTriggerHw>() != OK &&
+           registerPassthroughServiceImplementation<soundtrigger::V2_1::ISoundTriggerHw>() != OK &&
            registerPassthroughServiceImplementation<soundtrigger::V2_0::ISoundTriggerHw>() != OK,
-    ALOGW_IF(fail, "Could not register soundtrigger API 2.0 nor 2.1");
+    ALOGW_IF(fail, "Could not register soundtrigger API 2.0, 2.1 nor 2.2");
 
     fail =
         registerPassthroughServiceImplementation<bluetooth::a2dp::V1_0::IBluetoothAudioOffload>() !=
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index e1c5bac..049dfa4 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -393,7 +393,7 @@
     </hal>
     <hal format="hidl" optional="true">
         <name>android.hardware.soundtrigger</name>
-        <version>2.0-1</version>
+        <version>2.0-2</version>
         <interface>
             <name>ISoundTriggerHw</name>
             <instance>default</instance>
diff --git a/gnss/measurement_corrections/1.0/types.hal b/gnss/measurement_corrections/1.0/types.hal
index 4b48e4e..5f20734 100644
--- a/gnss/measurement_corrections/1.0/types.hal
+++ b/gnss/measurement_corrections/1.0/types.hal
@@ -47,8 +47,11 @@
      */
     float carrierFrequencyHz;
 
-    /** True if the satellite is in Line-of-Sight condition */
-    bool satIsLos;
+    /**
+     * The probability that the satellite is estimated to be in Line-of-Sight condition at the given
+     * location.
+     */
+    float probSatIsLos;
 
     /**
      * Excess path length to be subtracted from pseudorange before using it in calculating location.
@@ -123,8 +126,8 @@
 
 /** Bit mask to indicate which values are valid in a SingleSatCorrection object. */
 enum GnssSingleSatCorrectionFlags : uint16_t {
-    /** GnssSingleSatCorrectionFlags has valid satellite-is-line-of-sight field. */
-    HAS_SAT_IS_LOS                           = 0x0001,
+    /** GnssSingleSatCorrectionFlags has valid satellite-is-line-of-sight-probability field. */
+    HAS_SAT_IS_LOS_PROBABILITY               = 0x0001,
     /** GnssSingleSatCorrectionFlags has valid Excess Path Length field. */
     HAS_EXCESS_PATH_LENGTH                   = 0x0002,
     /** GnssSingleSatCorrectionFlags has valid Excess Path Length Uncertainty field. */
diff --git a/neuralnetworks/1.2/IDevice.hal b/neuralnetworks/1.2/IDevice.hal
index 6a77961..6c3b483 100644
--- a/neuralnetworks/1.2/IDevice.hal
+++ b/neuralnetworks/1.2/IDevice.hal
@@ -56,6 +56,26 @@
     getVersionString() generates (ErrorStatus status, string version);
 
     /**
+     * Get the type of a given device.
+     *
+     * The device type can be used to help application developers to distribute
+     * Machine Learning workloads and other workloads such as graphical rendering.
+     * E.g., for an app which renders AR scenes based on real time object detection
+     * results, the developer could choose an ACCELERATOR type device for ML
+     * workloads, and reserve GPU for graphical rendering.
+     *
+     * @param status Error status returned from querying the device type. Must be:
+     *               - NONE if the query was successful
+     *               - DEVICE_UNAVAILABLE if driver is offline or busy
+     *               - GENERAL_FAILURE if the query resulted in an
+     *                 unspecified error
+     * @param type The DeviceType of the device. Please note, this is not a
+     *             bitfield of DeviceTypes. Each device must only be of a
+     *             single DeviceType.
+     */
+    getType() generates (ErrorStatus status, DeviceType type);
+
+    /**
      * Gets the supported operations in a model.
      *
      * getSupportedOperations indicates which operations of a model are fully
diff --git a/neuralnetworks/1.2/types.hal b/neuralnetworks/1.2/types.hal
index c164d72..ac944c8 100644
--- a/neuralnetworks/1.2/types.hal
+++ b/neuralnetworks/1.2/types.hal
@@ -192,6 +192,26 @@
 };
 
 /**
+ * Device types.
+ *
+ * The type of NNAPI device.
+ */
+enum DeviceType : int32_t {
+    // Leaving 0 unused as it means unknown type in NDK NNAPI. There is no
+    // HAL equivalent of unknown type and a 1.2 HAL implementation must belong
+    // to one of the categories below.
+    /** The device does not fall into any category below. */
+    OTHER             = 1,
+    /** The device runs NNAPI models on single or multi-core CPU. */
+    CPU               = 2,
+    /** The device can run NNAPI models and also accelerate graphics APIs such
+      * as OpenGL ES and Vulkan. */
+    GPU               = 3,
+    /** Dedicated accelerator for Machine Learning workloads. */
+    ACCELERATOR       = 4,
+};
+
+/**
  * Describes one operation of the model's graph.
  */
 struct Operation {
diff --git a/neuralnetworks/1.2/vts/functional/BasicTests.cpp b/neuralnetworks/1.2/vts/functional/BasicTests.cpp
index eb3ebd3..8c3ad15 100644
--- a/neuralnetworks/1.2/vts/functional/BasicTests.cpp
+++ b/neuralnetworks/1.2/vts/functional/BasicTests.cpp
@@ -45,6 +45,16 @@
     });
     EXPECT_TRUE(ret.isOk());
 }
+
+// device type test
+TEST_F(NeuralnetworksHidlTest, GetDeviceTypeTest) {
+    Return<void> ret = device->getType([](ErrorStatus status, DeviceType type) {
+        EXPECT_EQ(ErrorStatus::NONE, status);
+        EXPECT_TRUE(type == DeviceType::OTHER || type == DeviceType::CPU ||
+                    type == DeviceType::GPU || type == DeviceType::ACCELERATOR);
+    });
+    EXPECT_TRUE(ret.isOk());
+}
 }  // namespace functional
 }  // namespace vts
 }  // namespace V1_2
diff --git a/power/stats/1.0/default/Android.bp b/power/stats/1.0/default/Android.bp
index 04270c1..b57466d 100644
--- a/power/stats/1.0/default/Android.bp
+++ b/power/stats/1.0/default/Android.bp
@@ -11,7 +11,7 @@
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 // See the License for the specific language governing permissions and
 
-cc_library_shared {
+cc_binary {
     name: "android.hardware.power.stats@1.0-service",
     relative_install_path: "hw",
     init_rc: ["android.hardware.power.stats@1.0-service.rc"],
diff --git a/power/stats/1.0/default/OWNERS b/power/stats/1.0/default/OWNERS
new file mode 100644
index 0000000..2d95a97
--- /dev/null
+++ b/power/stats/1.0/default/OWNERS
@@ -0,0 +1,3 @@
+krossmo@google.com
+bsschwar@google.com
+tstrudel@google.com
diff --git a/power/stats/1.0/default/PowerStats.cpp b/power/stats/1.0/default/PowerStats.cpp
index 810c575..350aa62 100644
--- a/power/stats/1.0/default/PowerStats.cpp
+++ b/power/stats/1.0/default/PowerStats.cpp
@@ -287,25 +287,218 @@
     return Void();
 }
 
+uint32_t PowerStats::addPowerEntity(const std::string& name, PowerEntityType type) {
+    uint32_t id = mPowerEntityInfos.size();
+    mPowerEntityInfos.push_back({id, name, type});
+    return id;
+}
+
+void PowerStats::addStateResidencyDataProvider(std::shared_ptr<IStateResidencyDataProvider> p) {
+    std::vector<PowerEntityStateSpace> stateSpaces = p->getStateSpaces();
+    for (auto stateSpace : stateSpaces) {
+        mPowerEntityStateSpaces.emplace(stateSpace.powerEntityId, stateSpace);
+        mStateResidencyDataProviders.emplace(stateSpace.powerEntityId, p);
+    }
+}
+
 Return<void> PowerStats::getPowerEntityInfo(getPowerEntityInfo_cb _hidl_cb) {
-    hidl_vec<PowerEntityInfo> eInfo;
-    _hidl_cb(eInfo, Status::NOT_SUPPORTED);
+    // If not configured, return NOT_SUPPORTED
+    if (mPowerEntityInfos.empty()) {
+        _hidl_cb({}, Status::NOT_SUPPORTED);
+        return Void();
+    }
+
+    _hidl_cb(mPowerEntityInfos, Status::SUCCESS);
     return Void();
 }
 
 Return<void> PowerStats::getPowerEntityStateInfo(const hidl_vec<uint32_t>& powerEntityIds,
                                                  getPowerEntityStateInfo_cb _hidl_cb) {
-    (void)powerEntityIds;
-    hidl_vec<PowerEntityStateSpace> powerEntityStateSpaces;
-    _hidl_cb(powerEntityStateSpaces, Status::NOT_SUPPORTED);
+    // If not configured, return NOT_SUPPORTED
+    if (mPowerEntityStateSpaces.empty()) {
+        _hidl_cb({}, Status::NOT_SUPPORTED);
+        return Void();
+    }
+
+    std::vector<PowerEntityStateSpace> stateSpaces;
+
+    // If powerEntityIds is empty then return state space info for all entities
+    if (powerEntityIds.size() == 0) {
+        stateSpaces.reserve(mPowerEntityStateSpaces.size());
+        for (auto i : mPowerEntityStateSpaces) {
+            stateSpaces.emplace_back(i.second);
+        }
+        _hidl_cb(stateSpaces, Status::SUCCESS);
+        return Void();
+    }
+
+    // Return state space information only for valid ids
+    auto ret = Status::SUCCESS;
+    stateSpaces.reserve(powerEntityIds.size());
+    for (const uint32_t id : powerEntityIds) {
+        auto stateSpace = mPowerEntityStateSpaces.find(id);
+        if (stateSpace != mPowerEntityStateSpaces.end()) {
+            stateSpaces.emplace_back(stateSpace->second);
+        } else {
+            ret = Status::INVALID_INPUT;
+        }
+    }
+
+    _hidl_cb(stateSpaces, ret);
     return Void();
 }
 
 Return<void> PowerStats::getPowerEntityStateResidencyData(
-    const hidl_vec<uint32_t>& powerEntityIds, getPowerEntityStateResidencyData_cb _hidl_cb) {
-    (void)powerEntityIds;
+        const hidl_vec<uint32_t>& powerEntityIds, getPowerEntityStateResidencyData_cb _hidl_cb) {
+    // If not configured, return NOT_SUPPORTED
+    if (mStateResidencyDataProviders.empty() || mPowerEntityStateSpaces.empty()) {
+        _hidl_cb({}, Status::NOT_SUPPORTED);
+        return Void();
+    }
+
+    // If powerEntityIds is empty then return data for all supported entities
+    if (powerEntityIds.size() == 0) {
+        std::vector<uint32_t> ids;
+        for (auto stateSpace : mPowerEntityStateSpaces) {
+            ids.emplace_back(stateSpace.first);
+        }
+        return getPowerEntityStateResidencyData(ids, _hidl_cb);
+    }
+
+    std::unordered_map<uint32_t, PowerEntityStateResidencyResult> stateResidencies;
+    std::vector<PowerEntityStateResidencyResult> results;
+    results.reserve(powerEntityIds.size());
+
+    // return results for only the given powerEntityIds
+    bool invalidInput = false;
+    bool filesystemError = false;
+    for (auto id : powerEntityIds) {
+        auto dataProvider = mStateResidencyDataProviders.find(id);
+        // skip if the given powerEntityId does not have an associated StateResidencyDataProvider
+        if (dataProvider == mStateResidencyDataProviders.end()) {
+            invalidInput = true;
+            continue;
+        }
+
+        // get the results if we have not already done so.
+        if (stateResidencies.find(id) == stateResidencies.end()) {
+            if (!dataProvider->second->getResults(stateResidencies)) {
+                filesystemError = true;
+            }
+        }
+
+        // append results
+        auto stateResidency = stateResidencies.find(id);
+        if (stateResidency != stateResidencies.end()) {
+            results.emplace_back(stateResidency->second);
+        }
+    }
+
+    auto ret = Status::SUCCESS;
+    if (filesystemError) {
+        ret = Status::FILESYSTEM_ERROR;
+    } else if (invalidInput) {
+        ret = Status::INVALID_INPUT;
+    }
+
+    _hidl_cb(results, ret);
+    return Void();
+}
+
+bool DumpResidencyDataToFd(const hidl_vec<PowerEntityInfo>& infos,
+                           const hidl_vec<PowerEntityStateSpace>& stateSpaces,
+                           const hidl_vec<PowerEntityStateResidencyResult>& results, int fd) {
+    // construct lookup table of powerEntityId to name
+    std::unordered_map<uint32_t, std::string> entityNames;
+    for (auto info : infos) {
+        entityNames.emplace(info.powerEntityId, info.powerEntityName);
+    }
+
+    // construct lookup table of powerEntityId, powerEntityStateId to state name
+    std::unordered_map<uint32_t, std::unordered_map<uint32_t, std::string>> stateNames;
+    for (auto stateSpace : stateSpaces) {
+        stateNames.emplace(stateSpace.powerEntityId, std::unordered_map<uint32_t, std::string>());
+        for (auto state : stateSpace.states) {
+            stateNames.at(stateSpace.powerEntityId)
+                    .emplace(state.powerEntityStateId, state.powerEntityStateName);
+        }
+    }
+
+    std::ostringstream dumpStats;
+    dumpStats << "\n========== PowerStats HAL 1.0 state residencies ==========\n";
+
+    const char* headerFormat = "  %14s   %14s   %16s   %15s   %16s\n";
+    const char* dataFormat =
+            "  %14s   %14s   %13" PRIu64 " ms   %15" PRIu64 "   %13" PRIu64 " ms\n";
+    dumpStats << android::base::StringPrintf(headerFormat, "Entity", "State", "Total time",
+                                             "Total entries", "Last entry timestamp");
+
+    for (auto result : results) {
+        for (auto stateResidency : result.stateResidencyData) {
+            dumpStats << android::base::StringPrintf(
+                    dataFormat, entityNames.at(result.powerEntityId).c_str(),
+                    stateNames.at(result.powerEntityId)
+                            .at(stateResidency.powerEntityStateId)
+                            .c_str(),
+                    stateResidency.totalTimeInStateMs, stateResidency.totalStateEntryCount,
+                    stateResidency.lastEntryTimestampMs);
+        }
+    }
+
+    dumpStats << "========== End of PowerStats HAL 1.0 state residencies ==========\n";
+
+    return android::base::WriteStringToFd(dumpStats.str(), fd);
+}
+
+Return<void> PowerStats::debug(const hidl_handle& handle, const hidl_vec<hidl_string>&) {
+    if (handle == nullptr || handle->numFds < 1) {
+        return Void();
+    }
+
+    int fd = handle->data[0];
+    Status status;
+    hidl_vec<PowerEntityInfo> infos;
+
+    // Get power entity information
+    getPowerEntityInfo([&status, &infos](auto rInfos, auto rStatus) {
+        status = rStatus;
+        infos = rInfos;
+    });
+    if (status != Status::SUCCESS) {
+        LOG(ERROR) << "Error getting power entity info";
+        return Void();
+    }
+
+    // Get power entity state information
+    hidl_vec<PowerEntityStateSpace> stateSpaces;
+    getPowerEntityStateInfo({}, [&status, &stateSpaces](auto rStateSpaces, auto rStatus) {
+        status = rStatus;
+        stateSpaces = rStateSpaces;
+    });
+    if (status != Status::SUCCESS) {
+        LOG(ERROR) << "Error getting state info";
+        return Void();
+    }
+
+    // Get power entity state residency data
     hidl_vec<PowerEntityStateResidencyResult> results;
-    _hidl_cb(results, Status::NOT_SUPPORTED);
+    getPowerEntityStateResidencyData({}, [&status, &results](auto rResults, auto rStatus) {
+        status = rStatus;
+        results = rResults;
+    });
+
+    // This implementation of getPowerEntityStateResidencyData supports the
+    // return of partial results if status == FILESYSTEM_ERROR.
+    if (status != Status::SUCCESS) {
+        LOG(ERROR) << "Error getting residency data -- Some results missing";
+    }
+
+    if (!DumpResidencyDataToFd(infos, stateSpaces, results, fd)) {
+        PLOG(ERROR) << "Failed to dump residency data to fd";
+    }
+
+    fsync(fd);
+
     return Void();
 }
 
diff --git a/power/stats/1.0/default/PowerStats.h b/power/stats/1.0/default/PowerStats.h
index fb2c6a8..d67fb35 100644
--- a/power/stats/1.0/default/PowerStats.h
+++ b/power/stats/1.0/default/PowerStats.h
@@ -21,6 +21,7 @@
 #include <fmq/MessageQueue.h>
 #include <hidl/MQDescriptor.h>
 #include <hidl/Status.h>
+#include <unordered_map>
 
 namespace android {
 namespace hardware {
@@ -60,8 +61,19 @@
     std::unique_ptr<MessageQueueSync> fmqSynchronized;
 };
 
+class IStateResidencyDataProvider {
+   public:
+    virtual ~IStateResidencyDataProvider() = default;
+    virtual bool getResults(
+            std::unordered_map<uint32_t, PowerEntityStateResidencyResult>& results) = 0;
+    virtual std::vector<PowerEntityStateSpace> getStateSpaces() = 0;
+};
+
 struct PowerStats : public IPowerStats {
+   public:
     PowerStats();
+    uint32_t addPowerEntity(const std::string& name, PowerEntityType type);
+    void addStateResidencyDataProvider(std::shared_ptr<IStateResidencyDataProvider> p);
     // Methods from ::android::hardware::power::stats::V1_0::IPowerStats follow.
     Return<void> getRailInfo(getRailInfo_cb _hidl_cb) override;
     Return<void> getEnergyData(const hidl_vec<uint32_t>& railIndices,
@@ -75,12 +87,19 @@
         const hidl_vec<uint32_t>& powerEntityIds,
         getPowerEntityStateResidencyData_cb _hidl_cb) override;
 
+    // Methods from ::android::hidl::base::V1_0::IBase follow.
+    Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& args) override;
+
    private:
     OnDeviceMmt mPm;
     void findIioPowerMonitorNodes();
     size_t parsePowerRails();
     int parseIioEnergyNode(std::string devName);
     Status parseIioEnergyNodes();
+    std::vector<PowerEntityInfo> mPowerEntityInfos;
+    std::unordered_map<uint32_t, PowerEntityStateSpace> mPowerEntityStateSpaces;
+    std::unordered_map<uint32_t, std::shared_ptr<IStateResidencyDataProvider>>
+            mStateResidencyDataProviders;
 };
 
 }  // namespace implementation
diff --git a/power/stats/1.0/default/service.cpp b/power/stats/1.0/default/service.cpp
index 80649f5..a516536 100644
--- a/power/stats/1.0/default/service.cpp
+++ b/power/stats/1.0/default/service.cpp
@@ -31,17 +31,69 @@
 
 // Generated HIDL files
 using android::hardware::power::stats::V1_0::IPowerStats;
+using android::hardware::power::stats::V1_0::PowerEntityStateResidencyResult;
+using android::hardware::power::stats::V1_0::PowerEntityStateSpace;
+using android::hardware::power::stats::V1_0::PowerEntityType;
+using android::hardware::power::stats::V1_0::implementation::IStateResidencyDataProvider;
 using android::hardware::power::stats::V1_0::implementation::PowerStats;
 
+class DefaultStateResidencyDataProvider : public IStateResidencyDataProvider {
+   public:
+    DefaultStateResidencyDataProvider(uint32_t id)
+        : mPowerEntityId(id), mActiveStateId(0), mSleepStateId(1) {}
+    ~DefaultStateResidencyDataProvider() = default;
+
+    bool getResults(std::unordered_map<uint32_t, PowerEntityStateResidencyResult>& results) {
+        PowerEntityStateResidencyResult result = { .powerEntityId = mPowerEntityId };
+        result.stateResidencyData.resize(2);
+
+        // Using fake numbers here for display only. A real implementation would
+        // use actual tracked stats.
+        result.stateResidencyData[0] = {
+            .powerEntityStateId = mActiveStateId,
+            .totalTimeInStateMs = 1,
+            .totalStateEntryCount = 2,
+            .lastEntryTimestampMs = 3
+        };
+        result.stateResidencyData[1] = {
+            .powerEntityStateId = mSleepStateId,
+            .totalTimeInStateMs = 4,
+            .totalStateEntryCount = 5,
+            .lastEntryTimestampMs = 6,
+        };
+        results.emplace(mPowerEntityId, result);
+        return true;
+    }
+
+    std::vector<PowerEntityStateSpace> getStateSpaces() {
+        return {{
+          .powerEntityId = mPowerEntityId,
+          .states = {
+              {.powerEntityStateId = mActiveStateId, .powerEntityStateName = "Active"},
+              {.powerEntityStateId = mSleepStateId, .powerEntityStateName = "Sleep"}
+          }
+        }};
+    }
+
+   private:
+    const uint32_t mPowerEntityId;
+    const uint32_t mActiveStateId;
+    const uint32_t mSleepStateId;
+};
+
 int main(int /* argc */, char** /* argv */) {
     ALOGI("power.stats service 1.0 is starting.");
 
-    android::sp<IPowerStats> service = new PowerStats();
+    PowerStats* service = new PowerStats();
     if (service == nullptr) {
         ALOGE("Can not create an instance of power.stats HAL Iface, exiting.");
         return 1;
     }
 
+    uint32_t defaultId = service->addPowerEntity("DefaultEntity", PowerEntityType::SUBSYSTEM);
+    auto defaultSdp = std::make_shared<DefaultStateResidencyDataProvider>(defaultId);
+    service->addStateResidencyDataProvider(std::move(defaultSdp));
+
     configureRpcThreadpool(1, true /*callerWillJoin*/);
 
     status_t status = service->registerAsService();
diff --git a/radio/1.4/Android.bp b/radio/1.4/Android.bp
index 32f9712..9fd0374 100644
--- a/radio/1.4/Android.bp
+++ b/radio/1.4/Android.bp
@@ -23,6 +23,7 @@
     types: [
         "AccessNetwork",
         "CardStatus",
+        "CarrierRestrictionsWithPriority",
         "CellConfigLte",
         "CellInfo",
         "CellInfoLte",
@@ -37,14 +38,15 @@
         "FrequencyRange",
         "LteVopsInfo",
         "NetworkScanResult",
+        "NrIndicators",
         "PdpProtocolType",
         "PhysicalChannelConfig",
         "RadioAccessFamily",
         "RadioCapability",
         "RadioFrequencyInfo",
         "RadioTechnology",
-        "NrIndicators",
         "SetupDataCallResult",
+        "SimLockMultiSimPolicy",
     ],
     gen_java: true,
 }
diff --git a/radio/1.4/IRadio.hal b/radio/1.4/IRadio.hal
index 3f4b1a5..dd69607 100644
--- a/radio/1.4/IRadio.hal
+++ b/radio/1.4/IRadio.hal
@@ -21,10 +21,12 @@
 import @1.2::NetworkScanRequest;
 import @1.3::IRadio;
 import @1.4::AccessNetwork;
+import @1.4::CarrierRestrictionsWithPriority;
 import @1.4::DataProfileInfo;
 import @1.4::EmergencyCallRouting;
 import @1.4::EmergencyServiceCategory;
 import @1.4::RadioAccessFamily;
+import @1.4::SimLockMultiSimPolicy;
 
 /**
  * This interface is used by telephony and telecom to talk to cellular radio.
@@ -177,4 +179,34 @@
      */
     oneway setPreferredNetworkTypeBitmap(
             int32_t serial, bitfield<RadioAccessFamily> networkTypeBitmap);
+
+    /**
+     * Set carrier restrictions. Expected modem behavior:
+     *  If never receives this command:
+     *  - Must allow all carriers
+     *  Receives this command:
+     *  - Only allow carriers specified in carriers. The restriction persists across power cycles
+     *    and FDR. If a present SIM is allowed, modem must not reload the SIM. If a present SIM is
+     *    *not* allowed, modem must detach from the registered network and only keep emergency
+     *    service, and notify Android SIM refresh reset with new SIM state being
+     *    CardState:RESTRICTED. Emergency service must be enabled.
+     *
+     * @param serial Serial number of request.
+     * @param carriers CarrierRestrictionsWithPriority consisting allowed and excluded carriers
+     *        as defined in types.hal
+     * @param multiSimPolicy Policy to be used for devices with multiple SIMs.
+     *
+     * Response callback is IRadioResponse.setAllowedCarriersResponse()
+     */
+    oneway setAllowedCarriers_1_4(int32_t serial, CarrierRestrictionsWithPriority carriers,
+            SimLockMultiSimPolicy multiSimPolicy);
+
+    /**
+     * Get carrier restrictions.
+     *
+     * @param serial Serial number of request.
+     *
+     * Response callback is IRadioResponse.getAllowedCarriersResponse_1_3()
+     */
+    oneway getAllowedCarriers_1_4(int32_t serial);
 };
diff --git a/radio/1.4/IRadioResponse.hal b/radio/1.4/IRadioResponse.hal
index a58a5c1..77aad03 100644
--- a/radio/1.4/IRadioResponse.hal
+++ b/radio/1.4/IRadioResponse.hal
@@ -18,6 +18,13 @@
 
 import @1.0::RadioResponseInfo;
 import @1.3::IRadioResponse;
+import @1.4::CardStatus;
+import @1.4::CarrierRestrictionsWithPriority;
+import @1.4::CellInfo;
+import @1.4::DataRegStateResult;
+import @1.4::RadioAccessFamily;
+import @1.4::SetupDataCallResult;
+import @1.4::SimLockMultiSimPolicy;
 
 /**
  * Interface declaring response functions to solicited radio requests.
@@ -181,4 +188,31 @@
      *   RadioError:SIM_ABSENT
      */
     oneway setupDataCallResponse_1_4(RadioResponseInfo info, SetupDataCallResult dcResponse);
+
+    /**
+     * @param info Response info struct containing response type, serial no. and error
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:REQUEST_NOT_SUPPORTED
+     */
+    oneway setAllowedCarriersResponse_1_4(RadioResponseInfo info);
+
+    /**
+     * Expected modem behavior:
+     *  Return list of allowed carriers, and if all carriers are allowed.
+     *
+     * @param info Response info struct containing response type, serial no. and error
+     * @param carriers Carrier restriction information.
+     * @param multiSimPolicy Policy used for devices with multiple SIM cards.
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:REQUEST_NOT_SUPPORTED
+     */
+    oneway getAllowedCarriersResponse_1_4(RadioResponseInfo info,
+            CarrierRestrictionsWithPriority carriers, SimLockMultiSimPolicy multiSimPolicy);
 };
diff --git a/radio/1.4/types.hal b/radio/1.4/types.hal
index 65f6608..76e8403 100644
--- a/radio/1.4/types.hal
+++ b/radio/1.4/types.hal
@@ -18,6 +18,7 @@
 
 import @1.0::ApnAuthType;
 import @1.0::ApnTypes;
+import @1.0::Carrier;
 import @1.0::CellInfoType;
 import @1.0::DataCallFailCause;
 import @1.0::DataProfileId;
@@ -1731,3 +1732,38 @@
      */
     int32_t mtu;
 };
+
+enum SimLockMultiSimPolicy : int32_t {
+    /**
+     * Indicates that configuration applies to each slot independently.
+     */
+    NO_MULTISIM_POLICY = 0,
+    /**
+     * Indicates that any SIM card can be used as far as one valid card is present in the device.
+     * For the modem, a SIM card is valid when its content (i.e. MCC, MNC, GID, SPN) matches the
+     * carrier restriction configuration.
+     */
+    ONE_VALID_SIM_MUST_BE_PRESENT = 1,
+};
+
+struct CarrierRestrictionsWithPriority {
+    /**
+     * List of allowed carriers.
+     * The character '?' is used as wildcard character to match any value.
+     */
+    vec<Carrier> allowedCarriers;
+    /**
+     * List of excluded carriers.
+     * The character '?' is used as wildcard character to match any value.
+     */
+    vec<Carrier> excludedCarriers;
+    /**
+     * True means that only carriers included in the allowed list and not in the excluded list
+     * are permitted. Eg. allowedCarriers match mcc/mnc, excludedCarriers has same mcc/mnc and
+     * gid1 is ABCD. It means except the carrier whose gid1 is ABCD, all carriers with the
+     * same mcc/mnc are allowed.
+     * False means that all carriers are allowed except those included in the excluded list
+     * and not in the allowed list.
+     */
+    bool allowedCarriersPrioritized;
+};
diff --git a/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp b/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp
index ac020ad..4a1f8f1 100644
--- a/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp
+++ b/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp
@@ -41,6 +41,8 @@
 using ::android::hardware::sensors::V1_0::SharedMemType;
 using ::android::hardware::sensors::V1_0::Vec3;
 
+constexpr size_t kEventSize = static_cast<size_t>(SensorsEventFormatOffset::TOTAL_LENGTH);
+
 class EventCallback : public IEventCallback {
    public:
     void reset() {
@@ -170,6 +172,7 @@
     std::vector<SensorInfo> getOneShotSensors();
     std::vector<SensorInfo> getInjectEventSensors();
     int32_t getInvalidSensorHandle();
+    bool getDirectChannelSensor(SensorInfo* sensor, SharedMemType* memType, RateLevel* rate);
     void verifyDirectChannel(SharedMemType memType);
     void verifyRegisterDirectChannel(const SensorInfo& sensor, SharedMemType memType,
                                      std::shared_ptr<SensorsTestSharedMemory> mem,
@@ -632,6 +635,32 @@
     activateAllSensors(false);
 }
 
+TEST_F(SensorsHidlTest, CleanupConnectionsOnInitialize) {
+    activateAllSensors(true);
+
+    // Verify that events are received
+    constexpr useconds_t kCollectionTimeoutUs = 1000 * 1000;  // 1s
+    constexpr int32_t kNumEvents = 1;
+    ASSERT_GE(collectEvents(kCollectionTimeoutUs, kNumEvents, getEnvironment()).size(), kNumEvents);
+
+    // Clear the active sensor handles so they are not disabled during TearDown
+    auto handles = mSensorHandles;
+    mSensorHandles.clear();
+    getEnvironment()->TearDown();
+    getEnvironment()->SetUp();
+
+    // Verify no events are received until sensors are re-activated
+    ASSERT_EQ(collectEvents(kCollectionTimeoutUs, kNumEvents, getEnvironment()).size(), 0);
+    activateAllSensors(true);
+    ASSERT_GE(collectEvents(kCollectionTimeoutUs, kNumEvents, getEnvironment()).size(), kNumEvents);
+
+    // Disable sensors
+    activateAllSensors(false);
+
+    // Restore active sensors prior to clearing the environment
+    mSensorHandles = handles;
+}
+
 void SensorsHidlTest::runSingleFlushTest(const std::vector<SensorInfo>& sensors,
                                          bool activateSensor, int32_t expectedFlushCount,
                                          Result expectedResponse) {
@@ -893,7 +922,6 @@
 }
 
 void SensorsHidlTest::verifyDirectChannel(SharedMemType memType) {
-    constexpr size_t kEventSize = static_cast<size_t>(SensorsEventFormatOffset::TOTAL_LENGTH);
     constexpr size_t kNumEvents = 1;
     constexpr size_t kMemSize = kNumEvents * kEventSize;
 
@@ -917,30 +945,96 @@
     verifyDirectChannel(SharedMemType::GRALLOC);
 }
 
-TEST_F(SensorsHidlTest, ConfigureDirectChannelWithInvalidHandle) {
-    for (const SensorInfo& sensor : getSensorsList()) {
-        if (isDirectChannelTypeSupported(sensor, SharedMemType::ASHMEM) ||
-            isDirectChannelTypeSupported(sensor, SharedMemType::GRALLOC)) {
-            // Find a supported rate level
-            RateLevel rate = RateLevel::STOP;
-            if (isDirectReportRateSupported(sensor, RateLevel::NORMAL)) {
-                rate = RateLevel::NORMAL;
-            } else if (isDirectReportRateSupported(sensor, RateLevel::FAST)) {
-                rate = RateLevel::FAST;
-            } else if (isDirectReportRateSupported(sensor, RateLevel::VERY_FAST)) {
-                rate = RateLevel::VERY_FAST;
-            }
-
-            // Ensure that at least one rate level is supported
-            ASSERT_NE(rate, RateLevel::STOP);
-
-            // Verify that an invalid channel handle produces a BAD_VALUE result
-            configDirectReport(sensor.sensorHandle, -1, rate,
-                               [](Result result, int32_t /* reportToken */) {
-                                   ASSERT_EQ(result, Result::BAD_VALUE);
-                               });
+bool SensorsHidlTest::getDirectChannelSensor(SensorInfo* sensor, SharedMemType* memType,
+                                             RateLevel* rate) {
+    bool found = false;
+    for (const SensorInfo& curSensor : getSensorsList()) {
+        if (isDirectChannelTypeSupported(curSensor, SharedMemType::ASHMEM)) {
+            *memType = SharedMemType::ASHMEM;
+            *sensor = curSensor;
+            found = true;
+            break;
+        } else if (isDirectChannelTypeSupported(curSensor, SharedMemType::GRALLOC)) {
+            *memType = SharedMemType::GRALLOC;
+            *sensor = curSensor;
+            found = true;
+            break;
         }
     }
+
+    if (found) {
+        // Find a supported rate level
+        constexpr int kNumRateLevels = 3;
+        RateLevel rates[kNumRateLevels] = {RateLevel::NORMAL, RateLevel::FAST,
+                                           RateLevel::VERY_FAST};
+        *rate = RateLevel::STOP;
+        for (int i = 0; i < kNumRateLevels; i++) {
+            if (isDirectReportRateSupported(*sensor, rates[i])) {
+                *rate = rates[i];
+            }
+        }
+
+        // At least one rate level must be supported
+        EXPECT_NE(*rate, RateLevel::STOP);
+    }
+    return found;
+}
+
+TEST_F(SensorsHidlTest, ConfigureDirectChannelWithInvalidHandle) {
+    SensorInfo sensor;
+    SharedMemType memType;
+    RateLevel rate;
+    if (!getDirectChannelSensor(&sensor, &memType, &rate)) {
+        return;
+    }
+
+    // Verify that an invalid channel handle produces a BAD_VALUE result
+    configDirectReport(sensor.sensorHandle, -1, rate, [](Result result, int32_t /* reportToken */) {
+        ASSERT_EQ(result, Result::BAD_VALUE);
+    });
+}
+
+TEST_F(SensorsHidlTest, CleanupDirectConnectionOnInitialize) {
+    constexpr size_t kNumEvents = 1;
+    constexpr size_t kMemSize = kNumEvents * kEventSize;
+
+    SensorInfo sensor;
+    SharedMemType memType;
+    RateLevel rate;
+
+    if (!getDirectChannelSensor(&sensor, &memType, &rate)) {
+        return;
+    }
+
+    std::shared_ptr<SensorsTestSharedMemory> mem(
+        SensorsTestSharedMemory::create(memType, kMemSize));
+    ASSERT_NE(mem, nullptr);
+
+    int32_t directChannelHandle = 0;
+    registerDirectChannel(mem->getSharedMemInfo(), [&](Result result, int32_t channelHandle) {
+        ASSERT_EQ(result, Result::OK);
+        directChannelHandle = channelHandle;
+    });
+
+    // Configure the channel and expect success
+    configDirectReport(
+        sensor.sensorHandle, directChannelHandle, rate,
+        [](Result result, int32_t /* reportToken */) { ASSERT_EQ(result, Result::OK); });
+
+    // Call initialize() via the environment setup to cause the HAL to re-initialize
+    // Clear the active direct connections so they are not stopped during TearDown
+    auto handles = mDirectChannelHandles;
+    mDirectChannelHandles.clear();
+    getEnvironment()->TearDown();
+    getEnvironment()->SetUp();
+
+    // Attempt to configure the direct channel and expect it to fail
+    configDirectReport(
+        sensor.sensorHandle, directChannelHandle, rate,
+        [](Result result, int32_t /* reportToken */) { ASSERT_EQ(result, Result::BAD_VALUE); });
+
+    // Restore original handles, though they should already be deactivated
+    mDirectChannelHandles = handles;
 }
 
 int main(int argc, char** argv) {
diff --git a/soundtrigger/2.2/default/SoundTriggerHw.cpp b/soundtrigger/2.2/default/SoundTriggerHw.cpp
index 3cf72c8..4586544 100644
--- a/soundtrigger/2.2/default/SoundTriggerHw.cpp
+++ b/soundtrigger/2.2/default/SoundTriggerHw.cpp
@@ -704,6 +704,11 @@
         }
     }
 
+    if (mHwDevice->common.version < SOUND_TRIGGER_DEVICE_API_VERSION_1_2) {
+        ALOGE("Get model state not supported");
+        return -ENODEV;
+    }
+
     if (mHwDevice->get_model_state == NULL) {
         ALOGE("Failed to get model state from device, no such method");
         return -ENODEV;