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#include <binder/IPCThreadState.h> 22 23#include <private/android_filesystem_config.h> 24 25#include "Client.h" 26#include "Layer.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 : Client(flinger, nullptr) 39{ 40} 41 42Client::Client(const sp<SurfaceFlinger>& flinger, const sp<Layer>& parentLayer) 43 : mFlinger(flinger), 44 mParentLayer(parentLayer) 45{ 46} 47 48Client::~Client() 49{ 50 const size_t count = mLayers.size(); 51 for (size_t i=0 ; i<count ; i++) { 52 sp<Layer> l = mLayers.valueAt(i).promote(); 53 if (l != nullptr) { 54 mFlinger->removeLayer(l); 55 } 56 } 57} 58 59void Client::setParentLayer(const sp<Layer>& parentLayer) { 60 Mutex::Autolock _l(mLock); 61 mParentLayer = parentLayer; 62} 63 64sp<Layer> Client::getParentLayer(bool* outParentDied) const { 65 Mutex::Autolock _l(mLock); 66 sp<Layer> parent = mParentLayer.promote(); 67 if (outParentDied != nullptr) { 68 *outParentDied = (mParentLayer != nullptr && parent == nullptr); 69 } 70 return parent; 71} 72 73status_t Client::initCheck() const { 74 return NO_ERROR; 75} 76 77void Client::attachLayer(const sp<IBinder>& handle, const sp<Layer>& layer) 78{ 79 Mutex::Autolock _l(mLock); 80 mLayers.add(handle, layer); 81} 82 83void Client::detachLayer(const Layer* layer) 84{ 85 Mutex::Autolock _l(mLock); 86 // we do a linear search here, because this doesn't happen often 87 const size_t count = mLayers.size(); 88 for (size_t i=0 ; i<count ; i++) { 89 if (mLayers.valueAt(i) == layer) { 90 mLayers.removeItemsAt(i, 1); 91 break; 92 } 93 } 94} 95sp<Layer> Client::getLayerUser(const sp<IBinder>& handle) const 96{ 97 Mutex::Autolock _l(mLock); 98 sp<Layer> lbc; 99 wp<Layer> layer(mLayers.valueFor(handle)); 100 if (layer != 0) { 101 lbc = layer.promote(); 102 ALOGE_IF(lbc==0, "getLayerUser(name=%p) is dead", handle.get()); 103 } 104 return lbc; 105} 106 107 108status_t Client::onTransact( 109 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 110{ 111 // these must be checked 112 IPCThreadState* ipc = IPCThreadState::self(); 113 const int pid = ipc->getCallingPid(); 114 const int uid = ipc->getCallingUid(); 115 const int self_pid = getpid(); 116 // If we are called from another non root process without the GRAPHICS, SYSTEM, or ROOT 117 // uid we require the sAccessSurfaceFlinger permission. 118 // We grant an exception in the case that the Client has a "parent layer", as its 119 // effects will be scoped to that layer. 120 if (CC_UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != AID_SYSTEM && uid != 0) 121 && (getParentLayer() == nullptr)) { 122 // we're called from a different process, do the real check 123 if (!PermissionCache::checkCallingPermission(sAccessSurfaceFlinger)) 124 { 125 ALOGE("Permission Denial: " 126 "can't openGlobalTransaction pid=%d, uid<=%d", pid, uid); 127 return PERMISSION_DENIED; 128 } 129 } 130 return BnSurfaceComposerClient::onTransact(code, data, reply, flags); 131} 132 133 134status_t Client::createSurface( 135 const String8& name, 136 uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, 137 const sp<IBinder>& parentHandle, uint32_t windowType, uint32_t ownerUid, 138 sp<IBinder>* handle, 139 sp<IGraphicBufferProducer>* gbp) 140{ 141 sp<Layer> parent = nullptr; 142 if (parentHandle != nullptr) { 143 parent = getLayerUser(parentHandle); 144 if (parent == nullptr) { 145 return NAME_NOT_FOUND; 146 } 147 } 148 if (parent == nullptr) { 149 bool parentDied; 150 parent = getParentLayer(&parentDied); 151 // If we had a parent, but it died, we've lost all 152 // our capabilities. 153 if (parentDied) { 154 return NAME_NOT_FOUND; 155 } 156 } 157 158 /* 159 * createSurface must be called from the GL thread so that it can 160 * have access to the GL context. 161 */ 162 class MessageCreateLayer : public MessageBase { 163 SurfaceFlinger* flinger; 164 Client* client; 165 sp<IBinder>* handle; 166 sp<IGraphicBufferProducer>* gbp; 167 status_t result; 168 const String8& name; 169 uint32_t w, h; 170 PixelFormat format; 171 uint32_t flags; 172 sp<Layer>* parent; 173 uint32_t windowType; 174 uint32_t ownerUid; 175 public: 176 MessageCreateLayer(SurfaceFlinger* flinger, 177 const String8& name, Client* client, 178 uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, 179 sp<IBinder>* handle, uint32_t windowType, uint32_t ownerUid, 180 sp<IGraphicBufferProducer>* gbp, 181 sp<Layer>* parent) 182 : flinger(flinger), client(client), 183 handle(handle), gbp(gbp), result(NO_ERROR), 184 name(name), w(w), h(h), format(format), flags(flags), 185 parent(parent), windowType(windowType), ownerUid(ownerUid) { 186 } 187 status_t getResult() const { return result; } 188 virtual bool handler() { 189 result = flinger->createLayer(name, client, w, h, format, flags, 190 windowType, ownerUid, handle, gbp, parent); 191 return true; 192 } 193 }; 194 195 sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(), 196 name, this, w, h, format, flags, handle, 197 windowType, ownerUid, gbp, &parent); 198 mFlinger->postMessageSync(msg); 199 return static_cast<MessageCreateLayer*>( msg.get() )->getResult(); 200} 201 202status_t Client::destroySurface(const sp<IBinder>& handle) { 203 return mFlinger->onLayerRemoved(this, handle); 204} 205 206status_t Client::clearLayerFrameStats(const sp<IBinder>& handle) const { 207 sp<Layer> layer = getLayerUser(handle); 208 if (layer == NULL) { 209 return NAME_NOT_FOUND; 210 } 211 layer->clearFrameStats(); 212 return NO_ERROR; 213} 214 215status_t Client::getLayerFrameStats(const sp<IBinder>& handle, FrameStats* outStats) const { 216 sp<Layer> layer = getLayerUser(handle); 217 if (layer == NULL) { 218 return NAME_NOT_FOUND; 219 } 220 layer->getFrameStats(outStats); 221 return NO_ERROR; 222} 223 224// --------------------------------------------------------------------------- 225}; // namespace android 226