Client.cpp revision 161410b01a37bcc5522d8e91fe0a743989c86e70
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{ 50db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian const size_t count = mLayers.size(); 51db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian for (size_t i=0 ; i<count ; i++) { 529524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr sp<Layer> l = mLayers.valueAt(i).promote(); 539524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr if (l != nullptr) { 549524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr mFlinger->removeLayer(l); 559524cb3b37a91b5741790c77ff24fd825b02bca7Robert Carr } 56db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian } 57db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian} 58db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian 591db73f66624e7d151710483dd58e03eed672f064Robert Carrvoid Client::setParentLayer(const sp<Layer>& parentLayer) { 60f456f32e0f9292d71b57b3255cde416b677faac2Chia-I Wu Mutex::Autolock _l(mLock); 611db73f66624e7d151710483dd58e03eed672f064Robert Carr mParentLayer = parentLayer; 621db73f66624e7d151710483dd58e03eed672f064Robert Carr} 631db73f66624e7d151710483dd58e03eed672f064Robert Carr 64f456f32e0f9292d71b57b3255cde416b677faac2Chia-I Wusp<Layer> Client::getParentLayer(bool* outParentDied) const { 65f456f32e0f9292d71b57b3255cde416b677faac2Chia-I Wu Mutex::Autolock _l(mLock); 66f456f32e0f9292d71b57b3255cde416b677faac2Chia-I Wu sp<Layer> parent = mParentLayer.promote(); 67f456f32e0f9292d71b57b3255cde416b677faac2Chia-I Wu if (outParentDied != nullptr) { 68f456f32e0f9292d71b57b3255cde416b677faac2Chia-I Wu *outParentDied = (mParentLayer != nullptr && parent == nullptr); 69f456f32e0f9292d71b57b3255cde416b677faac2Chia-I Wu } 70f456f32e0f9292d71b57b3255cde416b677faac2Chia-I Wu return parent; 71f456f32e0f9292d71b57b3255cde416b677faac2Chia-I Wu} 72f456f32e0f9292d71b57b3255cde416b677faac2Chia-I Wu 73db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopianstatus_t Client::initCheck() const { 74db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian return NO_ERROR; 75db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian} 76db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian 7713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Client::attachLayer(const sp<IBinder>& handle, const sp<Layer>& layer) 78db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian{ 79db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian Mutex::Autolock _l(mLock); 80ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian mLayers.add(handle, layer); 81db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian} 82db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian 8313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Client::detachLayer(const Layer* layer) 84db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian{ 85db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian Mutex::Autolock _l(mLock); 86db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian // we do a linear search here, because this doesn't happen often 87db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian const size_t count = mLayers.size(); 88db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian for (size_t i=0 ; i<count ; i++) { 89db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian if (mLayers.valueAt(i) == layer) { 90db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian mLayers.removeItemsAt(i, 1); 91db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian break; 92db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian } 93db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian } 94db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian} 9513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopiansp<Layer> Client::getLayerUser(const sp<IBinder>& handle) const 96db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian{ 97db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian Mutex::Autolock _l(mLock); 9813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian sp<Layer> lbc; 9913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian wp<Layer> layer(mLayers.valueFor(handle)); 100db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian if (layer != 0) { 101db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian lbc = layer.promote(); 102ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian ALOGE_IF(lbc==0, "getLayerUser(name=%p) is dead", handle.get()); 103db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian } 104db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian return lbc; 105db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian} 106db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian 107db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian 108db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopianstatus_t Client::onTransact( 109db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 110db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian{ 111db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian // these must be checked 112db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 113db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian const int pid = ipc->getCallingPid(); 114db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian const int uid = ipc->getCallingUid(); 115db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian const int self_pid = getpid(); 1161db73f66624e7d151710483dd58e03eed672f064Robert Carr // If we are called from another non root process without the GRAPHICS, SYSTEM, or ROOT 1171db73f66624e7d151710483dd58e03eed672f064Robert Carr // uid we require the sAccessSurfaceFlinger permission. 1181db73f66624e7d151710483dd58e03eed672f064Robert Carr // We grant an exception in the case that the Client has a "parent layer", as its 1191db73f66624e7d151710483dd58e03eed672f064Robert Carr // effects will be scoped to that layer. 1201db73f66624e7d151710483dd58e03eed672f064Robert Carr if (CC_UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != AID_SYSTEM && uid != 0) 121f456f32e0f9292d71b57b3255cde416b677faac2Chia-I Wu && (getParentLayer() == nullptr)) { 122db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian // we're called from a different process, do the real check 123db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian if (!PermissionCache::checkCallingPermission(sAccessSurfaceFlinger)) 124db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian { 125db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian ALOGE("Permission Denial: " 1261db73f66624e7d151710483dd58e03eed672f064Robert Carr "can't openGlobalTransaction pid=%d, uid<=%d", pid, uid); 127db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian return PERMISSION_DENIED; 128db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian } 129db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian } 130db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian return BnSurfaceComposerClient::onTransact(code, data, reply, flags); 131db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian} 132db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian 133db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian 1344d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t Client::createSurface( 135db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian const String8& name, 1364d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, 137479c60c85c40fd3536b0c88036e838dc1a4c56a0Albert Chaulk const sp<IBinder>& parentHandle, uint32_t windowType, uint32_t ownerUid, 1384d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<IBinder>* handle, 1394d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<IGraphicBufferProducer>* gbp) 140db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian{ 1411f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr sp<Layer> parent = nullptr; 1421f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr if (parentHandle != nullptr) { 143161410b01a37bcc5522d8e91fe0a743989c86e70chaviw auto layerHandle = reinterpret_cast<Layer::Handle*>(parentHandle.get()); 144161410b01a37bcc5522d8e91fe0a743989c86e70chaviw parent = layerHandle->owner.promote(); 1451f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr if (parent == nullptr) { 1461f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr return NAME_NOT_FOUND; 1471f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr } 1481f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr } 149f456f32e0f9292d71b57b3255cde416b677faac2Chia-I Wu if (parent == nullptr) { 150f456f32e0f9292d71b57b3255cde416b677faac2Chia-I Wu bool parentDied; 151f456f32e0f9292d71b57b3255cde416b677faac2Chia-I Wu parent = getParentLayer(&parentDied); 1521db73f66624e7d151710483dd58e03eed672f064Robert Carr // If we had a parent, but it died, we've lost all 1531db73f66624e7d151710483dd58e03eed672f064Robert Carr // our capabilities. 154f456f32e0f9292d71b57b3255cde416b677faac2Chia-I Wu if (parentDied) { 1551db73f66624e7d151710483dd58e03eed672f064Robert Carr return NAME_NOT_FOUND; 1561db73f66624e7d151710483dd58e03eed672f064Robert Carr } 1571db73f66624e7d151710483dd58e03eed672f064Robert Carr } 1581f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr 159db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian /* 160db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian * createSurface must be called from the GL thread so that it can 161db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian * have access to the GL context. 162db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian */ 163921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian class MessageCreateLayer : public MessageBase { 164db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian SurfaceFlinger* flinger; 165db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian Client* client; 1664d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<IBinder>* handle; 1674d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<IGraphicBufferProducer>* gbp; 1684d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian status_t result; 169db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian const String8& name; 170db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian uint32_t w, h; 171db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian PixelFormat format; 172db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian uint32_t flags; 1731f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr sp<Layer>* parent; 174479c60c85c40fd3536b0c88036e838dc1a4c56a0Albert Chaulk uint32_t windowType; 175479c60c85c40fd3536b0c88036e838dc1a4c56a0Albert Chaulk uint32_t ownerUid; 176db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian public: 177921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian MessageCreateLayer(SurfaceFlinger* flinger, 178db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian const String8& name, Client* client, 1794d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, 180479c60c85c40fd3536b0c88036e838dc1a4c56a0Albert Chaulk sp<IBinder>* handle, uint32_t windowType, uint32_t ownerUid, 1811f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr sp<IGraphicBufferProducer>* gbp, 1821f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr sp<Layer>* parent) 1834d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian : flinger(flinger), client(client), 18453390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos handle(handle), gbp(gbp), result(NO_ERROR), 1851f0a16a5d7cd00ba7fda82e7d315afa1fd1303b9Robert Carr name(name), w(w), h(h), format(format), flags(flags), 186479c60c85c40fd3536b0c88036e838dc1a4c56a0Albert Chaulk parent(parent), windowType(windowType), ownerUid(ownerUid) { 187db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian } 1884d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian status_t getResult() const { return result; } 189db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian virtual bool handler() { 1904d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian result = flinger->createLayer(name, client, w, h, format, flags, 191479c60c85c40fd3536b0c88036e838dc1a4c56a0Albert Chaulk windowType, ownerUid, handle, gbp, parent); 192db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian return true; 193db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian } 194db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian }; 195db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian 196921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(), 197479c60c85c40fd3536b0c88036e838dc1a4c56a0Albert Chaulk name, this, w, h, format, flags, handle, 198479c60c85c40fd3536b0c88036e838dc1a4c56a0Albert Chaulk windowType, ownerUid, gbp, &parent); 199db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian mFlinger->postMessageSync(msg); 200921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian return static_cast<MessageCreateLayer*>( msg.get() )->getResult(); 201db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian} 202ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian 203ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopianstatus_t Client::destroySurface(const sp<IBinder>& handle) { 204ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian return mFlinger->onLayerRemoved(this, handle); 205db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian} 206db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian 207d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t Client::clearLayerFrameStats(const sp<IBinder>& handle) const { 208d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav sp<Layer> layer = getLayerUser(handle); 209d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav if (layer == NULL) { 210d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav return NAME_NOT_FOUND; 211d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav } 212d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav layer->clearFrameStats(); 213d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav return NO_ERROR; 214d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav} 215d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav 216d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t Client::getLayerFrameStats(const sp<IBinder>& handle, FrameStats* outStats) const { 217d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav sp<Layer> layer = getLayerUser(handle); 218d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav if (layer == NULL) { 219d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav return NAME_NOT_FOUND; 220d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav } 221d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav layer->getFrameStats(outStats); 222d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav return NO_ERROR; 223d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav} 224d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav 225db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian// --------------------------------------------------------------------------- 226db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian}; // namespace android 227