Merge "qdutils: Default to GPU composition"
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index 6003688..5aca758 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.cpp
@@ -47,6 +47,8 @@
 using namespace gralloc;
 using namespace qdutils;
 
+ANDROID_SINGLETON_STATIC_INSTANCE(AdrenoMemInfo);
+
 //Common functions
 static bool canFallback(int usage, bool triedSystem)
 {
@@ -81,6 +83,35 @@
     return false;
 }
 
+//-------------- AdrenoMemInfo-----------------------//
+int AdrenoMemInfo::getStride(int width, int format)
+{
+    int stride = ALIGN(width, 32);
+    switch (format)
+    {
+        case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
+            stride = ALIGN(width, 32);
+            break;
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
+            stride = ALIGN(width, 128);
+            break;
+        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+        case HAL_PIXEL_FORMAT_YV12:
+        case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+        case HAL_PIXEL_FORMAT_YCrCb_422_SP:
+            stride = ALIGN(width, 16);
+            break;
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+            stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, width);
+            break;
+        default: break;
+    }
+    return stride;
+}
+
+//-------------- IAllocController-----------------------//
 IAllocController* IAllocController::sController = NULL;
 IAllocController* IAllocController::getInstance(void)
 {
@@ -176,7 +207,7 @@
 {
     size_t size;
 
-    alignedw = ALIGN(width, 32);
+    alignedw = AdrenoMemInfo::getInstance().getStride(width, format);
     alignedh = ALIGN(height, 32);
     switch (format) {
         case HAL_PIXEL_FORMAT_RGBA_8888:
@@ -202,7 +233,6 @@
             // The chroma plane is subsampled,
             // but the pitch in bytes is unchanged
             // The GPU needs 4K alignment, but the video decoder needs 8K
-            alignedw = ALIGN(width, 128);
             size  = ALIGN( alignedw * alignedh, 8192);
             size += ALIGN( alignedw * ALIGN(height/2, 32), 8192);
             break;
@@ -214,7 +244,6 @@
                 ALOGE("w or h is odd for the YV12 format");
                 return -EINVAL;
             }
-            alignedw = ALIGN(width, 16);
             alignedh = height;
             if (HAL_PIXEL_FORMAT_NV12_ENCODEABLE == format) {
                 // The encoder requires a 2K aligned chroma offset.
@@ -232,12 +261,10 @@
                 ALOGE("width is odd for the YUV422_SP format");
                 return -EINVAL;
             }
-            alignedw = ALIGN(width, 16);
             alignedh = height;
             size = ALIGN(alignedw * alignedh * 2, 4096);
             break;
         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
-            alignedw = VENUS_Y_STRIDE(COLOR_FMT_NV12, width);
             alignedh = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height);
             size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
             break;
diff --git a/libgralloc/gr.h b/libgralloc/gr.h
index cee47de..c6bd137 100644
--- a/libgralloc/gr.h
+++ b/libgralloc/gr.h
@@ -31,6 +31,7 @@
 #include <errno.h>
 
 #include <cutils/native_handle.h>
+#include <utils/Singleton.h>
 
 /*****************************************************************************/
 
@@ -79,4 +80,16 @@
     inline void unlock()   { pthread_mutex_unlock(&mutex); }
 };
 
+
+class AdrenoMemInfo : public android::Singleton <AdrenoMemInfo>
+{
+    public:
+    AdrenoMemInfo() {}
+
+    ~AdrenoMemInfo() {}
+
+    int getStride(int width, int format);
+
+    private:
+};
 #endif /* GR_H_ */
diff --git a/libgralloc/gralloc_priv.h b/libgralloc/gralloc_priv.h
index 2c50e77..d2f3073 100644
--- a/libgralloc/gralloc_priv.h
+++ b/libgralloc/gralloc_priv.h
@@ -85,6 +85,7 @@
     /* Gralloc perform enums
     */
     GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER = 1,
+    GRALLOC_MODULE_PERFORM_GET_STRIDE,
 };
 
 #define GRALLOC_HEAP_MASK   (GRALLOC_USAGE_PRIVATE_UI_CONTIG_HEAP |\
diff --git a/libgralloc/mapper.cpp b/libgralloc/mapper.cpp
index 4f28877..27761be 100644
--- a/libgralloc/mapper.cpp
+++ b/libgralloc/mapper.cpp
@@ -369,6 +369,14 @@
                 res = 0;
             }
             break;
+        case GRALLOC_MODULE_PERFORM_GET_STRIDE:
+            {
+                int width   = va_arg(args, int);
+                int format  = va_arg(args, int);
+                int *stride = va_arg(args, int *);
+                *stride = AdrenoMemInfo::getInstance().getStride(width, format);
+                res = 0;
+            } break;
 #endif
         default:
             break;
diff --git a/libhwcomposer/Android.mk b/libhwcomposer/Android.mk
index a9ada35..1618ef5 100644
--- a/libhwcomposer/Android.mk
+++ b/libhwcomposer/Android.mk
@@ -8,7 +8,7 @@
 LOCAL_C_INCLUDES              := $(common_includes) $(kernel_includes)
 LOCAL_SHARED_LIBRARIES        := $(common_libs) libEGL liboverlay libgenlock \
                                  libexternal libqdutils libhardware_legacy \
-                                 libdl libmemalloc libqservice libsync
+                                 libdl libmemalloc libqservice libsync libbinder
 LOCAL_CFLAGS                  := $(common_flags) -DLOG_TAG=\"qdhwcomposer\"
 LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
 LOCAL_SRC_FILES               := hwc.cpp          \
@@ -18,6 +18,7 @@
                                  hwc_vsync.cpp    \
                                  hwc_fbupdate.cpp \
                                  hwc_mdpcomp.cpp  \
-                                 hwc_copybit.cpp
+                                 hwc_copybit.cpp  \
+                                 hwc_qclient.cpp
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index 3a241c8..baf4523 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -401,7 +401,7 @@
 
 /*
  * MDPComp not possible when
- * 1. We have more than sMaxLayers
+ * 1. App layers > available pipes
  * 2. External display connected
  * 3. Composition is triggered by
  *    Idle timer expiry
@@ -417,6 +417,8 @@
 
     overlay::Overlay& ov = *ctx->mOverlay;
     int availablePipes = ov.availablePipes(dpy);
+    if (availablePipes > MAX_PIPES_PER_MIXER)
+        availablePipes = MAX_PIPES_PER_MIXER;
 
     if(numAppLayers < 1 || numAppLayers > availablePipes) {
         ALOGD_IF(isDebug(), "%s: Unsupported number of layers",__FUNCTION__);
diff --git a/libhwcomposer/hwc_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h
index 9ae9b2e..45cd77b 100644
--- a/libhwcomposer/hwc_mdpcomp.h
+++ b/libhwcomposer/hwc_mdpcomp.h
@@ -25,6 +25,7 @@
 #include <overlay.h>
 
 #define DEFAULT_IDLE_TIME 2000
+#define MAX_PIPES_PER_MIXER 4
 
 namespace qhwc {
 namespace ovutils = overlay::utils;
diff --git a/libhwcomposer/hwc_qclient.cpp b/libhwcomposer/hwc_qclient.cpp
new file mode 100644
index 0000000..32dc451
--- /dev/null
+++ b/libhwcomposer/hwc_qclient.cpp
@@ -0,0 +1,83 @@
+/*
+ *  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 CLIENTS; 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.
+ */
+
+#include <hwc_qclient.h>
+#include <IQService.h>
+#include <hwc_utils.h>
+
+#define QCLIENT_DEBUG 0
+
+using namespace android;
+using namespace qService;
+
+namespace qClient {
+
+// ----------------------------------------------------------------------------
+QClient::QClient(hwc_context_t *ctx) : mHwcContext(ctx)
+{
+    ALOGD_IF(QCLIENT_DEBUG, "QClient Constructor invoked");
+}
+
+QClient::~QClient()
+{
+    ALOGD_IF(QCLIENT_DEBUG,"QClient Destructor invoked");
+}
+
+void QClient::notifyCallback(uint32_t msg, uint32_t value) {
+    switch(msg) {
+        case IQService::SECURING:
+            securing(value);
+            break;
+        case IQService::UNSECURING:
+            unsecuring(value);
+            break;
+        default:
+            return;
+    }
+}
+
+void QClient::securing(uint32_t startEnd) {
+    mHwcContext->mSecuring = startEnd;
+    //We're done securing
+    if(startEnd == IQService::END)
+        mHwcContext->mSecureMode = true;
+    if(mHwcContext->proc)
+        mHwcContext->proc->invalidate(mHwcContext->proc);
+}
+
+void QClient::unsecuring(uint32_t startEnd) {
+    mHwcContext->mSecuring = startEnd;
+    //We're done unsecuring
+    if(startEnd == IQService::END)
+        mHwcContext->mSecureMode = false;
+    if(mHwcContext->proc)
+        mHwcContext->proc->invalidate(mHwcContext->proc);
+}
+
+}
diff --git a/libhwcomposer/hwc_qclient.h b/libhwcomposer/hwc_qclient.h
new file mode 100644
index 0000000..1f3944f
--- /dev/null
+++ b/libhwcomposer/hwc_qclient.h
@@ -0,0 +1,55 @@
+/*
+ *  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 CLIENTS; 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 ANDROID_QCLIENT_H
+#define ANDROID_QCLIENT_H
+
+#include <utils/Errors.h>
+#include <sys/types.h>
+#include <cutils/log.h>
+#include <binder/IServiceManager.h>
+#include <IQClient.h>
+
+struct hwc_context_t;
+
+namespace qClient {
+// ----------------------------------------------------------------------------
+
+class QClient : public BnQClient {
+public:
+    QClient(hwc_context_t *ctx);
+    virtual ~QClient();
+    virtual void notifyCallback(uint32_t msg, uint32_t value);
+private:
+    void securing(uint32_t startEnd);
+    void unsecuring(uint32_t startEnd);
+    hwc_context_t *mHwcContext;
+};
+}; // namespace qClient
+#endif // ANDROID_QCLIENT_H
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 093c0b3..0c26bda 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -19,6 +19,7 @@
  */
 #define HWC_UTILS_DEBUG 0
 #include <sys/ioctl.h>
+#include <binder/IServiceManager.h>
 #include <EGL/egl.h>
 #include <cutils/properties.h>
 #include <gralloc_priv.h>
@@ -30,8 +31,14 @@
 #include "mdp_version.h"
 #include "hwc_copybit.h"
 #include "external.h"
+#include "hwc_qclient.h"
 #include "QService.h"
 #include "comptype.h"
+
+using namespace qClient;
+using namespace qService;
+using namespace android;
+
 namespace qhwc {
 
 // Opens Framebuffer device
@@ -60,7 +67,6 @@
     openFramebufferDevice(ctx);
     overlay::Overlay::initOverlay();
     ctx->mOverlay = overlay::Overlay::getInstance();
-    ctx->mQService = qService::QService::getInstance(ctx);
     ctx->mMDP.version = qdutils::MDPVersion::getInstance().getMDPVersion();
     ctx->mMDP.hasOverlay = qdutils::MDPVersion::getInstance().hasOverlay();
     ctx->mMDP.panel = qdutils::MDPVersion::getInstance().getPanelType();
@@ -93,6 +99,15 @@
     pthread_cond_init(&(ctx->vstate.cond), NULL);
     ctx->vstate.enable = false;
     ctx->mExtDispConfiguring = false;
+
+    //Right now hwc starts the service but anybody could do it, or it could be
+    //independent process as well.
+    QService::init();
+    sp<IQClient> client = new QClient(ctx);
+    interface_cast<IQService>(
+            defaultServiceManager()->getService(
+            String16("display.qservice")))->connect(client);
+
     ALOGI("Initializing Qualcomm Hardware Composer");
     ALOGI("MDP version: %d", ctx->mMDP.version);
 }
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index c66f7ff..525fd75 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -40,10 +40,6 @@
 struct hwc_context_t;
 struct framebuffer_device_t;
 
-namespace qService {
-class QService;
-}
-
 namespace overlay {
 class Overlay;
 }
@@ -229,8 +225,6 @@
 
     //Overlay object - NULL for non overlay devices
     overlay::Overlay *mOverlay;
-    //QService object
-    qService::QService *mQService;
 
     //Primary and external FB updater
     qhwc::IFBUpdate *mFBUpdate[HWC_NUM_DISPLAY_TYPES];
diff --git a/libhwcomposer/hwc_vsync.cpp b/libhwcomposer/hwc_vsync.cpp
index 5f62eba..f83b6d7 100644
--- a/libhwcomposer/hwc_vsync.cpp
+++ b/libhwcomposer/hwc_vsync.cpp
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * Not a Contribution, Apache license notifications and license are
  * retained for attribution purposes only.
@@ -32,7 +32,7 @@
 #include "string.h"
 #include "external.h"
 
-
+using android::LogIfSlow;
 namespace qhwc {
 
 #define HWC_VSYNC_THREAD_NAME "hwcVsyncThread"
@@ -61,6 +61,7 @@
     bool fb1_vsync = false;
     bool enabled = false;
     bool fakevsync = false;
+    uint32_t log_threshold = ns2ms(ctx->dpyAttr[dpy].vsync_period)*2;
 
     char property[PROPERTY_VALUE_MAX];
     if(property_get("debug.hwc.fakevsync", property, NULL) > 0) {
@@ -111,6 +112,7 @@
 
         if(!fakevsync) {
             for(int i = 0; i < MAX_RETRY_COUNT; i++) {
+                ALOGD_IF_SLOW(log_threshold, "Excessive delay reading vsync");
                 len = pread(fd_timestamp, vdata, MAX_DATA, 0);
                 if(len < 0 && (errno == EAGAIN ||
                                errno == EINTR  ||
diff --git a/libqservice/Android.mk b/libqservice/Android.mk
index 8e82f42..e1585e4 100644
--- a/libqservice/Android.mk
+++ b/libqservice/Android.mk
@@ -10,6 +10,7 @@
 LOCAL_CFLAGS                  := $(common_flags) -DLOG_TAG=\"qdqservice\"
 LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
 LOCAL_SRC_FILES               := QService.cpp \
-                                 IQService.cpp
+                                 IQService.cpp \
+                                 IQClient.cpp
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/libqservice/IQClient.cpp b/libqservice/IQClient.cpp
new file mode 100644
index 0000000..4ff67dc
--- /dev/null
+++ b/libqservice/IQClient.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * Not a Contribution, Apache license notifications and license are
+ * retained for attribution purposes only.
+
+ * 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.
+ */
+
+#include <sys/types.h>
+#include <binder/Parcel.h>
+#include <binder/IBinder.h>
+#include <binder/IInterface.h>
+#include <utils/Errors.h>
+#include <IQClient.h>
+
+using namespace android;
+
+// ---------------------------------------------------------------------------
+
+namespace qClient {
+
+enum {
+    NOTIFY_CALLBACK = IBinder::FIRST_CALL_TRANSACTION,
+};
+
+class BpQClient : public BpInterface<IQClient>
+{
+public:
+    BpQClient(const sp<IBinder>& impl)
+        : BpInterface<IQClient>(impl) {}
+
+    virtual void notifyCallback(uint32_t msg, uint32_t value) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IQClient::getInterfaceDescriptor());
+        data.writeInt32(msg);
+        data.writeInt32(value);
+        remote()->transact(NOTIFY_CALLBACK, data, &reply);
+    }
+};
+
+IMPLEMENT_META_INTERFACE(QClient, "android.display.IQClient");
+
+// ----------------------------------------------------------------------
+
+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);
+            return NO_ERROR;
+        } break;
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+}; // namespace qClient
diff --git a/libqservice/IQClient.h b/libqservice/IQClient.h
new file mode 100644
index 0000000..68d8275
--- /dev/null
+++ b/libqservice/IQClient.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * Not a Contribution, Apache license notifications and license are
+ * retained for attribution purposes only.
+
+ * 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.
+ */
+
+#ifndef ANDROID_IQCLIENT_H
+#define ANDROID_IQCLIENT_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <binder/IInterface.h>
+
+namespace qClient {
+// ----------------------------------------------------------------------------
+class IQClient : public android::IInterface
+{
+public:
+    DECLARE_META_INTERFACE(QClient);
+    virtual void notifyCallback(uint32_t msg, uint32_t value) = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnQClient : public android::BnInterface<IQClient>
+{
+public:
+    virtual android::status_t onTransact( uint32_t code,
+                                          const android::Parcel& data,
+                                          android::Parcel* reply,
+                                          uint32_t flags = 0);
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace qClient
+
+#endif // ANDROID_IQCLIENT_H
diff --git a/libqservice/IQService.cpp b/libqservice/IQService.cpp
index 420d59c..7a88bdf 100644
--- a/libqservice/IQService.cpp
+++ b/libqservice/IQService.cpp
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * Not a Contribution, Apache license notifications and license are
  * retained for attribution purposes only.
@@ -31,6 +31,7 @@
 #include <IQService.h>
 
 using namespace android;
+using namespace qClient;
 
 // ---------------------------------------------------------------------------
 
@@ -55,6 +56,13 @@
         data.writeInt32(startEnd);
         remote()->transact(UNSECURING, data, &reply);
     }
+
+    virtual void connect(const sp<IQClient>& client) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IQService::getInterfaceDescriptor());
+        data.writeStrongBinder(client->asBinder());
+        remote()->transact(CONNECT, data, &reply);
+    }
 };
 
 IMPLEMENT_META_INTERFACE(QService, "android.display.IQService");
@@ -100,6 +108,18 @@
             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;
         default:
             return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/libqservice/IQService.h b/libqservice/IQService.h
index 8647efa..70e6c64 100644
--- a/libqservice/IQService.h
+++ b/libqservice/IQService.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * Not a Contribution, Apache license notifications and license are
  * retained for attribution purposes only.
@@ -26,6 +26,8 @@
 #include <utils/Errors.h>
 #include <utils/RefBase.h>
 #include <binder/IInterface.h>
+#include <binder/IBinder.h>
+#include <IQClient.h>
 
 namespace qService {
 // ----------------------------------------------------------------------------
@@ -34,8 +36,10 @@
 public:
     DECLARE_META_INTERFACE(QService);
     enum {
-        SECURING = 0, // Hardware securing start/end notification
+        // Hardware securing start/end notification
+        SECURING = android::IBinder::FIRST_CALL_TRANSACTION,
         UNSECURING, // Hardware unsecuring start/end notification
+        CONNECT,
     };
     enum {
         END = 0,
@@ -43,6 +47,7 @@
     };
     virtual void securing(uint32_t startEnd) = 0;
     virtual void unsecuring(uint32_t startEnd) = 0;
+    virtual void connect(const android::sp<qClient::IQClient>& client) = 0;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/libqservice/QService.cpp b/libqservice/QService.cpp
index 1c9f165..8fc7319 100644
--- a/libqservice/QService.cpp
+++ b/libqservice/QService.cpp
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *  Copyright (c) 2012-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
@@ -28,7 +28,6 @@
  */
 
 #include <QService.h>
-#include <hwc_utils.h>
 
 #define QSERVICE_DEBUG 0
 
@@ -38,7 +37,7 @@
 
 QService* QService::sQService = NULL;
 // ----------------------------------------------------------------------------
-QService::QService(hwc_context_t *ctx):mHwcContext(ctx)
+QService::QService()
 {
     ALOGD_IF(QSERVICE_DEBUG, "QService Constructor invoked");
 }
@@ -49,27 +48,25 @@
 }
 
 void QService::securing(uint32_t startEnd) {
-    mHwcContext->mSecuring = startEnd;
-    //We're done securing
-    if(startEnd == END)
-        mHwcContext->mSecureMode = true;
-    if(mHwcContext->proc)
-        mHwcContext->proc->invalidate(mHwcContext->proc);
+    if(mClient.get()) {
+        mClient->notifyCallback(SECURING, startEnd);
+    }
 }
 
 void QService::unsecuring(uint32_t startEnd) {
-    mHwcContext->mSecuring = startEnd;
-    //We're done unsecuring
-    if(startEnd == END)
-        mHwcContext->mSecureMode = false;
-    if(mHwcContext->proc)
-        mHwcContext->proc->invalidate(mHwcContext->proc);
+    if(mClient.get()) {
+        mClient->notifyCallback(UNSECURING, startEnd);
+    }
 }
 
-QService* QService::getInstance(hwc_context_t *ctx)
+void QService::connect(const sp<qClient::IQClient>& client) {
+    mClient = client;
+}
+
+void QService::init()
 {
     if(!sQService) {
-        sQService = new QService(ctx);
+        sQService = new QService();
         sp<IServiceManager> sm = defaultServiceManager();
         sm->addService(String16("display.qservice"), sQService);
         if(sm->checkService(String16("display.qservice")) != NULL)
@@ -77,7 +74,6 @@
         else
             ALOGD_IF(QSERVICE_DEBUG, "adding display.qservice failed");
     }
-    return sQService;
 }
 
 }
diff --git a/libqservice/QService.h b/libqservice/QService.h
index ab458a4..4f7e570 100644
--- a/libqservice/QService.h
+++ b/libqservice/QService.h
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *  Copyright (c) 2012-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
@@ -35,6 +35,7 @@
 #include <cutils/log.h>
 #include <binder/IServiceManager.h>
 #include <IQService.h>
+#include <IQClient.h>
 
 struct hwc_context_t;
 
@@ -46,11 +47,12 @@
     virtual ~QService();
     virtual void securing(uint32_t startEnd);
     virtual void unsecuring(uint32_t startEnd);
-    static QService* getInstance(hwc_context_t *ctx);
+    virtual void connect(const android::sp<qClient::IQClient>& client);
+    static void init();
 private:
-    QService(hwc_context_t *ctx);
+    QService();
+    android::sp<qClient::IQClient> mClient;
     static QService *sQService;
-    hwc_context_t *mHwcContext;
 };
 }; // namespace qService
 #endif // ANDROID_QSERVICE_H