| Mathias Agopian | db403e8 | 2012-06-18 16:47:56 -0700 | [diff] [blame] | 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> | 
| Mathias Agopian | 4f4f094 | 2013-08-19 17:26:18 -0700 | [diff] [blame] | 21 | #include <binder/IPCThreadState.h> | 
| Mathias Agopian | db403e8 | 2012-06-18 16:47:56 -0700 | [diff] [blame] | 22 |  | 
 | 23 | #include <private/android_filesystem_config.h> | 
 | 24 |  | 
 | 25 | #include "Client.h" | 
| Mathias Agopian | 921e6ac | 2012-07-23 23:11:29 -0700 | [diff] [blame] | 26 | #include "Layer.h" | 
| Mathias Agopian | db403e8 | 2012-06-18 16:47:56 -0700 | [diff] [blame] | 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) | 
| Mathias Agopian | ac9fa42 | 2013-02-11 16:40:36 -0800 | [diff] [blame] | 38 |     : mFlinger(flinger) | 
| Mathias Agopian | db403e8 | 2012-06-18 16:47:56 -0700 | [diff] [blame] | 39 | { | 
 | 40 | } | 
 | 41 |  | 
 | 42 | Client::~Client() | 
 | 43 | { | 
 | 44 |     const size_t count = mLayers.size(); | 
 | 45 |     for (size_t i=0 ; i<count ; i++) { | 
| Mathias Agopian | 13127d8 | 2013-03-05 17:47:11 -0800 | [diff] [blame] | 46 |         sp<Layer> layer(mLayers.valueAt(i).promote()); | 
| Mathias Agopian | db403e8 | 2012-06-18 16:47:56 -0700 | [diff] [blame] | 47 |         if (layer != 0) { | 
 | 48 |             mFlinger->removeLayer(layer); | 
 | 49 |         } | 
 | 50 |     } | 
 | 51 | } | 
 | 52 |  | 
 | 53 | status_t Client::initCheck() const { | 
 | 54 |     return NO_ERROR; | 
 | 55 | } | 
 | 56 |  | 
| Mathias Agopian | 13127d8 | 2013-03-05 17:47:11 -0800 | [diff] [blame] | 57 | void Client::attachLayer(const sp<IBinder>& handle, const sp<Layer>& layer) | 
| Mathias Agopian | db403e8 | 2012-06-18 16:47:56 -0700 | [diff] [blame] | 58 | { | 
 | 59 |     Mutex::Autolock _l(mLock); | 
| Mathias Agopian | ac9fa42 | 2013-02-11 16:40:36 -0800 | [diff] [blame] | 60 |     mLayers.add(handle, layer); | 
| Mathias Agopian | db403e8 | 2012-06-18 16:47:56 -0700 | [diff] [blame] | 61 | } | 
 | 62 |  | 
| Mathias Agopian | 13127d8 | 2013-03-05 17:47:11 -0800 | [diff] [blame] | 63 | void Client::detachLayer(const Layer* layer) | 
| Mathias Agopian | db403e8 | 2012-06-18 16:47:56 -0700 | [diff] [blame] | 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 | } | 
| Mathias Agopian | 13127d8 | 2013-03-05 17:47:11 -0800 | [diff] [blame] | 75 | sp<Layer> Client::getLayerUser(const sp<IBinder>& handle) const | 
| Mathias Agopian | db403e8 | 2012-06-18 16:47:56 -0700 | [diff] [blame] | 76 | { | 
 | 77 |     Mutex::Autolock _l(mLock); | 
| Mathias Agopian | 13127d8 | 2013-03-05 17:47:11 -0800 | [diff] [blame] | 78 |     sp<Layer> lbc; | 
 | 79 |     wp<Layer> layer(mLayers.valueFor(handle)); | 
| Mathias Agopian | db403e8 | 2012-06-18 16:47:56 -0700 | [diff] [blame] | 80 |     if (layer != 0) { | 
 | 81 |         lbc = layer.promote(); | 
| Mathias Agopian | ac9fa42 | 2013-02-11 16:40:36 -0800 | [diff] [blame] | 82 |         ALOGE_IF(lbc==0, "getLayerUser(name=%p) is dead", handle.get()); | 
| Mathias Agopian | db403e8 | 2012-06-18 16:47:56 -0700 | [diff] [blame] | 83 |     } | 
 | 84 |     return lbc; | 
 | 85 | } | 
 | 86 |  | 
 | 87 |  | 
 | 88 | status_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(); | 
| Jeff Brown | 3bfe51d | 2015-04-10 20:20:13 -0700 | [diff] [blame] | 96 |      if (CC_UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != AID_SYSTEM && uid != 0)) { | 
| Mathias Agopian | db403e8 | 2012-06-18 16:47:56 -0700 | [diff] [blame] | 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 |  | 
| Mathias Agopian | 4d9b822 | 2013-03-12 17:11:48 -0700 | [diff] [blame] | 109 | status_t Client::createSurface( | 
| Mathias Agopian | db403e8 | 2012-06-18 16:47:56 -0700 | [diff] [blame] | 110 |         const String8& name, | 
| Mathias Agopian | 4d9b822 | 2013-03-12 17:11:48 -0700 | [diff] [blame] | 111 |         uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, | 
 | 112 |         sp<IBinder>* handle, | 
 | 113 |         sp<IGraphicBufferProducer>* gbp) | 
| Mathias Agopian | db403e8 | 2012-06-18 16:47:56 -0700 | [diff] [blame] | 114 | { | 
 | 115 |     /* | 
 | 116 |      * createSurface must be called from the GL thread so that it can | 
 | 117 |      * have access to the GL context. | 
 | 118 |      */ | 
 | 119 |  | 
| Mathias Agopian | 921e6ac | 2012-07-23 23:11:29 -0700 | [diff] [blame] | 120 |     class MessageCreateLayer : public MessageBase { | 
| Mathias Agopian | db403e8 | 2012-06-18 16:47:56 -0700 | [diff] [blame] | 121 |         SurfaceFlinger* flinger; | 
| Mathias Agopian | db403e8 | 2012-06-18 16:47:56 -0700 | [diff] [blame] | 122 |         Client* client; | 
| Mathias Agopian | 4d9b822 | 2013-03-12 17:11:48 -0700 | [diff] [blame] | 123 |         sp<IBinder>* handle; | 
 | 124 |         sp<IGraphicBufferProducer>* gbp; | 
 | 125 |         status_t result; | 
| Mathias Agopian | db403e8 | 2012-06-18 16:47:56 -0700 | [diff] [blame] | 126 |         const String8& name; | 
| Mathias Agopian | db403e8 | 2012-06-18 16:47:56 -0700 | [diff] [blame] | 127 |         uint32_t w, h; | 
 | 128 |         PixelFormat format; | 
 | 129 |         uint32_t flags; | 
 | 130 |     public: | 
| Mathias Agopian | 921e6ac | 2012-07-23 23:11:29 -0700 | [diff] [blame] | 131 |         MessageCreateLayer(SurfaceFlinger* flinger, | 
| Mathias Agopian | db403e8 | 2012-06-18 16:47:56 -0700 | [diff] [blame] | 132 |                 const String8& name, Client* client, | 
| Mathias Agopian | 4d9b822 | 2013-03-12 17:11:48 -0700 | [diff] [blame] | 133 |                 uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, | 
 | 134 |                 sp<IBinder>* handle, | 
 | 135 |                 sp<IGraphicBufferProducer>* gbp) | 
 | 136 |             : flinger(flinger), client(client), | 
| Pablo Ceballos | 53390e1 | 2015-08-04 11:25:59 -0700 | [diff] [blame] | 137 |               handle(handle), gbp(gbp), result(NO_ERROR), | 
| Mathias Agopian | 4d9b822 | 2013-03-12 17:11:48 -0700 | [diff] [blame] | 138 |               name(name), w(w), h(h), format(format), flags(flags) { | 
| Mathias Agopian | db403e8 | 2012-06-18 16:47:56 -0700 | [diff] [blame] | 139 |         } | 
| Mathias Agopian | 4d9b822 | 2013-03-12 17:11:48 -0700 | [diff] [blame] | 140 |         status_t getResult() const { return result; } | 
| Mathias Agopian | db403e8 | 2012-06-18 16:47:56 -0700 | [diff] [blame] | 141 |         virtual bool handler() { | 
| Mathias Agopian | 4d9b822 | 2013-03-12 17:11:48 -0700 | [diff] [blame] | 142 |             result = flinger->createLayer(name, client, w, h, format, flags, | 
 | 143 |                     handle, gbp); | 
| Mathias Agopian | db403e8 | 2012-06-18 16:47:56 -0700 | [diff] [blame] | 144 |             return true; | 
 | 145 |         } | 
 | 146 |     }; | 
 | 147 |  | 
| Mathias Agopian | 921e6ac | 2012-07-23 23:11:29 -0700 | [diff] [blame] | 148 |     sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(), | 
| Mathias Agopian | 4d9b822 | 2013-03-12 17:11:48 -0700 | [diff] [blame] | 149 |             name, this, w, h, format, flags, handle, gbp); | 
| Mathias Agopian | db403e8 | 2012-06-18 16:47:56 -0700 | [diff] [blame] | 150 |     mFlinger->postMessageSync(msg); | 
| Mathias Agopian | 921e6ac | 2012-07-23 23:11:29 -0700 | [diff] [blame] | 151 |     return static_cast<MessageCreateLayer*>( msg.get() )->getResult(); | 
| Mathias Agopian | db403e8 | 2012-06-18 16:47:56 -0700 | [diff] [blame] | 152 | } | 
| Mathias Agopian | ac9fa42 | 2013-02-11 16:40:36 -0800 | [diff] [blame] | 153 |  | 
 | 154 | status_t Client::destroySurface(const sp<IBinder>& handle) { | 
 | 155 |     return mFlinger->onLayerRemoved(this, handle); | 
| Mathias Agopian | db403e8 | 2012-06-18 16:47:56 -0700 | [diff] [blame] | 156 | } | 
 | 157 |  | 
| Svetoslav | d85084b | 2014-03-20 10:28:31 -0700 | [diff] [blame] | 158 | status_t Client::clearLayerFrameStats(const sp<IBinder>& handle) const { | 
 | 159 |     sp<Layer> layer = getLayerUser(handle); | 
 | 160 |     if (layer == NULL) { | 
 | 161 |         return NAME_NOT_FOUND; | 
 | 162 |     } | 
 | 163 |     layer->clearFrameStats(); | 
 | 164 |     return NO_ERROR; | 
 | 165 | } | 
 | 166 |  | 
 | 167 | status_t Client::getLayerFrameStats(const sp<IBinder>& handle, FrameStats* outStats) const { | 
 | 168 |     sp<Layer> layer = getLayerUser(handle); | 
 | 169 |     if (layer == NULL) { | 
 | 170 |         return NAME_NOT_FOUND; | 
 | 171 |     } | 
 | 172 |     layer->getFrameStats(outStats); | 
 | 173 |     return NO_ERROR; | 
 | 174 | } | 
 | 175 |  | 
| Robert Carr | 367c568 | 2016-06-20 11:55:28 -0700 | [diff] [blame] | 176 | status_t Client::getTransformToDisplayInverse(const sp<IBinder>& handle, | 
 | 177 |         bool* outTransformToDisplayInverse) const { | 
 | 178 |     sp<Layer> layer = getLayerUser(handle); | 
 | 179 |     if (layer == NULL) { | 
 | 180 |         return NAME_NOT_FOUND; | 
 | 181 |     } | 
 | 182 |     *outTransformToDisplayInverse = layer->getTransformToDisplayInverse(); | 
 | 183 |     return NO_ERROR; | 
 | 184 | } | 
 | 185 |  | 
| Mathias Agopian | db403e8 | 2012-06-18 16:47:56 -0700 | [diff] [blame] | 186 | // --------------------------------------------------------------------------- | 
 | 187 | }; // namespace android |