You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
202 lines
6.3 KiB
202 lines
6.3 KiB
/*
|
|
* Copyright (C) 2018 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
#define LOG_TAG "BufferPoolConnection"
|
|
|
|
#include "Accessor.h"
|
|
#include "AccessorImpl.h"
|
|
#include "Connection.h"
|
|
|
|
namespace android {
|
|
namespace hardware {
|
|
namespace media {
|
|
namespace bufferpool {
|
|
namespace V1_0 {
|
|
namespace implementation {
|
|
|
|
void ConnectionDeathRecipient::add(
|
|
int64_t connectionId,
|
|
const sp<Accessor> &accessor) {
|
|
std::lock_guard<std::mutex> lock(mLock);
|
|
if (mAccessors.find(connectionId) == mAccessors.end()) {
|
|
mAccessors.insert(std::make_pair(connectionId, accessor));
|
|
}
|
|
}
|
|
|
|
void ConnectionDeathRecipient::remove(int64_t connectionId) {
|
|
std::lock_guard<std::mutex> lock(mLock);
|
|
mAccessors.erase(connectionId);
|
|
auto it = mConnectionToCookie.find(connectionId);
|
|
if (it != mConnectionToCookie.end()) {
|
|
uint64_t cookie = it->second;
|
|
mConnectionToCookie.erase(it);
|
|
auto cit = mCookieToConnections.find(cookie);
|
|
if (cit != mCookieToConnections.end()) {
|
|
cit->second.erase(connectionId);
|
|
if (cit->second.size() == 0) {
|
|
mCookieToConnections.erase(cit);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void ConnectionDeathRecipient::addCookieToConnection(
|
|
uint64_t cookie,
|
|
int64_t connectionId) {
|
|
std::lock_guard<std::mutex> lock(mLock);
|
|
if (mAccessors.find(connectionId) == mAccessors.end()) {
|
|
return;
|
|
}
|
|
mConnectionToCookie.insert(std::make_pair(connectionId, cookie));
|
|
auto it = mCookieToConnections.find(cookie);
|
|
if (it != mCookieToConnections.end()) {
|
|
it->second.insert(connectionId);
|
|
} else {
|
|
mCookieToConnections.insert(std::make_pair(
|
|
cookie, std::set<int64_t>{connectionId}));
|
|
}
|
|
}
|
|
|
|
void ConnectionDeathRecipient::serviceDied(
|
|
uint64_t cookie,
|
|
const wp<::android::hidl::base::V1_0::IBase>& /* who */
|
|
) {
|
|
std::map<int64_t, const wp<Accessor>> connectionsToClose;
|
|
{
|
|
std::lock_guard<std::mutex> lock(mLock);
|
|
|
|
auto it = mCookieToConnections.find(cookie);
|
|
if (it != mCookieToConnections.end()) {
|
|
for (auto conIt = it->second.begin(); conIt != it->second.end(); ++conIt) {
|
|
auto accessorIt = mAccessors.find(*conIt);
|
|
if (accessorIt != mAccessors.end()) {
|
|
connectionsToClose.insert(std::make_pair(*conIt, accessorIt->second));
|
|
mAccessors.erase(accessorIt);
|
|
}
|
|
mConnectionToCookie.erase(*conIt);
|
|
}
|
|
mCookieToConnections.erase(it);
|
|
}
|
|
}
|
|
|
|
if (connectionsToClose.size() > 0) {
|
|
sp<Accessor> accessor;
|
|
for (auto it = connectionsToClose.begin(); it != connectionsToClose.end(); ++it) {
|
|
accessor = it->second.promote();
|
|
|
|
if (accessor) {
|
|
accessor->close(it->first);
|
|
ALOGD("connection %lld closed on death", (long long)it->first);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
namespace {
|
|
static sp<ConnectionDeathRecipient> sConnectionDeathRecipient =
|
|
new ConnectionDeathRecipient();
|
|
}
|
|
|
|
sp<ConnectionDeathRecipient> Accessor::getConnectionDeathRecipient() {
|
|
return sConnectionDeathRecipient;
|
|
}
|
|
|
|
// Methods from ::android::hardware::media::bufferpool::V1_0::IAccessor follow.
|
|
Return<void> Accessor::connect(connect_cb _hidl_cb) {
|
|
sp<Connection> connection;
|
|
ConnectionId connectionId;
|
|
const QueueDescriptor* fmqDesc;
|
|
|
|
ResultStatus status = connect(&connection, &connectionId, &fmqDesc, false);
|
|
if (status == ResultStatus::OK) {
|
|
_hidl_cb(status, connection, connectionId, *fmqDesc);
|
|
} else {
|
|
_hidl_cb(status, nullptr, -1LL,
|
|
android::hardware::MQDescriptorSync<BufferStatusMessage>(
|
|
std::vector<android::hardware::GrantorDescriptor>(),
|
|
nullptr /* nhandle */, 0 /* size */));
|
|
}
|
|
return Void();
|
|
}
|
|
|
|
Accessor::Accessor(const std::shared_ptr<BufferPoolAllocator> &allocator)
|
|
: mImpl(new Impl(allocator)) {}
|
|
|
|
Accessor::~Accessor() {
|
|
}
|
|
|
|
bool Accessor::isValid() {
|
|
return (bool)mImpl;
|
|
}
|
|
|
|
ResultStatus Accessor::allocate(
|
|
ConnectionId connectionId,
|
|
const std::vector<uint8_t> ¶ms,
|
|
BufferId *bufferId, const native_handle_t** handle) {
|
|
if (mImpl) {
|
|
return mImpl->allocate(connectionId, params, bufferId, handle);
|
|
}
|
|
return ResultStatus::CRITICAL_ERROR;
|
|
}
|
|
|
|
ResultStatus Accessor::fetch(
|
|
ConnectionId connectionId, TransactionId transactionId,
|
|
BufferId bufferId, const native_handle_t** handle) {
|
|
if (mImpl) {
|
|
return mImpl->fetch(connectionId, transactionId, bufferId, handle);
|
|
}
|
|
return ResultStatus::CRITICAL_ERROR;
|
|
}
|
|
|
|
ResultStatus Accessor::connect(
|
|
sp<Connection> *connection, ConnectionId *pConnectionId,
|
|
const QueueDescriptor** fmqDescPtr, bool local) {
|
|
if (mImpl) {
|
|
ResultStatus status = mImpl->connect(this, connection, pConnectionId, fmqDescPtr);
|
|
if (!local && status == ResultStatus::OK) {
|
|
sp<Accessor> accessor(this);
|
|
sConnectionDeathRecipient->add(*pConnectionId, accessor);
|
|
}
|
|
return status;
|
|
}
|
|
return ResultStatus::CRITICAL_ERROR;
|
|
}
|
|
|
|
ResultStatus Accessor::close(ConnectionId connectionId) {
|
|
if (mImpl) {
|
|
ResultStatus status = mImpl->close(connectionId);
|
|
sConnectionDeathRecipient->remove(connectionId);
|
|
return status;
|
|
}
|
|
return ResultStatus::CRITICAL_ERROR;
|
|
}
|
|
|
|
void Accessor::cleanUp(bool clearCache) {
|
|
if (mImpl) {
|
|
mImpl->cleanUp(clearCache);
|
|
}
|
|
}
|
|
|
|
//IAccessor* HIDL_FETCH_IAccessor(const char* /* name */) {
|
|
// return new Accessor();
|
|
//}
|
|
|
|
} // namespace implementation
|
|
} // namespace V1_0
|
|
} // namespace bufferpool
|
|
} // namespace media
|
|
} // namespace hardware
|
|
} // namespace android
|