1db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian/*
2db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian * Copyright (C) 2012 The Android Open Source Project
3db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian *
4db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian * Licensed under the Apache License, Version 2.0 (the "License");
5db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian * you may not use this file except in compliance with the License.
6db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian * You may obtain a copy of the License at
7db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian *
8db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian *      http://www.apache.org/licenses/LICENSE-2.0
9db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian *
10db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian * Unless required by applicable law or agreed to in writing, software
11db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian * distributed under the License is distributed on an "AS IS" BASIS,
12db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian * See the License for the specific language governing permissions and
14db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian * limitations under the License.
15db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian */
16db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
17db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian#include <stdint.h>
18db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian#include <sys/types.h>
19db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
20db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian#include <binder/PermissionCache.h>
21db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
22db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian#include <private/android_filesystem_config.h>
23db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
24db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian#include "Client.h"
25921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include "Layer.h"
26db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian#include "LayerBase.h"
27db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian#include "SurfaceFlinger.h"
28db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
29db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopiannamespace android {
30db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
31db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian// ---------------------------------------------------------------------------
32db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
33db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopianconst String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
34db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
35db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian// ---------------------------------------------------------------------------
36db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
37db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias AgopianClient::Client(const sp<SurfaceFlinger>& flinger)
38db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    : mFlinger(flinger), mNameGenerator(1)
39db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian{
40db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian}
41db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
42db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias AgopianClient::~Client()
43db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian{
44db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    const size_t count = mLayers.size();
45db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    for (size_t i=0 ; i<count ; i++) {
46db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        sp<LayerBaseClient> layer(mLayers.valueAt(i).promote());
47db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        if (layer != 0) {
48db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian            mFlinger->removeLayer(layer);
49db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        }
50db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    }
51db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian}
52db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
53db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopianstatus_t Client::initCheck() const {
54db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    return NO_ERROR;
55db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian}
56db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
57db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopiansize_t Client::attachLayer(const sp<LayerBaseClient>& layer)
58db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian{
59db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    Mutex::Autolock _l(mLock);
60db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    size_t name = mNameGenerator++;
61db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    mLayers.add(name, layer);
62db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    return name;
63db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian}
64db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
65db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopianvoid Client::detachLayer(const LayerBaseClient* layer)
66db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian{
67db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    Mutex::Autolock _l(mLock);
68db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    // we do a linear search here, because this doesn't happen often
69db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    const size_t count = mLayers.size();
70db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    for (size_t i=0 ; i<count ; i++) {
71db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        if (mLayers.valueAt(i) == layer) {
72db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian            mLayers.removeItemsAt(i, 1);
73db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian            break;
74db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        }
75db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    }
76db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian}
77db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopiansp<LayerBaseClient> Client::getLayerUser(int32_t i) const
78db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian{
79db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    Mutex::Autolock _l(mLock);
80db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    sp<LayerBaseClient> lbc;
81db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    wp<LayerBaseClient> layer(mLayers.valueFor(i));
82db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    if (layer != 0) {
83db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        lbc = layer.promote();
84db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        ALOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i));
85db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    }
86db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    return lbc;
87db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian}
88db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
89db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
90db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopianstatus_t Client::onTransact(
91db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
92db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian{
93db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    // these must be checked
94db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian     IPCThreadState* ipc = IPCThreadState::self();
95db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian     const int pid = ipc->getCallingPid();
96db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian     const int uid = ipc->getCallingUid();
97db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian     const int self_pid = getpid();
98db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian     if (CC_UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != 0)) {
99db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian         // we're called from a different process, do the real check
100db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian         if (!PermissionCache::checkCallingPermission(sAccessSurfaceFlinger))
101db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian         {
102db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian             ALOGE("Permission Denial: "
103db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian                     "can't openGlobalTransaction pid=%d, uid=%d", pid, uid);
104db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian             return PERMISSION_DENIED;
105db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian         }
106db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian     }
107db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian     return BnSurfaceComposerClient::onTransact(code, data, reply, flags);
108db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian}
109db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
110db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
111db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopiansp<ISurface> Client::createSurface(
112db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        ISurfaceComposerClient::surface_data_t* params,
113db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        const String8& name,
1149d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown        uint32_t w, uint32_t h, PixelFormat format,
115db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        uint32_t flags)
116db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian{
117db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    /*
118db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian     * createSurface must be called from the GL thread so that it can
119db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian     * have access to the GL context.
120db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian     */
121db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
122921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    class MessageCreateLayer : public MessageBase {
123db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        sp<ISurface> result;
124db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        SurfaceFlinger* flinger;
125db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        ISurfaceComposerClient::surface_data_t* params;
126db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        Client* client;
127db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        const String8& name;
128db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        uint32_t w, h;
129db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        PixelFormat format;
130db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        uint32_t flags;
131db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    public:
132921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        MessageCreateLayer(SurfaceFlinger* flinger,
133db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian                ISurfaceComposerClient::surface_data_t* params,
134db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian                const String8& name, Client* client,
1359d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown                uint32_t w, uint32_t h, PixelFormat format,
136db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian                uint32_t flags)
137db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian            : flinger(flinger), params(params), client(client), name(name),
1389d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown              w(w), h(h), format(format), flags(flags)
139db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        {
140db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        }
141db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        sp<ISurface> getResult() const { return result; }
142db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        virtual bool handler() {
143921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian            result = flinger->createLayer(params, name, client,
1443ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian                    w, h, format, flags);
145db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian            return true;
146db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        }
147db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    };
148db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
149921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(),
1509d4e3d2f42e93e2d12bacabe97d307d30c3c20ddJeff Brown            params, name, this, w, h, format, flags);
151db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    mFlinger->postMessageSync(msg);
152921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    return static_cast<MessageCreateLayer*>( msg.get() )->getResult();
153db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian}
154db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopianstatus_t Client::destroySurface(SurfaceID sid) {
155921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    return mFlinger->onLayerRemoved(this, sid);
156db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian}
157db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
158db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian// ---------------------------------------------------------------------------
159db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian}; // namespace android
160