blob: 81bd1422badca03b16379ec5cc291e8798eef16f [file] [log] [blame]
Jiwen 'Steve' Caid9f2abe2018-10-20 17:03:13 -07001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Fan Xu93c94902018-11-01 12:22:05 -070017#include <android/hardware_buffer.h>
Jiwen 'Steve' Caid9f2abe2018-10-20 17:03:13 -070018#include <bufferhub/BufferHubService.h>
Fan Xu18d90ea2018-11-06 15:46:44 -080019#include <cutils/native_handle.h>
Fan Xu93c94902018-11-01 12:22:05 -070020#include <log/log.h>
Jiwen 'Steve' Caid9f2abe2018-10-20 17:03:13 -070021
22namespace android {
23namespace frameworks {
24namespace bufferhub {
25namespace V1_0 {
26namespace implementation {
27
Fan Xuca70b7b2018-10-31 13:20:12 -070028using hardware::Void;
Jiwen 'Steve' Caid9f2abe2018-10-20 17:03:13 -070029
Fan Xu93c94902018-11-01 12:22:05 -070030Return<void> BufferHubService::allocateBuffer(const HardwareBufferDescription& description,
31 const uint32_t userMetadataSize,
Fan Xuca70b7b2018-10-31 13:20:12 -070032 allocateBuffer_cb _hidl_cb) {
Fan Xu93c94902018-11-01 12:22:05 -070033 AHardwareBuffer_Desc desc;
34 memcpy(&desc, &description, sizeof(AHardwareBuffer_Desc));
35
36 std::shared_ptr<BufferNode> node =
37 std::make_shared<BufferNode>(desc.width, desc.height, desc.layers, desc.format,
Fan Xuffde7862018-11-08 16:29:13 -080038 desc.usage, userMetadataSize, nodeIdGenerator.getId());
Fan Xu93c94902018-11-01 12:22:05 -070039 if (node == nullptr || !node->IsValid()) {
40 ALOGE("%s: creating BufferNode failed.", __FUNCTION__);
41 _hidl_cb(/*bufferClient=*/nullptr, /*status=*/BufferHubStatus::ALLOCATION_FAILED);
42 return Void();
43 }
44
Fan Xu18d90ea2018-11-06 15:46:44 -080045 sp<BufferClient> client = BufferClient::create(this, node);
Fan Xu93c94902018-11-01 12:22:05 -070046 // Add it to list for bookkeeping and dumpsys.
Fan Xucd74d782018-11-26 13:51:25 -080047 std::lock_guard<std::mutex> lock(mClientSetMutex);
48 mClientSet.emplace(client);
Fan Xu93c94902018-11-01 12:22:05 -070049
50 _hidl_cb(/*bufferClient=*/client, /*status=*/BufferHubStatus::NO_ERROR);
Jiwen 'Steve' Caid9f2abe2018-10-20 17:03:13 -070051 return Void();
52}
53
Fan Xu467e08f2018-11-09 15:58:51 -080054Return<void> BufferHubService::importBuffer(const hidl_handle& tokenHandle,
Fan Xuca70b7b2018-10-31 13:20:12 -070055 importBuffer_cb _hidl_cb) {
Fan Xu467e08f2018-11-09 15:58:51 -080056 if (!tokenHandle.getNativeHandle() || tokenHandle->numFds != 0 || tokenHandle->numInts != 1) {
57 // nullptr handle or wrong format
58 _hidl_cb(/*bufferClient=*/nullptr, /*status=*/BufferHubStatus::INVALID_TOKEN);
59 return Void();
60 }
61
62 uint32_t token = tokenHandle->data[0];
63
64 wp<BufferClient> originClientWp;
65 {
66 std::lock_guard<std::mutex> lock(mTokenMapMutex);
67 auto iter = mTokenMap.find(token);
68 if (iter == mTokenMap.end()) {
69 // Invalid token
70 _hidl_cb(/*bufferClient=*/nullptr, /*status=*/BufferHubStatus::INVALID_TOKEN);
71 return Void();
72 }
73
74 originClientWp = iter->second;
75 mTokenMap.erase(iter);
76 }
77
78 // Check if original client is dead
79 sp<BufferClient> originClient = originClientWp.promote();
80 if (!originClient) {
81 // Should not happen since token should be removed if already gone
82 ALOGE("%s: original client %p gone!", __FUNCTION__, originClientWp.unsafe_get());
83 _hidl_cb(/*bufferClient=*/nullptr, /*status=*/BufferHubStatus::BUFFER_FREED);
84 return Void();
85 }
86
87 sp<BufferClient> client = new BufferClient(*originClient);
88
Fan Xucd74d782018-11-26 13:51:25 -080089 std::lock_guard<std::mutex> lock(mClientSetMutex);
90 mClientSet.emplace(client);
Fan Xu467e08f2018-11-09 15:58:51 -080091 _hidl_cb(/*bufferClient=*/client, /*status=*/BufferHubStatus::NO_ERROR);
Fan Xuca70b7b2018-10-31 13:20:12 -070092 return Void();
Jiwen 'Steve' Caid9f2abe2018-10-20 17:03:13 -070093}
94
Fan Xud6cd6ba2018-11-15 16:46:55 -080095hidl_handle BufferHubService::registerToken(const wp<BufferClient>& client) {
Fan Xu18d90ea2018-11-06 15:46:44 -080096 uint32_t token;
97 std::lock_guard<std::mutex> lock(mTokenMapMutex);
98 do {
99 token = mTokenEngine();
100 } while (mTokenMap.find(token) != mTokenMap.end());
101
102 // native_handle_t use int[], so here need one slots to fit in uint32_t
103 native_handle_t* handle = native_handle_create(/*numFds=*/0, /*numInts=*/1);
104 handle->data[0] = token;
105
106 // returnToken owns the native_handle_t* thus doing lifecycle management
107 hidl_handle returnToken;
108 returnToken.setTo(handle, /*shoudOwn=*/true);
109
110 mTokenMap.emplace(token, client);
111 return returnToken;
112}
113
Fan Xua7422fe2018-11-19 15:21:32 -0800114void BufferHubService::onClientClosed(const BufferClient* client) {
115 removeTokenByClient(client);
116
Fan Xucd74d782018-11-26 13:51:25 -0800117 std::lock_guard<std::mutex> lock(mClientSetMutex);
118 auto iter = std::find(mClientSet.begin(), mClientSet.end(), client);
119 if (iter != mClientSet.end()) {
120 mClientSet.erase(iter);
Fan Xua7422fe2018-11-19 15:21:32 -0800121 }
122}
123
124void BufferHubService::removeTokenByClient(const BufferClient* client) {
125 std::lock_guard<std::mutex> lock(mTokenMapMutex);
126 auto iter = mTokenMap.begin();
127 while (iter != mTokenMap.end()) {
128 if (iter->second == client) {
129 auto oldIter = iter;
130 ++iter;
131 mTokenMap.erase(oldIter);
132 } else {
133 ++iter;
134 }
135 }
136}
137
Jiwen 'Steve' Caid9f2abe2018-10-20 17:03:13 -0700138} // namespace implementation
139} // namespace V1_0
140} // namespace bufferhub
141} // namespace frameworks
142} // namespace android