Home | History | Annotate | Download | only in libdisplay
      1 #include "include/private/dvr/display_client.h"
      2 
      3 #include <cutils/native_handle.h>
      4 #include <log/log.h>
      5 #include <pdx/default_transport/client_channel.h>
      6 #include <pdx/default_transport/client_channel_factory.h>
      7 #include <pdx/status.h>
      8 
      9 #include <mutex>
     10 
     11 #include <private/dvr/display_protocol.h>
     12 
     13 using android::pdx::ErrorStatus;
     14 using android::pdx::LocalHandle;
     15 using android::pdx::LocalChannelHandle;
     16 using android::pdx::Status;
     17 using android::pdx::Transaction;
     18 using android::pdx::rpc::IfAnyOf;
     19 
     20 namespace android {
     21 namespace dvr {
     22 namespace display {
     23 
     24 Surface::Surface(LocalChannelHandle channel_handle, int* error)
     25     : BASE{pdx::default_transport::ClientChannel::Create(
     26           std::move(channel_handle))} {
     27   auto status = InvokeRemoteMethod<DisplayProtocol::GetSurfaceInfo>();
     28   if (!status) {
     29     ALOGE("Surface::Surface: Failed to get surface info: %s",
     30           status.GetErrorMessage().c_str());
     31     Close(status.error());
     32     if (error)
     33       *error = status.error();
     34   }
     35 
     36   surface_id_ = status.get().surface_id;
     37   z_order_ = status.get().z_order;
     38   visible_ = status.get().visible;
     39 }
     40 
     41 Surface::Surface(const SurfaceAttributes& attributes, int* error)
     42     : BASE{pdx::default_transport::ClientChannelFactory::Create(
     43                DisplayProtocol::kClientPath),
     44            kInfiniteTimeout} {
     45   auto status = InvokeRemoteMethod<DisplayProtocol::CreateSurface>(attributes);
     46   if (!status) {
     47     ALOGE("Surface::Surface: Failed to create display surface: %s",
     48           status.GetErrorMessage().c_str());
     49     Close(status.error());
     50     if (error)
     51       *error = status.error();
     52   }
     53 
     54   surface_id_ = status.get().surface_id;
     55   z_order_ = status.get().z_order;
     56   visible_ = status.get().visible;
     57 }
     58 
     59 Status<void> Surface::SetVisible(bool visible) {
     60   return SetAttributes(
     61       {{SurfaceAttribute::Visible, SurfaceAttributeValue{visible}}});
     62 }
     63 
     64 Status<void> Surface::SetZOrder(int z_order) {
     65   return SetAttributes(
     66       {{SurfaceAttribute::ZOrder, SurfaceAttributeValue{z_order}}});
     67 }
     68 
     69 Status<void> Surface::SetAttributes(const SurfaceAttributes& attributes) {
     70   auto status = InvokeRemoteMethod<DisplayProtocol::SetAttributes>(attributes);
     71   if (!status) {
     72     ALOGE(
     73         "Surface::SetAttributes: Failed to set display surface "
     74         "attributes: %s",
     75         status.GetErrorMessage().c_str());
     76     return status.error_status();
     77   }
     78 
     79   // Set the local cached copies of the attributes we care about from the full
     80   // set of attributes sent to the display service.
     81   for (const auto& attribute : attributes) {
     82     const auto& key = attribute.first;
     83     const auto* variant = &attribute.second;
     84     bool invalid_value = false;
     85     switch (key) {
     86       case SurfaceAttribute::Visible:
     87         invalid_value =
     88             !IfAnyOf<int32_t, int64_t, bool>::Get(variant, &visible_);
     89         break;
     90       case SurfaceAttribute::ZOrder:
     91         invalid_value = !IfAnyOf<int32_t>::Get(variant, &z_order_);
     92         break;
     93     }
     94 
     95     if (invalid_value) {
     96       ALOGW(
     97           "Surface::SetAttributes: Failed to set display surface "
     98           "attribute %d because of incompatible type: %d",
     99           key, variant->index());
    100     }
    101   }
    102 
    103   return {};
    104 }
    105 
    106 Status<std::unique_ptr<ProducerQueue>> Surface::CreateQueue(
    107     uint32_t width, uint32_t height, uint32_t format, size_t metadata_size) {
    108   ALOGD_IF(TRACE, "Surface::CreateQueue: Creating empty queue.");
    109   auto status = InvokeRemoteMethod<DisplayProtocol::CreateQueue>(
    110       ProducerQueueConfigBuilder()
    111           .SetDefaultWidth(width)
    112           .SetDefaultHeight(height)
    113           .SetDefaultFormat(format)
    114           .SetMetadataSize(metadata_size)
    115           .Build());
    116   if (!status) {
    117     ALOGE("Surface::CreateQueue: Failed to create queue: %s",
    118           status.GetErrorMessage().c_str());
    119     return status.error_status();
    120   }
    121 
    122   auto producer_queue = ProducerQueue::Import(status.take());
    123   if (!producer_queue) {
    124     ALOGE("Surface::CreateQueue: Failed to import producer queue!");
    125     return ErrorStatus(ENOMEM);
    126   }
    127 
    128   return {std::move(producer_queue)};
    129 }
    130 
    131 Status<std::unique_ptr<ProducerQueue>> Surface::CreateQueue(
    132     uint32_t width, uint32_t height, uint32_t layer_count, uint32_t format,
    133     uint64_t usage, size_t capacity, size_t metadata_size) {
    134   ALOGD_IF(TRACE,
    135            "Surface::CreateQueue: width=%u height=%u layer_count=%u format=%u "
    136            "usage=%" PRIx64 " capacity=%zu",
    137            width, height, layer_count, format, usage, capacity);
    138   auto status = CreateQueue(width, height, format, metadata_size);
    139   if (!status)
    140     return status.error_status();
    141 
    142   auto producer_queue = status.take();
    143 
    144   ALOGD_IF(TRACE, "Surface::CreateQueue: Allocating %zu buffers...", capacity);
    145   auto allocate_status = producer_queue->AllocateBuffers(
    146       width, height, layer_count, format, usage, capacity);
    147   if (!allocate_status) {
    148     ALOGE("Surface::CreateQueue: Failed to allocate buffer on queue_id=%d: %s",
    149           producer_queue->id(), allocate_status.GetErrorMessage().c_str());
    150     return allocate_status.error_status();
    151   }
    152 
    153   return {std::move(producer_queue)};
    154 }
    155 
    156 DisplayClient::DisplayClient(int* error)
    157     : BASE(pdx::default_transport::ClientChannelFactory::Create(
    158                DisplayProtocol::kClientPath),
    159            kInfiniteTimeout) {
    160   if (error)
    161     *error = Client::error();
    162 }
    163 
    164 Status<Metrics> DisplayClient::GetDisplayMetrics() {
    165   return InvokeRemoteMethod<DisplayProtocol::GetMetrics>();
    166 }
    167 
    168 Status<std::string> DisplayClient::GetConfigurationData(
    169     ConfigFileType config_type) {
    170   auto status =
    171       InvokeRemoteMethod<DisplayProtocol::GetConfigurationData>(config_type);
    172   if (!status && status.error() != ENOENT) {
    173     ALOGE(
    174         "DisplayClient::GetConfigurationData: Unable to get"
    175         "configuration data. Error: %s",
    176         status.GetErrorMessage().c_str());
    177   }
    178   return status;
    179 }
    180 
    181 Status<std::unique_ptr<Surface>> DisplayClient::CreateSurface(
    182     const SurfaceAttributes& attributes) {
    183   int error;
    184   if (auto client = Surface::Create(attributes, &error))
    185     return {std::move(client)};
    186   else
    187     return ErrorStatus(error);
    188 }
    189 
    190 pdx::Status<std::unique_ptr<IonBuffer>> DisplayClient::SetupGlobalBuffer(
    191     DvrGlobalBufferKey key, size_t size, uint64_t usage) {
    192   auto status =
    193       InvokeRemoteMethod<DisplayProtocol::SetupGlobalBuffer>(key, size, usage);
    194   if (!status) {
    195     ALOGE(
    196         "DisplayClient::SetupGlobalBuffer: Failed to create the global buffer "
    197         "%s",
    198         status.GetErrorMessage().c_str());
    199     return status.error_status();
    200   }
    201 
    202   auto ion_buffer = std::make_unique<IonBuffer>();
    203   auto native_buffer_handle = status.take();
    204   const int ret = native_buffer_handle.Import(ion_buffer.get());
    205   if (ret < 0) {
    206     ALOGE(
    207         "DisplayClient::GetGlobalBuffer: Failed to import global buffer: "
    208         "key=%d; error=%s",
    209         key, strerror(-ret));
    210     return ErrorStatus(-ret);
    211   }
    212 
    213   return {std::move(ion_buffer)};
    214 }
    215 
    216 pdx::Status<void> DisplayClient::DeleteGlobalBuffer(DvrGlobalBufferKey key) {
    217   auto status = InvokeRemoteMethod<DisplayProtocol::DeleteGlobalBuffer>(key);
    218   if (!status) {
    219     ALOGE("DisplayClient::DeleteGlobalBuffer Failed: %s",
    220           status.GetErrorMessage().c_str());
    221   }
    222 
    223   return status;
    224 }
    225 
    226 Status<std::unique_ptr<IonBuffer>> DisplayClient::GetGlobalBuffer(
    227     DvrGlobalBufferKey key) {
    228   auto status = InvokeRemoteMethod<DisplayProtocol::GetGlobalBuffer>(key);
    229   if (!status) {
    230     ALOGE(
    231         "DisplayClient::GetGlobalBuffer: Failed to get named buffer: key=%d; "
    232         "error=%s",
    233         key, status.GetErrorMessage().c_str());
    234     return status.error_status();
    235   }
    236 
    237   auto ion_buffer = std::make_unique<IonBuffer>();
    238   auto native_buffer_handle = status.take();
    239   const int ret = native_buffer_handle.Import(ion_buffer.get());
    240   if (ret < 0) {
    241     ALOGE(
    242         "DisplayClient::GetGlobalBuffer: Failed to import global buffer: "
    243         "key=%d; error=%s",
    244         key, strerror(-ret));
    245     return ErrorStatus(-ret);
    246   }
    247 
    248   return {std::move(ion_buffer)};
    249 }
    250 
    251 Status<bool> DisplayClient::IsVrAppRunning() {
    252   return InvokeRemoteMethod<DisplayProtocol::IsVrAppRunning>();
    253 }
    254 
    255 }  // namespace display
    256 }  // namespace dvr
    257 }  // namespace android
    258