summaryrefslogtreecommitdiffstats
path: root/libs/gui/ISurfaceComposerClient.cpp
diff options
context:
space:
mode:
authorMathias Agopian <mathias@google.com>2011-03-25 18:42:40 -0700
committerMathias Agopian <mathias@google.com>2011-03-25 18:42:40 -0700
commit696257ccf315a1da042787c5b2d1f80c7146fc94 (patch)
tree39c185c6f97540243e5d071e545343822f46f2cc /libs/gui/ISurfaceComposerClient.cpp
parent1be6cce70175bd90744498d5fca95e3f9eec1cf6 (diff)
downloadframeworks_base-696257ccf315a1da042787c5b2d1f80c7146fc94.zip
frameworks_base-696257ccf315a1da042787c5b2d1f80c7146fc94.tar.gz
frameworks_base-696257ccf315a1da042787c5b2d1f80c7146fc94.tar.bz2
merge libsurfaceflinger_client into libgui
this is the first step in unifying surfacetexture and surface. for this reason the header files were not moved, as most of them will eventually go away. NOTE: currently we keep libsurfaceflinger_client.so as an empty library to workaround prebuilt binaries wrongly linking against it. Change-Id: I130f0de2428e8579033dc41394d093f4e1431a00
Diffstat (limited to 'libs/gui/ISurfaceComposerClient.cpp')
-rw-r--r--libs/gui/ISurfaceComposerClient.cpp231
1 files changed, 231 insertions, 0 deletions
diff --git a/libs/gui/ISurfaceComposerClient.cpp b/libs/gui/ISurfaceComposerClient.cpp
new file mode 100644
index 0000000..7730eb1
--- /dev/null
+++ b/libs/gui/ISurfaceComposerClient.cpp
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// tag as surfaceflinger
+#define LOG_TAG "SurfaceFlinger"
+
+#include <stdio.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <binder/Parcel.h>
+#include <binder/IMemory.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+
+#include <ui/Point.h>
+#include <ui/Rect.h>
+
+#include <surfaceflinger/ISurface.h>
+#include <surfaceflinger/ISurfaceComposerClient.h>
+#include <private/surfaceflinger/LayerState.h>
+
+// ---------------------------------------------------------------------------
+
+/* ideally AID_GRAPHICS would be in a semi-public header
+ * or there would be a way to map a user/group name to its id
+ */
+#ifndef AID_GRAPHICS
+#define AID_GRAPHICS 1003
+#endif
+
+#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
+#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+enum {
+ GET_CBLK = IBinder::FIRST_CALL_TRANSACTION,
+ GET_TOKEN,
+ CREATE_SURFACE,
+ DESTROY_SURFACE,
+ SET_STATE
+};
+
+class BpSurfaceComposerClient : public BpInterface<ISurfaceComposerClient>
+{
+public:
+ BpSurfaceComposerClient(const sp<IBinder>& impl)
+ : BpInterface<ISurfaceComposerClient>(impl)
+ {
+ }
+
+ virtual sp<IMemoryHeap> getControlBlock() const
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
+ remote()->transact(GET_CBLK, data, &reply);
+ return interface_cast<IMemoryHeap>(reply.readStrongBinder());
+ }
+
+ virtual ssize_t getTokenForSurface(const sp<ISurface>& sur) const
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
+ data.writeStrongBinder(sur->asBinder());
+ remote()->transact(GET_TOKEN, data, &reply);
+ return reply.readInt32();
+ }
+
+ virtual sp<ISurface> createSurface( surface_data_t* params,
+ int pid,
+ const String8& name,
+ DisplayID display,
+ uint32_t w,
+ uint32_t h,
+ PixelFormat format,
+ uint32_t flags)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
+ data.writeInt32(pid);
+ data.writeString8(name);
+ data.writeInt32(display);
+ data.writeInt32(w);
+ data.writeInt32(h);
+ data.writeInt32(format);
+ data.writeInt32(flags);
+ remote()->transact(CREATE_SURFACE, data, &reply);
+ params->readFromParcel(reply);
+ return interface_cast<ISurface>(reply.readStrongBinder());
+ }
+
+ virtual status_t destroySurface(SurfaceID sid)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
+ data.writeInt32(sid);
+ remote()->transact(DESTROY_SURFACE, data, &reply);
+ return reply.readInt32();
+ }
+
+ virtual status_t setState(int32_t count, const layer_state_t* states)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
+ data.writeInt32(count);
+ for (int i=0 ; i<count ; i++)
+ states[i].write(data);
+ remote()->transact(SET_STATE, data, &reply);
+ return reply.readInt32();
+ }
+};
+
+IMPLEMENT_META_INTERFACE(SurfaceComposerClient, "android.ui.ISurfaceComposerClient");
+
+// ----------------------------------------------------------------------
+
+status_t BnSurfaceComposerClient::onTransact(
+ uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+ // codes that don't require permission check
+
+ switch(code) {
+ case GET_CBLK: {
+ CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
+ sp<IMemoryHeap> ctl(getControlBlock());
+ reply->writeStrongBinder(ctl->asBinder());
+ return NO_ERROR;
+ } break;
+ case GET_TOKEN: {
+ CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
+ sp<ISurface> sur = interface_cast<ISurface>(data.readStrongBinder());
+ ssize_t token = getTokenForSurface(sur);
+ reply->writeInt32(token);
+ return NO_ERROR;
+ } break;
+ }
+
+ // these must be checked
+
+ IPCThreadState* ipc = IPCThreadState::self();
+ const int pid = ipc->getCallingPid();
+ const int uid = ipc->getCallingUid();
+ const int self_pid = getpid();
+ if (UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != 0)) {
+ // we're called from a different process, do the real check
+ if (!checkCallingPermission(
+ String16("android.permission.ACCESS_SURFACE_FLINGER")))
+ {
+ LOGE("Permission Denial: "
+ "can't openGlobalTransaction pid=%d, uid=%d", pid, uid);
+ return PERMISSION_DENIED;
+ }
+ }
+
+ switch(code) {
+ case CREATE_SURFACE: {
+ CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
+ surface_data_t params;
+ int32_t pid = data.readInt32();
+ String8 name = data.readString8();
+ DisplayID display = data.readInt32();
+ uint32_t w = data.readInt32();
+ uint32_t h = data.readInt32();
+ PixelFormat format = data.readInt32();
+ uint32_t flags = data.readInt32();
+ sp<ISurface> s = createSurface(&params, pid, name, display, w, h,
+ format, flags);
+ params.writeToParcel(reply);
+ reply->writeStrongBinder(s->asBinder());
+ return NO_ERROR;
+ } break;
+ case DESTROY_SURFACE: {
+ CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
+ reply->writeInt32( destroySurface( data.readInt32() ) );
+ return NO_ERROR;
+ } break;
+ case SET_STATE: {
+ CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
+ int32_t count = data.readInt32();
+ layer_state_t* states = new layer_state_t[count];
+ for (int i=0 ; i<count ; i++)
+ states[i].read(data);
+ status_t err = setState(count, states);
+ delete [] states;
+ reply->writeInt32(err);
+ return NO_ERROR;
+ } break;
+ default:
+ return BBinder::onTransact(code, data, reply, flags);
+ }
+}
+
+// ----------------------------------------------------------------------
+
+status_t ISurfaceComposerClient::surface_data_t::readFromParcel(const Parcel& parcel)
+{
+ token = parcel.readInt32();
+ identity = parcel.readInt32();
+ width = parcel.readInt32();
+ height = parcel.readInt32();
+ format = parcel.readInt32();
+ return NO_ERROR;
+}
+
+status_t ISurfaceComposerClient::surface_data_t::writeToParcel(Parcel* parcel) const
+{
+ parcel->writeInt32(token);
+ parcel->writeInt32(identity);
+ parcel->writeInt32(width);
+ parcel->writeInt32(height);
+ parcel->writeInt32(format);
+ return NO_ERROR;
+}
+
+}; // namespace android