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 35 namespace android { 36 37 enum { 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_DEFAULT_MAX_BUFFER_COUNT, 47 DISABLE_ASYNC_BUFFER, 48 SET_MAX_ACQUIRED_BUFFER_COUNT, 49 SET_CONSUMER_NAME, 50 SET_DEFAULT_BUFFER_FORMAT, 51 SET_DEFAULT_BUFFER_DATA_SPACE, 52 SET_CONSUMER_USAGE_BITS, 53 SET_TRANSFORM_HINT, 54 GET_SIDEBAND_STREAM, 55 DUMP, 56 }; 57 58 59 class BpGraphicBufferConsumer : public BpInterface<IGraphicBufferConsumer> 60 { 61 public: 62 BpGraphicBufferConsumer(const sp<IBinder>& impl) 63 : BpInterface<IGraphicBufferConsumer>(impl) 64 { 65 } 66 67 virtual ~BpGraphicBufferConsumer(); 68 69 virtual status_t acquireBuffer(BufferItem *buffer, nsecs_t presentWhen, 70 uint64_t maxFrameNumber) { 71 Parcel data, reply; 72 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 73 data.writeInt64(presentWhen); 74 data.writeUint64(maxFrameNumber); 75 status_t result = remote()->transact(ACQUIRE_BUFFER, data, &reply); 76 if (result != NO_ERROR) { 77 return result; 78 } 79 result = reply.read(*buffer); 80 if (result != NO_ERROR) { 81 return result; 82 } 83 return reply.readInt32(); 84 } 85 86 virtual status_t detachBuffer(int slot) { 87 Parcel data, reply; 88 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 89 data.writeInt32(slot); 90 status_t result = remote()->transact(DETACH_BUFFER, data, &reply); 91 if (result != NO_ERROR) { 92 return result; 93 } 94 result = reply.readInt32(); 95 return result; 96 } 97 98 virtual status_t attachBuffer(int* slot, const sp<GraphicBuffer>& buffer) { 99 Parcel data, reply; 100 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 101 data.write(*buffer.get()); 102 status_t result = remote()->transact(ATTACH_BUFFER, data, &reply); 103 if (result != NO_ERROR) { 104 return result; 105 } 106 *slot = reply.readInt32(); 107 result = reply.readInt32(); 108 return result; 109 } 110 111 virtual status_t releaseBuffer(int buf, uint64_t frameNumber, 112 EGLDisplay display __attribute__((unused)), EGLSyncKHR fence __attribute__((unused)), 113 const sp<Fence>& releaseFence) { 114 Parcel data, reply; 115 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 116 data.writeInt32(buf); 117 data.writeInt64(static_cast<int64_t>(frameNumber)); 118 data.write(*releaseFence); 119 status_t result = remote()->transact(RELEASE_BUFFER, data, &reply); 120 if (result != NO_ERROR) { 121 return result; 122 } 123 return reply.readInt32(); 124 } 125 126 virtual status_t consumerConnect(const sp<IConsumerListener>& consumer, bool controlledByApp) { 127 Parcel data, reply; 128 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 129 data.writeStrongBinder(IInterface::asBinder(consumer)); 130 data.writeInt32(controlledByApp); 131 status_t result = remote()->transact(CONSUMER_CONNECT, data, &reply); 132 if (result != NO_ERROR) { 133 return result; 134 } 135 return reply.readInt32(); 136 } 137 138 virtual status_t consumerDisconnect() { 139 Parcel data, reply; 140 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 141 status_t result = remote()->transact(CONSUMER_DISCONNECT, data, &reply); 142 if (result != NO_ERROR) { 143 return result; 144 } 145 return reply.readInt32(); 146 } 147 148 virtual status_t getReleasedBuffers(uint64_t* slotMask) { 149 Parcel data, reply; 150 if (slotMask == NULL) { 151 ALOGE("getReleasedBuffers: slotMask must not be NULL"); 152 return BAD_VALUE; 153 } 154 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 155 status_t result = remote()->transact(GET_RELEASED_BUFFERS, data, &reply); 156 if (result != NO_ERROR) { 157 return result; 158 } 159 *slotMask = static_cast<uint64_t>(reply.readInt64()); 160 return reply.readInt32(); 161 } 162 163 virtual status_t setDefaultBufferSize(uint32_t width, uint32_t height) { 164 Parcel data, reply; 165 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 166 data.writeUint32(width); 167 data.writeUint32(height); 168 status_t result = remote()->transact(SET_DEFAULT_BUFFER_SIZE, data, &reply); 169 if (result != NO_ERROR) { 170 return result; 171 } 172 return reply.readInt32(); 173 } 174 175 virtual status_t setDefaultMaxBufferCount(int bufferCount) { 176 Parcel data, reply; 177 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 178 data.writeInt32(bufferCount); 179 status_t result = remote()->transact(SET_DEFAULT_MAX_BUFFER_COUNT, data, &reply); 180 if (result != NO_ERROR) { 181 return result; 182 } 183 return reply.readInt32(); 184 } 185 186 virtual status_t disableAsyncBuffer() { 187 Parcel data, reply; 188 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 189 status_t result = remote()->transact(DISABLE_ASYNC_BUFFER, data, &reply); 190 if (result != NO_ERROR) { 191 return result; 192 } 193 return reply.readInt32(); 194 } 195 196 virtual status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers) { 197 Parcel data, reply; 198 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 199 data.writeInt32(maxAcquiredBuffers); 200 status_t result = remote()->transact(SET_MAX_ACQUIRED_BUFFER_COUNT, data, &reply); 201 if (result != NO_ERROR) { 202 return result; 203 } 204 return reply.readInt32(); 205 } 206 207 virtual void setConsumerName(const String8& name) { 208 Parcel data, reply; 209 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 210 data.writeString8(name); 211 remote()->transact(SET_CONSUMER_NAME, data, &reply); 212 } 213 214 virtual status_t setDefaultBufferFormat(PixelFormat defaultFormat) { 215 Parcel data, reply; 216 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 217 data.writeInt32(static_cast<int32_t>(defaultFormat)); 218 status_t result = remote()->transact(SET_DEFAULT_BUFFER_FORMAT, data, &reply); 219 if (result != NO_ERROR) { 220 return result; 221 } 222 return reply.readInt32(); 223 } 224 225 virtual status_t setDefaultBufferDataSpace( 226 android_dataspace defaultDataSpace) { 227 Parcel data, reply; 228 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 229 data.writeInt32(static_cast<int32_t>(defaultDataSpace)); 230 status_t result = remote()->transact(SET_DEFAULT_BUFFER_DATA_SPACE, 231 data, &reply); 232 if (result != NO_ERROR) { 233 return result; 234 } 235 return reply.readInt32(); 236 } 237 238 virtual status_t setConsumerUsageBits(uint32_t usage) { 239 Parcel data, reply; 240 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 241 data.writeUint32(usage); 242 status_t result = remote()->transact(SET_CONSUMER_USAGE_BITS, data, &reply); 243 if (result != NO_ERROR) { 244 return result; 245 } 246 return reply.readInt32(); 247 } 248 249 virtual status_t setTransformHint(uint32_t hint) { 250 Parcel data, reply; 251 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 252 data.writeUint32(hint); 253 status_t result = remote()->transact(SET_TRANSFORM_HINT, data, &reply); 254 if (result != NO_ERROR) { 255 return result; 256 } 257 return reply.readInt32(); 258 } 259 260 virtual sp<NativeHandle> getSidebandStream() const { 261 Parcel data, reply; 262 status_t err; 263 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 264 if ((err = remote()->transact(GET_SIDEBAND_STREAM, data, &reply)) != NO_ERROR) { 265 return NULL; 266 } 267 sp<NativeHandle> stream; 268 if (reply.readInt32()) { 269 stream = NativeHandle::create(reply.readNativeHandle(), true); 270 } 271 return stream; 272 } 273 274 virtual void dump(String8& result, const char* prefix) const { 275 Parcel data, reply; 276 data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor()); 277 data.writeString8(result); 278 data.writeString8(String8(prefix ? prefix : "")); 279 remote()->transact(DUMP, data, &reply); 280 reply.readString8(); 281 } 282 }; 283 284 // Out-of-line virtual method definition to trigger vtable emission in this 285 // translation unit (see clang warning -Wweak-vtables) 286 BpGraphicBufferConsumer::~BpGraphicBufferConsumer() {} 287 288 IMPLEMENT_META_INTERFACE(GraphicBufferConsumer, "android.gui.IGraphicBufferConsumer"); 289 290 // ---------------------------------------------------------------------- 291 292 status_t BnGraphicBufferConsumer::onTransact( 293 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 294 { 295 switch(code) { 296 case ACQUIRE_BUFFER: { 297 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 298 BufferItem item; 299 int64_t presentWhen = data.readInt64(); 300 uint64_t maxFrameNumber = data.readUint64(); 301 status_t result = acquireBuffer(&item, presentWhen, maxFrameNumber); 302 status_t err = reply->write(item); 303 if (err) return err; 304 reply->writeInt32(result); 305 return NO_ERROR; 306 } 307 case DETACH_BUFFER: { 308 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 309 int slot = data.readInt32(); 310 int result = detachBuffer(slot); 311 reply->writeInt32(result); 312 return NO_ERROR; 313 } 314 case ATTACH_BUFFER: { 315 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 316 sp<GraphicBuffer> buffer = new GraphicBuffer(); 317 data.read(*buffer.get()); 318 int slot; 319 int result = attachBuffer(&slot, buffer); 320 reply->writeInt32(slot); 321 reply->writeInt32(result); 322 return NO_ERROR; 323 } 324 case RELEASE_BUFFER: { 325 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 326 int buf = data.readInt32(); 327 uint64_t frameNumber = static_cast<uint64_t>(data.readInt64()); 328 sp<Fence> releaseFence = new Fence(); 329 status_t err = data.read(*releaseFence); 330 if (err) return err; 331 status_t result = releaseBuffer(buf, frameNumber, 332 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, releaseFence); 333 reply->writeInt32(result); 334 return NO_ERROR; 335 } 336 case CONSUMER_CONNECT: { 337 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 338 sp<IConsumerListener> consumer = IConsumerListener::asInterface( data.readStrongBinder() ); 339 bool controlledByApp = data.readInt32(); 340 status_t result = consumerConnect(consumer, controlledByApp); 341 reply->writeInt32(result); 342 return NO_ERROR; 343 } 344 case CONSUMER_DISCONNECT: { 345 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 346 status_t result = consumerDisconnect(); 347 reply->writeInt32(result); 348 return NO_ERROR; 349 } 350 case GET_RELEASED_BUFFERS: { 351 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 352 uint64_t slotMask; 353 status_t result = getReleasedBuffers(&slotMask); 354 reply->writeInt64(static_cast<int64_t>(slotMask)); 355 reply->writeInt32(result); 356 return NO_ERROR; 357 } 358 case SET_DEFAULT_BUFFER_SIZE: { 359 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 360 uint32_t width = data.readUint32(); 361 uint32_t height = data.readUint32(); 362 status_t result = setDefaultBufferSize(width, height); 363 reply->writeInt32(result); 364 return NO_ERROR; 365 } 366 case SET_DEFAULT_MAX_BUFFER_COUNT: { 367 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 368 int bufferCount = data.readInt32(); 369 status_t result = setDefaultMaxBufferCount(bufferCount); 370 reply->writeInt32(result); 371 return NO_ERROR; 372 } 373 case DISABLE_ASYNC_BUFFER: { 374 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 375 status_t result = disableAsyncBuffer(); 376 reply->writeInt32(result); 377 return NO_ERROR; 378 } 379 case SET_MAX_ACQUIRED_BUFFER_COUNT: { 380 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 381 int maxAcquiredBuffers = data.readInt32(); 382 status_t result = setMaxAcquiredBufferCount(maxAcquiredBuffers); 383 reply->writeInt32(result); 384 return NO_ERROR; 385 } 386 case SET_CONSUMER_NAME: { 387 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 388 setConsumerName( data.readString8() ); 389 return NO_ERROR; 390 } 391 case SET_DEFAULT_BUFFER_FORMAT: { 392 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 393 PixelFormat defaultFormat = static_cast<PixelFormat>(data.readInt32()); 394 status_t result = setDefaultBufferFormat(defaultFormat); 395 reply->writeInt32(result); 396 return NO_ERROR; 397 } 398 case SET_DEFAULT_BUFFER_DATA_SPACE: { 399 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 400 android_dataspace defaultDataSpace = 401 static_cast<android_dataspace>(data.readInt32()); 402 status_t result = setDefaultBufferDataSpace(defaultDataSpace); 403 reply->writeInt32(result); 404 return NO_ERROR; 405 } 406 case SET_CONSUMER_USAGE_BITS: { 407 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 408 uint32_t usage = data.readUint32(); 409 status_t result = setConsumerUsageBits(usage); 410 reply->writeInt32(result); 411 return NO_ERROR; 412 } 413 case SET_TRANSFORM_HINT: { 414 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 415 uint32_t hint = data.readUint32(); 416 status_t result = setTransformHint(hint); 417 reply->writeInt32(result); 418 return NO_ERROR; 419 } 420 case GET_SIDEBAND_STREAM: { 421 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 422 sp<NativeHandle> stream = getSidebandStream(); 423 reply->writeInt32(static_cast<int32_t>(stream != NULL)); 424 if (stream != NULL) { 425 reply->writeNativeHandle(stream->handle()); 426 } 427 return NO_ERROR; 428 } 429 case DUMP: { 430 CHECK_INTERFACE(IGraphicBufferConsumer, data, reply); 431 String8 result = data.readString8(); 432 String8 prefix = data.readString8(); 433 static_cast<IGraphicBufferConsumer*>(this)->dump(result, prefix); 434 reply->writeString8(result); 435 return NO_ERROR; 436 } 437 } 438 return BBinder::onTransact(code, data, reply, flags); 439 } 440 441 }; // namespace android 442