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     : mFlinger(flinger)
     39 {
     40 }
     41 
     42 Client::~Client()
     43 {
     44     const size_t count = mLayers.size();
     45     for (size_t i=0 ; i<count ; i++) {
     46         mFlinger->removeLayer(mLayers.valueAt(i));
     47     }
     48 }
     49 
     50 status_t Client::initCheck() const {
     51     return NO_ERROR;
     52 }
     53 
     54 void Client::attachLayer(const sp<IBinder>& handle, const sp<Layer>& layer)
     55 {
     56     Mutex::Autolock _l(mLock);
     57     mLayers.add(handle, layer);
     58 }
     59 
     60 void Client::detachLayer(const Layer* layer)
     61 {
     62     Mutex::Autolock _l(mLock);
     63     // we do a linear search here, because this doesn't happen often
     64     const size_t count = mLayers.size();
     65     for (size_t i=0 ; i<count ; i++) {
     66         if (mLayers.valueAt(i) == layer) {
     67             mLayers.removeItemsAt(i, 1);
     68             break;
     69         }
     70     }
     71 }
     72 sp<Layer> Client::getLayerUser(const sp<IBinder>& handle) const
     73 {
     74     Mutex::Autolock _l(mLock);
     75     sp<Layer> lbc;
     76     wp<Layer> layer(mLayers.valueFor(handle));
     77     if (layer != 0) {
     78         lbc = layer.promote();
     79         ALOGE_IF(lbc==0, "getLayerUser(name=%p) is dead", handle.get());
     80     }
     81     return lbc;
     82 }
     83 
     84 
     85 status_t Client::onTransact(
     86     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
     87 {
     88     // these must be checked
     89      IPCThreadState* ipc = IPCThreadState::self();
     90      const int pid = ipc->getCallingPid();
     91      const int uid = ipc->getCallingUid();
     92      const int self_pid = getpid();
     93      if (CC_UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != AID_SYSTEM && uid != 0)) {
     94          // we're called from a different process, do the real check
     95          if (!PermissionCache::checkCallingPermission(sAccessSurfaceFlinger))
     96          {
     97              ALOGE("Permission Denial: "
     98                      "can't openGlobalTransaction pid=%d, uid=%d", pid, uid);
     99              return PERMISSION_DENIED;
    100          }
    101      }
    102      return BnSurfaceComposerClient::onTransact(code, data, reply, flags);
    103 }
    104 
    105 
    106 status_t Client::createSurface(
    107         const String8& name,
    108         uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
    109         sp<IBinder>* handle,
    110         sp<IGraphicBufferProducer>* gbp)
    111 {
    112     /*
    113      * createSurface must be called from the GL thread so that it can
    114      * have access to the GL context.
    115      */
    116 
    117     class MessageCreateLayer : public MessageBase {
    118         SurfaceFlinger* flinger;
    119         Client* client;
    120         sp<IBinder>* handle;
    121         sp<IGraphicBufferProducer>* gbp;
    122         status_t result;
    123         const String8& name;
    124         uint32_t w, h;
    125         PixelFormat format;
    126         uint32_t flags;
    127     public:
    128         MessageCreateLayer(SurfaceFlinger* flinger,
    129                 const String8& name, Client* client,
    130                 uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
    131                 sp<IBinder>* handle,
    132                 sp<IGraphicBufferProducer>* gbp)
    133             : flinger(flinger), client(client),
    134               handle(handle), gbp(gbp), result(NO_ERROR),
    135               name(name), w(w), h(h), format(format), flags(flags) {
    136         }
    137         status_t getResult() const { return result; }
    138         virtual bool handler() {
    139             result = flinger->createLayer(name, client, w, h, format, flags,
    140                     handle, gbp);
    141             return true;
    142         }
    143     };
    144 
    145     sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(),
    146             name, this, w, h, format, flags, handle, gbp);
    147     mFlinger->postMessageSync(msg);
    148     return static_cast<MessageCreateLayer*>( msg.get() )->getResult();
    149 }
    150 
    151 status_t Client::destroySurface(const sp<IBinder>& handle) {
    152     return mFlinger->onLayerRemoved(this, handle);
    153 }
    154 
    155 status_t Client::clearLayerFrameStats(const sp<IBinder>& handle) const {
    156     sp<Layer> layer = getLayerUser(handle);
    157     if (layer == NULL) {
    158         return NAME_NOT_FOUND;
    159     }
    160     layer->clearFrameStats();
    161     return NO_ERROR;
    162 }
    163 
    164 status_t Client::getLayerFrameStats(const sp<IBinder>& handle, FrameStats* outStats) const {
    165     sp<Layer> layer = getLayerUser(handle);
    166     if (layer == NULL) {
    167         return NAME_NOT_FOUND;
    168     }
    169     layer->getFrameStats(outStats);
    170     return NO_ERROR;
    171 }
    172 
    173 status_t Client::getTransformToDisplayInverse(const sp<IBinder>& handle,
    174         bool* outTransformToDisplayInverse) const {
    175     sp<Layer> layer = getLayerUser(handle);
    176     if (layer == NULL) {
    177         return NAME_NOT_FOUND;
    178     }
    179     *outTransformToDisplayInverse = layer->getTransformToDisplayInverse();
    180     return NO_ERROR;
    181 }
    182 
    183 // ---------------------------------------------------------------------------
    184 }; // namespace android
    185