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;