display: Clean up binder interface
The current binder implementation is inflexible when it comes to
adding new input/output parameters. It also needs a lot of
boilerplate code written when adding a simple enable/disable type
command.
Instead, let clients specify the parcels they want to pass and
unparcel them at the end points only.
Please note that it is assumed that all commands coming in
need the same permission checks. If this is no longer the case,
some commands need to be split out on the receiver end in
IQService.cpp.
This change also simplifies the code end clients need to write.
They should be able to include QServiceUtils and call a single
function to set the binder up and make the call.
Change-Id: I4db66f2427ecf16d7a6264462ae85815217a16b1
diff --git a/libhwcomposer/hwc_qclient.cpp b/libhwcomposer/hwc_qclient.cpp
index a17565b..3b98788 100644
--- a/libhwcomposer/hwc_qclient.cpp
+++ b/libhwcomposer/hwc_qclient.cpp
@@ -51,57 +51,28 @@
ALOGD_IF(QCLIENT_DEBUG,"QClient Destructor invoked");
}
-status_t QClient::notifyCallback(uint32_t msg, uint32_t value) {
-
- if (msg > IQService::VPU_COMMAND_LIST_START &&
- msg < IQService::VPU_COMMAND_LIST_END) {
- return vpuCommand(msg, value);
- }
-
- switch(msg) {
- case IQService::SECURING:
- securing(value);
- break;
- case IQService::UNSECURING:
- unsecuring(value);
- break;
- case IQService::SCREEN_REFRESH:
- return screenRefresh();
- break;
- case IQService::EXTERNAL_ORIENTATION:
- setExtOrientation(value);
- break;
- case IQService::BUFFER_MIRRORMODE:
- setBufferMirrorMode(value);
- break;
- default:
- return NO_ERROR;
- }
- return NO_ERROR;
-}
-
-void QClient::securing(uint32_t startEnd) {
- Locker::Autolock _sl(mHwcContext->mDrawLock);
+static void securing(hwc_context_t *ctx, uint32_t startEnd) {
+ Locker::Autolock _sl(ctx->mDrawLock);
//The only way to make this class in this process subscribe to media
//player's death.
IMediaDeathNotifier::getMediaPlayerService();
- mHwcContext->mSecuring = startEnd;
+ ctx->mSecuring = startEnd;
//We're done securing
if(startEnd == IQService::END)
- mHwcContext->mSecureMode = true;
- if(mHwcContext->proc)
- mHwcContext->proc->invalidate(mHwcContext->proc);
+ ctx->mSecureMode = true;
+ if(ctx->proc)
+ ctx->proc->invalidate(ctx->proc);
}
-void QClient::unsecuring(uint32_t startEnd) {
- Locker::Autolock _sl(mHwcContext->mDrawLock);
- mHwcContext->mSecuring = startEnd;
+static void unsecuring(hwc_context_t *ctx, uint32_t startEnd) {
+ Locker::Autolock _sl(ctx->mDrawLock);
+ ctx->mSecuring = startEnd;
//We're done unsecuring
if(startEnd == IQService::END)
- mHwcContext->mSecureMode = false;
- if(mHwcContext->proc)
- mHwcContext->proc->invalidate(mHwcContext->proc);
+ ctx->mSecureMode = false;
+ if(ctx->proc)
+ ctx->proc->invalidate(ctx->proc);
}
void QClient::MPDeathNotifier::died() {
@@ -113,33 +84,68 @@
mHwcContext->proc->invalidate(mHwcContext->proc);
}
-android::status_t QClient::screenRefresh() {
+static android::status_t screenRefresh(hwc_context_t *ctx) {
status_t result = NO_INIT;
#ifdef QCOM_BSP
- if(mHwcContext->proc) {
- mHwcContext->proc->invalidate(mHwcContext->proc);
+ if(ctx->proc) {
+ ctx->proc->invalidate(ctx->proc);
result = NO_ERROR;
}
#endif
return result;
}
-android::status_t QClient::vpuCommand(uint32_t command, uint32_t setting) {
+static android::status_t vpuCommand(hwc_context_t *ctx,
+ uint32_t command,
+ const Parcel* inParcel,
+ Parcel* outParcel) {
status_t result = NO_INIT;
#ifdef QCOM_BSP
#ifdef VPU_TARGET
- result = mHwcContext->mVPUClient->processCommand(command, setting);
+ result = ctx->mVPUClient->processCommand(command, inParcel, outParcel);
#endif
#endif
return result;
}
-void QClient::setExtOrientation(uint32_t orientation) {
- mHwcContext->mExtOrientation = orientation;
+static void setExtOrientation(hwc_context_t *ctx, uint32_t orientation) {
+ ctx->mExtOrientation = orientation;
}
-void QClient::setBufferMirrorMode(uint32_t enable) {
- mHwcContext->mBufferMirrorMode = enable;
+static void setBufferMirrorMode(hwc_context_t *ctx, uint32_t enable) {
+ ctx->mBufferMirrorMode = enable;
}
+status_t QClient::notifyCallback(uint32_t command, const Parcel* inParcel,
+ Parcel* outParcel) {
+
+ if (command > IQService::VPU_COMMAND_LIST_START &&
+ command < IQService::VPU_COMMAND_LIST_END) {
+ return vpuCommand(mHwcContext, command, inParcel, outParcel);
+ }
+
+ switch(command) {
+ case IQService::SECURING:
+ securing(mHwcContext, inParcel->readInt32());
+ break;
+ case IQService::UNSECURING:
+ unsecuring(mHwcContext, inParcel->readInt32());
+ break;
+ case IQService::SCREEN_REFRESH:
+ return screenRefresh(mHwcContext);
+ break;
+ case IQService::EXTERNAL_ORIENTATION:
+ setExtOrientation(mHwcContext, inParcel->readInt32());
+ break;
+ case IQService::BUFFER_MIRRORMODE:
+ setBufferMirrorMode(mHwcContext, inParcel->readInt32());
+ break;
+ default:
+ return NO_ERROR;
+ }
+ return NO_ERROR;
+}
+
+
+
}
diff --git a/libhwcomposer/hwc_qclient.h b/libhwcomposer/hwc_qclient.h
index fa1d6b0..d955377 100644
--- a/libhwcomposer/hwc_qclient.h
+++ b/libhwcomposer/hwc_qclient.h
@@ -39,6 +39,7 @@
struct hwc_context_t;
+class Params;
namespace qClient {
// ----------------------------------------------------------------------------
@@ -46,7 +47,9 @@
public:
QClient(hwc_context_t *ctx);
virtual ~QClient();
- virtual android::status_t notifyCallback(uint32_t msg, uint32_t value);
+ virtual android::status_t notifyCallback(uint32_t command,
+ const android::Parcel* inParcel,
+ android::Parcel* outParcel);
private:
//Notifies of Media Player death
@@ -57,13 +60,6 @@
hwc_context_t *mHwcContext;
};
- void securing(uint32_t startEnd);
- void unsecuring(uint32_t startEnd);
- android::status_t screenRefresh();
- void setExtOrientation(uint32_t orientation);
- void setBufferMirrorMode(uint32_t enable);
- android::status_t vpuCommand(uint32_t command, uint32_t setting);
-
hwc_context_t *mHwcContext;
const android::sp<android::IMediaDeathNotifier> mMPDeathNotifier;
};
diff --git a/libhwcomposer/hwc_vpuclient.cpp b/libhwcomposer/hwc_vpuclient.cpp
index bdfeae5..23c6841 100644
--- a/libhwcomposer/hwc_vpuclient.cpp
+++ b/libhwcomposer/hwc_vpuclient.cpp
@@ -31,9 +31,11 @@
#include "hwc_vpuclient.h"
#include "hwc_utils.h"
#include <vpu/vpu.h>
+#include <binder/Parcel.h>
using namespace vpu;
+using namespace android;
namespace qhwc {
VPUClient::VPUClient()
@@ -78,11 +80,14 @@
return err;
}
-int VPUClient::processCommand(uint32_t command, uint32_t setting)
+int VPUClient::processCommand(uint32_t command,
+ const Parcel* inParcel, Parcel* outParcel)
{
if(!mVPU)
return 0;
- return mVPU->processCommand(command, setting);
+ //XXX: Enable when VPU enables it
+ //return mVPU->processCommand(command, inParcel, outParcel);
+ return 0;
}
}; // namespace qhwc
diff --git a/libhwcomposer/hwc_vpuclient.h b/libhwcomposer/hwc_vpuclient.h
index 8cc7137..9985517 100644
--- a/libhwcomposer/hwc_vpuclient.h
+++ b/libhwcomposer/hwc_vpuclient.h
@@ -39,6 +39,9 @@
namespace vpu {
class VPU;
};
+namespace android {
+class Parcel;
+};
namespace qhwc {
@@ -52,7 +55,8 @@
int draw(hwc_context_t *ctx, hwc_display_contents_1_t* list);
- int processCommand(uint32_t command, uint32_t setting);
+ int processCommand(uint32_t command,
+ const android::Parcel* inParcel, android::Parcel* outParcel);
private:
vpu::VPU *mVPU;
diff --git a/libqservice/IQClient.cpp b/libqservice/IQClient.cpp
index 30fbb64..a6251c8 100644
--- a/libqservice/IQClient.cpp
+++ b/libqservice/IQClient.cpp
@@ -28,6 +28,9 @@
using namespace android;
// ---------------------------------------------------------------------------
+// XXX: Since qservice currently runs as part of hwc instead of a standalone
+// process, the implementation below is overridden and the notifyCallback in
+// hwc_qclient is directly called.
namespace qClient {
@@ -41,13 +44,17 @@
BpQClient(const sp<IBinder>& impl)
: BpInterface<IQClient>(impl) {}
- virtual status_t notifyCallback(uint32_t msg, uint32_t value) {
- Parcel data, reply;
+ virtual status_t notifyCallback(uint32_t command,
+ const Parcel* inParcel,
+ Parcel* outParcel) {
+ Parcel data;
+ Parcel *reply = outParcel;
data.writeInterfaceToken(IQClient::getInterfaceDescriptor());
- data.writeInt32(msg);
- data.writeInt32(value);
- remote()->transact(NOTIFY_CALLBACK, data, &reply);
- status_t result = reply.readInt32();
+ data.writeInt32(command);
+ if (inParcel->dataAvail())
+ data.appendFrom(inParcel, inParcel->dataPosition(),
+ inParcel->dataAvail());
+ status_t result = remote()->transact(NOTIFY_CALLBACK, data, reply);
return result;
}
};
@@ -55,21 +62,21 @@
IMPLEMENT_META_INTERFACE(QClient, "android.display.IQClient");
// ----------------------------------------------------------------------
-
+//Stub implementation - nothing needed here
status_t BnQClient::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
switch(code) {
case NOTIFY_CALLBACK: {
CHECK_INTERFACE(IQClient, data, reply);
- uint32_t msg = data.readInt32();
- uint32_t value = data.readInt32();
- notifyCallback(msg, value);
+ uint32_t command = data.readInt32();
+ notifyCallback(command, &data, reply);
return NO_ERROR;
} break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
+
}
}; // namespace qClient
diff --git a/libqservice/IQClient.h b/libqservice/IQClient.h
index a28f826..7d816d2 100644
--- a/libqservice/IQClient.h
+++ b/libqservice/IQClient.h
@@ -33,7 +33,9 @@
{
public:
DECLARE_META_INTERFACE(QClient);
- virtual android::status_t notifyCallback(uint32_t msg, uint32_t value) = 0;
+ virtual android::status_t notifyCallback(uint32_t command,
+ const android::Parcel* inParcel,
+ android::Parcel* outParcel) = 0;
};
// ----------------------------------------------------------------------------
diff --git a/libqservice/IQService.cpp b/libqservice/IQService.cpp
index 33f79c6..d2180bb 100644
--- a/libqservice/IQService.cpp
+++ b/libqservice/IQService.cpp
@@ -27,9 +27,10 @@
#include <binder/IPCThreadState.h>
#include <utils/Errors.h>
#include <private/android_filesystem_config.h>
-
#include <IQService.h>
+#define QSERVICE_DEBUG 0
+
using namespace android;
using namespace qClient;
@@ -43,56 +44,25 @@
BpQService(const sp<IBinder>& impl)
: BpInterface<IQService>(impl) {}
- virtual void securing(uint32_t startEnd) {
- Parcel data, reply;
- data.writeInterfaceToken(IQService::getInterfaceDescriptor());
- data.writeInt32(startEnd);
- remote()->transact(SECURING, data, &reply);
- }
-
- virtual void unsecuring(uint32_t startEnd) {
- Parcel data, reply;
- data.writeInterfaceToken(IQService::getInterfaceDescriptor());
- data.writeInt32(startEnd);
- remote()->transact(UNSECURING, data, &reply);
- }
-
virtual void connect(const sp<IQClient>& client) {
+ ALOGD_IF(QSERVICE_DEBUG, "%s: connect client", __FUNCTION__);
Parcel data, reply;
data.writeInterfaceToken(IQService::getInterfaceDescriptor());
data.writeStrongBinder(client->asBinder());
remote()->transact(CONNECT, data, &reply);
}
- virtual status_t screenRefresh() {
- Parcel data, reply;
+ virtual android::status_t dispatch(uint32_t command, const Parcel* inParcel,
+ Parcel* outParcel) {
+ ALOGD_IF(QSERVICE_DEBUG, "%s: dispatch in:%p", __FUNCTION__, inParcel);
+ status_t err = android::FAILED_TRANSACTION;
+ Parcel data;
+ Parcel *reply = outParcel;
data.writeInterfaceToken(IQService::getInterfaceDescriptor());
- remote()->transact(SCREEN_REFRESH, data, &reply);
- status_t result = reply.readInt32();
- return result;
- }
-
- virtual void setExtOrientation(uint32_t orientation) {
- Parcel data, reply;
- data.writeInterfaceToken(IQService::getInterfaceDescriptor());
- data.writeInt32(orientation);
- remote()->transact(EXTERNAL_ORIENTATION, data, &reply);
- }
-
- virtual void setBufferMirrorMode(uint32_t enable) {
- Parcel data, reply;
- data.writeInterfaceToken(IQService::getInterfaceDescriptor());
- data.writeInt32(enable);
- remote()->transact(BUFFER_MIRRORMODE, data, &reply);
- }
-
- virtual status_t vpuCommand(uint32_t command, uint32_t setting) {
- Parcel data, reply;
- data.writeInterfaceToken(IQService::getInterfaceDescriptor());
- data.writeInt32(setting);
- remote()->transact(command, data, &reply);
- status_t result = reply.readInt32();
- return result;
+ if (inParcel && inParcel->dataSize() > 0)
+ data.appendFrom(inParcel, 0, inParcel->dataSize());
+ err = remote()->transact(command, data, reply);
+ return err;
}
};
@@ -105,7 +75,8 @@
status_t BnQService::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
- // IPC should be from mediaserver only
+ ALOGD_IF(QSERVICE_DEBUG, "%s: code: %d", __FUNCTION__, code);
+ // IPC should be from certain processes only
IPCThreadState* ipc = IPCThreadState::self();
const int callerPid = ipc->getCallingPid();
const int callerUid = ipc->getCallingUid();
@@ -114,94 +85,35 @@
getProcName(callerPid, callingProcName, MAX_BUF_SIZE);
- const bool permission = (callerUid == AID_MEDIA);
+ const bool permission = (callerUid == AID_MEDIA ||
+ callerUid == AID_GRAPHICS ||
+ callerUid == AID_ROOT ||
+ callerUid == AID_SYSTEM);
- if (code > VPU_COMMAND_LIST_START && code < VPU_COMMAND_LIST_END) {
- if(callerUid != AID_SYSTEM && callerUid != AID_ROOT) {
- ALOGE("display.qservice VPU command access denied: \
- pid=%d uid=%d process=%s",callerPid,
+ if (code == CONNECT) {
+ CHECK_INTERFACE(IQService, data, reply);
+ if(callerUid != AID_GRAPHICS) {
+ ALOGE("display.qservice CONNECT access denied: \
+ pid=%d uid=%d process=%s",
+ callerPid, callerUid, callingProcName);
+ return PERMISSION_DENIED;
+ }
+ sp<IQClient> client =
+ interface_cast<IQClient>(data.readStrongBinder());
+ connect(client);
+ return NO_ERROR;
+ } else if (code > COMMAND_LIST_START && code < COMMAND_LIST_END) {
+ if(!permission) {
+ ALOGE("display.qservice access denied: command=%d\
+ pid=%d uid=%d process=%s", code, callerPid,
callerUid, callingProcName);
return PERMISSION_DENIED;
}
CHECK_INTERFACE(IQService, data, reply);
- int32_t setting = data.readInt32();
- return vpuCommand(code, setting);
- }
-
- switch(code) {
- case SECURING: {
- if(!permission) {
- ALOGE("display.qservice SECURING access denied: \
- pid=%d uid=%d process=%s",
- callerPid, callerUid, callingProcName);
- return PERMISSION_DENIED;
- }
- CHECK_INTERFACE(IQService, data, reply);
- uint32_t startEnd = data.readInt32();
- securing(startEnd);
- return NO_ERROR;
- } break;
- case UNSECURING: {
- if(!permission) {
- ALOGE("display.qservice UNSECURING access denied: \
- pid=%d uid=%d process=%s",
- callerPid, callerUid, callingProcName);
- return PERMISSION_DENIED;
- }
- CHECK_INTERFACE(IQService, data, reply);
- uint32_t startEnd = data.readInt32();
- unsecuring(startEnd);
- return NO_ERROR;
- } break;
- case CONNECT: {
- CHECK_INTERFACE(IQService, data, reply);
- if(callerUid != AID_GRAPHICS) {
- ALOGE("display.qservice CONNECT access denied: \
- pid=%d uid=%d process=%s",
- callerPid, callerUid, callingProcName);
- return PERMISSION_DENIED;
- }
- sp<IQClient> client =
- interface_cast<IQClient>(data.readStrongBinder());
- connect(client);
- return NO_ERROR;
- } break;
- case SCREEN_REFRESH: {
- CHECK_INTERFACE(IQService, data, reply);
- if(callerUid != AID_SYSTEM) {
- ALOGE("display.qservice SCREEN_REFRESH access denied: \
- pid=%d uid=%d process=%s",callerPid,
- callerUid, callingProcName);
- return PERMISSION_DENIED;
- }
- return screenRefresh();
- } break;
- case EXTERNAL_ORIENTATION: {
- CHECK_INTERFACE(IQService, data, reply);
- if(callerUid != AID_SYSTEM) {
- ALOGE("display.qservice EXTERNAL_ORIENTATION access denied: \
- pid=%d uid=%d process=%s",callerPid,
- callerUid, callingProcName);
- return PERMISSION_DENIED;
- }
- uint32_t orientation = data.readInt32();
- setExtOrientation(orientation);
- return NO_ERROR;
- } break;
- case BUFFER_MIRRORMODE: {
- CHECK_INTERFACE(IQService, data, reply);
- if(callerUid != AID_SYSTEM) {
- ALOGE("display.qservice BUFFER_MIRRORMODE access denied: \
- pid=%d uid=%d process=%s",callerPid,
- callerUid, callingProcName);
- return PERMISSION_DENIED;
- }
- uint32_t enable = data.readInt32();
- setBufferMirrorMode(enable);
- return NO_ERROR;
- } break;
- default:
- return BBinder::onTransact(code, data, reply, flags);
+ dispatch(code, &data, reply);
+ return NO_ERROR;
+ } else {
+ return BBinder::onTransact(code, data, reply, flags);
}
}
diff --git a/libqservice/IQService.h b/libqservice/IQService.h
index 9cd122e..7ad443d 100644
--- a/libqservice/IQService.h
+++ b/libqservice/IQService.h
@@ -29,35 +29,39 @@
#include <binder/IBinder.h>
#include <IQClient.h>
+
namespace qService {
// ----------------------------------------------------------------------------
+
class IQService : public android::IInterface
{
public:
DECLARE_META_INTERFACE(QService);
enum {
- // Hardware securing start/end notification
- SECURING = android::IBinder::FIRST_CALL_TRANSACTION,
- UNSECURING, // Hardware unsecuring start/end notification
- CONNECT,
- SCREEN_REFRESH,
- EXTERNAL_ORIENTATION,
- BUFFER_MIRRORMODE,
- //VPU command codes - list is defined in vpu.h
- VPU_COMMAND_LIST_START = 100,
- VPU_COMMAND_LIST_END = 200,
+ COMMAND_LIST_START = android::IBinder::FIRST_CALL_TRANSACTION,
+ SECURING, // Hardware securing start/end notification
+ UNSECURING, // Hardware unsecuring start/end notification
+ CONNECT, // Connect to qservice
+ SCREEN_REFRESH, // Refresh screen through SF invalidate
+ EXTERNAL_ORIENTATION, // Set external orientation
+ BUFFER_MIRRORMODE, // Buffer mirrormode
+ VPU_COMMAND_LIST_START = 100, //Reserved block for VPU commands
+ VPU_COMMAND_LIST_END = 200,
+ COMMAND_LIST_END = 400,
};
+
enum {
END = 0,
START,
};
- virtual void securing(uint32_t startEnd) = 0;
- virtual void unsecuring(uint32_t startEnd) = 0;
+
+ // Register a client that can be notified
virtual void connect(const android::sp<qClient::IQClient>& client) = 0;
- virtual android::status_t screenRefresh() = 0;
- virtual void setExtOrientation(uint32_t orientation) = 0;
- virtual void setBufferMirrorMode(uint32_t enable) = 0;
- virtual android::status_t vpuCommand(uint32_t command, uint32_t setting) = 0;
+ // Generic function to dispatch binder commands
+ // The type of command decides how the data is parceled
+ virtual android::status_t dispatch(uint32_t command,
+ const android::Parcel* inParcel,
+ android::Parcel* outParcel) = 0;
};
// ----------------------------------------------------------------------------
diff --git a/libqservice/QService.cpp b/libqservice/QService.cpp
index 327888c..aac5788 100644
--- a/libqservice/QService.cpp
+++ b/libqservice/QService.cpp
@@ -47,49 +47,19 @@
ALOGD_IF(QSERVICE_DEBUG,"QService Destructor invoked");
}
-void QService::securing(uint32_t startEnd) {
- if(mClient.get()) {
- mClient->notifyCallback(SECURING, startEnd);
- }
-}
-
-void QService::unsecuring(uint32_t startEnd) {
- if(mClient.get()) {
- mClient->notifyCallback(UNSECURING, startEnd);
- }
-}
-
void QService::connect(const sp<qClient::IQClient>& client) {
+ ALOGD_IF(QSERVICE_DEBUG,"client connected");
mClient = client;
}
-android::status_t QService::screenRefresh() {
- status_t result = NO_ERROR;
- if(mClient.get()) {
- result = mClient->notifyCallback(SCREEN_REFRESH, 0);
+status_t QService::dispatch(uint32_t command, const Parcel* inParcel,
+ Parcel* outParcel) {
+ status_t err = FAILED_TRANSACTION;
+ if (mClient.get()) {
+ ALOGD_IF(QSERVICE_DEBUG, "Dispatching command: %d", command);
+ err = mClient->notifyCallback(command, inParcel, outParcel);
}
- return result;
-}
-
-android::status_t QService::vpuCommand(uint32_t command, uint32_t setting ) {
- status_t result = NO_ERROR;
- if(mClient.get()) {
- result = mClient->notifyCallback(command, setting);
- }
- return result;
-}
-
-
-void QService::setExtOrientation(uint32_t orientation) {
- if(mClient.get()) {
- mClient->notifyCallback(EXTERNAL_ORIENTATION, orientation);
- }
-}
-
-void QService::setBufferMirrorMode(uint32_t enable) {
- if(mClient.get()) {
- mClient->notifyCallback(BUFFER_MIRRORMODE, enable);
- }
+ return err;
}
void QService::init()
diff --git a/libqservice/QService.h b/libqservice/QService.h
index de18b59..a8e4cdb 100644
--- a/libqservice/QService.h
+++ b/libqservice/QService.h
@@ -45,13 +45,10 @@
class QService : public BnQService {
public:
virtual ~QService();
- virtual void securing(uint32_t startEnd);
- virtual void unsecuring(uint32_t startEnd);
virtual void connect(const android::sp<qClient::IQClient>& client);
- virtual android::status_t screenRefresh();
- virtual void setExtOrientation(uint32_t orientation);
- virtual void setBufferMirrorMode(uint32_t enable);
- virtual android::status_t vpuCommand(uint32_t command, uint32_t setting);
+ virtual android::status_t dispatch(uint32_t command,
+ const android::Parcel* data,
+ android::Parcel* reply);
static void init();
private:
QService();
diff --git a/libqservice/QServiceUtils.h b/libqservice/QServiceUtils.h
new file mode 100644
index 0000000..3d1adc0
--- /dev/null
+++ b/libqservice/QServiceUtils.h
@@ -0,0 +1,86 @@
+/*
+* Copyright (c) 2013 The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation. nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef QSERVICEUTILS_H
+#define QSERVICEUTILS_H
+#include <binder/Parcel.h>
+#include <binder/IServiceManager.h>
+#include <utils/RefBase.h>
+#include <IQService.h>
+
+// ----------------------------------------------------------------------------
+// Helpers
+// ----------------------------------------------------------------------------
+inline android::sp<qService::IQService> getBinder() {
+ android::sp<android::IServiceManager> sm = android::defaultServiceManager();
+ android::sp<qService::IQService> binder =
+ android::interface_cast<qService::IQService>
+ (sm->getService(android::String16("display.qservice")));
+ if (binder == NULL) {
+ ALOGE("%s: invalid binder object", __FUNCTION__);
+ }
+ return binder;
+}
+
+inline android::status_t sendSingleParam(uint32_t command, uint32_t value) {
+ android::status_t err = android::FAILED_TRANSACTION;
+ android::sp<qService::IQService> binder = getBinder();
+ android::Parcel inParcel, outParcel;
+ inParcel.writeInt32(value);
+ if(binder != NULL) {
+ err = binder->dispatch(command, &inParcel , &outParcel);
+ }
+ return err;
+}
+
+// ----------------------------------------------------------------------------
+// Convenience wrappers that clients can call
+// ----------------------------------------------------------------------------
+inline android::status_t securing(uint32_t startEnd) {
+ return sendSingleParam(qService::IQService::SECURING, startEnd);
+}
+
+inline android::status_t unsecuring(uint32_t startEnd) {
+ return sendSingleParam(qService::IQService::UNSECURING, startEnd);
+}
+
+inline android::status_t screenRefresh() {
+ return sendSingleParam(qService::IQService::SCREEN_REFRESH, 1);
+}
+
+inline android::status_t setExtOrientation(uint32_t orientation) {
+ return sendSingleParam(qService::IQService::EXTERNAL_ORIENTATION,
+ orientation);
+}
+
+inline android::status_t setBufferMirrorMode(uint32_t enable) {
+ return sendSingleParam(qService::IQService::BUFFER_MIRRORMODE, enable);
+}
+
+#endif /* end of include guard: QSERVICEUTILS_H */