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;