Home | History | Annotate | Download | only in surfaceflinger
      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     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 
     59 void Client::setParentLayer(const sp<Layer>& parentLayer) {
     60     Mutex::Autolock _l(mLock);
     61     mParentLayer = parentLayer;
     62 }
     63 
     64 sp<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 
     73 status_t Client::initCheck() const {
     74     return NO_ERROR;
     75 }
     76 
     77 void Client::attachLayer(const sp<IBinder>& handle, const sp<Layer>& layer)
     78 {
     79     Mutex::Autolock _l(mLock);
     80     mLayers.add(handle, layer);
     81 }
     82 
     83 void 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 }
     95 sp<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 
    108 status_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 
    134 status_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 
    202 status_t Client::destroySurface(const sp<IBinder>& handle) {
    203     return mFlinger->onLayerRemoved(this, handle);
    204 }
    205 
    206 status_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 
    215 status_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