libbinder: RpcConnection: add ID

In preparation to have the server be able to distinguish clients and
clients to be able to dynamically create threads that are assigned to
them.

Future considerations:
- make ID impossible to guess (right now, one client might be able to
  get ahold of a thread from a server). We may implement something here
  or go for something existing like TLS.
- combine getting max threads and this? will wait until dynamic threads
  are actually implemented and we know we need this ID and we're looking
  at performance. For now this is a placeholder to enable dynamic client
  APIs.

Bug: 185167543
Test: binderRpcTest
Change-Id: If8563c69930c23b9ca91090b4f59ef1f51073f24
diff --git a/libs/binder/RpcState.cpp b/libs/binder/RpcState.cpp
index 6bfcc42..19dea7e 100644
--- a/libs/binder/RpcState.cpp
+++ b/libs/binder/RpcState.cpp
@@ -249,7 +249,7 @@
 }
 
 status_t RpcState::getMaxThreads(const base::unique_fd& fd, const sp<RpcConnection>& connection,
-                                 size_t* maxThreads) {
+                                 size_t* maxThreadsOut) {
     Parcel data;
     data.markForRpc(connection);
     Parcel reply;
@@ -261,15 +261,36 @@
         return status;
     }
 
-    int32_t threads;
-    status = reply.readInt32(&threads);
+    int32_t maxThreads;
+    status = reply.readInt32(&maxThreads);
     if (status != OK) return status;
-    if (threads <= 0) {
-        ALOGE("Error invalid max threads: %d", threads);
+    if (maxThreads <= 0) {
+        ALOGE("Error invalid max maxThreads: %d", maxThreads);
         return BAD_VALUE;
     }
 
-    *maxThreads = threads;
+    *maxThreadsOut = maxThreads;
+    return OK;
+}
+
+status_t RpcState::getConnectionId(const base::unique_fd& fd, const sp<RpcConnection>& connection,
+                                   int32_t* connectionIdOut) {
+    Parcel data;
+    data.markForRpc(connection);
+    Parcel reply;
+
+    status_t status = transact(fd, RpcAddress::zero(), RPC_SPECIAL_TRANSACT_GET_CONNECTION_ID, data,
+                               connection, &reply, 0);
+    if (status != OK) {
+        ALOGE("Error getting connection ID: %s", statusToString(status).c_str());
+        return status;
+    }
+
+    int32_t connectionId;
+    status = reply.readInt32(&connectionId);
+    if (status != OK) return status;
+
+    *connectionIdOut = connectionId;
     return OK;
 }
 
@@ -554,6 +575,16 @@
                         replyStatus = reply.writeInt32(server->getMaxThreads());
                         break;
                     }
+                    case RPC_SPECIAL_TRANSACT_GET_CONNECTION_ID: {
+                        // only connections w/ services can be the source of a
+                        // connection ID (so still guarded by non-null server)
+                        //
+                        // connections associated with servers must have an ID
+                        // (hence abort)
+                        int32_t id = connection->getPrivateAccessorForId().get().value();
+                        replyStatus = reply.writeInt32(id);
+                        break;
+                    }
                     default: {
                         replyStatus = UNKNOWN_TRANSACTION;
                     }