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