Allow to set the network used for an update attempt.

When triggering an update attempt in Android, we can force all the
traffic to go through a given network by passing a NETWORK_ID=<id>
in the extra key-value pair field.

Bug: 29921093
TEST=Called update_engine_client passing NETWORK_ID.

Change-Id: I13becdd133cccc912b542d48061fcfe9f566099a
diff --git a/Android.mk b/Android.mk
index f0645d8..e7847d8 100644
--- a/Android.mk
+++ b/Android.mk
@@ -383,6 +383,7 @@
     $(ue_libpayload_consumer_exported_static_libraries)
 ue_libupdate_engine_android_exported_shared_libraries := \
     $(ue_libpayload_consumer_exported_shared_libraries) \
+    libandroid \
     libbinder \
     libbinderwrapper \
     libbrillo-binder \
@@ -419,6 +420,7 @@
     daemon.cc \
     daemon_state_android.cc \
     hardware_android.cc \
+    network_selector_android.cc \
     proxy_resolver.cc \
     update_attempter_android.cc \
     update_status_utils.cc \
diff --git a/common/constants.cc b/common/constants.cc
index 0ac22f3..324bdc5 100644
--- a/common/constants.cc
+++ b/common/constants.cc
@@ -93,5 +93,6 @@
 const char kPayloadPropertyAuthorization[] = "AUTHORIZATION";
 const char kPayloadPropertyUserAgent[] = "USER_AGENT";
 const char kPayloadPropertyPowerwash[] = "POWERWASH";
+const char kPayloadPropertyNetworkId[] = "NETWORK_ID";
 
 }  // namespace chromeos_update_engine
diff --git a/common/constants.h b/common/constants.h
index 649034e..ab66921 100644
--- a/common/constants.h
+++ b/common/constants.h
@@ -94,6 +94,7 @@
 extern const char kPayloadPropertyAuthorization[];
 extern const char kPayloadPropertyUserAgent[];
 extern const char kPayloadPropertyPowerwash[];
+extern const char kPayloadPropertyNetworkId[];
 
 // A download source is any combination of protocol and server (that's of
 // interest to us when looking at UMA metrics) using which we may download
diff --git a/network_selector.h b/network_selector.h
new file mode 100644
index 0000000..22aed8e
--- /dev/null
+++ b/network_selector.h
@@ -0,0 +1,33 @@
+//
+// Copyright (C) 2016 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.
+//
+
+#ifndef UPDATE_ENGINE_NETWORK_SELECTOR_H_
+#define UPDATE_ENGINE_NETWORK_SELECTOR_H_
+
+#include <memory>
+
+#include "update_engine/network_selector_interface.h"
+
+namespace chromeos_update_engine {
+namespace network {
+
+// Creates the NetworkSelectorInterface instance for the given platform.
+std::unique_ptr<NetworkSelectorInterface> CreateNetworkSelector();
+
+}  // namespace network
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_NETWORK_SELECTOR_H_
diff --git a/network_selector_android.cc b/network_selector_android.cc
new file mode 100644
index 0000000..6879b69
--- /dev/null
+++ b/network_selector_android.cc
@@ -0,0 +1,45 @@
+//
+// Copyright (C) 2016 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 "update_engine/network_selector_android.h"
+
+#include <android/multinetwork.h>
+#include <base/logging.h>
+#include <brillo/make_unique_ptr.h>
+
+namespace chromeos_update_engine {
+
+namespace network {
+
+// Factory defined in network_selector.h.
+std::unique_ptr<NetworkSelectorInterface> CreateNetworkSelector() {
+  return brillo::make_unique_ptr(new NetworkSelectorAndroid());
+}
+
+}  // namespace network
+
+// Defined in network_selector_interface.h.
+const NetworkId kDefaultNetworkId = NETWORK_UNSPECIFIED;
+
+bool NetworkSelectorAndroid::SetProcessNetwork(NetworkId network_id) {
+  if (android_setprocnetwork(network_id) < 0) {
+    PLOG(ERROR) << "Binding the network to " << network_id;
+    return false;
+  }
+  return true;
+}
+
+}  // namespace chromeos_update_engine
diff --git a/network_selector_android.h b/network_selector_android.h
new file mode 100644
index 0000000..135536c
--- /dev/null
+++ b/network_selector_android.h
@@ -0,0 +1,40 @@
+//
+// Copyright (C) 2016 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.
+//
+
+#ifndef UPDATE_ENGINE_NETWORK_SELECTOR_ANDROID_H_
+#define UPDATE_ENGINE_NETWORK_SELECTOR_ANDROID_H_
+
+#include <base/macros.h>
+
+#include "update_engine/network_selector_interface.h"
+
+namespace chromeos_update_engine {
+
+class NetworkSelectorAndroid final : public NetworkSelectorInterface {
+ public:
+  NetworkSelectorAndroid() = default;
+  ~NetworkSelectorAndroid() override = default;
+
+  // NetworkSelectorInterface overrides.
+  bool SetProcessNetwork(NetworkId network_id) override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(NetworkSelectorAndroid);
+};
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_NETWORK_SELECTOR_ANDROID_H_
diff --git a/network_selector_interface.h b/network_selector_interface.h
new file mode 100644
index 0000000..6c17b2c
--- /dev/null
+++ b/network_selector_interface.h
@@ -0,0 +1,49 @@
+//
+// Copyright (C) 2016 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.
+//
+
+#ifndef UPDATE_ENGINE_NETWORK_SELECTOR_INTERFACE_H_
+#define UPDATE_ENGINE_NETWORK_SELECTOR_INTERFACE_H_
+
+#include <cstdint>
+
+namespace chromeos_update_engine {
+
+typedef uint64_t NetworkId;
+
+// A constant value used to indicate the default network id. Defined in the
+// network_selector_*.cc file.
+extern const NetworkId kDefaultNetworkId;
+
+// A class that handles the network used for the connections performed from this
+// process in a platform-specific way.
+
+class NetworkSelectorInterface {
+ public:
+
+  virtual ~NetworkSelectorInterface() = default;
+
+  // Set the current process network. All sockets created in the future will be
+  // bound to this particular network. Call this with the special value
+  // kNetworkId to use the default network.
+  virtual bool SetProcessNetwork(NetworkId network_id) = 0;
+
+ protected:
+  NetworkSelectorInterface() = default;
+};
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_NETWORK_SELECTOR_INTERFACE_H_
diff --git a/network_selector_stub.cc b/network_selector_stub.cc
new file mode 100644
index 0000000..218d454
--- /dev/null
+++ b/network_selector_stub.cc
@@ -0,0 +1,44 @@
+//
+// Copyright (C) 2016 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 "update_engine/network_selector_stub.h"
+
+#include <base/logging.h>
+#include <brillo/make_unique_ptr.h>
+
+namespace chromeos_update_engine {
+
+namespace network {
+
+// Factory defined in network_selector.h.
+std::unique_ptr<NetworkSelectorInterface> CreateNetworkSelector() {
+  return brillo::make_unique_ptr(new NetworkSelectorStub());
+}
+
+}  // namespace network
+
+// Defined in network_selector_interface.h.
+const NetworkId kDefaultNetworkId = 0;
+
+bool NetworkSelectorStub::SetProcessNetwork(NetworkId network_id) {
+  if (network_id != kDefaultNetworkId) {
+    LOG(ERROR) << "SetProcessNetwork not implemented.";
+    return false;
+  }
+  return true;
+}
+
+}  // namespace chromeos_update_engine
diff --git a/network_selector_stub.h b/network_selector_stub.h
new file mode 100644
index 0000000..b3f7b48
--- /dev/null
+++ b/network_selector_stub.h
@@ -0,0 +1,40 @@
+//
+// Copyright (C) 2016 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.
+//
+
+#ifndef UPDATE_ENGINE_NETWORK_SELECTOR_STUB_H_
+#define UPDATE_ENGINE_NETWORK_SELECTOR_STUB_H_
+
+#include <base/macros.h>
+
+#include "update_engine/network_selector_interface.h"
+
+namespace chromeos_update_engine {
+
+class NetworkSelectorStub final : public NetworkSelectorInterface {
+ public:
+  NetworkSelectorStub() = default;
+  ~NetworkSelectorStub() override = default;
+
+  // NetworkSelectorInterface overrides.
+  bool SetProcessNetwork(NetworkId network_id) override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(NetworkSelectorStub);
+};
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_NETWORK_SELECTOR_STUB_H_
diff --git a/update_attempter_android.cc b/update_attempter_android.cc
index d435b52..c823e34 100644
--- a/update_attempter_android.cc
+++ b/update_attempter_android.cc
@@ -33,6 +33,7 @@
 #include "update_engine/common/multi_range_http_fetcher.h"
 #include "update_engine/common/utils.h"
 #include "update_engine/daemon_state_android.h"
+#include "update_engine/network_selector.h"
 #include "update_engine/payload_consumer/download_action.h"
 #include "update_engine/payload_consumer/filesystem_verifier_action.h"
 #include "update_engine/payload_consumer/postinstall_runner_action.h"
@@ -80,6 +81,7 @@
       boot_control_(boot_control),
       hardware_(hardware),
       processor_(new ActionProcessor()) {
+  network_selector_ = network::CreateNetworkSelector();
 }
 
 UpdateAttempterAndroid::~UpdateAttempterAndroid() {
@@ -175,6 +177,20 @@
       base::StringToInt(headers[kPayloadPropertyPowerwash], &data_wipe) &&
       data_wipe != 0;
 
+  NetworkId network_id = kDefaultNetworkId;
+  if (!headers[kPayloadPropertyNetworkId].empty()) {
+    if (!base::StringToUint64(headers[kPayloadPropertyNetworkId],
+                              &network_id)) {
+      return LogAndSetError(
+          error,
+          FROM_HERE,
+          "Invalid network_id: " + headers[kPayloadPropertyNetworkId]);
+    }
+    if (!network_selector_->SetProcessNetwork(network_id)) {
+      LOG(WARNING) << "Unable to set network_id, continuing with the update.";
+    }
+  }
+
   LOG(INFO) << "Using this install plan:";
   install_plan_.Dump();
 
diff --git a/update_attempter_android.h b/update_attempter_android.h
index f6f45f6..9e91dca 100644
--- a/update_attempter_android.h
+++ b/update_attempter_android.h
@@ -31,6 +31,7 @@
 #include "update_engine/common/cpu_limiter.h"
 #include "update_engine/common/hardware_interface.h"
 #include "update_engine/common/prefs_interface.h"
+#include "update_engine/network_selector_interface.h"
 #include "update_engine/payload_consumer/download_action.h"
 #include "update_engine/payload_consumer/postinstall_runner_action.h"
 #include "update_engine/service_delegate_android_interface.h"
@@ -163,6 +164,9 @@
   // CPU limiter during the update.
   CPULimiter cpu_limiter_;
 
+  // Helper class to select the network to use during the update.
+  std::unique_ptr<NetworkSelectorInterface> network_selector_;
+
   // Whether we have marked the current slot as good. This step is required
   // before applying an update to the other slot.
   bool updated_boot_flags_ = false;