Client.cpp revision 13127d8921356dff794250e04208c3ed60b3a3df
1064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org/*
2064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org * Copyright (C) 2012 The Android Open Source Project
3064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org *
4064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org * Licensed under the Apache License, Version 2.0 (the "License");
5064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org * you may not use this file except in compliance with the License.
6064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org * You may obtain a copy of the License at
7064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org *
8064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org *      http://www.apache.org/licenses/LICENSE-2.0
9064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org *
10293f01939ccb3a97ce3c3e907829fa3a11b78fa0tfarina@chromium.org * Unless required by applicable law or agreed to in writing, software
11064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org * distributed under the License is distributed on an "AS IS" BASIS,
12064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org * See the License for the specific language governing permissions and
14064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org * limitations under the License.
15064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org */
16064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org
17064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org#include <stdint.h>
18064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org#include <sys/types.h>
19064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org
20064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org#include <binder/PermissionCache.h>
21064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org
22064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org#include <private/android_filesystem_config.h>
23064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org
24064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org#include "Client.h"
25064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org#include "Layer.h"
26064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org#include "SurfaceFlinger.h"
27064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org
28d43f6449129f11c9823bdeb0fb8ac38ab6d76a28commit-bot@chromium.orgnamespace android {
29064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org
30064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org// ---------------------------------------------------------------------------
31064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org
32064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.orgconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
33064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org
34064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org// ---------------------------------------------------------------------------
35064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org
36d43f6449129f11c9823bdeb0fb8ac38ab6d76a28commit-bot@chromium.orgClient::Client(const sp<SurfaceFlinger>& flinger)
37064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org    : mFlinger(flinger)
38064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org{
39064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org}
40064779aa18694b68536c113f7d5b74ccbe38d3bacommit-bot@chromium.org
41Client::~Client()
42{
43    const size_t count = mLayers.size();
44    for (size_t i=0 ; i<count ; i++) {
45        sp<Layer> 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
56void Client::attachLayer(const sp<IBinder>& handle, const sp<Layer>& layer)
57{
58    Mutex::Autolock _l(mLock);
59    mLayers.add(handle, layer);
60}
61
62void Client::detachLayer(const Layer* layer)
63{
64    Mutex::Autolock _l(mLock);
65    // we do a linear search here, because this doesn't happen often
66    const size_t count = mLayers.size();
67    for (size_t i=0 ; i<count ; i++) {
68        if (mLayers.valueAt(i) == layer) {
69            mLayers.removeItemsAt(i, 1);
70            break;
71        }
72    }
73}
74sp<Layer> Client::getLayerUser(const sp<IBinder>& handle) const
75{
76    Mutex::Autolock _l(mLock);
77    sp<Layer> lbc;
78    wp<Layer> layer(mLayers.valueFor(handle));
79    if (layer != 0) {
80        lbc = layer.promote();
81        ALOGE_IF(lbc==0, "getLayerUser(name=%p) is dead", handle.get());
82    }
83    return lbc;
84}
85
86
87status_t Client::onTransact(
88    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
89{
90    // these must be checked
91     IPCThreadState* ipc = IPCThreadState::self();
92     const int pid = ipc->getCallingPid();
93     const int uid = ipc->getCallingUid();
94     const int self_pid = getpid();
95     if (CC_UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != 0)) {
96         // we're called from a different process, do the real check
97         if (!PermissionCache::checkCallingPermission(sAccessSurfaceFlinger))
98         {
99             ALOGE("Permission Denial: "
100                     "can't openGlobalTransaction pid=%d, uid=%d", pid, uid);
101             return PERMISSION_DENIED;
102         }
103     }
104     return BnSurfaceComposerClient::onTransact(code, data, reply, flags);
105}
106
107
108sp<ISurface> Client::createSurface(
109        const String8& name,
110        uint32_t w, uint32_t h, PixelFormat format,
111        uint32_t flags)
112{
113    /*
114     * createSurface must be called from the GL thread so that it can
115     * have access to the GL context.
116     */
117
118    class MessageCreateLayer : public MessageBase {
119        sp<ISurface> result;
120        SurfaceFlinger* flinger;
121        Client* client;
122        const String8& name;
123        uint32_t w, h;
124        PixelFormat format;
125        uint32_t flags;
126    public:
127        MessageCreateLayer(SurfaceFlinger* flinger,
128                const String8& name, Client* client,
129                uint32_t w, uint32_t h, PixelFormat format,
130                uint32_t flags)
131            : flinger(flinger), client(client), name(name),
132              w(w), h(h), format(format), flags(flags)
133        {
134        }
135        sp<ISurface> getResult() const { return result; }
136        virtual bool handler() {
137            result = flinger->createLayer(name, client, w, h, format, flags);
138            return true;
139        }
140    };
141
142    sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(),
143            name, this, w, h, format, flags);
144    mFlinger->postMessageSync(msg);
145    return static_cast<MessageCreateLayer*>( msg.get() )->getResult();
146}
147
148status_t Client::destroySurface(const sp<IBinder>& handle) {
149    return mFlinger->onLayerRemoved(this, handle);
150}
151
152// ---------------------------------------------------------------------------
153}; // namespace android
154