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) 38ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian : mFlinger(flinger) 39db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian{ 40db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian} 41db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian 42db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias AgopianClient::~Client() 43db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian{ 44db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian const size_t count = mLayers.size(); 45db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian for (size_t i=0 ; i<count ; i++) { 4613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian sp<Layer> layer(mLayers.valueAt(i).promote()); 47db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian if (layer != 0) { 48db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian mFlinger->removeLayer(layer); 49db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian } 50db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian } 51db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian} 52db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian 53db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopianstatus_t Client::initCheck() const { 54db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian return NO_ERROR; 55db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian} 56db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian 5713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Client::attachLayer(const sp<IBinder>& handle, const sp<Layer>& layer) 58db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian{ 59db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian Mutex::Autolock _l(mLock); 60ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian mLayers.add(handle, layer); 61db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian} 62db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian 6313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Client::detachLayer(const Layer* layer) 64db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian{ 65db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian Mutex::Autolock _l(mLock); 66db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian // we do a linear search here, because this doesn't happen often 67db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian const size_t count = mLayers.size(); 68db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian for (size_t i=0 ; i<count ; i++) { 69db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian if (mLayers.valueAt(i) == layer) { 70db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian mLayers.removeItemsAt(i, 1); 71db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian break; 72db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian } 73db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian } 74db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian} 7513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopiansp<Layer> Client::getLayerUser(const sp<IBinder>& handle) const 76db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian{ 77db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian Mutex::Autolock _l(mLock); 7813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian sp<Layer> lbc; 7913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian wp<Layer> layer(mLayers.valueFor(handle)); 80db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian if (layer != 0) { 81db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian lbc = layer.promote(); 82ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian ALOGE_IF(lbc==0, "getLayerUser(name=%p) is dead", handle.get()); 83db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian } 84db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian return lbc; 85db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian} 86db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian 87db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian 88db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopianstatus_t Client::onTransact( 89db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 90db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian{ 91db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian // these must be checked 92db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 93db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian const int pid = ipc->getCallingPid(); 94db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian const int uid = ipc->getCallingUid(); 95db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian const int self_pid = getpid(); 963bfe51d7901e99e7f122f76ed2708e2b67b71cf9Jeff Brown if (CC_UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != AID_SYSTEM && uid != 0)) { 97db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian // we're called from a different process, do the real check 98db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian if (!PermissionCache::checkCallingPermission(sAccessSurfaceFlinger)) 99db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian { 100db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian ALOGE("Permission Denial: " 101db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian "can't openGlobalTransaction pid=%d, uid=%d", pid, uid); 102db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian return PERMISSION_DENIED; 103db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian } 104db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian } 105db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian return BnSurfaceComposerClient::onTransact(code, data, reply, flags); 106db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian} 107db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian 108db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian 1094d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t Client::createSurface( 110db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian const String8& name, 1114d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, 1124d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<IBinder>* handle, 1134d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<IGraphicBufferProducer>* gbp) 114db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian{ 115db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian /* 116db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian * createSurface must be called from the GL thread so that it can 117db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian * have access to the GL context. 118db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian */ 119db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian 120921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian class MessageCreateLayer : public MessageBase { 121db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian SurfaceFlinger* flinger; 122db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian Client* client; 1234d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<IBinder>* handle; 1244d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<IGraphicBufferProducer>* gbp; 1254d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian status_t result; 126db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian const String8& name; 127db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian uint32_t w, h; 128db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian PixelFormat format; 129db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian uint32_t flags; 130db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian public: 131921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian MessageCreateLayer(SurfaceFlinger* flinger, 132db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian const String8& name, Client* client, 1334d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, 1344d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<IBinder>* handle, 1354d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian sp<IGraphicBufferProducer>* gbp) 1364d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian : flinger(flinger), client(client), 13753390e1e8c33ebee5bb8100e846f5263ba05ff73Pablo Ceballos handle(handle), gbp(gbp), result(NO_ERROR), 1384d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian name(name), w(w), h(h), format(format), flags(flags) { 139db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian } 1404d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian status_t getResult() const { return result; } 141db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian virtual bool handler() { 1424d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian result = flinger->createLayer(name, client, w, h, format, flags, 1434d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian handle, gbp); 144db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian return true; 145db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian } 146db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian }; 147db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian 148921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(), 1494d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian name, this, w, h, format, flags, handle, gbp); 150db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian mFlinger->postMessageSync(msg); 151921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian return static_cast<MessageCreateLayer*>( msg.get() )->getResult(); 152db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian} 153ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian 154ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopianstatus_t Client::destroySurface(const sp<IBinder>& handle) { 155ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian return mFlinger->onLayerRemoved(this, handle); 156db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian} 157db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian 158d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t Client::clearLayerFrameStats(const sp<IBinder>& handle) const { 159d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav sp<Layer> layer = getLayerUser(handle); 160d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav if (layer == NULL) { 161d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav return NAME_NOT_FOUND; 162d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav } 163d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav layer->clearFrameStats(); 164d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav return NO_ERROR; 165d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav} 166d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav 167d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t Client::getLayerFrameStats(const sp<IBinder>& handle, FrameStats* outStats) const { 168d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav sp<Layer> layer = getLayerUser(handle); 169d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav if (layer == NULL) { 170d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav return NAME_NOT_FOUND; 171d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav } 172d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav layer->getFrameStats(outStats); 173d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav return NO_ERROR; 174d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav} 175d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav 176db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian// --------------------------------------------------------------------------- 177db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian}; // namespace android 178