1e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include "include/private/dvr/display_client.h"
2e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
3e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <cutils/native_handle.h>
44fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko#include <log/log.h>
5e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/default_transport/client_channel.h>
6e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/default_transport/client_channel_factory.h>
7e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/status.h>
8e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
9e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <mutex>
10e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
113f82d31341f66d0c58e1ec3360ea5f528ffe0ea4Corey Tabaka#include <private/dvr/display_protocol.h>
12e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
132251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakausing android::pdx::ErrorStatus;
14e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::LocalHandle;
15e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::LocalChannelHandle;
16e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::Status;
17e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::Transaction;
18e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::rpc::IfAnyOf;
19e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
20e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace android {
21e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace dvr {
222251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakanamespace display {
23e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
242251d822dac2a96aad4184a6fdc2690f0a58af7cCorey TabakaSurface::Surface(LocalChannelHandle channel_handle, int* error)
252251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    : BASE{pdx::default_transport::ClientChannel::Create(
262251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka          std::move(channel_handle))} {
272251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  auto status = InvokeRemoteMethod<DisplayProtocol::GetSurfaceInfo>();
282251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  if (!status) {
292251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    ALOGE("Surface::Surface: Failed to get surface info: %s",
30e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko          status.GetErrorMessage().c_str());
312251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    Close(status.error());
322251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    if (error)
332251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka      *error = status.error();
34e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
35e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
362251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  surface_id_ = status.get().surface_id;
372251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  z_order_ = status.get().z_order;
382251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  visible_ = status.get().visible;
39e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
40e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
412251d822dac2a96aad4184a6fdc2690f0a58af7cCorey TabakaSurface::Surface(const SurfaceAttributes& attributes, int* error)
422251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    : BASE{pdx::default_transport::ClientChannelFactory::Create(
432251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka               DisplayProtocol::kClientPath),
442251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka           kInfiniteTimeout} {
452251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  auto status = InvokeRemoteMethod<DisplayProtocol::CreateSurface>(attributes);
46e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (!status) {
472251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    ALOGE("Surface::Surface: Failed to create display surface: %s",
482251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka          status.GetErrorMessage().c_str());
49e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    Close(status.error());
502251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    if (error)
512251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka      *error = status.error();
52e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
53e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
542251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  surface_id_ = status.get().surface_id;
552251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  z_order_ = status.get().z_order;
562251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  visible_ = status.get().visible;
57e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
58e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
592251d822dac2a96aad4184a6fdc2690f0a58af7cCorey TabakaStatus<void> Surface::SetVisible(bool visible) {
602251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  return SetAttributes(
612251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka      {{SurfaceAttribute::Visible, SurfaceAttributeValue{visible}}});
62e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
63e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
642251d822dac2a96aad4184a6fdc2690f0a58af7cCorey TabakaStatus<void> Surface::SetZOrder(int z_order) {
652251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  return SetAttributes(
662251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka      {{SurfaceAttribute::ZOrder, SurfaceAttributeValue{z_order}}});
67e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
68e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
692251d822dac2a96aad4184a6fdc2690f0a58af7cCorey TabakaStatus<void> Surface::SetAttributes(const SurfaceAttributes& attributes) {
702251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  auto status = InvokeRemoteMethod<DisplayProtocol::SetAttributes>(attributes);
71e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (!status) {
72e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    ALOGE(
732251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka        "Surface::SetAttributes: Failed to set display surface "
74e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        "attributes: %s",
75e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        status.GetErrorMessage().c_str());
762251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    return status.error_status();
77e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
78e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
79e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Set the local cached copies of the attributes we care about from the full
80e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // set of attributes sent to the display service.
81e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  for (const auto& attribute : attributes) {
82e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    const auto& key = attribute.first;
83e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    const auto* variant = &attribute.second;
84e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    bool invalid_value = false;
85e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    switch (key) {
862251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka      case SurfaceAttribute::Visible:
87e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        invalid_value =
88e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko            !IfAnyOf<int32_t, int64_t, bool>::Get(variant, &visible_);
89e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        break;
902251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka      case SurfaceAttribute::ZOrder:
91e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        invalid_value = !IfAnyOf<int32_t>::Get(variant, &z_order_);
92e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        break;
93e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    }
94e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
95e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (invalid_value) {
96e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      ALOGW(
972251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka          "Surface::SetAttributes: Failed to set display surface "
982251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka          "attribute %d because of incompatible type: %d",
992251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka          key, variant->index());
100e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    }
101e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
1022251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka
1032251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  return {};
104e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
105e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
10699c2d73588dad4a4d12a17d37354237b8c11a16aCorey TabakaStatus<std::unique_ptr<ProducerQueue>> Surface::CreateQueue(
10799c2d73588dad4a4d12a17d37354237b8c11a16aCorey Tabaka    uint32_t width, uint32_t height, uint32_t format, size_t metadata_size) {
1082251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  ALOGD_IF(TRACE, "Surface::CreateQueue: Creating empty queue.");
109656f406fcb0c45fd3c729a513bdd3f353cc6ec1fJiwen 'Steve' Cai  auto status = InvokeRemoteMethod<DisplayProtocol::CreateQueue>(
110656f406fcb0c45fd3c729a513bdd3f353cc6ec1fJiwen 'Steve' Cai      ProducerQueueConfigBuilder()
111656f406fcb0c45fd3c729a513bdd3f353cc6ec1fJiwen 'Steve' Cai          .SetDefaultWidth(width)
112656f406fcb0c45fd3c729a513bdd3f353cc6ec1fJiwen 'Steve' Cai          .SetDefaultHeight(height)
113656f406fcb0c45fd3c729a513bdd3f353cc6ec1fJiwen 'Steve' Cai          .SetDefaultFormat(format)
114532e529ec8f87578d024da0c5b71d4b12da21862Jiwen 'Steve' Cai          .SetMetadataSize(metadata_size)
115656f406fcb0c45fd3c729a513bdd3f353cc6ec1fJiwen 'Steve' Cai          .Build());
1162251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  if (!status) {
1172251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    ALOGE("Surface::CreateQueue: Failed to create queue: %s",
118e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko          status.GetErrorMessage().c_str());
1192251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    return status.error_status();
120a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai  }
121e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1222251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  auto producer_queue = ProducerQueue::Import(status.take());
1232251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  if (!producer_queue) {
1242251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    ALOGE("Surface::CreateQueue: Failed to import producer queue!");
1252251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    return ErrorStatus(ENOMEM);
126e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
127e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1282251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  return {std::move(producer_queue)};
129e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
130e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
131108e84f7e6a9117b66dba000dcf16c6d8c862e16Hendrik WagenaarStatus<std::unique_ptr<ProducerQueue>> Surface::CreateQueue(
132108e84f7e6a9117b66dba000dcf16c6d8c862e16Hendrik Wagenaar    uint32_t width, uint32_t height, uint32_t layer_count, uint32_t format,
133532e529ec8f87578d024da0c5b71d4b12da21862Jiwen 'Steve' Cai    uint64_t usage, size_t capacity, size_t metadata_size) {
1342251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  ALOGD_IF(TRACE,
135108e84f7e6a9117b66dba000dcf16c6d8c862e16Hendrik Wagenaar           "Surface::CreateQueue: width=%u height=%u layer_count=%u format=%u "
136108e84f7e6a9117b66dba000dcf16c6d8c862e16Hendrik Wagenaar           "usage=%" PRIx64 " capacity=%zu",
137108e84f7e6a9117b66dba000dcf16c6d8c862e16Hendrik Wagenaar           width, height, layer_count, format, usage, capacity);
138532e529ec8f87578d024da0c5b71d4b12da21862Jiwen 'Steve' Cai  auto status = CreateQueue(width, height, format, metadata_size);
1392251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  if (!status)
1402251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    return status.error_status();
1412251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka
1422251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  auto producer_queue = status.take();
1432251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka
1442251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  ALOGD_IF(TRACE, "Surface::CreateQueue: Allocating %zu buffers...", capacity);
1458fa4e107ab6cbc24c0e54d44db3341f006fe939aJiwen 'Steve' Cai  auto allocate_status = producer_queue->AllocateBuffers(
1468fa4e107ab6cbc24c0e54d44db3341f006fe939aJiwen 'Steve' Cai      width, height, layer_count, format, usage, capacity);
1478fa4e107ab6cbc24c0e54d44db3341f006fe939aJiwen 'Steve' Cai  if (!allocate_status) {
1488fa4e107ab6cbc24c0e54d44db3341f006fe939aJiwen 'Steve' Cai    ALOGE("Surface::CreateQueue: Failed to allocate buffer on queue_id=%d: %s",
149b7ca5dee2045d9426e68f863b244012a2b223ea8Corey Tabaka          producer_queue->id(), allocate_status.GetErrorMessage().c_str());
1508fa4e107ab6cbc24c0e54d44db3341f006fe939aJiwen 'Steve' Cai    return allocate_status.error_status();
151e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
1522251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka
1532251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  return {std::move(producer_queue)};
154e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
155e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
156e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoDisplayClient::DisplayClient(int* error)
157e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    : BASE(pdx::default_transport::ClientChannelFactory::Create(
1582251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka               DisplayProtocol::kClientPath),
159e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko           kInfiniteTimeout) {
160e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (error)
161e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    *error = Client::error();
162e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
163e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1642251d822dac2a96aad4184a6fdc2690f0a58af7cCorey TabakaStatus<Metrics> DisplayClient::GetDisplayMetrics() {
1652251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  return InvokeRemoteMethod<DisplayProtocol::GetMetrics>();
166e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
167e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
168bcb03d005a4ccca20a0723f087e90e8b503b4848Hendrik WagenaarStatus<std::string> DisplayClient::GetConfigurationData(
169bcb03d005a4ccca20a0723f087e90e8b503b4848Hendrik Wagenaar    ConfigFileType config_type) {
170bcb03d005a4ccca20a0723f087e90e8b503b4848Hendrik Wagenaar  auto status =
171bcb03d005a4ccca20a0723f087e90e8b503b4848Hendrik Wagenaar      InvokeRemoteMethod<DisplayProtocol::GetConfigurationData>(config_type);
172bcb03d005a4ccca20a0723f087e90e8b503b4848Hendrik Wagenaar  if (!status && status.error() != ENOENT) {
173bcb03d005a4ccca20a0723f087e90e8b503b4848Hendrik Wagenaar    ALOGE(
174bcb03d005a4ccca20a0723f087e90e8b503b4848Hendrik Wagenaar        "DisplayClient::GetConfigurationData: Unable to get"
175bcb03d005a4ccca20a0723f087e90e8b503b4848Hendrik Wagenaar        "configuration data. Error: %s",
176bcb03d005a4ccca20a0723f087e90e8b503b4848Hendrik Wagenaar        status.GetErrorMessage().c_str());
177bcb03d005a4ccca20a0723f087e90e8b503b4848Hendrik Wagenaar  }
178bcb03d005a4ccca20a0723f087e90e8b503b4848Hendrik Wagenaar  return status;
179bcb03d005a4ccca20a0723f087e90e8b503b4848Hendrik Wagenaar}
180bcb03d005a4ccca20a0723f087e90e8b503b4848Hendrik Wagenaar
1812251d822dac2a96aad4184a6fdc2690f0a58af7cCorey TabakaStatus<std::unique_ptr<Surface>> DisplayClient::CreateSurface(
1822251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    const SurfaceAttributes& attributes) {
1832251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  int error;
1842251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  if (auto client = Surface::Create(attributes, &error))
1852251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    return {std::move(client)};
1862251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  else
1872251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    return ErrorStatus(error);
188e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
189e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
19099c2d73588dad4a4d12a17d37354237b8c11a16aCorey Tabakapdx::Status<std::unique_ptr<IonBuffer>> DisplayClient::SetupGlobalBuffer(
19199c2d73588dad4a4d12a17d37354237b8c11a16aCorey Tabaka    DvrGlobalBufferKey key, size_t size, uint64_t usage) {
19299c2d73588dad4a4d12a17d37354237b8c11a16aCorey Tabaka  auto status =
19399c2d73588dad4a4d12a17d37354237b8c11a16aCorey Tabaka      InvokeRemoteMethod<DisplayProtocol::SetupGlobalBuffer>(key, size, usage);
19499c2d73588dad4a4d12a17d37354237b8c11a16aCorey Tabaka  if (!status) {
19599c2d73588dad4a4d12a17d37354237b8c11a16aCorey Tabaka    ALOGE(
19699c2d73588dad4a4d12a17d37354237b8c11a16aCorey Tabaka        "DisplayClient::SetupGlobalBuffer: Failed to create the global buffer "
19799c2d73588dad4a4d12a17d37354237b8c11a16aCorey Tabaka        "%s",
19899c2d73588dad4a4d12a17d37354237b8c11a16aCorey Tabaka        status.GetErrorMessage().c_str());
19999c2d73588dad4a4d12a17d37354237b8c11a16aCorey Tabaka    return status.error_status();
20099c2d73588dad4a4d12a17d37354237b8c11a16aCorey Tabaka  }
20199c2d73588dad4a4d12a17d37354237b8c11a16aCorey Tabaka
20299c2d73588dad4a4d12a17d37354237b8c11a16aCorey Tabaka  auto ion_buffer = std::make_unique<IonBuffer>();
20399c2d73588dad4a4d12a17d37354237b8c11a16aCorey Tabaka  auto native_buffer_handle = status.take();
20499c2d73588dad4a4d12a17d37354237b8c11a16aCorey Tabaka  const int ret = native_buffer_handle.Import(ion_buffer.get());
20599c2d73588dad4a4d12a17d37354237b8c11a16aCorey Tabaka  if (ret < 0) {
20699c2d73588dad4a4d12a17d37354237b8c11a16aCorey Tabaka    ALOGE(
20799c2d73588dad4a4d12a17d37354237b8c11a16aCorey Tabaka        "DisplayClient::GetGlobalBuffer: Failed to import global buffer: "
20899c2d73588dad4a4d12a17d37354237b8c11a16aCorey Tabaka        "key=%d; error=%s",
20999c2d73588dad4a4d12a17d37354237b8c11a16aCorey Tabaka        key, strerror(-ret));
21099c2d73588dad4a4d12a17d37354237b8c11a16aCorey Tabaka    return ErrorStatus(-ret);
21199c2d73588dad4a4d12a17d37354237b8c11a16aCorey Tabaka  }
21299c2d73588dad4a4d12a17d37354237b8c11a16aCorey Tabaka
21399c2d73588dad4a4d12a17d37354237b8c11a16aCorey Tabaka  return {std::move(ion_buffer)};
21499c2d73588dad4a4d12a17d37354237b8c11a16aCorey Tabaka}
21599c2d73588dad4a4d12a17d37354237b8c11a16aCorey Tabaka
21699c2d73588dad4a4d12a17d37354237b8c11a16aCorey Tabakapdx::Status<void> DisplayClient::DeleteGlobalBuffer(DvrGlobalBufferKey key) {
21799c2d73588dad4a4d12a17d37354237b8c11a16aCorey Tabaka  auto status = InvokeRemoteMethod<DisplayProtocol::DeleteGlobalBuffer>(key);
21899c2d73588dad4a4d12a17d37354237b8c11a16aCorey Tabaka  if (!status) {
21999c2d73588dad4a4d12a17d37354237b8c11a16aCorey Tabaka    ALOGE("DisplayClient::DeleteGlobalBuffer Failed: %s",
22099c2d73588dad4a4d12a17d37354237b8c11a16aCorey Tabaka          status.GetErrorMessage().c_str());
22199c2d73588dad4a4d12a17d37354237b8c11a16aCorey Tabaka  }
22299c2d73588dad4a4d12a17d37354237b8c11a16aCorey Tabaka
22399c2d73588dad4a4d12a17d37354237b8c11a16aCorey Tabaka  return status;
22499c2d73588dad4a4d12a17d37354237b8c11a16aCorey Tabaka}
22599c2d73588dad4a4d12a17d37354237b8c11a16aCorey Tabaka
22636d23803882c64b1006cd3b8a47e00a4193a9b49Okan ArikanStatus<std::unique_ptr<IonBuffer>> DisplayClient::GetGlobalBuffer(
22736d23803882c64b1006cd3b8a47e00a4193a9b49Okan Arikan    DvrGlobalBufferKey key) {
22836d23803882c64b1006cd3b8a47e00a4193a9b49Okan Arikan  auto status = InvokeRemoteMethod<DisplayProtocol::GetGlobalBuffer>(key);
22910e68eb8aa4db8b6f8cfbf2c3754e2677d7bf848Hendrik Wagenaar  if (!status) {
23010e68eb8aa4db8b6f8cfbf2c3754e2677d7bf848Hendrik Wagenaar    ALOGE(
23136d23803882c64b1006cd3b8a47e00a4193a9b49Okan Arikan        "DisplayClient::GetGlobalBuffer: Failed to get named buffer: key=%d; "
232eaa5522feac452703a0836310047d4b15702487dHendrik Wagenaar        "error=%s",
23336d23803882c64b1006cd3b8a47e00a4193a9b49Okan Arikan        key, status.GetErrorMessage().c_str());
2342251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    return status.error_status();
23510e68eb8aa4db8b6f8cfbf2c3754e2677d7bf848Hendrik Wagenaar  }
23610e68eb8aa4db8b6f8cfbf2c3754e2677d7bf848Hendrik Wagenaar
237eaa5522feac452703a0836310047d4b15702487dHendrik Wagenaar  auto ion_buffer = std::make_unique<IonBuffer>();
2382251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  auto native_buffer_handle = status.take();
2392251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  const int ret = native_buffer_handle.Import(ion_buffer.get());
2402251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  if (ret < 0) {
2412251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    ALOGE(
24236d23803882c64b1006cd3b8a47e00a4193a9b49Okan Arikan        "DisplayClient::GetGlobalBuffer: Failed to import global buffer: "
24336d23803882c64b1006cd3b8a47e00a4193a9b49Okan Arikan        "key=%d; error=%s",
24436d23803882c64b1006cd3b8a47e00a4193a9b49Okan Arikan        key, strerror(-ret));
2452251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka    return ErrorStatus(-ret);
2462251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  }
2472251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka
2482251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  return {std::move(ion_buffer)};
24910e68eb8aa4db8b6f8cfbf2c3754e2677d7bf848Hendrik Wagenaar}
25010e68eb8aa4db8b6f8cfbf2c3754e2677d7bf848Hendrik Wagenaar
2512251d822dac2a96aad4184a6fdc2690f0a58af7cCorey TabakaStatus<bool> DisplayClient::IsVrAppRunning() {
2522251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka  return InvokeRemoteMethod<DisplayProtocol::IsVrAppRunning>();
253b7c8a4bd8131ce18fb4ab4ee986c3b6b1ed27ad5Albert Chaulk}
25410e68eb8aa4db8b6f8cfbf2c3754e2677d7bf848Hendrik Wagenaar
2552251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka}  // namespace display
256e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}  // namespace dvr
257e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}  // namespace android
258