[automerger skipped] Support for P256 curve in RKP for Strongbox am: 8785f89b1d am: 59737c281f -s ours am: b222638c56 -s ours
am skip reason: Merged-In Ic38fd2318dd8749ae125f1e78d25f2722bd367e5 with SHA-1 fb213d6031 is already in history
Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/2962596
Change-Id: I0e27cb26016dc573fbf672207d454acaeaafb527
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/audio/common/all-versions/default/7.0/HidlUtils.cpp b/audio/common/all-versions/default/7.0/HidlUtils.cpp
index 0fd2947..f89c898 100644
--- a/audio/common/all-versions/default/7.0/HidlUtils.cpp
+++ b/audio/common/all-versions/default/7.0/HidlUtils.cpp
@@ -898,7 +898,7 @@
for (const auto& transport : transports) {
switch (transport.audioCapability.getDiscriminator()) {
case AudioTransport::AudioCapability::hidl_discriminator::profile:
- if (halPort->num_audio_profiles > AUDIO_PORT_MAX_AUDIO_PROFILES) {
+ if (halPort->num_audio_profiles >= AUDIO_PORT_MAX_AUDIO_PROFILES) {
ALOGE("%s, too many audio profiles", __func__);
result = BAD_VALUE;
break;
@@ -914,7 +914,8 @@
result);
break;
case AudioTransport::AudioCapability::hidl_discriminator::edid:
- if (halPort->num_extra_audio_descriptors > AUDIO_PORT_MAX_EXTRA_AUDIO_DESCRIPTORS) {
+ if (halPort->num_extra_audio_descriptors >=
+ AUDIO_PORT_MAX_EXTRA_AUDIO_DESCRIPTORS) {
ALOGE("%s, too many extra audio descriptors", __func__);
result = BAD_VALUE;
break;
diff --git a/audio/common/all-versions/default/tests/hidlutils_tests.cpp b/audio/common/all-versions/default/tests/hidlutils_tests.cpp
index ec16b02..e6e2280 100644
--- a/audio/common/all-versions/default/tests/hidlutils_tests.cpp
+++ b/audio/common/all-versions/default/tests/hidlutils_tests.cpp
@@ -954,6 +954,18 @@
EXPECT_TRUE(audio_port_configs_are_equal(&halConfig, &halConfigBack));
}
+static AudioProfile generateValidAudioProfile() {
+ AudioProfile profile;
+ profile.format = toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT);
+ profile.sampleRates.resize(2);
+ profile.sampleRates[0] = 44100;
+ profile.sampleRates[1] = 48000;
+ profile.channelMasks.resize(2);
+ profile.channelMasks[0] = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_MONO);
+ profile.channelMasks[1] = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO);
+ return profile;
+}
+
TEST(HidlUtils, ConvertInvalidAudioTransports) {
hidl_vec<AudioTransport> invalid;
struct audio_port_v7 halInvalid = {};
@@ -973,20 +985,32 @@
invalid[0].audioCapability.edid(hidl_vec<uint8_t>(EXTRA_AUDIO_DESCRIPTOR_SIZE + 1));
invalid[1].encapsulationType = "random string";
EXPECT_EQ(BAD_VALUE, HidlUtils::audioTransportsToHal(invalid, &halInvalid));
+
+ // The size of audio profile must not be greater than the maximum value.
+ invalid.resize(0);
+ invalid.resize(AUDIO_PORT_MAX_AUDIO_PROFILES + 1);
+ for (size_t i = 0; i < invalid.size(); ++i) {
+ invalid[i].audioCapability.profile(generateValidAudioProfile());
+ invalid[i].encapsulationType =
+ toString(xsd::AudioEncapsulationType::AUDIO_ENCAPSULATION_TYPE_NONE);
+ }
+ EXPECT_EQ(BAD_VALUE, HidlUtils::audioTransportsToHal(invalid, &halInvalid));
+
+ // The size of extra audio descriptors must not be greater than the maximum value.
+ invalid.resize(0);
+ invalid.resize(AUDIO_PORT_MAX_EXTRA_AUDIO_DESCRIPTORS + 1);
+ for (size_t i = 0; i < invalid.size(); ++i) {
+ invalid[i].audioCapability.edid({0x11, 0x06, 0x01});
+ invalid[i].encapsulationType =
+ toString(xsd::AudioEncapsulationType::AUDIO_ENCAPSULATION_TYPE_IEC61937);
+ }
+ EXPECT_EQ(BAD_VALUE, HidlUtils::audioTransportsToHal(invalid, &halInvalid));
}
TEST(HidlUtils, ConvertAudioTransports) {
hidl_vec<AudioTransport> transports;
transports.resize(2);
- AudioProfile profile;
- profile.format = toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT);
- profile.sampleRates.resize(2);
- profile.sampleRates[0] = 44100;
- profile.sampleRates[1] = 48000;
- profile.channelMasks.resize(2);
- profile.channelMasks[0] = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_MONO);
- profile.channelMasks[1] = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO);
- transports[0].audioCapability.profile(profile);
+ transports[0].audioCapability.profile(generateValidAudioProfile());
hidl_vec<uint8_t> shortAudioDescriptor({0x11, 0x06, 0x01});
transports[0].encapsulationType =
toString(xsd::AudioEncapsulationType::AUDIO_ENCAPSULATION_TYPE_NONE);
diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp
index cf2c90d..2d6490c 100644
--- a/gnss/aidl/default/Gnss.cpp
+++ b/gnss/aidl/default/Gnss.cpp
@@ -68,7 +68,7 @@
IGnssCallback::GnssSystemInfo systemInfo = {
.yearOfHw = 2022,
- .name = "Google Mock GNSS Implementation AIDL v2",
+ .name = "Google, Cuttlefish, AIDL v2",
};
status = sGnssCallback->gnssSetSystemInfoCb(systemInfo);
if (!status.isOk()) {
diff --git a/health/aidl/default/Health.cpp b/health/aidl/default/Health.cpp
index d41d01a..3558e0a 100644
--- a/health/aidl/default/Health.cpp
+++ b/health/aidl/default/Health.cpp
@@ -36,6 +36,11 @@
LinkedCallback* linked = reinterpret_cast<LinkedCallback*>(cookie);
linked->OnCallbackDied();
}
+// Delete the owned cookie.
+void onCallbackUnlinked(void* cookie) {
+ LinkedCallback* linked = reinterpret_cast<LinkedCallback*>(cookie);
+ delete linked;
+}
} // namespace
/*
@@ -57,6 +62,7 @@
: instance_name_(instance_name),
healthd_config_(std::move(config)),
death_recipient_(AIBinder_DeathRecipient_new(&OnCallbackDiedWrapped)) {
+ AIBinder_DeathRecipient_setOnUnlinked(death_recipient_.get(), onCallbackUnlinked);
battery_monitor_.init(healthd_config_.get());
}
@@ -231,7 +237,11 @@
{
std::lock_guard<decltype(callbacks_lock_)> lock(callbacks_lock_);
- callbacks_.emplace_back(LinkedCallback::Make(ref<Health>(), callback));
+ LinkedCallback* linked_callback_result = LinkedCallback::Make(ref<Health>(), callback);
+ if (!linked_callback_result) {
+ return ndk::ScopedAStatus::fromStatus(STATUS_UNEXPECTED_NULL);
+ }
+ callbacks_[linked_callback_result] = callback;
// unlock
}
@@ -257,12 +267,24 @@
std::lock_guard<decltype(callbacks_lock_)> lock(callbacks_lock_);
- auto matches = [callback](const auto& linked) {
- return linked->callback()->asBinder() == callback->asBinder(); // compares binder object
+ auto matches = [callback](const auto& cb) {
+ return cb->asBinder() == callback->asBinder(); // compares binder object
};
- auto it = std::remove_if(callbacks_.begin(), callbacks_.end(), matches);
- bool removed = (it != callbacks_.end());
- callbacks_.erase(it, callbacks_.end()); // calls unlinkToDeath on deleted callbacks.
+ bool removed = false;
+ for (auto it = callbacks_.begin(); it != callbacks_.end();) {
+ if (it->second->asBinder() == callback->asBinder()) {
+ auto status = AIBinder_unlinkToDeath(callback->asBinder().get(), death_recipient_.get(),
+ reinterpret_cast<void*>(it->first));
+ if (status != STATUS_OK && status != STATUS_DEAD_OBJECT) {
+ LOG(WARNING) << __func__
+ << "Cannot unlink to death: " << ::android::statusToString(status);
+ }
+ it = callbacks_.erase(it);
+ removed = true;
+ } else {
+ it++;
+ }
+ }
return removed ? ndk::ScopedAStatus::ok()
: ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
@@ -290,13 +312,20 @@
void Health::OnHealthInfoChanged(const HealthInfo& health_info) {
// Notify all callbacks
std::unique_lock<decltype(callbacks_lock_)> lock(callbacks_lock_);
- // is_dead notifies a callback and return true if it is dead.
- auto is_dead = [&](const auto& linked) {
- auto res = linked->callback()->healthInfoChanged(health_info);
- return IsDeadObjectLogged(res);
- };
- auto it = std::remove_if(callbacks_.begin(), callbacks_.end(), is_dead);
- callbacks_.erase(it, callbacks_.end()); // calls unlinkToDeath on deleted callbacks.
+ for (auto it = callbacks_.begin(); it != callbacks_.end();) {
+ auto res = it->second->healthInfoChanged(health_info);
+ if (IsDeadObjectLogged(res)) {
+ // if it's dead, remove it
+ it = callbacks_.erase(it);
+ } else {
+ it++;
+ if (!res.isOk()) {
+ LOG(DEBUG)
+ << "Cannot call healthInfoChanged:" << res.getDescription()
+ << ". Do nothing here if callback is dead as it will be cleaned up later.";
+ }
+ }
+ }
lock.unlock();
// Let HalHealthLoop::OnHealthInfoChanged() adjusts uevent / wakealarm periods
diff --git a/health/aidl/default/LinkedCallback.cpp b/health/aidl/default/LinkedCallback.cpp
index 2985ffe..12a8df3 100644
--- a/health/aidl/default/LinkedCallback.cpp
+++ b/health/aidl/default/LinkedCallback.cpp
@@ -24,35 +24,24 @@
namespace aidl::android::hardware::health {
-std::unique_ptr<LinkedCallback> LinkedCallback::Make(
- std::shared_ptr<Health> service, std::shared_ptr<IHealthInfoCallback> callback) {
- std::unique_ptr<LinkedCallback> ret(new LinkedCallback());
+LinkedCallback* LinkedCallback::Make(std::shared_ptr<Health> service,
+ std::shared_ptr<IHealthInfoCallback> callback) {
+ LinkedCallback* ret(new LinkedCallback());
+ // pass ownership of this object to the death recipient
binder_status_t linkRet =
AIBinder_linkToDeath(callback->asBinder().get(), service->death_recipient_.get(),
- reinterpret_cast<void*>(ret.get()));
+ reinterpret_cast<void*>(ret));
if (linkRet != ::STATUS_OK) {
LOG(WARNING) << __func__ << "Cannot link to death: " << linkRet;
return nullptr;
}
ret->service_ = service;
- ret->callback_ = std::move(callback);
+ ret->callback_ = callback;
return ret;
}
LinkedCallback::LinkedCallback() = default;
-LinkedCallback::~LinkedCallback() {
- if (callback_ == nullptr) {
- return;
- }
- auto status =
- AIBinder_unlinkToDeath(callback_->asBinder().get(), service()->death_recipient_.get(),
- reinterpret_cast<void*>(this));
- if (status != STATUS_OK && status != STATUS_DEAD_OBJECT) {
- LOG(WARNING) << __func__ << "Cannot unlink to death: " << ::android::statusToString(status);
- }
-}
-
std::shared_ptr<Health> LinkedCallback::service() {
auto service_sp = service_.lock();
CHECK_NE(nullptr, service_sp);
@@ -60,7 +49,10 @@
}
void LinkedCallback::OnCallbackDied() {
- service()->unregisterCallback(callback_);
+ auto sCb = callback_.lock();
+ if (sCb) {
+ service()->unregisterCallback(sCb);
+ }
}
} // namespace aidl::android::hardware::health
diff --git a/health/aidl/default/LinkedCallback.h b/health/aidl/default/LinkedCallback.h
index 82490a7..0494921 100644
--- a/health/aidl/default/LinkedCallback.h
+++ b/health/aidl/default/LinkedCallback.h
@@ -31,18 +31,10 @@
class LinkedCallback {
public:
// Automatically linkToDeath upon construction with the returned object as the cookie.
- // service->death_reciepient() should be from CreateDeathRecipient().
- // Not using a strong reference to |service| to avoid circular reference. The lifetime
- // of |service| must be longer than this LinkedCallback object.
- static std::unique_ptr<LinkedCallback> Make(std::shared_ptr<Health> service,
- std::shared_ptr<IHealthInfoCallback> callback);
-
- // Automatically unlinkToDeath upon destruction. So, it is always safe to reinterpret_cast
- // the cookie back to the LinkedCallback object.
- ~LinkedCallback();
-
- // The wrapped IHealthInfoCallback object.
- const std::shared_ptr<IHealthInfoCallback>& callback() const { return callback_; }
+ // The deathRecipient owns the LinkedCallback object and will delete it with
+ // cookie when it's unlinked.
+ static LinkedCallback* Make(std::shared_ptr<Health> service,
+ std::shared_ptr<IHealthInfoCallback> callback);
// On callback died, unreigster it from the service.
void OnCallbackDied();
@@ -54,7 +46,7 @@
std::shared_ptr<Health> service();
std::weak_ptr<Health> service_;
- std::shared_ptr<IHealthInfoCallback> callback_;
+ std::weak_ptr<IHealthInfoCallback> callback_;
};
} // namespace aidl::android::hardware::health
diff --git a/health/aidl/default/include/health-impl/Health.h b/health/aidl/default/include/health-impl/Health.h
index 6bd4946..4fc4953 100644
--- a/health/aidl/default/include/health-impl/Health.h
+++ b/health/aidl/default/include/health-impl/Health.h
@@ -16,6 +16,7 @@
#pragma once
+#include <map>
#include <memory>
#include <optional>
@@ -108,7 +109,7 @@
ndk::ScopedAIBinder_DeathRecipient death_recipient_;
int binder_fd_ = -1;
std::mutex callbacks_lock_;
- std::vector<std::unique_ptr<LinkedCallback>> callbacks_;
+ std::map<LinkedCallback*, std::shared_ptr<IHealthInfoCallback>> callbacks_;
};
} // namespace aidl::android::hardware::health
diff --git a/neuralnetworks/1.2/utils/src/BurstUtils.cpp b/neuralnetworks/1.2/utils/src/BurstUtils.cpp
index b589c46..c4c096d 100644
--- a/neuralnetworks/1.2/utils/src/BurstUtils.cpp
+++ b/neuralnetworks/1.2/utils/src/BurstUtils.cpp
@@ -190,12 +190,13 @@
size_t index = 0;
// validate packet information
- if (data.size() == 0 || data[index].getDiscriminator() != discriminator::packetInformation) {
+ if (index >= data.size() ||
+ data.at(index).getDiscriminator() != discriminator::packetInformation) {
return NN_ERROR() << "FMQ Request packet ill-formed";
}
// unpackage packet information
- const FmqRequestDatum::PacketInformation& packetInfo = data[index].packetInformation();
+ const FmqRequestDatum::PacketInformation& packetInfo = data.at(index).packetInformation();
index++;
const uint32_t packetSize = packetInfo.packetSize;
const uint32_t numberOfInputOperands = packetInfo.numberOfInputOperands;
@@ -212,13 +213,14 @@
inputs.reserve(numberOfInputOperands);
for (size_t operand = 0; operand < numberOfInputOperands; ++operand) {
// validate input operand information
- if (data[index].getDiscriminator() != discriminator::inputOperandInformation) {
+ if (index >= data.size() ||
+ data.at(index).getDiscriminator() != discriminator::inputOperandInformation) {
return NN_ERROR() << "FMQ Request packet ill-formed";
}
// unpackage operand information
const FmqRequestDatum::OperandInformation& operandInfo =
- data[index].inputOperandInformation();
+ data.at(index).inputOperandInformation();
index++;
const bool hasNoValue = operandInfo.hasNoValue;
const V1_0::DataLocation location = operandInfo.location;
@@ -229,12 +231,13 @@
dimensions.reserve(numberOfDimensions);
for (size_t i = 0; i < numberOfDimensions; ++i) {
// validate dimension
- if (data[index].getDiscriminator() != discriminator::inputOperandDimensionValue) {
+ if (index >= data.size() ||
+ data.at(index).getDiscriminator() != discriminator::inputOperandDimensionValue) {
return NN_ERROR() << "FMQ Request packet ill-formed";
}
// unpackage dimension
- const uint32_t dimension = data[index].inputOperandDimensionValue();
+ const uint32_t dimension = data.at(index).inputOperandDimensionValue();
index++;
// store result
@@ -251,13 +254,14 @@
outputs.reserve(numberOfOutputOperands);
for (size_t operand = 0; operand < numberOfOutputOperands; ++operand) {
// validate output operand information
- if (data[index].getDiscriminator() != discriminator::outputOperandInformation) {
+ if (index >= data.size() ||
+ data.at(index).getDiscriminator() != discriminator::outputOperandInformation) {
return NN_ERROR() << "FMQ Request packet ill-formed";
}
// unpackage operand information
const FmqRequestDatum::OperandInformation& operandInfo =
- data[index].outputOperandInformation();
+ data.at(index).outputOperandInformation();
index++;
const bool hasNoValue = operandInfo.hasNoValue;
const V1_0::DataLocation location = operandInfo.location;
@@ -268,12 +272,13 @@
dimensions.reserve(numberOfDimensions);
for (size_t i = 0; i < numberOfDimensions; ++i) {
// validate dimension
- if (data[index].getDiscriminator() != discriminator::outputOperandDimensionValue) {
+ if (index >= data.size() ||
+ data.at(index).getDiscriminator() != discriminator::outputOperandDimensionValue) {
return NN_ERROR() << "FMQ Request packet ill-formed";
}
// unpackage dimension
- const uint32_t dimension = data[index].outputOperandDimensionValue();
+ const uint32_t dimension = data.at(index).outputOperandDimensionValue();
index++;
// store result
@@ -290,12 +295,13 @@
slots.reserve(numberOfPools);
for (size_t pool = 0; pool < numberOfPools; ++pool) {
// validate input operand information
- if (data[index].getDiscriminator() != discriminator::poolIdentifier) {
+ if (index >= data.size() ||
+ data.at(index).getDiscriminator() != discriminator::poolIdentifier) {
return NN_ERROR() << "FMQ Request packet ill-formed";
}
// unpackage operand information
- const int32_t poolId = data[index].poolIdentifier();
+ const int32_t poolId = data.at(index).poolIdentifier();
index++;
// store result
@@ -303,17 +309,17 @@
}
// validate measureTiming
- if (data[index].getDiscriminator() != discriminator::measureTiming) {
+ if (index >= data.size() || data.at(index).getDiscriminator() != discriminator::measureTiming) {
return NN_ERROR() << "FMQ Request packet ill-formed";
}
// unpackage measureTiming
- const V1_2::MeasureTiming measure = data[index].measureTiming();
+ const V1_2::MeasureTiming measure = data.at(index).measureTiming();
index++;
// validate packet information
if (index != packetSize) {
- return NN_ERROR() << "FMQ Result packet ill-formed";
+ return NN_ERROR() << "FMQ Request packet ill-formed";
}
// return request
@@ -328,12 +334,13 @@
size_t index = 0;
// validate packet information
- if (data.size() == 0 || data[index].getDiscriminator() != discriminator::packetInformation) {
+ if (index >= data.size() ||
+ data.at(index).getDiscriminator() != discriminator::packetInformation) {
return NN_ERROR() << "FMQ Result packet ill-formed";
}
// unpackage packet information
- const FmqResultDatum::PacketInformation& packetInfo = data[index].packetInformation();
+ const FmqResultDatum::PacketInformation& packetInfo = data.at(index).packetInformation();
index++;
const uint32_t packetSize = packetInfo.packetSize;
const V1_0::ErrorStatus errorStatus = packetInfo.errorStatus;
@@ -349,12 +356,13 @@
outputShapes.reserve(numberOfOperands);
for (size_t operand = 0; operand < numberOfOperands; ++operand) {
// validate operand information
- if (data[index].getDiscriminator() != discriminator::operandInformation) {
+ if (index >= data.size() ||
+ data.at(index).getDiscriminator() != discriminator::operandInformation) {
return NN_ERROR() << "FMQ Result packet ill-formed";
}
// unpackage operand information
- const FmqResultDatum::OperandInformation& operandInfo = data[index].operandInformation();
+ const FmqResultDatum::OperandInformation& operandInfo = data.at(index).operandInformation();
index++;
const bool isSufficient = operandInfo.isSufficient;
const uint32_t numberOfDimensions = operandInfo.numberOfDimensions;
@@ -364,12 +372,13 @@
dimensions.reserve(numberOfDimensions);
for (size_t i = 0; i < numberOfDimensions; ++i) {
// validate dimension
- if (data[index].getDiscriminator() != discriminator::operandDimensionValue) {
+ if (index >= data.size() ||
+ data.at(index).getDiscriminator() != discriminator::operandDimensionValue) {
return NN_ERROR() << "FMQ Result packet ill-formed";
}
// unpackage dimension
- const uint32_t dimension = data[index].operandDimensionValue();
+ const uint32_t dimension = data.at(index).operandDimensionValue();
index++;
// store result
@@ -381,12 +390,13 @@
}
// validate execution timing
- if (data[index].getDiscriminator() != discriminator::executionTiming) {
+ if (index >= data.size() ||
+ data.at(index).getDiscriminator() != discriminator::executionTiming) {
return NN_ERROR() << "FMQ Result packet ill-formed";
}
// unpackage execution timing
- const V1_2::Timing timing = data[index].executionTiming();
+ const V1_2::Timing timing = data.at(index).executionTiming();
index++;
// validate packet information
diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/ProtectCallback.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/ProtectCallback.h
index 92ed1cd..9a7fe5e 100644
--- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/ProtectCallback.h
+++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/ProtectCallback.h
@@ -56,6 +56,8 @@
// Thread safe class
class DeathMonitor final {
public:
+ explicit DeathMonitor(uintptr_t cookieKey) : kCookieKey(cookieKey) {}
+
static void serviceDied(void* cookie);
void serviceDied();
// Precondition: `killable` must be non-null.
@@ -63,9 +65,18 @@
// Precondition: `killable` must be non-null.
void remove(IProtectedCallback* killable) const;
+ uintptr_t getCookieKey() const { return kCookieKey; }
+
+ ~DeathMonitor();
+ DeathMonitor(const DeathMonitor&) = delete;
+ DeathMonitor(DeathMonitor&&) noexcept = delete;
+ DeathMonitor& operator=(const DeathMonitor&) = delete;
+ DeathMonitor& operator=(DeathMonitor&&) noexcept = delete;
+
private:
mutable std::mutex mMutex;
mutable std::vector<IProtectedCallback*> mObjects GUARDED_BY(mMutex);
+ const uintptr_t kCookieKey;
};
class DeathHandler final {
diff --git a/neuralnetworks/aidl/utils/src/ProtectCallback.cpp b/neuralnetworks/aidl/utils/src/ProtectCallback.cpp
index 54a673c..4a7ac08 100644
--- a/neuralnetworks/aidl/utils/src/ProtectCallback.cpp
+++ b/neuralnetworks/aidl/utils/src/ProtectCallback.cpp
@@ -25,6 +25,7 @@
#include <algorithm>
#include <functional>
+#include <map>
#include <memory>
#include <mutex>
#include <vector>
@@ -33,6 +34,16 @@
namespace aidl::android::hardware::neuralnetworks::utils {
+namespace {
+
+// Only dereference the cookie if it's valid (if it's in this set)
+// Only used with ndk
+std::mutex sCookiesMutex;
+uintptr_t sCookieKeyCounter GUARDED_BY(sCookiesMutex) = 0;
+std::map<uintptr_t, std::weak_ptr<DeathMonitor>> sCookies GUARDED_BY(sCookiesMutex);
+
+} // namespace
+
void DeathMonitor::serviceDied() {
std::lock_guard guard(mMutex);
std::for_each(mObjects.begin(), mObjects.end(),
@@ -40,8 +51,24 @@
}
void DeathMonitor::serviceDied(void* cookie) {
- auto deathMonitor = static_cast<DeathMonitor*>(cookie);
- deathMonitor->serviceDied();
+ std::shared_ptr<DeathMonitor> monitor;
+ {
+ std::lock_guard<std::mutex> guard(sCookiesMutex);
+ if (auto it = sCookies.find(reinterpret_cast<uintptr_t>(cookie)); it != sCookies.end()) {
+ monitor = it->second.lock();
+ sCookies.erase(it);
+ } else {
+ LOG(INFO)
+ << "Service died, but cookie is no longer valid so there is nothing to notify.";
+ return;
+ }
+ }
+ if (monitor) {
+ LOG(INFO) << "Notifying DeathMonitor from serviceDied.";
+ monitor->serviceDied();
+ } else {
+ LOG(INFO) << "Tried to notify DeathMonitor from serviceDied but could not promote.";
+ }
}
void DeathMonitor::add(IProtectedCallback* killable) const {
@@ -57,12 +84,25 @@
mObjects.erase(removedIter);
}
+DeathMonitor::~DeathMonitor() {
+ // lock must be taken so object is not used in OnBinderDied"
+ std::lock_guard<std::mutex> guard(sCookiesMutex);
+ sCookies.erase(kCookieKey);
+}
+
nn::GeneralResult<DeathHandler> DeathHandler::create(std::shared_ptr<ndk::ICInterface> object) {
if (object == nullptr) {
return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT)
<< "utils::DeathHandler::create must have non-null object";
}
- auto deathMonitor = std::make_shared<DeathMonitor>();
+
+ std::shared_ptr<DeathMonitor> deathMonitor;
+ {
+ std::lock_guard<std::mutex> guard(sCookiesMutex);
+ deathMonitor = std::make_shared<DeathMonitor>(sCookieKeyCounter++);
+ sCookies[deathMonitor->getCookieKey()] = deathMonitor;
+ }
+
auto deathRecipient = ndk::ScopedAIBinder_DeathRecipient(
AIBinder_DeathRecipient_new(DeathMonitor::serviceDied));
@@ -70,8 +110,9 @@
// STATUS_INVALID_OPERATION. We ignore this case because we only use local binders in tests
// where this is not an error.
if (object->isRemote()) {
- const auto ret = ndk::ScopedAStatus::fromStatus(AIBinder_linkToDeath(
- object->asBinder().get(), deathRecipient.get(), deathMonitor.get()));
+ const auto ret = ndk::ScopedAStatus::fromStatus(
+ AIBinder_linkToDeath(object->asBinder().get(), deathRecipient.get(),
+ reinterpret_cast<void*>(deathMonitor->getCookieKey())));
HANDLE_ASTATUS(ret) << "AIBinder_linkToDeath failed";
}
@@ -91,8 +132,9 @@
DeathHandler::~DeathHandler() {
if (kObject != nullptr && kDeathRecipient.get() != nullptr && kDeathMonitor != nullptr) {
- const auto ret = ndk::ScopedAStatus::fromStatus(AIBinder_unlinkToDeath(
- kObject->asBinder().get(), kDeathRecipient.get(), kDeathMonitor.get()));
+ const auto ret = ndk::ScopedAStatus::fromStatus(
+ AIBinder_unlinkToDeath(kObject->asBinder().get(), kDeathRecipient.get(),
+ reinterpret_cast<void*>(kDeathMonitor->getCookieKey())));
const auto maybeSuccess = handleTransportError(ret);
if (!maybeSuccess.ok()) {
LOG(ERROR) << maybeSuccess.error().message;
diff --git a/neuralnetworks/aidl/utils/test/DeviceTest.cpp b/neuralnetworks/aidl/utils/test/DeviceTest.cpp
index 73727b3..ffd3b8e 100644
--- a/neuralnetworks/aidl/utils/test/DeviceTest.cpp
+++ b/neuralnetworks/aidl/utils/test/DeviceTest.cpp
@@ -697,7 +697,8 @@
const auto mockDevice = createMockDevice();
const auto device = Device::create(kName, mockDevice, kVersion).value();
const auto ret = [&device]() {
- DeathMonitor::serviceDied(device->getDeathMonitor());
+ DeathMonitor::serviceDied(
+ reinterpret_cast<void*>(device->getDeathMonitor()->getCookieKey()));
return ndk::ScopedAStatus::ok();
};
EXPECT_CALL(*mockDevice, prepareModel(_, _, _, _, _, _, _, _))
@@ -846,7 +847,8 @@
const auto mockDevice = createMockDevice();
const auto device = Device::create(kName, mockDevice, kVersion).value();
const auto ret = [&device]() {
- DeathMonitor::serviceDied(device->getDeathMonitor());
+ DeathMonitor::serviceDied(
+ reinterpret_cast<void*>(device->getDeathMonitor()->getCookieKey()));
return ndk::ScopedAStatus::ok();
};
EXPECT_CALL(*mockDevice, prepareModelWithConfig(_, _, _))
@@ -970,7 +972,8 @@
const auto mockDevice = createMockDevice();
const auto device = Device::create(kName, mockDevice, kVersion).value();
const auto ret = [&device]() {
- DeathMonitor::serviceDied(device->getDeathMonitor());
+ DeathMonitor::serviceDied(
+ reinterpret_cast<void*>(device->getDeathMonitor()->getCookieKey()));
return ndk::ScopedAStatus::ok();
};
EXPECT_CALL(*mockDevice, prepareModelFromCache(_, _, _, _, _))
diff --git a/wifi/netlinkinterceptor/aidl/default/InterceptorRelay.cpp b/wifi/netlinkinterceptor/aidl/default/InterceptorRelay.cpp
index ded9122..e84a5cf 100644
--- a/wifi/netlinkinterceptor/aidl/default/InterceptorRelay.cpp
+++ b/wifi/netlinkinterceptor/aidl/default/InterceptorRelay.cpp
@@ -28,7 +28,7 @@
using namespace std::chrono_literals;
static constexpr std::chrono::milliseconds kPollTimeout = 300ms;
-static constexpr bool kSuperVerbose = true;
+static constexpr bool kSuperVerbose = false;
InterceptorRelay::InterceptorRelay(uint32_t nlFamily, uint32_t clientNlPid,
const std::string& clientName)