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