libqservice: Add a client interface.

Add a client interface which interfaces with hwc.
qservice upon receiving IPC, provides a callback notification to the qclient
which does appropriate stuff in hwc.

In future, qservice can safely be even made a separate process with no changes
to exisiting code. This was not true earlier owing to the hwc pointer held by
qservice forcing it to be in the same process that hwc is in.

CRs-fixed: 452977
Change-Id: I05838c213f5d4606a6573693de1bacbc5876107e
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);
     }