1/* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <stdint.h> 18#include <sys/types.h> 19 20#include <utils/Errors.h> 21#include <utils/NativeHandle.h> 22 23#include <binder/Parcel.h> 24#include <binder/IInterface.h> 25 26#include <gui/BufferItem.h> 27#include <gui/IConsumerListener.h> 28#include <gui/IGraphicBufferConsumer.h> 29 30#include <ui/GraphicBuffer.h> 31#include <ui/Fence.h> 32 33#include <system/window.h> 34 35namespace android { 36 37enum { 38 ACQUIRE_BUFFER = IBinder::FIRST_CALL_TRANSACTION, 39 DETACH_BUFFER, 40 ATTACH_BUFFER, 41 RELEASE_BUFFER, 42 CONSUMER_CONNECT, 43 CONSUMER_DISCONNECT, 44 GET_RELEASED_BUFFERS, 45 SET_DEFAULT_BUFFER_SIZE, 46 SET_MAX_BUFFER_COUNT, 47 SET_MAX_ACQUIRED_BUFFER_COUNT, 48 SET_CONSUMER_NAME, 49 SET_DEFAULT_BUFFER_FORMAT, 50 SET_DEFAULT_BUFFER_DATA_SPACE, 51 SET_CONSUMER_USAGE_BITS, 52 SET_TRANSFORM_HINT, 53 GET_SIDEBAND_STREAM, 54 DUMP, 55}; 56 57 58class BpGraphicBufferConsumer : public BpInterface<IGraphicBufferConsumer> 59{ 60public: 61 BpGraphicBufferConsumer(const sp<IBinder>& impl) 62 : BpInterface<IGraphicBufferConsumer>(impl) 63 { 64 } 65 66 virtual ~BpGraphicBufferConsumer(); 67 68 virtual status_t acquireBuffer(BufferItem *buffer, nsecs_t presentWhen, 69 uint64_t maxFrameNumber) { 70 Parcel data, reply; 71 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 72 data.writeInt64(presentWhen); 73 data.writeUint64(maxFrameNumber); 74 status_t result = remote()->transact(ACQUIRE_BUFFER, data, &reply); 75 if (result != NO_ERROR) { 76 return result; 77 } 78 result = reply.read(*buffer); 79 if (result != NO_ERROR) { 80 return result; 81 } 82 return reply.readInt32(); 83 } 84 85 virtual status_t detachBuffer(int slot) { 86 Parcel data, reply; 87 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 88 data.writeInt32(slot); 89 status_t result = remote()->transact(DETACH_BUFFER, data, &reply); 90 if (result != NO_ERROR) { 91 return result; 92 } 93 result = reply.readInt32(); 94 return result; 95 } 96 97 virtual status_t attachBuffer(int* slot, const sp<GraphicBuffer>& buffer) { 98 Parcel data, reply; 99 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 100 data.write(*buffer.get()); 101 status_t result = remote()->transact(ATTACH_BUFFER, data, &reply); 102 if (result != NO_ERROR) { 103 return result; 104 } 105 *slot = reply.readInt32(); 106 result = reply.readInt32(); 107 return result; 108 } 109 110 virtual status_t releaseBuffer(int buf, uint64_t frameNumber, 111 EGLDisplay display __attribute__((unused)), EGLSyncKHR fence __attribute__((unused)), 112 const sp<Fence>& releaseFence) { 113 Parcel data, reply; 114 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 115 data.writeInt32(buf); 116 data.writeInt64(static_cast<int64_t>(frameNumber)); 117 data.write(*releaseFence); 118 status_t result = remote()->transact(RELEASE_BUFFER, data, &reply); 119 if (result != NO_ERROR) { 120 return result; 121 } 122 return reply.readInt32(); 123 } 124 125 virtual status_t consumerConnect(const sp<IConsumerListener>& consumer, bool controlledByApp) { 126 Parcel data, reply; 127 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 128 data.writeStrongBinder(IInterface::asBinder(consumer)); 129 data.writeInt32(controlledByApp); 130 status_t result = remote()->transact(CONSUMER_CONNECT, data, &reply); 131 if (result != NO_ERROR) { 132 return result; 133 } 134 return reply.readInt32(); 135 } 136 137 virtual status_t consumerDisconnect() { 138 Parcel data, reply; 139 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 140 status_t result = remote()->transact(CONSUMER_DISCONNECT, data, &reply); 141 if (result != NO_ERROR) { 142 return result; 143 } 144 return reply.readInt32(); 145 } 146 147 virtual status_t getReleasedBuffers(uint64_t* slotMask) { 148 Parcel data, reply; 149 if (slotMask == NULL) { 150 ALOGE("getReleasedBuffers: slotMask must not be NULL"); 151 return BAD_VALUE; 152 } 153 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 154 status_t result = remote()->transact(GET_RELEASED_BUFFERS, data, &reply); 155 if (result != NO_ERROR) { 156 return result; 157 } 158 *slotMask = static_cast<uint64_t>(reply.readInt64()); 159 return reply.readInt32(); 160 } 161 162 virtual status_t setDefaultBufferSize(uint32_t width, uint32_t height) { 163 Parcel data, reply; 164 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 165 data.writeUint32(width); 166 data.writeUint32(height); 167 status_t result = remote()->transact(SET_DEFAULT_BUFFER_SIZE, data, &reply); 168 if (result != NO_ERROR) { 169 return result; 170 } 171 return reply.readInt32(); 172 } 173 174 virtual status_t setMaxBufferCount(int bufferCount) { 175 Parcel data, reply; 176 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 177 data.writeInt32(bufferCount); 178 status_t result = remote()->transact(SET_MAX_BUFFER_COUNT, data, &reply); 179 if (result != NO_ERROR) { 180 return result; 181 } 182 return reply.readInt32(); 183 } 184 185 virtual status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers) { 186 Parcel data, reply; 187 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 188 data.writeInt32(maxAcquiredBuffers); 189 status_t result = remote()->transact(SET_MAX_ACQUIRED_BUFFER_COUNT, data, &reply); 190 if (result != NO_ERROR) { 191 return result; 192 } 193 return reply.readInt32(); 194 } 195 196 virtual void setConsumerName(const String8& name) { 197 Parcel data, reply; 198 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 199 data.writeString8(name); 200 remote()->transact(SET_CONSUMER_NAME, data, &reply); 201 } 202 203 virtual status_t setDefaultBufferFormat(PixelFormat defaultFormat) { 204 Parcel data, reply; 205 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 206 data.writeInt32(static_cast<int32_t>(defaultFormat)); 207 status_t result = remote()->transact(SET_DEFAULT_BUFFER_FORMAT, data, &reply); 208 if (result != NO_ERROR) { 209 return result; 210 } 211 return reply.readInt32(); 212 } 213 214 virtual status_t setDefaultBufferDataSpace( 215 android_dataspace defaultDataSpace) { 216 Parcel data, reply; 217 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 218 data.writeInt32(static_cast<int32_t>(defaultDataSpace)); 219 status_t result = remote()->transact(SET_DEFAULT_BUFFER_DATA_SPACE, 220 data, &reply); 221 if (result != NO_ERROR) { 222 return result; 223 } 224 return reply.readInt32(); 225 } 226 227 virtual status_t setConsumerUsageBits(uint32_t usage) { 228 Parcel data, reply; 229 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 230 data.writeUint32(usage); 231 status_t result = remote()->transact(SET_CONSUMER_USAGE_BITS, data, &reply); 232 if (result != NO_ERROR) { 233 return result; 234 } 235 return reply.readInt32(); 236 } 237 238 virtual status_t setTransformHint(uint32_t hint) { 239 Parcel data, reply; 240 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 241 data.writeUint32(hint); 242 status_t result = remote()->transact(SET_TRANSFORM_HINT, data, &reply); 243 if (result != NO_ERROR) { 244 return result; 245 } 246 return reply.readInt32(); 247 } 248 249 virtual sp<NativeHandle> getSidebandStream() const { 250 Parcel data, reply; 251 status_t err; 252 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 253 if ((err = remote()->transact(GET_SIDEBAND_STREAM, data, &reply)) != NO_ERROR) { 254 return NULL; 255 } 256 sp<NativeHandle> stream; 257 if (reply.readInt32()) { 258 stream = NativeHandle::create(reply.readNativeHandle(), true); 259 } 260 return stream; 261 } 262 263 virtual void dump(String8& result, const char* prefix) const { 264 Parcel data, reply; 265 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 266 data.writeString8(result); 267 data.writeString8(String8(prefix ? prefix : "")); 268 remote()->transact(DUMP, data, &reply); 269 reply.readString8(); 270 } 271}; 272 273// Out-of-line virtual method definition to trigger vtable emission in this 274// translation unit (see clang warning -Wweak-vtables) 275BpGraphicBufferConsumer::~BpGraphicBufferConsumer() {} 276 277IMPLEMENT_META_INTERFACE(GraphicBufferConsumer, "android.gui.IGraphicBufferConsumer"); 278 279// ---------------------------------------------------------------------- 280 281status_t BnGraphicBufferConsumer::onTransact( 282 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 283{ 284 switch(code) { 285 case ACQUIRE_BUFFER: { 286 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 287 BufferItem item; 288 int64_t presentWhen = data.readInt64(); 289 uint64_t maxFrameNumber = data.readUint64(); 290 status_t result = acquireBuffer(&item, presentWhen, maxFrameNumber); 291 status_t err = reply->write(item); 292 if (err) return err; 293 reply->writeInt32(result); 294 return NO_ERROR; 295 } 296 case DETACH_BUFFER: { 297 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 298 int slot = data.readInt32(); 299 int result = detachBuffer(slot); 300 reply->writeInt32(result); 301 return NO_ERROR; 302 } 303 case ATTACH_BUFFER: { 304 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 305 sp<GraphicBuffer> buffer = new GraphicBuffer(); 306 data.read(*buffer.get()); 307 int slot = -1; 308 int result = attachBuffer(&slot, buffer); 309 reply->writeInt32(slot); 310 reply->writeInt32(result); 311 return NO_ERROR; 312 } 313 case RELEASE_BUFFER: { 314 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 315 int buf = data.readInt32(); 316 uint64_t frameNumber = static_cast<uint64_t>(data.readInt64()); 317 sp<Fence> releaseFence = new Fence(); 318 status_t err = data.read(*releaseFence); 319 if (err) return err; 320 status_t result = releaseBuffer(buf, frameNumber, 321 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, releaseFence); 322 reply->writeInt32(result); 323 return NO_ERROR; 324 } 325 case CONSUMER_CONNECT: { 326 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 327 sp<IConsumerListener> consumer = IConsumerListener::asInterface( data.readStrongBinder() ); 328 bool controlledByApp = data.readInt32(); 329 status_t result = consumerConnect(consumer, controlledByApp); 330 reply->writeInt32(result); 331 return NO_ERROR; 332 } 333 case CONSUMER_DISCONNECT: { 334 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 335 status_t result = consumerDisconnect(); 336 reply->writeInt32(result); 337 return NO_ERROR; 338 } 339 case GET_RELEASED_BUFFERS: { 340 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 341 uint64_t slotMask = 0; 342 status_t result = getReleasedBuffers(&slotMask); 343 reply->writeInt64(static_cast<int64_t>(slotMask)); 344 reply->writeInt32(result); 345 return NO_ERROR; 346 } 347 case SET_DEFAULT_BUFFER_SIZE: { 348 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 349 uint32_t width = data.readUint32(); 350 uint32_t height = data.readUint32(); 351 status_t result = setDefaultBufferSize(width, height); 352 reply->writeInt32(result); 353 return NO_ERROR; 354 } 355 case SET_MAX_BUFFER_COUNT: { 356 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 357 int bufferCount = data.readInt32(); 358 status_t result = setMaxBufferCount(bufferCount); 359 reply->writeInt32(result); 360 return NO_ERROR; 361 } 362 case SET_MAX_ACQUIRED_BUFFER_COUNT: { 363 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 364 int maxAcquiredBuffers = data.readInt32(); 365 status_t result = setMaxAcquiredBufferCount(maxAcquiredBuffers); 366 reply->writeInt32(result); 367 return NO_ERROR; 368 } 369 case SET_CONSUMER_NAME: { 370 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 371 setConsumerName( data.readString8() ); 372 return NO_ERROR; 373 } 374 case SET_DEFAULT_BUFFER_FORMAT: { 375 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 376 PixelFormat defaultFormat = static_cast<PixelFormat>(data.readInt32()); 377 status_t result = setDefaultBufferFormat(defaultFormat); 378 reply->writeInt32(result); 379 return NO_ERROR; 380 } 381 case SET_DEFAULT_BUFFER_DATA_SPACE: { 382 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 383 android_dataspace defaultDataSpace = 384 static_cast<android_dataspace>(data.readInt32()); 385 status_t result = setDefaultBufferDataSpace(defaultDataSpace); 386 reply->writeInt32(result); 387 return NO_ERROR; 388 } 389 case SET_CONSUMER_USAGE_BITS: { 390 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 391 uint32_t usage = data.readUint32(); 392 status_t result = setConsumerUsageBits(usage); 393 reply->writeInt32(result); 394 return NO_ERROR; 395 } 396 case SET_TRANSFORM_HINT: { 397 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 398 uint32_t hint = data.readUint32(); 399 status_t result = setTransformHint(hint); 400 reply->writeInt32(result); 401 return NO_ERROR; 402 } 403 case GET_SIDEBAND_STREAM: { 404 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 405 sp<NativeHandle> stream = getSidebandStream(); 406 reply->writeInt32(static_cast<int32_t>(stream != NULL)); 407 if (stream != NULL) { 408 reply->writeNativeHandle(stream->handle()); 409 } 410 return NO_ERROR; 411 } 412 case DUMP: { 413 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 414 String8 result = data.readString8(); 415 String8 prefix = data.readString8(); 416 static_cast<IGraphicBufferConsumer*>(this)->dump(result, prefix); 417 reply->writeString8(result); 418 return NO_ERROR; 419 } 420 } 421 return BBinder::onTransact(code, data, reply, flags); 422} 423 424}; // namespace android 425