Client.cpp revision b79f61d41ef053bee1087ec612896c59f95f9686
1/* 2 * Copyright (C) 2012 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#include <stdint.h> 18#include <sys/types.h> 19 20#include <binder/PermissionCache.h> 21 22#include <private/android_filesystem_config.h> 23 24#include "Client.h" 25#include "Layer.h" 26#include "LayerBase.h" 27#include "SurfaceFlinger.h" 28 29namespace android { 30 31// --------------------------------------------------------------------------- 32 33const String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"); 34 35// --------------------------------------------------------------------------- 36 37Client::Client(const sp<SurfaceFlinger>& flinger) 38 : mFlinger(flinger) 39{ 40} 41 42Client::~Client() 43{ 44 const size_t count = mLayers.size(); 45 for (size_t i=0 ; i<count ; i++) { 46 sp<LayerBase> layer(mLayers.valueAt(i).promote()); 47 if (layer != 0) { 48 mFlinger->removeLayer(layer); 49 } 50 } 51} 52 53status_t Client::initCheck() const { 54 return NO_ERROR; 55} 56 57void Client::attachLayer(const sp<IBinder>& handle, const sp<LayerBase>& layer) 58{ 59 Mutex::Autolock _l(mLock); 60 mLayers.add(handle, layer); 61} 62 63void Client::detachLayer(const LayerBase* layer) 64{ 65 Mutex::Autolock _l(mLock); 66 // we do a linear search here, because this doesn't happen often 67 const size_t count = mLayers.size(); 68 for (size_t i=0 ; i<count ; i++) { 69 if (mLayers.valueAt(i) == layer) { 70 mLayers.removeItemsAt(i, 1); 71 break; 72 } 73 } 74} 75sp<LayerBase> Client::getLayerUser(const sp<IBinder>& handle) const 76{ 77 Mutex::Autolock _l(mLock); 78 sp<LayerBase> lbc; 79 wp<LayerBase> layer(mLayers.valueFor(handle)); 80 if (layer != 0) { 81 lbc = layer.promote(); 82 ALOGE_IF(lbc==0, "getLayerUser(name=%p) is dead", handle.get()); 83 } 84 return lbc; 85} 86 87 88status_t Client::onTransact( 89 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 90{ 91 // these must be checked 92 IPCThreadState* ipc = IPCThreadState::self(); 93 const int pid = ipc->getCallingPid(); 94 const int uid = ipc->getCallingUid(); 95 const int self_pid = getpid(); 96 if (CC_UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != 0)) { 97 // we're called from a different process, do the real check 98 if (!PermissionCache::checkCallingPermission(sAccessSurfaceFlinger)) 99 { 100 ALOGE("Permission Denial: " 101 "can't openGlobalTransaction pid=%d, uid=%d", pid, uid); 102 return PERMISSION_DENIED; 103 } 104 } 105 return BnSurfaceComposerClient::onTransact(code, data, reply, flags); 106} 107 108 109sp<ISurface> Client::createSurface( 110 const String8& name, 111 uint32_t w, uint32_t h, PixelFormat format, 112 uint32_t flags) 113{ 114 /* 115 * createSurface must be called from the GL thread so that it can 116 * have access to the GL context. 117 */ 118 119 class MessageCreateLayer : public MessageBase { 120 sp<ISurface> result; 121 SurfaceFlinger* flinger; 122 Client* client; 123 const String8& name; 124 uint32_t w, h; 125 PixelFormat format; 126 uint32_t flags; 127 public: 128 MessageCreateLayer(SurfaceFlinger* flinger, 129 const String8& name, Client* client, 130 uint32_t w, uint32_t h, PixelFormat format, 131 uint32_t flags) 132 : flinger(flinger), client(client), name(name), 133 w(w), h(h), format(format), flags(flags) 134 { 135 } 136 sp<ISurface> getResult() const { return result; } 137 virtual bool handler() { 138 result = flinger->createLayer(name, client, w, h, format, flags); 139 return true; 140 } 141 }; 142 143 sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(), 144 name, this, w, h, format, flags); 145 mFlinger->postMessageSync(msg); 146 return static_cast<MessageCreateLayer*>( msg.get() )->getResult(); 147} 148 149status_t Client::destroySurface(const sp<IBinder>& handle) { 150 return mFlinger->onLayerRemoved(this, handle); 151} 152 153// --------------------------------------------------------------------------- 154}; // namespace android 155