1db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian/*
2db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian * Copyright (C) 2012 The Android Open Source Project
3db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian *
4db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian * Licensed under the Apache License, Version 2.0 (the "License");
5db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian * you may not use this file except in compliance with the License.
6db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian * You may obtain a copy of the License at
7db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian *
8db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian *      http://www.apache.org/licenses/LICENSE-2.0
9db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian *
10db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian * Unless required by applicable law or agreed to in writing, software
11db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian * distributed under the License is distributed on an "AS IS" BASIS,
12db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian * See the License for the specific language governing permissions and
14db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian * limitations under the License.
15db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian */
16db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
17db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian#include <stdint.h>
18db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian#include <sys/types.h>
19db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
20db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian#include <binder/PermissionCache.h>
214f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian#include <binder/IPCThreadState.h>
22db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
23db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian#include <private/android_filesystem_config.h>
24db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
25db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian#include "Client.h"
26921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include "Layer.h"
27db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian#include "SurfaceFlinger.h"
28db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
29db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopiannamespace android {
30db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
31db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian// ---------------------------------------------------------------------------
32db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
33db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
34db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
35db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian// ---------------------------------------------------------------------------
36db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
37db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias AgopianClient::Client(const sp<SurfaceFlinger>& flinger)
381db73f66624e7d151710483dd58e03eed672f064Robert Carr    : Client(flinger, nullptr)
391db73f66624e7d151710483dd58e03eed672f064Robert Carr{
401db73f66624e7d151710483dd58e03eed672f064Robert Carr}
411db73f66624e7d151710483dd58e03eed672f064Robert Carr
421db73f66624e7d151710483dd58e03eed672f064Robert CarrClient::Client(const sp<SurfaceFlinger>& flinger, const sp<Layer>& parentLayer)
431db73f66624e7d151710483dd58e03eed672f064Robert Carr    : mFlinger(flinger),
441db73f66624e7d151710483dd58e03eed672f064Robert Carr      mParentLayer(parentLayer)
45db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian{
46db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian}
47db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
48db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias AgopianClient::~Client()
49db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian{
505e8e1f00889b0e7a56bffac5e999591a73ba92deRobert Carr    // We need to post a message to remove our remaining layers rather than
515e8e1f00889b0e7a56bffac5e999591a73ba92deRobert Carr    // do so directly by acquiring the SurfaceFlinger lock. If we were to
525e8e1f00889b0e7a56bffac5e999591a73ba92deRobert Carr    // attempt to directly call the lock it becomes effectively impossible
535e8e1f00889b0e7a56bffac5e999591a73ba92deRobert Carr    // to use sp<Client> while holding the SF lock as descoping it could
545e8e1f00889b0e7a56bffac5e999591a73ba92deRobert Carr    // then trigger a dead-lock.
555e8e1f00889b0e7a56bffac5e999591a73ba92deRobert Carr
56db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    const size_t count = mLayers.size();
57db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    for (size_t i=0 ; i<count ; i++) {
589524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr        sp<Layer> l = mLayers.valueAt(i).promote();
595e8e1f00889b0e7a56bffac5e999591a73ba92deRobert Carr        if (l == nullptr) {
605e8e1f00889b0e7a56bffac5e999591a73ba92deRobert Carr            continue;
619524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr        }
625e8e1f00889b0e7a56bffac5e999591a73ba92deRobert Carr        mFlinger->postMessageAsync(new LambdaMessage([flinger = mFlinger, l]() {
635e8e1f00889b0e7a56bffac5e999591a73ba92deRobert Carr            flinger->removeLayer(l);
645e8e1f00889b0e7a56bffac5e999591a73ba92deRobert Carr        }));
65db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    }
66db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian}
67db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
6894c7d3d948beff287eed53e6d841e29e05cad8b3Robert Carrvoid Client::updateParent(const sp<Layer>& parentLayer) {
69f456f32e0f9292d71b57b3255cde416b677faac2Chia-I Wu    Mutex::Autolock _l(mLock);
7094c7d3d948beff287eed53e6d841e29e05cad8b3Robert Carr
7194c7d3d948beff287eed53e6d841e29e05cad8b3Robert Carr    // If we didn't ever have a parent, then we must instead be
7294c7d3d948beff287eed53e6d841e29e05cad8b3Robert Carr    // relying on permissions and we never need a parent.
7394c7d3d948beff287eed53e6d841e29e05cad8b3Robert Carr    if (mParentLayer != nullptr) {
7494c7d3d948beff287eed53e6d841e29e05cad8b3Robert Carr        mParentLayer = parentLayer;
7594c7d3d948beff287eed53e6d841e29e05cad8b3Robert Carr    }
761db73f66624e7d151710483dd58e03eed672f064Robert Carr}
771db73f66624e7d151710483dd58e03eed672f064Robert Carr
78f456f32e0f9292d71b57b3255cde416b677faac2Chia-I Wusp<Layer> Client::getParentLayer(bool* outParentDied) const {
79f456f32e0f9292d71b57b3255cde416b677faac2Chia-I Wu    Mutex::Autolock _l(mLock);
80f456f32e0f9292d71b57b3255cde416b677faac2Chia-I Wu    sp<Layer> parent = mParentLayer.promote();
81f456f32e0f9292d71b57b3255cde416b677faac2Chia-I Wu    if (outParentDied != nullptr) {
82f456f32e0f9292d71b57b3255cde416b677faac2Chia-I Wu        *outParentDied = (mParentLayer != nullptr && parent == nullptr);
83f456f32e0f9292d71b57b3255cde416b677faac2Chia-I Wu    }
84f456f32e0f9292d71b57b3255cde416b677faac2Chia-I Wu    return parent;
85f456f32e0f9292d71b57b3255cde416b677faac2Chia-I Wu}
86f456f32e0f9292d71b57b3255cde416b677faac2Chia-I Wu
87db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopianstatus_t Client::initCheck() const {
88db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    return NO_ERROR;
89db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian}
90db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
9113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Client::attachLayer(const sp<IBinder>& handle, const sp<Layer>& layer)
92db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian{
93db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    Mutex::Autolock _l(mLock);
94ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian    mLayers.add(handle, layer);
95db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian}
96db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
9713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Client::detachLayer(const Layer* layer)
98db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian{
99db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    Mutex::Autolock _l(mLock);
100db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    // we do a linear search here, because this doesn't happen often
101db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    const size_t count = mLayers.size();
102db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    for (size_t i=0 ; i<count ; i++) {
103db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        if (mLayers.valueAt(i) == layer) {
104db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian            mLayers.removeItemsAt(i, 1);
105db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian            break;
106db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        }
107db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    }
108db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian}
10913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopiansp<Layer> Client::getLayerUser(const sp<IBinder>& handle) const
110db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian{
111db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    Mutex::Autolock _l(mLock);
11213127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Layer> lbc;
11313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    wp<Layer> layer(mLayers.valueFor(handle));
114db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    if (layer != 0) {
115db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        lbc = layer.promote();
116ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian        ALOGE_IF(lbc==0, "getLayerUser(name=%p) is dead", handle.get());
117db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    }
118db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    return lbc;
119db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian}
120db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
121db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
122db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopianstatus_t Client::onTransact(
123db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
124db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian{
125db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    // these must be checked
126db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian     IPCThreadState* ipc = IPCThreadState::self();
127db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian     const int pid = ipc->getCallingPid();
128db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian     const int uid = ipc->getCallingUid();
129db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian     const int self_pid = getpid();
1301db73f66624e7d151710483dd58e03eed672f064Robert Carr     // If we are called from another non root process without the GRAPHICS, SYSTEM, or ROOT
1311db73f66624e7d151710483dd58e03eed672f064Robert Carr     // uid we require the sAccessSurfaceFlinger permission.
1321db73f66624e7d151710483dd58e03eed672f064Robert Carr     // We grant an exception in the case that the Client has a "parent layer", as its
1331db73f66624e7d151710483dd58e03eed672f064Robert Carr     // effects will be scoped to that layer.
1341db73f66624e7d151710483dd58e03eed672f064Robert Carr     if (CC_UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != AID_SYSTEM && uid != 0)
135f456f32e0f9292d71b57b3255cde416b677faac2Chia-I Wu             && (getParentLayer() == nullptr)) {
136db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian         // we're called from a different process, do the real check
137db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian         if (!PermissionCache::checkCallingPermission(sAccessSurfaceFlinger))
138db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian         {
139db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian             ALOGE("Permission Denial: "
1401db73f66624e7d151710483dd58e03eed672f064Robert Carr                     "can't openGlobalTransaction pid=%d, uid<=%d", pid, uid);
141db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian             return PERMISSION_DENIED;
142db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian         }
143db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian     }
144db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian     return BnSurfaceComposerClient::onTransact(code, data, reply, flags);
145db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian}
146db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
147db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
1484d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t Client::createSurface(
149db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        const String8& name,
1504d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
151ccd348460ca25890a8fb709e82e6f780e3ce878erongliu        const sp<IBinder>& parentHandle, int32_t windowType, int32_t ownerUid,
1524d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle,
1534d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IGraphicBufferProducer>* gbp)
154db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian{
1551f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    sp<Layer> parent = nullptr;
1561f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    if (parentHandle != nullptr) {
157161410b01a37bcc5522d8e91fe0a743989c86e70chaviw        auto layerHandle = reinterpret_cast<Layer::Handle*>(parentHandle.get());
158161410b01a37bcc5522d8e91fe0a743989c86e70chaviw        parent = layerHandle->owner.promote();
1591f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        if (parent == nullptr) {
1601f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr            return NAME_NOT_FOUND;
1611f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        }
1621f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr    }
163f456f32e0f9292d71b57b3255cde416b677faac2Chia-I Wu    if (parent == nullptr) {
164f456f32e0f9292d71b57b3255cde416b677faac2Chia-I Wu        bool parentDied;
165f456f32e0f9292d71b57b3255cde416b677faac2Chia-I Wu        parent = getParentLayer(&parentDied);
1661db73f66624e7d151710483dd58e03eed672f064Robert Carr        // If we had a parent, but it died, we've lost all
1671db73f66624e7d151710483dd58e03eed672f064Robert Carr        // our capabilities.
168f456f32e0f9292d71b57b3255cde416b677faac2Chia-I Wu        if (parentDied) {
1691db73f66624e7d151710483dd58e03eed672f064Robert Carr            return NAME_NOT_FOUND;
1701db73f66624e7d151710483dd58e03eed672f064Robert Carr        }
1711db73f66624e7d151710483dd58e03eed672f064Robert Carr    }
1721f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr
173db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    /*
174db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian     * createSurface must be called from the GL thread so that it can
175db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian     * have access to the GL context.
176db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian     */
177921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    class MessageCreateLayer : public MessageBase {
178db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        SurfaceFlinger* flinger;
179db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        Client* client;
1804d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle;
1814d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IGraphicBufferProducer>* gbp;
1824d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        status_t result;
183db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        const String8& name;
184db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        uint32_t w, h;
185db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        PixelFormat format;
186db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        uint32_t flags;
1871f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr        sp<Layer>* parent;
188ccd348460ca25890a8fb709e82e6f780e3ce878erongliu        int32_t windowType;
189ccd348460ca25890a8fb709e82e6f780e3ce878erongliu        int32_t ownerUid;
190db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    public:
191921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        MessageCreateLayer(SurfaceFlinger* flinger,
192db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian                const String8& name, Client* client,
1934d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
194ccd348460ca25890a8fb709e82e6f780e3ce878erongliu                sp<IBinder>* handle, int32_t windowType, int32_t ownerUid,
1951f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                sp<IGraphicBufferProducer>* gbp,
1961f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr                sp<Layer>* parent)
1974d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            : flinger(flinger), client(client),
19853390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos              handle(handle), gbp(gbp), result(NO_ERROR),
1991f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr              name(name), w(w), h(h), format(format), flags(flags),
200479c60c85c40fd3536b0c88036e838dc1a4c56a0Albert Chaulk              parent(parent), windowType(windowType), ownerUid(ownerUid) {
201db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        }
2024d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        status_t getResult() const { return result; }
203db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        virtual bool handler() {
2044d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = flinger->createLayer(name, client, w, h, format, flags,
205479c60c85c40fd3536b0c88036e838dc1a4c56a0Albert Chaulk                    windowType, ownerUid, handle, gbp, parent);
206db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian            return true;
207db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        }
208db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    };
209db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
210921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(),
211479c60c85c40fd3536b0c88036e838dc1a4c56a0Albert Chaulk            name, this, w, h, format, flags, handle,
212479c60c85c40fd3536b0c88036e838dc1a4c56a0Albert Chaulk            windowType, ownerUid, gbp, &parent);
213db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    mFlinger->postMessageSync(msg);
214921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    return static_cast<MessageCreateLayer*>( msg.get() )->getResult();
215db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian}
216ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian
217ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopianstatus_t Client::destroySurface(const sp<IBinder>& handle) {
218ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian    return mFlinger->onLayerRemoved(this, handle);
219db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian}
220db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
221d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t Client::clearLayerFrameStats(const sp<IBinder>& handle) const {
222d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    sp<Layer> layer = getLayerUser(handle);
223566a3b4a1d1a2a6d38257113700eea92aa44ea2bPeiyong Lin    if (layer == nullptr) {
224d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        return NAME_NOT_FOUND;
225d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    }
226d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    layer->clearFrameStats();
227d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    return NO_ERROR;
228d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
229d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
230d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t Client::getLayerFrameStats(const sp<IBinder>& handle, FrameStats* outStats) const {
231d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    sp<Layer> layer = getLayerUser(handle);
232566a3b4a1d1a2a6d38257113700eea92aa44ea2bPeiyong Lin    if (layer == nullptr) {
233d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        return NAME_NOT_FOUND;
234d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    }
235d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    layer->getFrameStats(outStats);
236d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    return NO_ERROR;
237d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
238d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
239db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian// ---------------------------------------------------------------------------
240db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian}; // namespace android
241