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