19a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai/*
29a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai * Copyright 2018 The Android Open Source Project
39a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai *
49a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai * Licensed under the Apache License, Version 2.0 (the "License");
59a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai * you may not use this file except in compliance with the License.
69a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai * You may obtain a copy of the License at
79a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai *
89a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai *      http://www.apache.org/licenses/LICENSE-2.0
99a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai *
109a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai * Unless required by applicable law or agreed to in writing, software
119a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai * distributed under the License is distributed on an "AS IS" BASIS,
129a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai * See the License for the specific language governing permissions and
149a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai * limitations under the License.
159a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai */
169a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
17d6cb17f84067ac0374ac28ef65f2e862c8cbb167Jiwen 'Steve' Cai#include <dvr/dvr_api.h>
180f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Cai#include <gui/BufferHubProducer.h>
194fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko#include <inttypes.h>
204fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko#include <log/log.h>
216a3c05bcfab588fd99dd8d619a53d15374e99507Mathias Agopian#include <system/window.h>
224fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko
23e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace android {
24e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
25c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Caiusing namespace dvr;
26c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai
27d6cb17f84067ac0374ac28ef65f2e862c8cbb167Jiwen 'Steve' Cai/* static */
28c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Caisp<BufferHubProducer> BufferHubProducer::Create(const std::shared_ptr<ProducerQueue>& queue) {
299a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    sp<BufferHubProducer> producer = new BufferHubProducer;
309a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    producer->queue_ = queue;
319a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    return producer;
32d6cb17f84067ac0374ac28ef65f2e862c8cbb167Jiwen 'Steve' Cai}
33e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
345afb74036103e20bf2ca50aaf621bbb085a50ad5Jiwen 'Steve' Cai/* static */
35c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Caisp<BufferHubProducer> BufferHubProducer::Create(ProducerQueueParcelable parcelable) {
369a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    if (!parcelable.IsValid()) {
379a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        ALOGE("BufferHubProducer::Create: Invalid producer parcelable.");
389a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        return nullptr;
399a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    }
409a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
419a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    sp<BufferHubProducer> producer = new BufferHubProducer;
42c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai    producer->queue_ = ProducerQueue::Import(parcelable.TakeChannelHandle());
439a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    return producer;
445afb74036103e20bf2ca50aaf621bbb085a50ad5Jiwen 'Steve' Cai}
455afb74036103e20bf2ca50aaf621bbb085a50ad5Jiwen 'Steve' Cai
460f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Caistatus_t BufferHubProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
479a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    ALOGV("requestBuffer: slot=%d", slot);
489a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
499a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    std::unique_lock<std::mutex> lock(mutex_);
509a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
519a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    if (connected_api_ == kNoConnectedApi) {
529a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        ALOGE("requestBuffer: BufferHubProducer has no connected producer");
539a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        return NO_INIT;
549a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    }
559a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
569a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    if (slot < 0 || slot >= max_buffer_count_) {
579a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        ALOGE("requestBuffer: slot index %d out of range [0, %d)", slot, max_buffer_count_);
589a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        return BAD_VALUE;
599a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    } else if (!buffers_[slot].mBufferState.isDequeued()) {
609a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        ALOGE("requestBuffer: slot %d is not owned by the producer (state = %s)", slot,
619a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai              buffers_[slot].mBufferState.string());
629a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        return BAD_VALUE;
639a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    } else if (buffers_[slot].mGraphicBuffer != nullptr) {
649a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        ALOGE("requestBuffer: slot %d is not empty.", slot);
659a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        return BAD_VALUE;
669a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    } else if (buffers_[slot].mBufferProducer == nullptr) {
679a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        ALOGE("requestBuffer: slot %d is not dequeued.", slot);
689a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        return BAD_VALUE;
699a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    }
709a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
719a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    const auto& buffer_producer = buffers_[slot].mBufferProducer;
729a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    sp<GraphicBuffer> graphic_buffer = buffer_producer->buffer()->buffer();
739a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
749a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    buffers_[slot].mGraphicBuffer = graphic_buffer;
759a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    buffers_[slot].mRequestBufferCalled = true;
769a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
779a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    *buf = graphic_buffer;
789a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    return NO_ERROR;
79e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
80e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
819a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Caistatus_t BufferHubProducer::setMaxDequeuedBufferCount(int max_dequeued_buffers) {
829a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    ALOGV("setMaxDequeuedBufferCount: max_dequeued_buffers=%d", max_dequeued_buffers);
839a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
849a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    std::unique_lock<std::mutex> lock(mutex_);
859a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
869a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    if (max_dequeued_buffers <= 0 ||
879a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        max_dequeued_buffers >
88c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai                int(BufferHubQueue::kMaxQueueCapacity - kDefaultUndequeuedBuffers)) {
899a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        ALOGE("setMaxDequeuedBufferCount: %d out of range (0, %zu]", max_dequeued_buffers,
90c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai              BufferHubQueue::kMaxQueueCapacity);
919a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        return BAD_VALUE;
929a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    }
939a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
949a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    // The new dequeued_buffers count should not be violated by the number
959a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    // of currently dequeued buffers.
969a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    int dequeued_count = 0;
979a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    for (const auto& buf : buffers_) {
989a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        if (buf.mBufferState.isDequeued()) {
999a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            dequeued_count++;
1009a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        }
1019a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    }
1029a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    if (dequeued_count > max_dequeued_buffers) {
1039a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        ALOGE("setMaxDequeuedBufferCount: the requested dequeued_buffers"
1049a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai              "count (%d) exceeds the current dequeued buffer count (%d)",
1059a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai              max_dequeued_buffers, dequeued_count);
1069a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        return BAD_VALUE;
1079a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    }
1089a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
1099a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    max_dequeued_buffer_count_ = max_dequeued_buffers;
1109a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    return NO_ERROR;
111e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
112e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1130f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Caistatus_t BufferHubProducer::setAsyncMode(bool async) {
1149a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    if (async) {
1159a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        // TODO(b/36724099) BufferHubQueue's consumer end always acquires the buffer
1169a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        // automatically and behaves differently from IGraphicBufferConsumer. Thus,
1179a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        // android::BufferQueue's async mode (a.k.a. allocating an additional buffer
1189a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        // to prevent dequeueBuffer from being blocking) technically does not apply
1199a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        // here.
1209a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        //
1219a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        // In Daydream, non-blocking producer side dequeue is guaranteed by careful
1229a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        // buffer consumer implementations. In another word, BufferHubQueue based
1239a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        // dequeueBuffer should never block whether setAsyncMode(true) is set or
1249a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        // not.
1259a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        //
1269a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        // See: IGraphicBufferProducer::setAsyncMode and
1279a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        // BufferQueueProducer::setAsyncMode for more about original implementation.
1289a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        ALOGW("BufferHubProducer::setAsyncMode: BufferHubQueue should always be "
1299a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai              "asynchronous. This call makes no effact.");
1309a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        return NO_ERROR;
1319a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    }
1321601bcfa9cdc07cea8f5980349608e1526690db5Jiwen 'Steve' Cai    return NO_ERROR;
133e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
134e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1359a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Caistatus_t BufferHubProducer::dequeueBuffer(int* out_slot, sp<Fence>* out_fence, uint32_t width,
1369a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai                                          uint32_t height, PixelFormat format, uint64_t usage,
1379a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai                                          uint64_t* /*outBufferAge*/,
1389a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai                                          FrameEventHistoryDelta* /* out_timestamps */) {
139e7cf62ab152d273849b7d80fe4dd709d00e5f9daJiwen 'Steve' Cai    ALOGV("dequeueBuffer: w=%u, h=%u, format=%d, usage=%" PRIu64, width, height, format, usage);
1409a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
1419a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    status_t ret;
1429a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    std::unique_lock<std::mutex> lock(mutex_);
1439a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
1449a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    if (connected_api_ == kNoConnectedApi) {
1459a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        ALOGE("dequeueBuffer: BufferQueue has no connected producer");
1469a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        return NO_INIT;
1479a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    }
1489a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
1499a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    const uint32_t kLayerCount = 1;
1509a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    if (int32_t(queue_->capacity()) < max_dequeued_buffer_count_ + kDefaultUndequeuedBuffers) {
1519a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        // Lazy allocation. When the capacity of |queue_| has not reached
1529a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        // |max_dequeued_buffer_count_|, allocate new buffer.
1539a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        // TODO(jwcai) To save memory, the really reasonable thing to do is to go
1549a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        // over existing slots and find first existing one to dequeue.
1559a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        ret = AllocateBuffer(width, height, kLayerCount, format, usage);
1569a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        if (ret < 0) return ret;
1579a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    }
1589a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
1599a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    size_t slot = 0;
160c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai    std::shared_ptr<BufferProducer> buffer_producer;
1619a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
162c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai    for (size_t retry = 0; retry < BufferHubQueue::kMaxQueueCapacity; retry++) {
1639a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        LocalHandle fence;
1649a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        auto buffer_status = queue_->Dequeue(dequeue_timeout_ms_, &slot, &fence);
1659a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        if (!buffer_status) return NO_MEMORY;
1669a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
1679a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        buffer_producer = buffer_status.take();
1689a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        if (!buffer_producer) return NO_MEMORY;
1699a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
1709a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        if (width == buffer_producer->width() && height == buffer_producer->height() &&
1719a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            uint32_t(format) == buffer_producer->format()) {
1729a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            // The producer queue returns a buffer producer matches the request.
1739a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            break;
1749a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        }
1759a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
1769a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        // Needs reallocation.
1779a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        // TODO(jwcai) Consider use VLOG instead if we find this log is not useful.
1789a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        ALOGI("dequeueBuffer: requested buffer (w=%u, h=%u, format=%u) is different "
1799a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai              "from the buffer returned at slot: %zu (w=%u, h=%u, format=%u). Need "
1809a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai              "re-allocattion.",
1819a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai              width, height, format, slot, buffer_producer->width(), buffer_producer->height(),
1829a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai              buffer_producer->format());
1839a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        // Mark the slot as reallocating, so that later we can set
1849a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        // BUFFER_NEEDS_REALLOCATION when the buffer actually get dequeued.
1859a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        buffers_[slot].mIsReallocating = true;
1869a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
1879a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        // Remove the old buffer once the allocation before allocating its
1889a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        // replacement.
1899a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        RemoveBuffer(slot);
1909a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
1919a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        // Allocate a new producer buffer with new buffer configs. Note that if
1929a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        // there are already multiple buffers in the queue, the next one returned
1939a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        // from |queue_->Dequeue| may not be the new buffer we just reallocated.
1949a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        // Retry up to BufferHubQueue::kMaxQueueCapacity times.
1959a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        ret = AllocateBuffer(width, height, kLayerCount, format, usage);
1969a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        if (ret < 0) return ret;
1979a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    }
1989a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
1999a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    // With the BufferHub backed solution. Buffer slot returned from
2009a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    // |queue_->Dequeue| is guaranteed to avaiable for producer's use.
2019a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    // It's either in free state (if the buffer has never been used before) or
2029a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    // in queued state (if the buffer has been dequeued and queued back to
2039a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    // BufferHubQueue).
2049a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    LOG_ALWAYS_FATAL_IF((!buffers_[slot].mBufferState.isFree() &&
2059a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai                         !buffers_[slot].mBufferState.isQueued()),
2069a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai                        "dequeueBuffer: slot %zu is not free or queued, actual state: %s.", slot,
2079a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai                        buffers_[slot].mBufferState.string());
2089a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
2099a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    buffers_[slot].mBufferState.freeQueued();
2109a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    buffers_[slot].mBufferState.dequeue();
211e7cf62ab152d273849b7d80fe4dd709d00e5f9daJiwen 'Steve' Cai    ALOGV("dequeueBuffer: slot=%zu", slot);
2129a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
2139a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    // TODO(jwcai) Handle fence properly. |BufferHub| has full fence support, we
2149a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    // just need to exopose that through |BufferHubQueue| once we need fence.
2159a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    *out_fence = Fence::NO_FENCE;
2169a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    *out_slot = int(slot);
2179a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    ret = NO_ERROR;
2189a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
2199a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    if (buffers_[slot].mIsReallocating) {
2209a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        ret |= BUFFER_NEEDS_REALLOCATION;
2219a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        buffers_[slot].mIsReallocating = false;
2229a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    }
2239a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
2249a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    return ret;
225e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
226e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
2270f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Caistatus_t BufferHubProducer::detachBuffer(int /* slot */) {
2289a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    ALOGE("BufferHubProducer::detachBuffer not implemented.");
2299a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    return INVALID_OPERATION;
230e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
231e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
2329a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Caistatus_t BufferHubProducer::detachNextBuffer(sp<GraphicBuffer>* /* out_buffer */,
2339a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai                                             sp<Fence>* /* out_fence */) {
2349a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    ALOGE("BufferHubProducer::detachNextBuffer not implemented.");
2359a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    return INVALID_OPERATION;
236e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
237e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
2389a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Caistatus_t BufferHubProducer::attachBuffer(int* /* out_slot */,
2399a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai                                         const sp<GraphicBuffer>& /* buffer */) {
2409a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    // With this BufferHub backed implementation, we assume (for now) all buffers
2419a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    // are allocated and owned by the BufferHub. Thus the attempt of transfering
2429a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    // ownership of a buffer to the buffer queue is intentionally unsupported.
2439a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    LOG_ALWAYS_FATAL("BufferHubProducer::attachBuffer not supported.");
2449a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    return INVALID_OPERATION;
245e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
246e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
2470f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Caistatus_t BufferHubProducer::queueBuffer(int slot, const QueueBufferInput& input,
2480f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Cai                                        QueueBufferOutput* output) {
2499a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    ALOGV("queueBuffer: slot %d", slot);
2509a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
2519a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    if (output == nullptr) {
2529a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        return BAD_VALUE;
2539a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    }
2549a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
2559a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    int64_t timestamp;
2569a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    bool is_auto_timestamp;
2579a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    android_dataspace dataspace;
2589a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    Rect crop(Rect::EMPTY_RECT);
2599a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    int scaling_mode;
2609a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    uint32_t transform;
2619a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    sp<Fence> fence;
2629a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
2639a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    input.deflate(&timestamp, &is_auto_timestamp, &dataspace, &crop, &scaling_mode, &transform,
2649a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai                  &fence);
2659a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
2669a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    // Check input scaling mode is valid.
2679a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    switch (scaling_mode) {
2689a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        case NATIVE_WINDOW_SCALING_MODE_FREEZE:
2699a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
2709a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
2719a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP:
2729a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            break;
2739a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        default:
2749a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            ALOGE("queueBuffer: unknown scaling mode %d", scaling_mode);
2759a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            return BAD_VALUE;
2769a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    }
2779a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
2789a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    // Check input fence is valid.
2799a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    if (fence == nullptr) {
2809a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        ALOGE("queueBuffer: fence is NULL");
2819a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        return BAD_VALUE;
2829a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    }
2839a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
2849a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    std::unique_lock<std::mutex> lock(mutex_);
2859a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
2869a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    if (connected_api_ == kNoConnectedApi) {
2879a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        ALOGE("queueBuffer: BufferQueue has no connected producer");
2889a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        return NO_INIT;
2899a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    }
2909a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
2919a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    if (slot < 0 || slot >= max_buffer_count_) {
2929a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        ALOGE("queueBuffer: slot index %d out of range [0, %d)", slot, max_buffer_count_);
2939a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        return BAD_VALUE;
2949a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    } else if (!buffers_[slot].mBufferState.isDequeued()) {
2959a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        ALOGE("queueBuffer: slot %d is not owned by the producer (state = %s)", slot,
2969a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai              buffers_[slot].mBufferState.string());
2979a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        return BAD_VALUE;
2989a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    } else if ((!buffers_[slot].mRequestBufferCalled || buffers_[slot].mGraphicBuffer == nullptr)) {
2999a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        ALOGE("queueBuffer: slot %d is not requested (mRequestBufferCalled=%d, "
3009a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai              "mGraphicBuffer=%p)",
3019a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai              slot, buffers_[slot].mRequestBufferCalled, buffers_[slot].mGraphicBuffer.get());
3029a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        return BAD_VALUE;
3039a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    }
3049a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
3059a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    // Post the buffer producer with timestamp in the metadata.
3069a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    const auto& buffer_producer = buffers_[slot].mBufferProducer;
3079a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
3089a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    // Check input crop is not out of boundary of current buffer.
3099a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    Rect buffer_rect(buffer_producer->width(), buffer_producer->height());
3109a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    Rect cropped_rect(Rect::EMPTY_RECT);
3119a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    crop.intersect(buffer_rect, &cropped_rect);
3129a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    if (cropped_rect != crop) {
3139a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        ALOGE("queueBuffer: slot %d has out-of-boundary crop.", slot);
3149a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        return BAD_VALUE;
3159a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    }
3169a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
3179a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    LocalHandle fence_fd(fence->isValid() ? fence->dup() : -1);
3189a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
3199a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    DvrNativeBufferMetadata meta_data;
3209a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    meta_data.timestamp = timestamp;
3219a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    meta_data.is_auto_timestamp = int32_t(is_auto_timestamp);
3229a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    meta_data.dataspace = int32_t(dataspace);
3239a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    meta_data.crop_left = crop.left;
3249a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    meta_data.crop_top = crop.top;
3259a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    meta_data.crop_right = crop.right;
3269a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    meta_data.crop_bottom = crop.bottom;
3279a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    meta_data.scaling_mode = int32_t(scaling_mode);
3289a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    meta_data.transform = int32_t(transform);
3299a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
3309a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    buffer_producer->PostAsync(&meta_data, fence_fd);
3319a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    buffers_[slot].mBufferState.queue();
3329a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
3339a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    output->width = buffer_producer->width();
3349a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    output->height = buffer_producer->height();
3359a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    output->transformHint = 0; // default value, we don't use it yet.
3369a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
3379a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    // |numPendingBuffers| counts of the number of buffers that has been enqueued
3389a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    // by the producer but not yet acquired by the consumer. Due to the nature
3399a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    // of BufferHubQueue design, this is hard to trace from the producer's client
3409a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    // side, but it's safe to assume it's zero.
3419a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    output->numPendingBuffers = 0;
3429a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
3439a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    // Note that we are not setting nextFrameNumber here as it seems to be only
3449a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    // used by surface flinger. See more at b/22802885, ag/791760.
3459a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    output->nextFrameNumber = 0;
3469a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
3479a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    return NO_ERROR;
348e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
349e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
3500f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Caistatus_t BufferHubProducer::cancelBuffer(int slot, const sp<Fence>& fence) {
3519a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    ALOGV(__FUNCTION__);
3529a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
3539a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    std::unique_lock<std::mutex> lock(mutex_);
3549a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
3559a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    if (connected_api_ == kNoConnectedApi) {
3569a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        ALOGE("cancelBuffer: BufferQueue has no connected producer");
3579a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        return NO_INIT;
3589a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    }
3599a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
3609a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    if (slot < 0 || slot >= max_buffer_count_) {
3619a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        ALOGE("cancelBuffer: slot index %d out of range [0, %d)", slot, max_buffer_count_);
3629a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        return BAD_VALUE;
3639a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    } else if (!buffers_[slot].mBufferState.isDequeued()) {
3649a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        ALOGE("cancelBuffer: slot %d is not owned by the producer (state = %s)", slot,
3659a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai              buffers_[slot].mBufferState.string());
3669a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        return BAD_VALUE;
3679a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    } else if (fence == nullptr) {
3689a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        ALOGE("cancelBuffer: fence is NULL");
3699a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        return BAD_VALUE;
3709a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    }
3719a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
3729a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    auto buffer_producer = buffers_[slot].mBufferProducer;
3739a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    queue_->Enqueue(buffer_producer, size_t(slot), 0ULL);
3749a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    buffers_[slot].mBufferState.cancel();
3759a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    buffers_[slot].mFence = fence;
3769a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    ALOGV("cancelBuffer: slot %d", slot);
3779a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
3789a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    return NO_ERROR;
379e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
380e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
3810f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Caistatus_t BufferHubProducer::query(int what, int* out_value) {
3829a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    ALOGV(__FUNCTION__);
3839a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
3849a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    std::unique_lock<std::mutex> lock(mutex_);
3859a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
3869a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    if (out_value == nullptr) {
3879a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        ALOGE("query: out_value was NULL");
3889a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        return BAD_VALUE;
3899a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    }
3909a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
3919a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    int value = 0;
3929a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    switch (what) {
3939a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
3949a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            // TODO(b/36187402) This should be the maximum number of buffers that this
3959a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            // producer queue's consumer can acquire. Set to be at least one. Need to
3969a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            // find a way to set from the consumer side.
3979a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            value = kDefaultUndequeuedBuffers;
3989a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            break;
3999a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        case NATIVE_WINDOW_BUFFER_AGE:
4009a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            value = 0;
4019a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            break;
4029a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        case NATIVE_WINDOW_WIDTH:
4039a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            value = int32_t(queue_->default_width());
4049a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            break;
4059a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        case NATIVE_WINDOW_HEIGHT:
4069a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            value = int32_t(queue_->default_height());
4079a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            break;
4089a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        case NATIVE_WINDOW_FORMAT:
4099a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            value = int32_t(queue_->default_format());
4109a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            break;
4119a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND:
4129a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            // BufferHubQueue is always operating in async mode, thus semantically
4139a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            // consumer can never be running behind. See BufferQueueCore.cpp core
4149a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            // for more information about the original meaning of this flag.
4159a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            value = 0;
4169a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            break;
4179a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        case NATIVE_WINDOW_CONSUMER_USAGE_BITS:
4189a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            // TODO(jwcai) This is currently not implement as we don't need
4199a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            // IGraphicBufferConsumer parity.
4209a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            value = 0;
4219a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            break;
4229a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        case NATIVE_WINDOW_DEFAULT_DATASPACE:
4239a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            // TODO(jwcai) Return the default value android::BufferQueue is using as
4249a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            // there is no way dvr::ConsumerQueue can set it.
4259a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            value = 0; // HAL_DATASPACE_UNKNOWN
4269a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            break;
4279a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        case NATIVE_WINDOW_STICKY_TRANSFORM:
4289a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            // TODO(jwcai) Return the default value android::BufferQueue is using as
4299a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            // there is no way dvr::ConsumerQueue can set it.
4309a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            value = 0;
4319a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            break;
4329a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        case NATIVE_WINDOW_CONSUMER_IS_PROTECTED:
4339a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            // In Daydream's implementation, the consumer end (i.e. VR Compostior)
4349a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            // knows how to handle protected buffers.
4359a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            value = 1;
4369a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            break;
4379a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        default:
4389a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            return BAD_VALUE;
4399a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    }
4409a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
4419a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    ALOGV("query: key=%d, v=%d", what, value);
4429a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    *out_value = value;
4439a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    return NO_ERROR;
444e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
445e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
4469a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Caistatus_t BufferHubProducer::connect(const sp<IProducerListener>& /* listener */, int api,
4470f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Cai                                    bool /* producer_controlled_by_app */,
4480f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Cai                                    QueueBufferOutput* output) {
4499a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    // Consumer interaction are actually handled by buffer hub, and we need
4509a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    // to maintain consumer operations here. We only need to perform basic input
4519a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    // parameter checks here.
4529a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    ALOGV(__FUNCTION__);
4539a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
4549a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    if (output == nullptr) {
4559a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        return BAD_VALUE;
4569a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    }
4579a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
4589a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    std::unique_lock<std::mutex> lock(mutex_);
4599a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
4609a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    if (connected_api_ != kNoConnectedApi) {
4619a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        return BAD_VALUE;
4629a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    }
4639a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
4649a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    if (!queue_->is_connected()) {
4659a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        ALOGE("BufferHubProducer::connect: This BufferHubProducer is not "
4669a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai              "connected to bufferhud. Has it been taken out as a parcelable?");
4679a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        return BAD_VALUE;
4689a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    }
4699a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
4709a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    switch (api) {
4719a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        case NATIVE_WINDOW_API_EGL:
4729a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        case NATIVE_WINDOW_API_CPU:
4739a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        case NATIVE_WINDOW_API_MEDIA:
4749a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        case NATIVE_WINDOW_API_CAMERA:
4759a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            connected_api_ = api;
4769a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
4779a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            output->width = queue_->default_width();
4789a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            output->height = queue_->default_height();
4799a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
4809a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            // default values, we don't use them yet.
4819a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            output->transformHint = 0;
4829a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            output->numPendingBuffers = 0;
4839a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            output->nextFrameNumber = 0;
4849a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            output->bufferReplaced = false;
4859a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
4869a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            break;
4879a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        default:
4889a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            ALOGE("BufferHubProducer::connect: unknow API %d", api);
4899a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai            return BAD_VALUE;
4909a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    }
4919a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
4929a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    return NO_ERROR;
493e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
494e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
4950f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Caistatus_t BufferHubProducer::disconnect(int api, DisconnectMode /*mode*/) {
4969a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    // Consumer interaction are actually handled by buffer hub, and we need
4979a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    // to maintain consumer operations here.  We only need to perform basic input
4989a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    // parameter checks here.
4999a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    ALOGV(__FUNCTION__);
5009a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
5019a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    std::unique_lock<std::mutex> lock(mutex_);
5029a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
5039a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    if (kNoConnectedApi == connected_api_) {
5049a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        return NO_INIT;
5059a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    } else if (api != connected_api_) {
5069a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        return BAD_VALUE;
5079a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    }
5089a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
5099a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    FreeAllBuffers();
5109a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    connected_api_ = kNoConnectedApi;
5119a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    return NO_ERROR;
512e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
513e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
5140f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Caistatus_t BufferHubProducer::setSidebandStream(const sp<NativeHandle>& stream) {
5159a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    if (stream != nullptr) {
5169a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        // TODO(jwcai) Investigate how is is used, maybe use BufferHubBuffer's
5179a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        // metadata.
5189a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        ALOGE("SidebandStream is not currently supported.");
5199a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        return INVALID_OPERATION;
5209a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    }
5219a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    return NO_ERROR;
522e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
523e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
5249a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Caivoid BufferHubProducer::allocateBuffers(uint32_t /* width */, uint32_t /* height */,
5259a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai                                        PixelFormat /* format */, uint64_t /* usage */) {
5269a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    // TODO(jwcai) |allocateBuffers| aims to preallocate up to the maximum number
5279a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    // of buffers permitted by the current BufferQueue configuration (aka
5289a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    // |max_buffer_count_|).
5299a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    ALOGE("BufferHubProducer::allocateBuffers not implemented.");
530e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
531e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
5320f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Caistatus_t BufferHubProducer::allowAllocation(bool /* allow */) {
5339a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    ALOGE("BufferHubProducer::allowAllocation not implemented.");
5349a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    return INVALID_OPERATION;
535e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
536e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
5370f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Caistatus_t BufferHubProducer::setGenerationNumber(uint32_t generation_number) {
5389a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    ALOGV(__FUNCTION__);
539e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
5409a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    std::unique_lock<std::mutex> lock(mutex_);
5419a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    generation_number_ = generation_number;
5429a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    return NO_ERROR;
543e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
544e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
5450f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' CaiString8 BufferHubProducer::getConsumerName() const {
5469a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    // BufferHub based implementation could have one to many producer/consumer
5479a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    // relationship, thus |getConsumerName| from the producer side does not
5489a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    // make any sense.
5499a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    ALOGE("BufferHubProducer::getConsumerName not supported.");
5509a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    return String8("BufferHubQueue::DummyConsumer");
551e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
552e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
5530f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Caistatus_t BufferHubProducer::setSharedBufferMode(bool shared_buffer_mode) {
5549a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    if (shared_buffer_mode) {
5559a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        ALOGE("BufferHubProducer::setSharedBufferMode(true) is not supported.");
5569a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        // TODO(b/36373181) Front buffer mode for buffer hub queue as ANativeWindow.
5579a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        return INVALID_OPERATION;
5589a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    }
5599a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    // Setting to default should just work as a no-op.
5609a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    return NO_ERROR;
561e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
562e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
5630f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Caistatus_t BufferHubProducer::setAutoRefresh(bool auto_refresh) {
5649a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    if (auto_refresh) {
5659a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        ALOGE("BufferHubProducer::setAutoRefresh(true) is not supported.");
5669a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        return INVALID_OPERATION;
5679a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    }
5689a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    // Setting to default should just work as a no-op.
5699a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    return NO_ERROR;
570e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
571e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
5720f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Caistatus_t BufferHubProducer::setDequeueTimeout(nsecs_t timeout) {
5739a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    ALOGV(__FUNCTION__);
574e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
5759a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    std::unique_lock<std::mutex> lock(mutex_);
576c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai    dequeue_timeout_ms_ = static_cast<int>(timeout / (1000 * 1000));
5779a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    return NO_ERROR;
578e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
579e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
5809a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Caistatus_t BufferHubProducer::getLastQueuedBuffer(sp<GraphicBuffer>* /* out_buffer */,
5819a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai                                                sp<Fence>* /* out_fence */,
5829a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai                                                float /*out_transform_matrix*/[16]) {
5839a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    ALOGE("BufferHubProducer::getLastQueuedBuffer not implemented.");
5849a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    return INVALID_OPERATION;
585e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
586e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
5879a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Caivoid BufferHubProducer::getFrameTimestamps(FrameEventHistoryDelta* /*outDelta*/) {
5889a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    ALOGE("BufferHubProducer::getFrameTimestamps not implemented.");
589e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
590e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
5910f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Caistatus_t BufferHubProducer::getUniqueId(uint64_t* out_id) const {
5929a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    ALOGV(__FUNCTION__);
593e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
5949a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    *out_id = unique_id_;
5959a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    return NO_ERROR;
596d6cb17f84067ac0374ac28ef65f2e862c8cbb167Jiwen 'Steve' Cai}
597d6cb17f84067ac0374ac28ef65f2e862c8cbb167Jiwen 'Steve' Cai
5980f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Caistatus_t BufferHubProducer::getConsumerUsage(uint64_t* out_usage) const {
5999a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    ALOGV(__FUNCTION__);
600e2786ea5aec3a12d948feb85ffbb535fc89c0fe6Chia-I Wu
6019a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    // same value as returned by querying NATIVE_WINDOW_CONSUMER_USAGE_BITS
6029a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    *out_usage = 0;
6039a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    return NO_ERROR;
604e2786ea5aec3a12d948feb85ffbb535fc89c0fe6Chia-I Wu}
605e2786ea5aec3a12d948feb85ffbb535fc89c0fe6Chia-I Wu
606c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Caistatus_t BufferHubProducer::TakeAsParcelable(ProducerQueueParcelable* out_parcelable) {
6079a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    if (!out_parcelable || out_parcelable->IsValid()) return BAD_VALUE;
6089a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
6099a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    if (connected_api_ != kNoConnectedApi) {
6109a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        ALOGE("BufferHubProducer::TakeAsParcelable: BufferHubProducer has "
6119a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai              "connected client. Must disconnect first.");
6129a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        return BAD_VALUE;
6139a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    }
6149a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
6159a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    if (!queue_->is_connected()) {
6169a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        ALOGE("BufferHubProducer::TakeAsParcelable: This BufferHubProducer "
6179a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai              "is not connected to bufferhud. Has it been taken out as a "
6189a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai              "parcelable?");
6199a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        return BAD_VALUE;
6209a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    }
6219a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
6229a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    auto status = queue_->TakeAsParcelable();
6239a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    if (!status) {
6249a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        ALOGE("BufferHubProducer::TakeAsParcelable: Failed to take out "
6259a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai              "ProducuerQueueParcelable from the producer queue, error: %s.",
6269a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai              status.GetErrorMessage().c_str());
6279a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        return BAD_VALUE;
6289a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    }
6299a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
6309a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    *out_parcelable = status.take();
6319a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    return NO_ERROR;
6325afb74036103e20bf2ca50aaf621bbb085a50ad5Jiwen 'Steve' Cai}
6335afb74036103e20bf2ca50aaf621bbb085a50ad5Jiwen 'Steve' Cai
6349a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Caistatus_t BufferHubProducer::AllocateBuffer(uint32_t width, uint32_t height, uint32_t layer_count,
6350f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Cai                                           PixelFormat format, uint64_t usage) {
6369a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    auto status = queue_->AllocateBuffer(width, height, layer_count, uint32_t(format), usage);
6379a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    if (!status) {
6389a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        ALOGE("BufferHubProducer::AllocateBuffer: Failed to allocate buffer: %s",
6399a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai              status.GetErrorMessage().c_str());
6409a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        return NO_MEMORY;
6419a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    }
642d6cb17f84067ac0374ac28ef65f2e862c8cbb167Jiwen 'Steve' Cai
6439a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    size_t slot = status.get();
6449a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    auto buffer_producer = queue_->GetBuffer(slot);
645d6cb17f84067ac0374ac28ef65f2e862c8cbb167Jiwen 'Steve' Cai
6469a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    LOG_ALWAYS_FATAL_IF(buffer_producer == nullptr, "Failed to get buffer producer at slot: %zu",
6479a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai                        slot);
648d6cb17f84067ac0374ac28ef65f2e862c8cbb167Jiwen 'Steve' Cai
6499a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    buffers_[slot].mBufferProducer = buffer_producer;
650d6cb17f84067ac0374ac28ef65f2e862c8cbb167Jiwen 'Steve' Cai
6519a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    return NO_ERROR;
652e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
653e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
6540f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Caistatus_t BufferHubProducer::RemoveBuffer(size_t slot) {
6559a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    auto status = queue_->RemoveBuffer(slot);
6569a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    if (!status) {
6579a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        ALOGE("BufferHubProducer::RemoveBuffer: Failed to remove buffer: %s",
6589a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai              status.GetErrorMessage().c_str());
6599a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        return INVALID_OPERATION;
6609a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    }
661d6cb17f84067ac0374ac28ef65f2e862c8cbb167Jiwen 'Steve' Cai
6629a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    // Reset in memory objects related the the buffer.
6639a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    buffers_[slot].mBufferProducer = nullptr;
6649a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    buffers_[slot].mGraphicBuffer = nullptr;
6659a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    buffers_[slot].mBufferState.detachProducer();
6669a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    return NO_ERROR;
667e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
668e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
6690f950843530825907f8311b199b01c32899c2c92Jiwen 'Steve' Caistatus_t BufferHubProducer::FreeAllBuffers() {
670c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai    for (size_t slot = 0; slot < BufferHubQueue::kMaxQueueCapacity; slot++) {
6719a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        // Reset in memory objects related the the buffer.
6729a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        buffers_[slot].mGraphicBuffer = nullptr;
6739a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        buffers_[slot].mBufferState.reset();
6749a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        buffers_[slot].mRequestBufferCalled = false;
6759a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        buffers_[slot].mBufferProducer = nullptr;
6769a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        buffers_[slot].mFence = Fence::NO_FENCE;
6779a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    }
6789a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
6799a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    auto status = queue_->FreeAllBuffers();
6809a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    if (!status) {
6819a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        ALOGE("BufferHubProducer::FreeAllBuffers: Failed to free all buffers on "
6829a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai              "the queue: %s",
6839a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai              status.GetErrorMessage().c_str());
6849a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    }
6859a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
6869a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    if (queue_->capacity() != 0 || queue_->count() != 0) {
6879a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai        LOG_ALWAYS_FATAL("BufferHubProducer::FreeAllBuffers: Not all buffers are freed.");
6889a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    }
6899a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai
6909a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai    return NO_ERROR;
691005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai}
692005f45d7bb059c0ef8d69f1cac81bca4f70852afJiwen 'Steve' Cai
693c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Caistatus_t BufferHubProducer::exportToParcel(Parcel* parcel) {
694c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai    status_t res = TakeAsParcelable(&pending_producer_parcelable_);
695c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai    if (res != NO_ERROR) return res;
696c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai
697c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai    if (!pending_producer_parcelable_.IsValid()) {
698c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai        ALOGE("BufferHubProducer::exportToParcel: Invalid parcelable object.");
699c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai        return BAD_VALUE;
700c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai    }
701c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai
702c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai    res = parcel->writeUint32(USE_BUFFER_HUB);
703c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai    if (res != NO_ERROR) {
704c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai        ALOGE("BufferHubProducer::exportToParcel: Cannot write magic, res=%d.", res);
705c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai        return res;
706c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai    }
707c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai
708c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai    return pending_producer_parcelable_.writeToParcel(parcel);
709c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai}
710c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai
711c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' CaiIBinder* BufferHubProducer::onAsBinder() {
712c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai    ALOGE("BufferHubProducer::onAsBinder: BufferHubProducer should never be used as an Binder "
713c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai          "object.");
714c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai    return nullptr;
715c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai}
716c90a77f1e5b42d8fcf336d2b9bd2259280814df2Jiwen 'Steve' Cai
7179a6ddf78e1920a0f467bd38de1835746c6f4c3caJiwen 'Steve' Cai} // namespace android
718