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