1/* 2 * Copyright (C) 2007 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// tag as surfaceflinger 18#define LOG_TAG "SurfaceFlinger" 19 20#include <stdint.h> 21#include <sys/types.h> 22 23#include <binder/Parcel.h> 24#include <binder/IMemory.h> 25#include <binder/IPCThreadState.h> 26#include <binder/IServiceManager.h> 27 28#include <gui/BitTube.h> 29#include <gui/IDisplayEventConnection.h> 30#include <gui/ISurfaceComposer.h> 31#include <gui/IGraphicBufferProducer.h> 32 33#include <private/gui/LayerState.h> 34 35#include <system/graphics.h> 36 37#include <ui/DisplayInfo.h> 38#include <ui/DisplayStatInfo.h> 39#include <ui/HdrCapabilities.h> 40 41#include <utils/Log.h> 42 43// --------------------------------------------------------------------------- 44 45namespace android { 46 47class IDisplayEventConnection; 48 49class BpSurfaceComposer : public BpInterface<ISurfaceComposer> 50{ 51public: 52 BpSurfaceComposer(const sp<IBinder>& impl) 53 : BpInterface<ISurfaceComposer>(impl) 54 { 55 } 56 57 virtual ~BpSurfaceComposer(); 58 59 virtual sp<ISurfaceComposerClient> createConnection() 60 { 61 Parcel data, reply; 62 data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); 63 remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, &reply); 64 return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder()); 65 } 66 67 virtual sp<IGraphicBufferAlloc> createGraphicBufferAlloc() 68 { 69 Parcel data, reply; 70 data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); 71 remote()->transact(BnSurfaceComposer::CREATE_GRAPHIC_BUFFER_ALLOC, data, &reply); 72 return interface_cast<IGraphicBufferAlloc>(reply.readStrongBinder()); 73 } 74 75 virtual void setTransactionState( 76 const Vector<ComposerState>& state, 77 const Vector<DisplayState>& displays, 78 uint32_t flags) 79 { 80 Parcel data, reply; 81 data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); 82 83 data.writeUint32(static_cast<uint32_t>(state.size())); 84 for (const auto& s : state) { 85 s.write(data); 86 } 87 88 data.writeUint32(static_cast<uint32_t>(displays.size())); 89 for (const auto& d : displays) { 90 d.write(data); 91 } 92 93 data.writeUint32(flags); 94 remote()->transact(BnSurfaceComposer::SET_TRANSACTION_STATE, data, &reply); 95 } 96 97 virtual void bootFinished() 98 { 99 Parcel data, reply; 100 data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); 101 remote()->transact(BnSurfaceComposer::BOOT_FINISHED, data, &reply); 102 } 103 104 virtual status_t captureScreen(const sp<IBinder>& display, 105 const sp<IGraphicBufferProducer>& producer, 106 Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, 107 uint32_t minLayerZ, uint32_t maxLayerZ, 108 bool useIdentityTransform, 109 ISurfaceComposer::Rotation rotation) 110 { 111 Parcel data, reply; 112 data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); 113 data.writeStrongBinder(display); 114 data.writeStrongBinder(IInterface::asBinder(producer)); 115 data.write(sourceCrop); 116 data.writeUint32(reqWidth); 117 data.writeUint32(reqHeight); 118 data.writeUint32(minLayerZ); 119 data.writeUint32(maxLayerZ); 120 data.writeInt32(static_cast<int32_t>(useIdentityTransform)); 121 data.writeInt32(static_cast<int32_t>(rotation)); 122 remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply); 123 return reply.readInt32(); 124 } 125 126 virtual bool authenticateSurfaceTexture( 127 const sp<IGraphicBufferProducer>& bufferProducer) const 128 { 129 Parcel data, reply; 130 int err = NO_ERROR; 131 err = data.writeInterfaceToken( 132 ISurfaceComposer::getInterfaceDescriptor()); 133 if (err != NO_ERROR) { 134 ALOGE("ISurfaceComposer::authenticateSurfaceTexture: error writing " 135 "interface descriptor: %s (%d)", strerror(-err), -err); 136 return false; 137 } 138 err = data.writeStrongBinder(IInterface::asBinder(bufferProducer)); 139 if (err != NO_ERROR) { 140 ALOGE("ISurfaceComposer::authenticateSurfaceTexture: error writing " 141 "strong binder to parcel: %s (%d)", strerror(-err), -err); 142 return false; 143 } 144 err = remote()->transact(BnSurfaceComposer::AUTHENTICATE_SURFACE, data, 145 &reply); 146 if (err != NO_ERROR) { 147 ALOGE("ISurfaceComposer::authenticateSurfaceTexture: error " 148 "performing transaction: %s (%d)", strerror(-err), -err); 149 return false; 150 } 151 int32_t result = 0; 152 err = reply.readInt32(&result); 153 if (err != NO_ERROR) { 154 ALOGE("ISurfaceComposer::authenticateSurfaceTexture: error " 155 "retrieving result: %s (%d)", strerror(-err), -err); 156 return false; 157 } 158 return result != 0; 159 } 160 161 virtual sp<IDisplayEventConnection> createDisplayEventConnection() 162 { 163 Parcel data, reply; 164 sp<IDisplayEventConnection> result; 165 int err = data.writeInterfaceToken( 166 ISurfaceComposer::getInterfaceDescriptor()); 167 if (err != NO_ERROR) { 168 return result; 169 } 170 err = remote()->transact( 171 BnSurfaceComposer::CREATE_DISPLAY_EVENT_CONNECTION, 172 data, &reply); 173 if (err != NO_ERROR) { 174 ALOGE("ISurfaceComposer::createDisplayEventConnection: error performing " 175 "transaction: %s (%d)", strerror(-err), -err); 176 return result; 177 } 178 result = interface_cast<IDisplayEventConnection>(reply.readStrongBinder()); 179 return result; 180 } 181 182 virtual sp<IBinder> createDisplay(const String8& displayName, bool secure) 183 { 184 Parcel data, reply; 185 data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); 186 data.writeString8(displayName); 187 data.writeInt32(secure ? 1 : 0); 188 remote()->transact(BnSurfaceComposer::CREATE_DISPLAY, data, &reply); 189 return reply.readStrongBinder(); 190 } 191 192 virtual void destroyDisplay(const sp<IBinder>& display) 193 { 194 Parcel data, reply; 195 data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); 196 data.writeStrongBinder(display); 197 remote()->transact(BnSurfaceComposer::DESTROY_DISPLAY, data, &reply); 198 } 199 200 virtual sp<IBinder> getBuiltInDisplay(int32_t id) 201 { 202 Parcel data, reply; 203 data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); 204 data.writeInt32(id); 205 remote()->transact(BnSurfaceComposer::GET_BUILT_IN_DISPLAY, data, &reply); 206 return reply.readStrongBinder(); 207 } 208 209 virtual void setPowerMode(const sp<IBinder>& display, int mode) 210 { 211 Parcel data, reply; 212 data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); 213 data.writeStrongBinder(display); 214 data.writeInt32(mode); 215 remote()->transact(BnSurfaceComposer::SET_POWER_MODE, data, &reply); 216 } 217 218 virtual status_t getDisplayConfigs(const sp<IBinder>& display, 219 Vector<DisplayInfo>* configs) 220 { 221 Parcel data, reply; 222 data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); 223 data.writeStrongBinder(display); 224 remote()->transact(BnSurfaceComposer::GET_DISPLAY_CONFIGS, data, &reply); 225 status_t result = reply.readInt32(); 226 if (result == NO_ERROR) { 227 size_t numConfigs = reply.readUint32(); 228 configs->clear(); 229 configs->resize(numConfigs); 230 for (size_t c = 0; c < numConfigs; ++c) { 231 memcpy(&(configs->editItemAt(c)), 232 reply.readInplace(sizeof(DisplayInfo)), 233 sizeof(DisplayInfo)); 234 } 235 } 236 return result; 237 } 238 239 virtual status_t getDisplayStats(const sp<IBinder>& display, 240 DisplayStatInfo* stats) 241 { 242 Parcel data, reply; 243 data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); 244 data.writeStrongBinder(display); 245 remote()->transact(BnSurfaceComposer::GET_DISPLAY_STATS, data, &reply); 246 status_t result = reply.readInt32(); 247 if (result == NO_ERROR) { 248 memcpy(stats, 249 reply.readInplace(sizeof(DisplayStatInfo)), 250 sizeof(DisplayStatInfo)); 251 } 252 return result; 253 } 254 255 virtual int getActiveConfig(const sp<IBinder>& display) 256 { 257 Parcel data, reply; 258 data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); 259 data.writeStrongBinder(display); 260 remote()->transact(BnSurfaceComposer::GET_ACTIVE_CONFIG, data, &reply); 261 return reply.readInt32(); 262 } 263 264 virtual status_t setActiveConfig(const sp<IBinder>& display, int id) 265 { 266 Parcel data, reply; 267 data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); 268 data.writeStrongBinder(display); 269 data.writeInt32(id); 270 remote()->transact(BnSurfaceComposer::SET_ACTIVE_CONFIG, data, &reply); 271 return reply.readInt32(); 272 } 273 274 virtual status_t getDisplayColorModes(const sp<IBinder>& display, 275 Vector<android_color_mode_t>* outColorModes) { 276 Parcel data, reply; 277 status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); 278 if (result != NO_ERROR) { 279 ALOGE("getDisplayColorModes failed to writeInterfaceToken: %d", result); 280 return result; 281 } 282 result = data.writeStrongBinder(display); 283 if (result != NO_ERROR) { 284 ALOGE("getDisplayColorModes failed to writeStrongBinder: %d", result); 285 return result; 286 } 287 result = remote()->transact(BnSurfaceComposer::GET_DISPLAY_COLOR_MODES, data, &reply); 288 if (result != NO_ERROR) { 289 ALOGE("getDisplayColorModes failed to transact: %d", result); 290 return result; 291 } 292 result = static_cast<status_t>(reply.readInt32()); 293 if (result == NO_ERROR) { 294 size_t numModes = reply.readUint32(); 295 outColorModes->clear(); 296 outColorModes->resize(numModes); 297 for (size_t i = 0; i < numModes; ++i) { 298 outColorModes->replaceAt(static_cast<android_color_mode_t>(reply.readInt32()), i); 299 } 300 } 301 return result; 302 } 303 304 virtual android_color_mode_t getActiveColorMode(const sp<IBinder>& display) { 305 Parcel data, reply; 306 status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); 307 if (result != NO_ERROR) { 308 ALOGE("getActiveColorMode failed to writeInterfaceToken: %d", result); 309 return static_cast<android_color_mode_t>(result); 310 } 311 result = data.writeStrongBinder(display); 312 if (result != NO_ERROR) { 313 ALOGE("getActiveColorMode failed to writeStrongBinder: %d", result); 314 return static_cast<android_color_mode_t>(result); 315 } 316 result = remote()->transact(BnSurfaceComposer::GET_ACTIVE_COLOR_MODE, data, &reply); 317 if (result != NO_ERROR) { 318 ALOGE("getActiveColorMode failed to transact: %d", result); 319 return static_cast<android_color_mode_t>(result); 320 } 321 return static_cast<android_color_mode_t>(reply.readInt32()); 322 } 323 324 virtual status_t setActiveColorMode(const sp<IBinder>& display, 325 android_color_mode_t colorMode) { 326 Parcel data, reply; 327 status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); 328 if (result != NO_ERROR) { 329 ALOGE("setActiveColorMode failed to writeInterfaceToken: %d", result); 330 return result; 331 } 332 result = data.writeStrongBinder(display); 333 if (result != NO_ERROR) { 334 ALOGE("setActiveColorMode failed to writeStrongBinder: %d", result); 335 return result; 336 } 337 result = data.writeInt32(colorMode); 338 if (result != NO_ERROR) { 339 ALOGE("setActiveColorMode failed to writeInt32: %d", result); 340 return result; 341 } 342 result = remote()->transact(BnSurfaceComposer::SET_ACTIVE_COLOR_MODE, data, &reply); 343 if (result != NO_ERROR) { 344 ALOGE("setActiveColorMode failed to transact: %d", result); 345 return result; 346 } 347 return static_cast<status_t>(reply.readInt32()); 348 } 349 350 virtual status_t clearAnimationFrameStats() { 351 Parcel data, reply; 352 data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); 353 remote()->transact(BnSurfaceComposer::CLEAR_ANIMATION_FRAME_STATS, data, &reply); 354 return reply.readInt32(); 355 } 356 357 virtual status_t getAnimationFrameStats(FrameStats* outStats) const { 358 Parcel data, reply; 359 data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); 360 remote()->transact(BnSurfaceComposer::GET_ANIMATION_FRAME_STATS, data, &reply); 361 reply.read(*outStats); 362 return reply.readInt32(); 363 } 364 365 virtual status_t getHdrCapabilities(const sp<IBinder>& display, 366 HdrCapabilities* outCapabilities) const { 367 Parcel data, reply; 368 data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); 369 status_t result = data.writeStrongBinder(display); 370 if (result != NO_ERROR) { 371 ALOGE("getHdrCapabilities failed to writeStrongBinder: %d", result); 372 return result; 373 } 374 result = remote()->transact(BnSurfaceComposer::GET_HDR_CAPABILITIES, 375 data, &reply); 376 if (result != NO_ERROR) { 377 ALOGE("getHdrCapabilities failed to transact: %d", result); 378 return result; 379 } 380 result = reply.readInt32(); 381 if (result == NO_ERROR) { 382 result = reply.readParcelable(outCapabilities); 383 } 384 return result; 385 } 386}; 387 388// Out-of-line virtual method definition to trigger vtable emission in this 389// translation unit (see clang warning -Wweak-vtables) 390BpSurfaceComposer::~BpSurfaceComposer() {} 391 392IMPLEMENT_META_INTERFACE(SurfaceComposer, "android.ui.ISurfaceComposer"); 393 394// ---------------------------------------------------------------------- 395 396status_t BnSurfaceComposer::onTransact( 397 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 398{ 399 switch(code) { 400 case CREATE_CONNECTION: { 401 CHECK_INTERFACE(ISurfaceComposer, data, reply); 402 sp<IBinder> b = IInterface::asBinder(createConnection()); 403 reply->writeStrongBinder(b); 404 return NO_ERROR; 405 } 406 case CREATE_GRAPHIC_BUFFER_ALLOC: { 407 CHECK_INTERFACE(ISurfaceComposer, data, reply); 408 sp<IBinder> b = IInterface::asBinder(createGraphicBufferAlloc()); 409 reply->writeStrongBinder(b); 410 return NO_ERROR; 411 } 412 case SET_TRANSACTION_STATE: { 413 CHECK_INTERFACE(ISurfaceComposer, data, reply); 414 415 size_t count = data.readUint32(); 416 if (count > data.dataSize()) { 417 return BAD_VALUE; 418 } 419 ComposerState s; 420 Vector<ComposerState> state; 421 state.setCapacity(count); 422 for (size_t i = 0; i < count; i++) { 423 if (s.read(data) == BAD_VALUE) { 424 return BAD_VALUE; 425 } 426 state.add(s); 427 } 428 429 count = data.readUint32(); 430 if (count > data.dataSize()) { 431 return BAD_VALUE; 432 } 433 DisplayState d; 434 Vector<DisplayState> displays; 435 displays.setCapacity(count); 436 for (size_t i = 0; i < count; i++) { 437 if (d.read(data) == BAD_VALUE) { 438 return BAD_VALUE; 439 } 440 displays.add(d); 441 } 442 443 uint32_t stateFlags = data.readUint32(); 444 setTransactionState(state, displays, stateFlags); 445 return NO_ERROR; 446 } 447 case BOOT_FINISHED: { 448 CHECK_INTERFACE(ISurfaceComposer, data, reply); 449 bootFinished(); 450 return NO_ERROR; 451 } 452 case CAPTURE_SCREEN: { 453 CHECK_INTERFACE(ISurfaceComposer, data, reply); 454 sp<IBinder> display = data.readStrongBinder(); 455 sp<IGraphicBufferProducer> producer = 456 interface_cast<IGraphicBufferProducer>(data.readStrongBinder()); 457 Rect sourceCrop(Rect::EMPTY_RECT); 458 data.read(sourceCrop); 459 uint32_t reqWidth = data.readUint32(); 460 uint32_t reqHeight = data.readUint32(); 461 uint32_t minLayerZ = data.readUint32(); 462 uint32_t maxLayerZ = data.readUint32(); 463 bool useIdentityTransform = static_cast<bool>(data.readInt32()); 464 int32_t rotation = data.readInt32(); 465 466 status_t res = captureScreen(display, producer, 467 sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, 468 useIdentityTransform, 469 static_cast<ISurfaceComposer::Rotation>(rotation)); 470 reply->writeInt32(res); 471 return NO_ERROR; 472 } 473 case AUTHENTICATE_SURFACE: { 474 CHECK_INTERFACE(ISurfaceComposer, data, reply); 475 sp<IGraphicBufferProducer> bufferProducer = 476 interface_cast<IGraphicBufferProducer>(data.readStrongBinder()); 477 int32_t result = authenticateSurfaceTexture(bufferProducer) ? 1 : 0; 478 reply->writeInt32(result); 479 return NO_ERROR; 480 } 481 case CREATE_DISPLAY_EVENT_CONNECTION: { 482 CHECK_INTERFACE(ISurfaceComposer, data, reply); 483 sp<IDisplayEventConnection> connection(createDisplayEventConnection()); 484 reply->writeStrongBinder(IInterface::asBinder(connection)); 485 return NO_ERROR; 486 } 487 case CREATE_DISPLAY: { 488 CHECK_INTERFACE(ISurfaceComposer, data, reply); 489 String8 displayName = data.readString8(); 490 bool secure = bool(data.readInt32()); 491 sp<IBinder> display(createDisplay(displayName, secure)); 492 reply->writeStrongBinder(display); 493 return NO_ERROR; 494 } 495 case DESTROY_DISPLAY: { 496 CHECK_INTERFACE(ISurfaceComposer, data, reply); 497 sp<IBinder> display = data.readStrongBinder(); 498 destroyDisplay(display); 499 return NO_ERROR; 500 } 501 case GET_BUILT_IN_DISPLAY: { 502 CHECK_INTERFACE(ISurfaceComposer, data, reply); 503 int32_t id = data.readInt32(); 504 sp<IBinder> display(getBuiltInDisplay(id)); 505 reply->writeStrongBinder(display); 506 return NO_ERROR; 507 } 508 case GET_DISPLAY_CONFIGS: { 509 CHECK_INTERFACE(ISurfaceComposer, data, reply); 510 Vector<DisplayInfo> configs; 511 sp<IBinder> display = data.readStrongBinder(); 512 status_t result = getDisplayConfigs(display, &configs); 513 reply->writeInt32(result); 514 if (result == NO_ERROR) { 515 reply->writeUint32(static_cast<uint32_t>(configs.size())); 516 for (size_t c = 0; c < configs.size(); ++c) { 517 memcpy(reply->writeInplace(sizeof(DisplayInfo)), 518 &configs[c], sizeof(DisplayInfo)); 519 } 520 } 521 return NO_ERROR; 522 } 523 case GET_DISPLAY_STATS: { 524 CHECK_INTERFACE(ISurfaceComposer, data, reply); 525 DisplayStatInfo stats; 526 sp<IBinder> display = data.readStrongBinder(); 527 status_t result = getDisplayStats(display, &stats); 528 reply->writeInt32(result); 529 if (result == NO_ERROR) { 530 memcpy(reply->writeInplace(sizeof(DisplayStatInfo)), 531 &stats, sizeof(DisplayStatInfo)); 532 } 533 return NO_ERROR; 534 } 535 case GET_ACTIVE_CONFIG: { 536 CHECK_INTERFACE(ISurfaceComposer, data, reply); 537 sp<IBinder> display = data.readStrongBinder(); 538 int id = getActiveConfig(display); 539 reply->writeInt32(id); 540 return NO_ERROR; 541 } 542 case SET_ACTIVE_CONFIG: { 543 CHECK_INTERFACE(ISurfaceComposer, data, reply); 544 sp<IBinder> display = data.readStrongBinder(); 545 int id = data.readInt32(); 546 status_t result = setActiveConfig(display, id); 547 reply->writeInt32(result); 548 return NO_ERROR; 549 } 550 case GET_DISPLAY_COLOR_MODES: { 551 CHECK_INTERFACE(ISurfaceComposer, data, reply); 552 Vector<android_color_mode_t> colorModes; 553 sp<IBinder> display = nullptr; 554 status_t result = data.readStrongBinder(&display); 555 if (result != NO_ERROR) { 556 ALOGE("getDisplayColorModes failed to readStrongBinder: %d", result); 557 return result; 558 } 559 result = getDisplayColorModes(display, &colorModes); 560 reply->writeInt32(result); 561 if (result == NO_ERROR) { 562 reply->writeUint32(static_cast<uint32_t>(colorModes.size())); 563 for (size_t i = 0; i < colorModes.size(); ++i) { 564 reply->writeInt32(colorModes[i]); 565 } 566 } 567 return NO_ERROR; 568 } 569 case GET_ACTIVE_COLOR_MODE: { 570 CHECK_INTERFACE(ISurfaceComposer, data, reply); 571 sp<IBinder> display = nullptr; 572 status_t result = data.readStrongBinder(&display); 573 if (result != NO_ERROR) { 574 ALOGE("getActiveColorMode failed to readStrongBinder: %d", result); 575 return result; 576 } 577 android_color_mode_t colorMode = getActiveColorMode(display); 578 result = reply->writeInt32(static_cast<int32_t>(colorMode)); 579 return result; 580 } 581 case SET_ACTIVE_COLOR_MODE: { 582 CHECK_INTERFACE(ISurfaceComposer, data, reply); 583 sp<IBinder> display = nullptr; 584 status_t result = data.readStrongBinder(&display); 585 if (result != NO_ERROR) { 586 ALOGE("getActiveColorMode failed to readStrongBinder: %d", result); 587 return result; 588 } 589 int32_t colorModeInt = 0; 590 result = data.readInt32(&colorModeInt); 591 if (result != NO_ERROR) { 592 ALOGE("setActiveColorMode failed to readInt32: %d", result); 593 return result; 594 } 595 result = setActiveColorMode(display, 596 static_cast<android_color_mode_t>(colorModeInt)); 597 result = reply->writeInt32(result); 598 return result; 599 } 600 case CLEAR_ANIMATION_FRAME_STATS: { 601 CHECK_INTERFACE(ISurfaceComposer, data, reply); 602 status_t result = clearAnimationFrameStats(); 603 reply->writeInt32(result); 604 return NO_ERROR; 605 } 606 case GET_ANIMATION_FRAME_STATS: { 607 CHECK_INTERFACE(ISurfaceComposer, data, reply); 608 FrameStats stats; 609 status_t result = getAnimationFrameStats(&stats); 610 reply->write(stats); 611 reply->writeInt32(result); 612 return NO_ERROR; 613 } 614 case SET_POWER_MODE: { 615 CHECK_INTERFACE(ISurfaceComposer, data, reply); 616 sp<IBinder> display = data.readStrongBinder(); 617 int32_t mode = data.readInt32(); 618 setPowerMode(display, mode); 619 return NO_ERROR; 620 } 621 case GET_HDR_CAPABILITIES: { 622 CHECK_INTERFACE(ISurfaceComposer, data, reply); 623 sp<IBinder> display = nullptr; 624 status_t result = data.readStrongBinder(&display); 625 if (result != NO_ERROR) { 626 ALOGE("getHdrCapabilities failed to readStrongBinder: %d", 627 result); 628 return result; 629 } 630 HdrCapabilities capabilities; 631 result = getHdrCapabilities(display, &capabilities); 632 reply->writeInt32(result); 633 if (result == NO_ERROR) { 634 reply->writeParcelable(capabilities); 635 } 636 return NO_ERROR; 637 } 638 default: { 639 return BBinder::onTransact(code, data, reply, flags); 640 } 641 } 642} 643 644// ---------------------------------------------------------------------------- 645 646}; 647