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>
214f4f0943489d9113c66ac22b58cfba8c21dfa879Mathias Agopian#include <binder/IPCThreadState.h>
22db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
23db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian#include <private/android_filesystem_config.h>
24db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
25db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian#include "Client.h"
26921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include "Layer.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)
38ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian    : mFlinger(flinger)
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++) {
4613127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        sp<Layer> 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
5713127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Client::attachLayer(const sp<IBinder>& handle, const sp<Layer>& layer)
58db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian{
59db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    Mutex::Autolock _l(mLock);
60ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian    mLayers.add(handle, layer);
61db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian}
62db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
6313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid Client::detachLayer(const Layer* layer)
64db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian{
65db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    Mutex::Autolock _l(mLock);
66db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    // we do a linear search here, because this doesn't happen often
67db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    const size_t count = mLayers.size();
68db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    for (size_t i=0 ; i<count ; i++) {
69db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        if (mLayers.valueAt(i) == layer) {
70db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian            mLayers.removeItemsAt(i, 1);
71db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian            break;
72db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        }
73db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    }
74db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian}
7513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopiansp<Layer> Client::getLayerUser(const sp<IBinder>& handle) const
76db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian{
77db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    Mutex::Autolock _l(mLock);
7813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    sp<Layer> lbc;
7913127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian    wp<Layer> layer(mLayers.valueFor(handle));
80db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    if (layer != 0) {
81db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        lbc = layer.promote();
82ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian        ALOGE_IF(lbc==0, "getLayerUser(name=%p) is dead", handle.get());
83db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    }
84db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    return lbc;
85db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian}
86db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
87db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
88db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopianstatus_t Client::onTransact(
89db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
90db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian{
91db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    // these must be checked
92db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian     IPCThreadState* ipc = IPCThreadState::self();
93db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian     const int pid = ipc->getCallingPid();
94db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian     const int uid = ipc->getCallingUid();
95db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian     const int self_pid = getpid();
96db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian     if (CC_UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != 0)) {
97db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian         // we're called from a different process, do the real check
98db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian         if (!PermissionCache::checkCallingPermission(sAccessSurfaceFlinger))
99db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian         {
100db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian             ALOGE("Permission Denial: "
101db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian                     "can't openGlobalTransaction pid=%d, uid=%d", pid, uid);
102db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian             return PERMISSION_DENIED;
103db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian         }
104db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian     }
105db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian     return BnSurfaceComposerClient::onTransact(code, data, reply, flags);
106db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian}
107db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
108db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
1094d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopianstatus_t Client::createSurface(
110db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        const String8& name,
1114d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
1124d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle,
1134d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IGraphicBufferProducer>* gbp)
114db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian{
115db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    /*
116db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian     * createSurface must be called from the GL thread so that it can
117db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian     * have access to the GL context.
118db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian     */
119db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
120921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    class MessageCreateLayer : public MessageBase {
121db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        SurfaceFlinger* flinger;
122db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        Client* client;
1234d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IBinder>* handle;
1244d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        sp<IGraphicBufferProducer>* gbp;
1254d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        status_t result;
126db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        const String8& name;
127db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        uint32_t w, h;
128db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        PixelFormat format;
129db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        uint32_t flags;
130db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    public:
131921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian        MessageCreateLayer(SurfaceFlinger* flinger,
132db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian                const String8& name, Client* client,
1334d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
1344d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                sp<IBinder>* handle,
1354d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                sp<IGraphicBufferProducer>* gbp)
1364d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            : flinger(flinger), client(client),
1374d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian              handle(handle), gbp(gbp),
1384d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian              name(name), w(w), h(h), format(format), flags(flags) {
139db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        }
1404d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian        status_t getResult() const { return result; }
141db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        virtual bool handler() {
1424d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            result = flinger->createLayer(name, client, w, h, format, flags,
1434d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian                    handle, gbp);
144db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian            return true;
145db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian        }
146db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    };
147db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
148921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(),
1494d9b822e2c18142e55fe2611aa6cd7dc7d4a62c6Mathias Agopian            name, this, w, h, format, flags, handle, gbp);
150db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian    mFlinger->postMessageSync(msg);
151921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian    return static_cast<MessageCreateLayer*>( msg.get() )->getResult();
152db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian}
153ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian
154ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopianstatus_t Client::destroySurface(const sp<IBinder>& handle) {
155ac9fa427d4a86745e60a5f7fd8e3ea340c4db907Mathias Agopian    return mFlinger->onLayerRemoved(this, handle);
156db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian}
157db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian
158d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t Client::clearLayerFrameStats(const sp<IBinder>& handle) const {
159d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    sp<Layer> layer = getLayerUser(handle);
160d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    if (layer == NULL) {
161d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        return NAME_NOT_FOUND;
162d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    }
163d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    layer->clearFrameStats();
164d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    return NO_ERROR;
165d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
166d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
167d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslavstatus_t Client::getLayerFrameStats(const sp<IBinder>& handle, FrameStats* outStats) const {
168d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    sp<Layer> layer = getLayerUser(handle);
169d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    if (layer == NULL) {
170d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav        return NAME_NOT_FOUND;
171d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    }
172d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    layer->getFrameStats(outStats);
173d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav    return NO_ERROR;
174d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav}
175d85084b2b65828442eafaff9b811e9b6c9ca9fadSvetoslav
176db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian// ---------------------------------------------------------------------------
177db403e8ff0d7727015e1a5009bab20eb7ec205bcMathias Agopian}; // namespace android
178