Merge "display: Clean up binder interface"
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 */