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> 21db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian 22db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian#include <private/android_filesystem_config.h> 23db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian 24db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian#include "Client.h" 25921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include "Layer.h" 26db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian#include "LayerBase.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) 38db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian : mFlinger(flinger), mNameGenerator(1) 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++) { 46db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian sp<LayerBaseClient> 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 57db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopiansize_t Client::attachLayer(const sp<LayerBaseClient>& layer) 58db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian{ 59db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian Mutex::Autolock _l(mLock); 60db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian size_t name = mNameGenerator++; 61db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian mLayers.add(name, layer); 62db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian return name; 63db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian} 64db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian 65db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopianvoid Client::detachLayer(const LayerBaseClient* layer) 66db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian{ 67db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian Mutex::Autolock _l(mLock); 68db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian // we do a linear search here, because this doesn't happen often 69db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian const size_t count = mLayers.size(); 70db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian for (size_t i=0 ; i<count ; i++) { 71db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian if (mLayers.valueAt(i) == layer) { 72db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian mLayers.removeItemsAt(i, 1); 73db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian break; 74db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian } 75db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian } 76db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian} 77db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopiansp<LayerBaseClient> Client::getLayerUser(int32_t i) const 78db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian{ 79db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian Mutex::Autolock _l(mLock); 80db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian sp<LayerBaseClient> lbc; 81db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian wp<LayerBaseClient> layer(mLayers.valueFor(i)); 82db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian if (layer != 0) { 83db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian lbc = layer.promote(); 84db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian ALOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i)); 85db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian } 86db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian return lbc; 87db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian} 88db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian 89db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian 90db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopianstatus_t Client::onTransact( 91db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 92db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian{ 93db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian // these must be checked 94db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 95db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian const int pid = ipc->getCallingPid(); 96db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian const int uid = ipc->getCallingUid(); 97db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian const int self_pid = getpid(); 98db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian if (CC_UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != 0)) { 99db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian // we're called from a different process, do the real check 100db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian if (!PermissionCache::checkCallingPermission(sAccessSurfaceFlinger)) 101db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian { 102db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian ALOGE("Permission Denial: " 103db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian "can't openGlobalTransaction pid=%d, uid=%d", pid, uid); 104db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian return PERMISSION_DENIED; 105db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian } 106db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian } 107db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian return BnSurfaceComposerClient::onTransact(code, data, reply, flags); 108db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian} 109db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian 110db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian 111db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopiansp<ISurface> Client::createSurface( 112db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian ISurfaceComposerClient::surface_data_t* params, 113db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian const String8& name, 1149d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown uint32_t w, uint32_t h, PixelFormat format, 115db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian uint32_t flags) 116db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian{ 117db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian /* 118db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian * createSurface must be called from the GL thread so that it can 119db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian * have access to the GL context. 120db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian */ 121db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian 122921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian class MessageCreateLayer : public MessageBase { 123db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian sp<ISurface> result; 124db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian SurfaceFlinger* flinger; 125db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian ISurfaceComposerClient::surface_data_t* params; 126db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian Client* client; 127db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian const String8& name; 128db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian uint32_t w, h; 129db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian PixelFormat format; 130db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian uint32_t flags; 131db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian public: 132921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian MessageCreateLayer(SurfaceFlinger* flinger, 133db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian ISurfaceComposerClient::surface_data_t* params, 134db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian const String8& name, Client* client, 1359d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown uint32_t w, uint32_t h, PixelFormat format, 136db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian uint32_t flags) 137db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian : flinger(flinger), params(params), client(client), name(name), 1389d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown w(w), h(h), format(format), flags(flags) 139db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian { 140db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian } 141db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian sp<ISurface> getResult() const { return result; } 142db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian virtual bool handler() { 143921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian result = flinger->createLayer(params, name, client, 1443ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian w, h, format, flags); 145db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian return true; 146db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian } 147db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian }; 148db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian 149921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(), 1509d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown params, name, this, w, h, format, flags); 151db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian mFlinger->postMessageSync(msg); 152921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian return static_cast<MessageCreateLayer*>( msg.get() )->getResult(); 153db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian} 154db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopianstatus_t Client::destroySurface(SurfaceID sid) { 155921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian return mFlinger->onLayerRemoved(this, sid); 156db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian} 157db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian 158db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian// --------------------------------------------------------------------------- 159db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian}; // namespace android 160