netd: HAL implmentation

Implement Netd HAL server and register service.
OEM network create and destroy

Test: ran VtsHalNetNetdV1_0TargetTest, netd_unit_test, netd_integration_test
Bug: 36682246
CRs-fixed: 2070022
Change-Id: I35681f0fbffbe09bf6db0ad25a276844ea997398
(cherry picked from commit 9560bedd6ce334d64d4e9e9331d00f90f5103e0e)
diff --git a/server/NetdHwService.cpp b/server/NetdHwService.cpp
new file mode 100644
index 0000000..6fb6700
--- /dev/null
+++ b/server/NetdHwService.cpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * 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 <binder/IPCThreadState.h>
+#include <hidl/HidlTransportSupport.h>
+#include <hwbinder/IPCThreadState.h>
+#include "Controllers.h"
+#include "Fwmark.h"
+#include "NetdHwService.h"
+
+using android::hardware::configureRpcThreadpool;
+using android::hardware::IPCThreadState;
+using android::hardware::Void;
+
+namespace android {
+namespace net {
+
+/**
+ * This lock exists to make NetdHwService RPCs (which come in on multiple HwBinder threads)
+ * coexist with the commands in CommandListener.cpp. These are presumed not thread-safe because
+ * CommandListener has only one user (NetworkManagementService), which is connected through a
+ * FrameworkListener that passes in commands one at a time.
+ */
+extern android::RWLock gBigNetdLock;
+
+static INetd::StatusCode toHalStatus(int ret) {
+    switch(ret) {
+        case 0:
+            return INetd::StatusCode::OK;
+        case -EINVAL:
+            return INetd::StatusCode::INVALID_ARGUMENTS;
+        case -EEXIST:
+            return INetd::StatusCode::ALREADY_EXISTS;
+        case -ENONET:
+            return INetd::StatusCode::NO_NETWORK;
+        case -EPERM:
+            return INetd::StatusCode::PERMISSION_DENIED;
+        default:
+            ALOGE("HAL service error=%d", ret);
+            return INetd::StatusCode::UNKNOWN_ERROR;
+    }
+}
+
+// Minimal service start.
+status_t NetdHwService::start() {
+    IPCThreadState::self()->disableBackgroundScheduling(true);
+    // Usage of this HAL is anticipated to be thin; one thread should suffice.
+    configureRpcThreadpool(1, false /* callerWillNotJoin */);
+    // Register hardware service with ServiceManager.
+    return INetd::registerAsService();
+}
+
+Return<void> NetdHwService::createOemNetwork(createOemNetwork_cb _hidl_cb) {
+    unsigned netId;
+    Permission permission = PERMISSION_SYSTEM;
+
+    android::RWLock::AutoWLock _lock(gBigNetdLock);
+    int ret = gCtls->netCtrl.createPhysicalOemNetwork(permission, &netId);
+
+    Fwmark fwmark;
+    fwmark.netId = netId;
+    fwmark.explicitlySelected = true;
+    fwmark.protectedFromVpn = true;
+    fwmark.permission = PERMISSION_SYSTEM;
+    _hidl_cb(netIdToNetHandle(netId), fwmark.intValue, toHalStatus(ret));
+
+    return Void();
+}
+
+Return<INetd::StatusCode> NetdHwService::destroyOemNetwork(uint64_t netHandle) {
+    unsigned netId = netHandleToNetId(netHandle);
+    if ((netId < NetworkController::MIN_OEM_ID) ||
+            (netId > NetworkController::MAX_OEM_ID)) {
+        return INetd::StatusCode::INVALID_ARGUMENTS;
+    }
+
+    android::RWLock::AutoWLock _lock(gBigNetdLock);
+
+    return toHalStatus(gCtls->netCtrl.destroyNetwork(netId));
+}
+
+}  // namespace net
+}  // namespace android