blob: 6eaf0abe8ed89c0d3a3c3cb16921efee3ac57a84 [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 Xu1c16df52018-11-19 16:27:27 -080038 desc.usage, userMetadataSize,
39 BufferHubIdGenerator::getInstance().getId());
Fan Xu93c94902018-11-01 12:22:05 -070040 if (node == nullptr || !node->IsValid()) {
41 ALOGE("%s: creating BufferNode failed.", __FUNCTION__);
42 _hidl_cb(/*bufferClient=*/nullptr, /*status=*/BufferHubStatus::ALLOCATION_FAILED);
43 return Void();
44 }
45
Fan Xu18d90ea2018-11-06 15:46:44 -080046 sp<BufferClient> client = BufferClient::create(this, node);
Fan Xu93c94902018-11-01 12:22:05 -070047 // Add it to list for bookkeeping and dumpsys.
48 std::lock_guard<std::mutex> lock(mClientListMutex);
49 mClientList.push_back(client);
50
51 _hidl_cb(/*bufferClient=*/client, /*status=*/BufferHubStatus::NO_ERROR);
Jiwen 'Steve' Caid9f2abe2018-10-20 17:03:13 -070052 return Void();
53}
54
Fan Xu467e08f2018-11-09 15:58:51 -080055Return<void> BufferHubService::importBuffer(const hidl_handle& tokenHandle,
Fan Xuca70b7b2018-10-31 13:20:12 -070056 importBuffer_cb _hidl_cb) {
Fan Xu467e08f2018-11-09 15:58:51 -080057 if (!tokenHandle.getNativeHandle() || tokenHandle->numFds != 0 || tokenHandle->numInts != 1) {
58 // nullptr handle or wrong format
59 _hidl_cb(/*bufferClient=*/nullptr, /*status=*/BufferHubStatus::INVALID_TOKEN);
60 return Void();
61 }
62
63 uint32_t token = tokenHandle->data[0];
64
65 wp<BufferClient> originClientWp;
66 {
67 std::lock_guard<std::mutex> lock(mTokenMapMutex);
68 auto iter = mTokenMap.find(token);
69 if (iter == mTokenMap.end()) {
70 // Invalid token
71 _hidl_cb(/*bufferClient=*/nullptr, /*status=*/BufferHubStatus::INVALID_TOKEN);
72 return Void();
73 }
74
75 originClientWp = iter->second;
76 mTokenMap.erase(iter);
77 }
78
79 // Check if original client is dead
80 sp<BufferClient> originClient = originClientWp.promote();
81 if (!originClient) {
82 // Should not happen since token should be removed if already gone
83 ALOGE("%s: original client %p gone!", __FUNCTION__, originClientWp.unsafe_get());
84 _hidl_cb(/*bufferClient=*/nullptr, /*status=*/BufferHubStatus::BUFFER_FREED);
85 return Void();
86 }
87
88 sp<BufferClient> client = new BufferClient(*originClient);
89
90 std::lock_guard<std::mutex> lock(mClientListMutex);
91 mClientList.push_back(client);
92 _hidl_cb(/*bufferClient=*/client, /*status=*/BufferHubStatus::NO_ERROR);
Fan Xuca70b7b2018-10-31 13:20:12 -070093 return Void();
Jiwen 'Steve' Caid9f2abe2018-10-20 17:03:13 -070094}
95
Fan Xud6cd6ba2018-11-15 16:46:55 -080096hidl_handle BufferHubService::registerToken(const wp<BufferClient>& client) {
Fan Xu18d90ea2018-11-06 15:46:44 -080097 uint32_t token;
98 std::lock_guard<std::mutex> lock(mTokenMapMutex);
99 do {
100 token = mTokenEngine();
101 } while (mTokenMap.find(token) != mTokenMap.end());
102
103 // native_handle_t use int[], so here need one slots to fit in uint32_t
104 native_handle_t* handle = native_handle_create(/*numFds=*/0, /*numInts=*/1);
105 handle->data[0] = token;
106
107 // returnToken owns the native_handle_t* thus doing lifecycle management
108 hidl_handle returnToken;
109 returnToken.setTo(handle, /*shoudOwn=*/true);
110
111 mTokenMap.emplace(token, client);
112 return returnToken;
113}
114
Jiwen 'Steve' Caid9f2abe2018-10-20 17:03:13 -0700115} // namespace implementation
116} // namespace V1_0
117} // namespace bufferhub
118} // namespace frameworks
119} // namespace android