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 13using android::pdx::ErrorStatus; 14using android::pdx::LocalHandle; 15using android::pdx::LocalChannelHandle; 16using android::pdx::Status; 17using android::pdx::Transaction; 18using android::pdx::rpc::IfAnyOf; 19 20namespace android { 21namespace dvr { 22namespace display { 23 24Surface::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 41Surface::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 59Status<void> Surface::SetVisible(bool visible) { 60 return SetAttributes( 61 {{SurfaceAttribute::Visible, SurfaceAttributeValue{visible}}}); 62} 63 64Status<void> Surface::SetZOrder(int z_order) { 65 return SetAttributes( 66 {{SurfaceAttribute::ZOrder, SurfaceAttributeValue{z_order}}}); 67} 68 69Status<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 106Status<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 131Status<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 156DisplayClient::DisplayClient(int* error) 157 : BASE(pdx::default_transport::ClientChannelFactory::Create( 158 DisplayProtocol::kClientPath), 159 kInfiniteTimeout) { 160 if (error) 161 *error = Client::error(); 162} 163 164Status<Metrics> DisplayClient::GetDisplayMetrics() { 165 return InvokeRemoteMethod<DisplayProtocol::GetMetrics>(); 166} 167 168Status<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 181Status<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 190pdx::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 216pdx::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 226Status<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 251Status<bool> DisplayClient::IsVrAppRunning() { 252 return InvokeRemoteMethod<DisplayProtocol::IsVrAppRunning>(); 253} 254 255} // namespace display 256} // namespace dvr 257} // namespace android 258