Add maximum timestamp to the payload. am: f8527ada7b  -s ours am: 962bfa3b27  -s ours am: ace31a8858  -s ours am: 58183c9d7a  -s ours am: 15ad0e9ec9  -s ours
am: 0ae64f6c59  -s ours

Change-Id: I93a36da1fa1187188a278f1ac3b02d5d28393f9f
diff --git a/Android.mk b/Android.mk
index d545cd5..4801a49 100644
--- a/Android.mk
+++ b/Android.mk
@@ -26,7 +26,6 @@
 # the system layer.
 local_use_libcros := $(if $(BRILLO_USE_LIBCROS),$(BRILLO_USE_LIBCROS),0)
 local_use_mtd := $(if $(BRILLO_USE_MTD),$(BRILLO_USE_MTD),0)
-local_use_weave := $(if $(BRILLO_USE_WEAVE),$(BRILLO_USE_WEAVE),0)
 
 # IoT devices use Omaha for updates.
 local_use_omaha := $(if $(filter true,$(PRODUCT_IOT)),1,0)
@@ -37,7 +36,6 @@
     -DUSE_LIBCROS=$(local_use_libcros) \
     -DUSE_MTD=$(local_use_mtd) \
     -DUSE_OMAHA=$(local_use_omaha) \
-    -DUSE_WEAVE=$(local_use_weave) \
     -D_FILE_OFFSET_BITS=64 \
     -D_POSIX_C_SOURCE=199309L \
     -Wa,--noexecstack \
@@ -100,11 +98,9 @@
 # The payload application component and common dependencies.
 ue_libpayload_consumer_exported_static_libraries := \
     update_metadata-protos \
-    libxz-host \
+    libxz \
     libbz \
-    libimgpatch \
     libbspatch \
-    libz \
     $(ue_update_metadata_protos_exported_static_libraries)
 ue_libpayload_consumer_exported_shared_libraries := \
     libcrypto \
@@ -260,12 +256,6 @@
     libbrillo-binder \
     libutils
 endif  # local_use_binder == 1
-ifeq ($(local_use_weave),1)
-ue_libupdate_engine_exported_shared_libraries += \
-    libbinderwrapper \
-    libbrillo-binder \
-    libweaved
-endif  # local_use_weave == 1
 
 include $(CLEAR_VARS)
 LOCAL_MODULE := libupdate_engine
@@ -327,8 +317,7 @@
     update_manager/state_factory.cc \
     update_manager/update_manager.cc \
     update_status_utils.cc \
-    utils_android.cc \
-    weave_service_factory.cc
+    utils_android.cc
 ifeq ($(local_use_binder),1)
 LOCAL_AIDL_INCLUDES += $(LOCAL_PATH)/binder_bindings
 LOCAL_SRC_FILES += \
@@ -337,10 +326,6 @@
     binder_service_brillo.cc \
     parcelable_update_engine_status.cc
 endif  # local_use_binder == 1
-ifeq ($(local_use_weave),1)
-LOCAL_SRC_FILES += \
-    weave_service.cc
-endif  # local_use_weave == 1
 ifeq ($(local_use_libcros),1)
 LOCAL_SRC_FILES += \
     chrome_browser_proxy_resolver.cc
@@ -425,9 +410,6 @@
 LOCAL_MODULE_CLASS := EXECUTABLES
 LOCAL_REQUIRED_MODULES := \
     cacerts_google
-ifeq ($(local_use_weave),1)
-LOCAL_REQUIRED_MODULES += updater.json
-endif  # local_use_weave == 1
 LOCAL_CPP_EXTENSION := .cc
 LOCAL_CLANG := true
 LOCAL_CFLAGS := $(ue_common_cflags)
@@ -1029,15 +1011,6 @@
 endif  # local_use_libcros == 1
 include $(BUILD_NATIVE_TEST)
 
-# Weave schema files
-# ========================================================
-include $(CLEAR_VARS)
-LOCAL_MODULE := updater.json
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/weaved/traits
-LOCAL_SRC_FILES := weaved/traits/$(LOCAL_MODULE)
-include $(BUILD_PREBUILT)
-
 # Update payload signing public key.
 # ========================================================
 ifdef BRILLO
diff --git a/binder_service_android.h b/binder_service_android.h
index 3fb38bc..3293c0e 100644
--- a/binder_service_android.h
+++ b/binder_service_android.h
@@ -52,9 +52,6 @@
                         int64_t new_size) override;
   void SendPayloadApplicationComplete(ErrorCode error_code) override;
 
-  // Channel tracking changes are ignored.
-  void SendChannelChangeUpdate(const std::string& tracking_channel) override {}
-
   // android::os::BnUpdateEngine overrides.
   android::binder::Status applyPayload(
       const android::String16& url,
diff --git a/binder_service_brillo.h b/binder_service_brillo.h
index fad0f8c..982c7b1 100644
--- a/binder_service_brillo.h
+++ b/binder_service_brillo.h
@@ -52,8 +52,6 @@
                         const std::string& new_version,
                         int64_t new_size) override;
   void SendPayloadApplicationComplete(ErrorCode error_code) override {}
-  // Channel tracking changes are ignored.
-  void SendChannelChangeUpdate(const std::string& tracking_channel) override {}
 
   // android::brillo::BnUpdateEngine overrides.
   android::binder::Status AttemptUpdate(const android::String16& app_version,
diff --git a/chrome_browser_proxy_resolver.cc b/chrome_browser_proxy_resolver.cc
index 09365c1..12a8328 100644
--- a/chrome_browser_proxy_resolver.cc
+++ b/chrome_browser_proxy_resolver.cc
@@ -16,141 +16,37 @@
 
 #include "update_engine/chrome_browser_proxy_resolver.h"
 
-#include <deque>
-#include <string>
+#include <utility>
 
 #include <base/bind.h>
+#include <base/memory/ptr_util.h>
 #include <base/strings/string_tokenizer.h>
 #include <base/strings/string_util.h>
 
-#include "update_engine/common/utils.h"
+#include "network_proxy/dbus-proxies.h"
 
 namespace chromeos_update_engine {
 
 using base::StringTokenizer;
-using base::TimeDelta;
-using brillo::MessageLoop;
 using std::deque;
 using std::string;
 
-const char kLibCrosServiceName[] = "org.chromium.LibCrosService";
-const char kLibCrosProxyResolveName[] = "ProxyResolved";
-const char kLibCrosProxyResolveSignalInterface[] =
-    "org.chromium.UpdateEngineLibcrosProxyResolvedInterface";
-
 namespace {
 
-const int kTimeout = 5;  // seconds
+// Timeout for D-Bus calls in milliseconds.
+constexpr int kTimeoutMs = 5000;
 
 }  // namespace
 
 ChromeBrowserProxyResolver::ChromeBrowserProxyResolver(
-    LibCrosProxy* libcros_proxy)
-    : libcros_proxy_(libcros_proxy), timeout_(kTimeout) {}
+    org::chromium::NetworkProxyServiceInterfaceProxyInterface* dbus_proxy)
+    : dbus_proxy_(dbus_proxy),
+      next_request_id_(kProxyRequestIdNull + 1),
+      weak_ptr_factory_(this) {}
 
-bool ChromeBrowserProxyResolver::Init() {
-  libcros_proxy_->ue_proxy_resolved_interface()
-      ->RegisterProxyResolvedSignalHandler(
-          base::Bind(&ChromeBrowserProxyResolver::OnProxyResolvedSignal,
-                     base::Unretained(this)),
-          base::Bind(&ChromeBrowserProxyResolver::OnSignalConnected,
-                     base::Unretained(this)));
-  return true;
-}
+ChromeBrowserProxyResolver::~ChromeBrowserProxyResolver() = default;
 
-ChromeBrowserProxyResolver::~ChromeBrowserProxyResolver() {
-  // Kill outstanding timers.
-  for (const auto& it : callbacks_) {
-    MessageLoop::current()->CancelTask(it.second->timeout_id);
-  }
-}
-
-ProxyRequestId ChromeBrowserProxyResolver::GetProxiesForUrl(
-    const string& url, const ProxiesResolvedFn& callback) {
-  int timeout = timeout_;
-  brillo::ErrorPtr error;
-  if (!libcros_proxy_->service_interface_proxy()->ResolveNetworkProxy(
-          url.c_str(),
-          kLibCrosProxyResolveSignalInterface,
-          kLibCrosProxyResolveName,
-          &error)) {
-    LOG(WARNING) << "Can't resolve the proxy. Continuing with no proxy.";
-    timeout = 0;
-  }
-
-  std::unique_ptr<ProxyRequestData> request(new ProxyRequestData());
-  request->callback = callback;
-  ProxyRequestId timeout_id = MessageLoop::current()->PostDelayedTask(
-      FROM_HERE,
-      base::Bind(&ChromeBrowserProxyResolver::HandleTimeout,
-                 base::Unretained(this),
-                 url,
-                 request.get()),
-      TimeDelta::FromSeconds(timeout));
-  request->timeout_id = timeout_id;
-  callbacks_.emplace(url, std::move(request));
-
-  // We re-use the timeout_id from the MessageLoop as the request id.
-  return timeout_id;
-}
-
-bool ChromeBrowserProxyResolver::CancelProxyRequest(ProxyRequestId request) {
-  // Finding the timeout_id in the callbacks_ structure requires a linear search
-  // but we expect this operation to not be so frequent and to have just a few
-  // proxy requests, so this should be fast enough.
-  for (auto it = callbacks_.begin(); it != callbacks_.end(); ++it) {
-    if (it->second->timeout_id == request) {
-      MessageLoop::current()->CancelTask(request);
-      callbacks_.erase(it);
-      return true;
-    }
-  }
-  return false;
-}
-
-void ChromeBrowserProxyResolver::ProcessUrlResponse(
-    const string& source_url, const deque<string>& proxies) {
-  // Call all the occurrences of the |source_url| and erase them.
-  auto lower_end = callbacks_.lower_bound(source_url);
-  auto upper_end = callbacks_.upper_bound(source_url);
-  for (auto it = lower_end; it != upper_end; ++it) {
-    ProxyRequestData* request = it->second.get();
-    MessageLoop::current()->CancelTask(request->timeout_id);
-    request->callback.Run(proxies);
-  }
-  callbacks_.erase(lower_end, upper_end);
-}
-
-void ChromeBrowserProxyResolver::OnSignalConnected(const string& interface_name,
-                                                   const string& signal_name,
-                                                   bool successful) {
-  if (!successful) {
-    LOG(ERROR) << "Couldn't connect to the signal " << interface_name << "."
-               << signal_name;
-  }
-}
-
-void ChromeBrowserProxyResolver::OnProxyResolvedSignal(
-    const string& source_url,
-    const string& proxy_info,
-    const string& error_message) {
-  if (!error_message.empty()) {
-    LOG(WARNING) << "ProxyResolved error: " << error_message;
-  }
-  ProcessUrlResponse(source_url, ParseProxyString(proxy_info));
-}
-
-void ChromeBrowserProxyResolver::HandleTimeout(string source_url,
-                                               ProxyRequestData* request) {
-  LOG(INFO) << "Timeout handler called. Seems Chrome isn't responding.";
-  // Mark the timer_id that produced this callback as invalid to prevent
-  // canceling the timeout callback that already fired.
-  request->timeout_id = MessageLoop::kTaskIdNull;
-
-  deque<string> proxies = {kNoProxy};
-  ProcessUrlResponse(source_url, proxies);
-}
-
+// static
 deque<string> ChromeBrowserProxyResolver::ParseProxyString(
     const string& input) {
   deque<string> ret;
@@ -193,4 +89,50 @@
   return ret;
 }
 
-}  // namespace chromeos_update_engine
+ProxyRequestId ChromeBrowserProxyResolver::GetProxiesForUrl(
+    const string& url, const ProxiesResolvedFn& callback) {
+  const ProxyRequestId id = next_request_id_++;
+  dbus_proxy_->ResolveProxyAsync(
+      url,
+      base::Bind(&ChromeBrowserProxyResolver::OnResolveProxyResponse,
+                 weak_ptr_factory_.GetWeakPtr(), id),
+      base::Bind(&ChromeBrowserProxyResolver::OnResolveProxyError,
+                 weak_ptr_factory_.GetWeakPtr(), id),
+      kTimeoutMs);
+  pending_callbacks_[id] = callback;
+  return id;
+}
+
+bool ChromeBrowserProxyResolver::CancelProxyRequest(ProxyRequestId request) {
+  return pending_callbacks_.erase(request) != 0;
+}
+
+void ChromeBrowserProxyResolver::OnResolveProxyResponse(
+    ProxyRequestId request_id,
+    const std::string& proxy_info,
+    const std::string& error_message) {
+  if (!error_message.empty())
+    LOG(WARNING) << "Got error resolving proxy: " << error_message;
+  RunCallback(request_id, ParseProxyString(proxy_info));
+}
+
+void ChromeBrowserProxyResolver::OnResolveProxyError(ProxyRequestId request_id,
+                                                     brillo::Error* error) {
+  LOG(WARNING) << "Failed to resolve proxy: "
+               << (error ? error->GetMessage() : "[null]");
+  RunCallback(request_id, deque<string>{kNoProxy});
+}
+
+void ChromeBrowserProxyResolver::RunCallback(
+    ProxyRequestId request_id,
+    const std::deque<std::string>& proxies) {
+  auto it = pending_callbacks_.find(request_id);
+  if (it == pending_callbacks_.end())
+    return;
+
+  ProxiesResolvedFn callback = it->second;
+  pending_callbacks_.erase(it);
+  callback.Run(proxies);
+}
+
+} // namespace chromeos_update_engine
diff --git a/chrome_browser_proxy_resolver.h b/chrome_browser_proxy_resolver.h
index eb92bac..03dbdad 100644
--- a/chrome_browser_proxy_resolver.h
+++ b/chrome_browser_proxy_resolver.h
@@ -18,78 +18,66 @@
 #define UPDATE_ENGINE_CHROME_BROWSER_PROXY_RESOLVER_H_
 
 #include <deque>
+#include <map>
 #include <string>
 
-#include <gtest/gtest_prod.h>  // for FRIEND_TEST
+#include <base/memory/weak_ptr.h>
 
-#include <brillo/message_loops/message_loop.h>
-
-#include "update_engine/libcros_proxy.h"
 #include "update_engine/proxy_resolver.h"
 
+namespace brillo {
+class Error;
+}  // namespace brillo
+
+namespace org {
+namespace chromium {
+class NetworkProxyServiceInterfaceProxyInterface;
+}  // namespace chromium
+}  // namespace org
+
 namespace chromeos_update_engine {
 
-extern const char kLibCrosServiceName[];
-extern const char kLibCrosProxyResolveName[];
-extern const char kLibCrosProxyResolveSignalInterface[];
-
 class ChromeBrowserProxyResolver : public ProxyResolver {
  public:
-  explicit ChromeBrowserProxyResolver(LibCrosProxy* libcros_proxy);
+  explicit ChromeBrowserProxyResolver(
+      org::chromium::NetworkProxyServiceInterfaceProxyInterface* dbus_proxy);
   ~ChromeBrowserProxyResolver() override;
 
-  // Initialize the ProxyResolver using the provided DBus proxies.
-  bool Init();
-
-  ProxyRequestId GetProxiesForUrl(const std::string& url,
-                                  const ProxiesResolvedFn& callback) override;
-  bool CancelProxyRequest(ProxyRequestId request) override;
-
- private:
-  FRIEND_TEST(ChromeBrowserProxyResolverTest, ParseTest);
-  FRIEND_TEST(ChromeBrowserProxyResolverTest, SuccessTest);
-  struct ProxyRequestData {
-    brillo::MessageLoop::TaskId timeout_id;
-    ProxiesResolvedFn callback;
-  };
-  typedef std::multimap<std::string, std::unique_ptr<ProxyRequestData>>
-      CallbacksMap;
-
-  // Called when the signal in UpdateEngineLibcrosProxyResolvedInterface is
-  // connected.
-  void OnSignalConnected(const std::string& interface_name,
-                         const std::string& signal_name,
-                         bool successful);
-
-  // Handle a reply from Chrome:
-  void OnProxyResolvedSignal(const std::string& source_url,
-                             const std::string& proxy_info,
-                             const std::string& error_message);
-
-  // Handle no reply. The |request| pointer points to the ProxyRequestData in
-  // the |callbacks_| map that triggered this timeout.
-  void HandleTimeout(std::string source_url, ProxyRequestData* request);
-
   // Parses a string-encoded list of proxies and returns a deque
   // of individual proxies. The last one will always be kNoProxy.
   static std::deque<std::string> ParseProxyString(const std::string& input);
 
-  // Process a proxy response by calling all the callbacks associated with the
-  // passed |source_url|. All the timeouts associated with these callbacks will
-  // be removed.
-  void ProcessUrlResponse(const std::string& source_url,
-                          const std::deque<std::string>& proxies);
+  // ProxyResolver:
+  ProxyRequestId GetProxiesForUrl(const std::string& url,
+                                  const ProxiesResolvedFn& callback) override;
+  bool CancelProxyRequest(ProxyRequestId request) override;
 
-  // Shutdown the dbus proxy object.
-  void Shutdown();
+private:
+  // Callback for successful D-Bus calls made by GetProxiesForUrl().
+  void OnResolveProxyResponse(ProxyRequestId request_id,
+                              const std::string& proxy_info,
+                              const std::string& error_message);
 
-  // DBus proxies to request a HTTP proxy resolution. The request is done in the
-  // service_interface_proxy() interface and the response is received as a
-  // signal in the ue_proxy_resolved_interface().
-  LibCrosProxy* libcros_proxy_;
+  // Callback for failed D-Bus calls made by GetProxiesForUrl().
+  void OnResolveProxyError(ProxyRequestId request_id, brillo::Error* error);
 
-  int timeout_;
-  CallbacksMap callbacks_;
+  // Finds the callback identified by |request_id| in |pending_callbacks_|,
+  // passes |proxies| to it, and deletes it. Does nothing if the request has
+  // been cancelled.
+  void RunCallback(ProxyRequestId request_id,
+                   const std::deque<std::string>& proxies);
+
+  // D-Bus proxy for resolving network proxies.
+  org::chromium::NetworkProxyServiceInterfaceProxyInterface* dbus_proxy_;
+
+  // Next ID to return from GetProxiesForUrl().
+  ProxyRequestId next_request_id_;
+
+  // Callbacks that were passed to GetProxiesForUrl() but haven't yet been run.
+  std::map<ProxyRequestId, ProxiesResolvedFn> pending_callbacks_;
+
+  base::WeakPtrFactory<ChromeBrowserProxyResolver> weak_ptr_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(ChromeBrowserProxyResolver);
 };
 
diff --git a/chrome_browser_proxy_resolver_unittest.cc b/chrome_browser_proxy_resolver_unittest.cc
index 24f8a2e..dc71d2b 100644
--- a/chrome_browser_proxy_resolver_unittest.cc
+++ b/chrome_browser_proxy_resolver_unittest.cc
@@ -20,147 +20,68 @@
 #include <string>
 #include <vector>
 
+#include <gmock/gmock.h>
 #include <gtest/gtest.h>
 
-#include <base/bind.h>
-#include <brillo/make_unique_ptr.h>
-#include <brillo/message_loops/fake_message_loop.h>
+#include <base/macros.h>
+#include <brillo/errors/error.h>
 
-#include "libcros/dbus-proxies.h"
-#include "libcros/dbus-proxy-mocks.h"
+#include "network_proxy/dbus-proxies.h"
+#include "network_proxy/dbus-proxy-mocks.h"
 #include "update_engine/dbus_test_utils.h"
 
-using ::testing::Return;
+using ::testing::DoAll;
+using ::testing::SaveArg;
 using ::testing::StrEq;
 using ::testing::_;
-using brillo::MessageLoop;
-using org::chromium::LibCrosServiceInterfaceProxyMock;
-using org::chromium::UpdateEngineLibcrosProxyResolvedInterfaceProxyMock;
+using org::chromium::NetworkProxyServiceInterfaceProxyMock;
 using std::deque;
 using std::string;
 using std::vector;
 
 namespace chromeos_update_engine {
 
-class ChromeBrowserProxyResolverTest : public ::testing::Test {
- protected:
-  ChromeBrowserProxyResolverTest()
-      : service_interface_mock_(new LibCrosServiceInterfaceProxyMock()),
-        ue_proxy_resolved_interface_mock_(
-            new UpdateEngineLibcrosProxyResolvedInterfaceProxyMock()),
-        libcros_proxy_(
-            brillo::make_unique_ptr(service_interface_mock_),
-            brillo::make_unique_ptr(ue_proxy_resolved_interface_mock_)) {}
-
-  void SetUp() override {
-    loop_.SetAsCurrent();
-    // The ProxyResolved signal should be subscribed to.
-    MOCK_SIGNAL_HANDLER_EXPECT_SIGNAL_HANDLER(
-        ue_proxy_resolved_signal_,
-        *ue_proxy_resolved_interface_mock_,
-        ProxyResolved);
-
-    EXPECT_TRUE(resolver_.Init());
-    // Run the loop once to dispatch the successfully registered signal handler.
-    EXPECT_TRUE(loop_.RunOnce(false));
-  }
-
-  void TearDown() override {
-    EXPECT_FALSE(loop_.PendingTasks());
-  }
-
-  // Send the signal to the callback passed during registration of the
-  // ProxyResolved.
-  void SendReplySignal(const string& source_url,
-                       const string& proxy_info,
-                       const string& error_message);
-
-  void RunTest(bool chrome_replies, bool chrome_alive);
-
-  brillo::FakeMessageLoop loop_{nullptr};
-
-  // Local pointers to the mocks. The instances are owned by the
-  // |libcros_proxy_|.
-  LibCrosServiceInterfaceProxyMock* service_interface_mock_;
-  UpdateEngineLibcrosProxyResolvedInterfaceProxyMock*
-      ue_proxy_resolved_interface_mock_;
-
-  // The registered signal handler for the signal
-  // UpdateEngineLibcrosProxyResolvedInterface.ProxyResolved.
-  chromeos_update_engine::dbus_test_utils::MockSignalHandler<
-      void(const string&, const string&, const string&)>
-      ue_proxy_resolved_signal_;
-
-  LibCrosProxy libcros_proxy_;
-  ChromeBrowserProxyResolver resolver_{&libcros_proxy_};
-};
-
-
-void ChromeBrowserProxyResolverTest::SendReplySignal(
-    const string& source_url,
-    const string& proxy_info,
-    const string& error_message) {
-  ASSERT_TRUE(ue_proxy_resolved_signal_.IsHandlerRegistered());
-  ue_proxy_resolved_signal_.signal_callback().Run(
-      source_url, proxy_info, error_message);
-}
-
 namespace {
-void CheckResponseResolved(const deque<string>& proxies) {
-  EXPECT_EQ(2U, proxies.size());
-  EXPECT_EQ("socks5://192.168.52.83:5555", proxies[0]);
-  EXPECT_EQ(kNoProxy, proxies[1]);
-  MessageLoop::current()->BreakLoop();
+
+// Callback for ProxyResolver::GetProxiesForUrl() that copies |src| to |dest|.
+void CopyProxies(deque<string>* dest, const deque<string>& src) {
+  *dest = src;
 }
 
-void CheckResponseNoReply(const deque<string>& proxies) {
-  EXPECT_EQ(1U, proxies.size());
-  EXPECT_EQ(kNoProxy, proxies[0]);
-  MessageLoop::current()->BreakLoop();
-}
 }  // namespace
 
-// chrome_replies should be set to whether or not we fake a reply from
-// chrome. If there's no reply, the resolver should time out.
-// If chrome_alive is false, assume that sending to chrome fails.
-void ChromeBrowserProxyResolverTest::RunTest(bool chrome_replies,
-                                             bool chrome_alive) {
-  char kUrl[] = "http://example.com/blah";
-  char kProxyConfig[] = "SOCKS5 192.168.52.83:5555;DIRECT";
+class ChromeBrowserProxyResolverTest : public ::testing::Test {
+ public:
+  ChromeBrowserProxyResolverTest() = default;
+  ~ChromeBrowserProxyResolverTest() override = default;
 
-  EXPECT_CALL(*service_interface_mock_,
-              ResolveNetworkProxy(StrEq(kUrl),
-                                  StrEq(kLibCrosProxyResolveSignalInterface),
-                                  StrEq(kLibCrosProxyResolveName),
-                                  _,
-                                  _))
-      .WillOnce(Return(chrome_alive));
-
-  ProxiesResolvedFn get_proxies_response = base::Bind(&CheckResponseNoReply);
-  if (chrome_replies) {
-    get_proxies_response = base::Bind(&CheckResponseResolved);
-    MessageLoop::current()->PostDelayedTask(
-        FROM_HERE,
-        base::Bind(&ChromeBrowserProxyResolverTest::SendReplySignal,
-                   base::Unretained(this),
-                   kUrl,
-                   kProxyConfig,
-                   ""),
-        base::TimeDelta::FromSeconds(1));
+ protected:
+  // Adds a GoogleMock expectation for a call to |dbus_proxy_|'s
+  // ResolveProxyAsync method to resolve |url|.
+  void AddResolveProxyExpectation(const std::string& url) {
+    EXPECT_CALL(dbus_proxy_, ResolveProxyAsync(StrEq(url), _, _, _))
+        .WillOnce(DoAll(SaveArg<1>(&success_callback_),
+                        SaveArg<2>(&error_callback_)));
   }
 
-  EXPECT_NE(kProxyRequestIdNull,
-            resolver_.GetProxiesForUrl(kUrl, get_proxies_response));
-  MessageLoop::current()->Run();
-}
+  NetworkProxyServiceInterfaceProxyMock dbus_proxy_;
+  ChromeBrowserProxyResolver resolver_{&dbus_proxy_};
 
+  // Callbacks that were passed to |dbus_proxy_|'s ResolveProxyAsync method.
+  base::Callback<void(const std::string&, const std::string&)>
+      success_callback_;
+  base::Callback<void(brillo::Error*)> error_callback_;
 
-TEST_F(ChromeBrowserProxyResolverTest, ParseTest) {
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ChromeBrowserProxyResolverTest);
+};
+
+TEST_F(ChromeBrowserProxyResolverTest, Parse) {
   // Test ideas from
   // http://src.chromium.org/svn/trunk/src/net/proxy/proxy_list_unittest.cc
   vector<string> inputs = {
       "PROXY foopy:10",
-      " DIRECT",  // leading space.
+      " DIRECT", // leading space.
       "PROXY foopy1 ; proxy foopy2;\t DIRECT",
       "proxy foopy1 ; SOCKS foopy2",
       "DIRECT ; proxy foopy1 ; DIRECT ; SOCKS5 foopy2;DIRECT ",
@@ -168,7 +89,8 @@
       "PROXY-foopy:10",
       "PROXY",
       "PROXY foopy1 ; JUNK ; JUNK ; SOCKS5 foopy2 ; ;",
-      "HTTP foopy1; SOCKS5 foopy2"};
+      "HTTP foopy1; SOCKS5 foopy2",
+  };
   vector<deque<string>> outputs = {
       {"http://foopy:10", kNoProxy},
       {kNoProxy},
@@ -179,7 +101,8 @@
       {kNoProxy},
       {kNoProxy},
       {"http://foopy1", "socks5://foopy2", kNoProxy},
-      {"socks5://foopy2", kNoProxy}};
+      {"socks5://foopy2", kNoProxy},
+  };
   ASSERT_EQ(inputs.size(), outputs.size());
 
   for (size_t i = 0; i < inputs.size(); i++) {
@@ -195,44 +118,63 @@
   }
 }
 
-TEST_F(ChromeBrowserProxyResolverTest, SuccessTest) {
-  RunTest(true, true);
+TEST_F(ChromeBrowserProxyResolverTest, Success) {
+  const char kUrl[] = "http://example.com/blah";
+  const char kProxyConfig[] = "SOCKS5 192.168.52.83:5555;DIRECT";
+  AddResolveProxyExpectation(kUrl);
+  deque<string> proxies;
+  resolver_.GetProxiesForUrl(kUrl, base::Bind(&CopyProxies, &proxies));
+
+  // Run the D-Bus success callback and verify that the proxies are passed to
+  // the supplied function.
+  ASSERT_FALSE(success_callback_.is_null());
+  success_callback_.Run(kProxyConfig, string());
+  ASSERT_EQ(2u, proxies.size());
+  EXPECT_EQ("socks5://192.168.52.83:5555", proxies[0]);
+  EXPECT_EQ(kNoProxy, proxies[1]);
 }
 
-TEST_F(ChromeBrowserProxyResolverTest, NoReplyTest) {
-  RunTest(false, true);
+TEST_F(ChromeBrowserProxyResolverTest, Failure) {
+  const char kUrl[] = "http://example.com/blah";
+  AddResolveProxyExpectation(kUrl);
+  deque<string> proxies;
+  resolver_.GetProxiesForUrl(kUrl, base::Bind(&CopyProxies, &proxies));
+
+  // Run the D-Bus error callback and verify that the supplied function is
+  // instructed to use a direct connection.
+  ASSERT_FALSE(error_callback_.is_null());
+  brillo::ErrorPtr error = brillo::Error::Create(FROM_HERE, "", "", "");
+  error_callback_.Run(error.get());
+  ASSERT_EQ(1u, proxies.size());
+  EXPECT_EQ(kNoProxy, proxies[0]);
 }
 
-TEST_F(ChromeBrowserProxyResolverTest, NoChromeTest) {
-  RunTest(false, false);
-}
-
-TEST_F(ChromeBrowserProxyResolverTest, CancelCallbackTest) {
+TEST_F(ChromeBrowserProxyResolverTest, CancelCallback) {
+  const char kUrl[] = "http://example.com/blah";
+  AddResolveProxyExpectation(kUrl);
   int called = 0;
   auto callback = base::Bind(
       [](int* called, const deque<string>& proxies) { (*called)++; }, &called);
+  ProxyRequestId request = resolver_.GetProxiesForUrl(kUrl, callback);
 
-  EXPECT_CALL(*service_interface_mock_, ResolveNetworkProxy(_, _, _, _, _))
-      .Times(4)
-      .WillRepeatedly(Return(true));
-
-  EXPECT_NE(kProxyRequestIdNull,
-            resolver_.GetProxiesForUrl("http://urlA", callback));
-  ProxyRequestId req_b = resolver_.GetProxiesForUrl("http://urlB", callback);
-  // Note that we add twice the same url.
-  ProxyRequestId req_c = resolver_.GetProxiesForUrl("http://urlC", callback);
-  EXPECT_NE(kProxyRequestIdNull,
-            resolver_.GetProxiesForUrl("http://urlC", callback));
-
+  // Cancel the request and then run the D-Bus success callback. The original
+  // callback shouldn't be run.
+  EXPECT_TRUE(resolver_.CancelProxyRequest(request));
+  ASSERT_FALSE(success_callback_.is_null());
+  success_callback_.Run("DIRECT", string());
   EXPECT_EQ(0, called);
-  EXPECT_TRUE(resolver_.CancelProxyRequest(req_b));
-  EXPECT_TRUE(resolver_.CancelProxyRequest(req_c));
-  // Canceling the same request twice should fail even if there's another
-  // request for the same URL.
-  EXPECT_FALSE(resolver_.CancelProxyRequest(req_c));
+}
 
-  loop_.Run();
-  EXPECT_EQ(2, called);
+TEST_F(ChromeBrowserProxyResolverTest, CancelCallbackTwice) {
+  const char kUrl[] = "http://example.com/blah";
+  AddResolveProxyExpectation(kUrl);
+  deque<string> proxies;
+  ProxyRequestId request =
+      resolver_.GetProxiesForUrl(kUrl, base::Bind(&CopyProxies, &proxies));
+
+  // Cancel the same request twice. The second call should fail.
+  EXPECT_TRUE(resolver_.CancelProxyRequest(request));
+  EXPECT_FALSE(resolver_.CancelProxyRequest(request));
 }
 
 }  // namespace chromeos_update_engine
diff --git a/common/http_fetcher.cc b/common/http_fetcher.cc
index 4fd1082..73c0d48 100644
--- a/common/http_fetcher.cc
+++ b/common/http_fetcher.cc
@@ -43,7 +43,7 @@
 }
 
 // Proxy methods to set the proxies, then to pop them off.
-bool HttpFetcher::ResolveProxiesForUrl(const string& url,
+void HttpFetcher::ResolveProxiesForUrl(const string& url,
                                        const Closure& callback) {
   CHECK_EQ(static_cast<Closure*>(nullptr), callback_.get());
   callback_.reset(new Closure(callback));
@@ -54,15 +54,10 @@
         FROM_HERE,
         base::Bind(&HttpFetcher::NoProxyResolverCallback,
                    base::Unretained(this)));
-    return true;
+    return;
   }
   proxy_request_ = proxy_resolver_->GetProxiesForUrl(
       url, base::Bind(&HttpFetcher::ProxiesResolved, base::Unretained(this)));
-  if (proxy_request_ == kProxyRequestIdNull) {
-    callback_.reset();
-    return false;
-  }
-  return true;
 }
 
 void HttpFetcher::NoProxyResolverCallback() {
diff --git a/common/http_fetcher.h b/common/http_fetcher.h
index fb15689..3f7b2e8 100644
--- a/common/http_fetcher.h
+++ b/common/http_fetcher.h
@@ -66,8 +66,7 @@
   void SetPostData(const void* data, size_t size);
 
   // Proxy methods to set the proxies, then to pop them off.
-  // Returns true on success.
-  bool ResolveProxiesForUrl(const std::string& url,
+  void ResolveProxiesForUrl(const std::string& url,
                             const base::Closure& callback);
 
   void SetProxies(const std::deque<std::string>& proxies) {
diff --git a/common/subprocess_unittest.cc b/common/subprocess_unittest.cc
index 7dbdf98..cbc9a85 100644
--- a/common/subprocess_unittest.cc
+++ b/common/subprocess_unittest.cc
@@ -236,7 +236,18 @@
       kBinPath "/sh",
       "-c",
       base::StringPrintf(
-          "echo -n  X >\"%s\"; sleep 60; echo -n  Y >\"%s\"; exit 1",
+          // The 'sleep' launched below could be left behind as an orphaned
+          // process when the 'sh' process is terminated by SIGTERM. As a
+          // remedy, trap SIGTERM and kill the 'sleep' process, which requires
+          // launching 'sleep' in background and then waiting for it.
+          "cleanup() { kill \"${sleep_pid}\"; exit 0; }; "
+          "trap cleanup TERM; "
+          "sleep 60 & "
+          "sleep_pid=$!; "
+          "printf X >\"%s\"; "
+          "wait; "
+          "printf Y >\"%s\"; "
+          "exit 1",
           fifo_path.c_str(),
           fifo_path.c_str())};
   uint32_t tag = Subprocess::Get().Exec(cmd, base::Bind(&CallbackBad));
diff --git a/common/test_utils.cc b/common/test_utils.cc
index dfdc6b8..fb22c80 100644
--- a/common/test_utils.cc
+++ b/common/test_utils.cc
@@ -25,6 +25,7 @@
 #include <stdlib.h>
 #include <sys/ioctl.h>
 #include <sys/stat.h>
+#include <sys/sysmacros.h>
 #include <sys/types.h>
 #include <sys/xattr.h>
 #include <unistd.h>
diff --git a/common_service.cc b/common_service.cc
index c2473b2..1a41b63 100644
--- a/common_service.cc
+++ b/common_service.cc
@@ -173,8 +173,6 @@
     LogAndSetError(error, FROM_HERE, error_message);
     return false;
   }
-  // Update the weave state because updated the target channel.
-  system_state_->update_attempter()->BroadcastChannel();
   return true;
 }
 
diff --git a/daemon.cc b/daemon.cc
index 4155243..f016fec 100644
--- a/daemon.cc
+++ b/daemon.cc
@@ -20,9 +20,9 @@
 
 #include <base/bind.h>
 #include <base/location.h>
-#if USE_WEAVE || USE_BINDER
+#if USE_BINDER
 #include <binderwrapper/binder_wrapper.h>
-#endif  // USE_WEAVE || USE_BINDER
+#endif  // USE_BINDER
 
 #if USE_OMAHA
 #include "update_engine/real_system_state.h"
@@ -41,10 +41,10 @@
   if (exit_code != EX_OK)
     return exit_code;
 
-#if USE_WEAVE || USE_BINDER
+#if USE_BINDER
   android::BinderWrapper::Create();
   binder_watcher_.Init();
-#endif  // USE_WEAVE || USE_BINDER
+#endif  // USE_BINDER
 
 #if USE_OMAHA
   // Initialize update engine global state but continue if something fails.
diff --git a/daemon.h b/daemon.h
index 5910783..c10bb28 100644
--- a/daemon.h
+++ b/daemon.h
@@ -20,9 +20,9 @@
 #include <memory>
 #include <string>
 
-#if USE_WEAVE || USE_BINDER
+#if USE_BINDER
 #include <brillo/binder_watcher.h>
-#endif  // USE_WEAVE || USE_BINDER
+#endif  // USE_BINDER
 #include <brillo/daemons/daemon.h>
 
 #if USE_BINDER
@@ -63,9 +63,9 @@
   // the main() function.
   Subprocess subprocess_;
 
-#if USE_WEAVE || USE_BINDER
+#if USE_BINDER
   brillo::BinderWatcher binder_watcher_;
-#endif  // USE_WEAVE || USE_BINDER
+#endif  // USE_BINDER
 
 #if USE_BINDER
 #if USE_OMAHA
diff --git a/dbus_bindings/org.chromium.LibCrosService.dbus-xml b/dbus_bindings/org.chromium.LibCrosService.dbus-xml
index 2da1929..3111c63 100644
--- a/dbus_bindings/org.chromium.LibCrosService.dbus-xml
+++ b/dbus_bindings/org.chromium.LibCrosService.dbus-xml
@@ -3,21 +3,8 @@
 <node name="/org/chromium/LibCrosService"
       xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
   <interface name="org.chromium.LibCrosServiceInterface">
-    <method name="ResolveNetworkProxy">
-      <arg name="source_url" type="s" direction="in" />
-      <arg name="signal_interface" type="s" direction="in" />
-      <arg name="signal_name" type="s" direction="in" />
-      <annotation name="org.chromium.DBus.Method.Kind" value="simple" />
-    </method>
     <method name="GetKioskAppRequiredPlatformVersion">
       <arg name="required_platform_version" type="s" direction="out" />
     </method>
   </interface>
-  <interface name="org.chromium.UpdateEngineLibcrosProxyResolvedInterface">
-    <signal name="ProxyResolved">
-      <arg name="source_url" type="s" direction="out" />
-      <arg name="proxy_info" type="s" direction="out" />
-      <arg name="error_message" type="s" direction="out" />
-    </signal>
-  </interface>
 </node>
diff --git a/dbus_bindings/org.chromium.NetworkProxyService.dbus-xml b/dbus_bindings/org.chromium.NetworkProxyService.dbus-xml
new file mode 100644
index 0000000..90686ca
--- /dev/null
+++ b/dbus_bindings/org.chromium.NetworkProxyService.dbus-xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<node name="/org/chromium/NetworkProxyService"
+      xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+  <interface name="org.chromium.NetworkProxyServiceInterface">
+    <method name="ResolveProxy">
+      <arg name="source_url" type="s" direction="in" />
+      <arg name="proxy_info" type="s" direction="out" />
+      <arg name="error_message" type="s" direction="out" />
+      <annotation name="org.chromium.DBus.Method.Kind" value="async" />
+    </method>
+  </interface>
+</node>
diff --git a/dbus_service.h b/dbus_service.h
index 62984f6..2b36ae9 100644
--- a/dbus_service.h
+++ b/dbus_service.h
@@ -175,9 +175,6 @@
 
   void SendPayloadApplicationComplete(ErrorCode error_code) override {}
 
-  // Channel tracking changes are ignored.
-  void SendChannelChangeUpdate(const std::string& tracking_channel) override {}
-
  private:
   scoped_refptr<dbus::Bus> bus_;
   DBusUpdateEngineService dbus_service_;
diff --git a/fake_system_state.h b/fake_system_state.h
index 030cb07..2225933 100644
--- a/fake_system_state.h
+++ b/fake_system_state.h
@@ -84,8 +84,6 @@
     return update_attempter_;
   }
 
-  inline WeaveServiceInterface* weave_service() override { return nullptr; }
-
   inline OmahaRequestParams* request_params() override {
     return request_params_;
   }
diff --git a/image_properties_chromeos.cc b/image_properties_chromeos.cc
index 024eebf..6bab63f 100644
--- a/image_properties_chromeos.cc
+++ b/image_properties_chromeos.cc
@@ -116,7 +116,7 @@
       GetStringWithDefault(lsb_release, kLsbReleaseAutoUpdateServerKey,
                            constants::kOmahaDefaultProductionURL);
   // Build fingerprint not used in Chrome OS.
-  result.buiild_fingerprint = "";
+  result.build_fingerprint = "";
 
   return result;
 }
diff --git a/libcros_proxy.cc b/libcros_proxy.cc
deleted file mode 100644
index 3aa87cb..0000000
--- a/libcros_proxy.cc
+++ /dev/null
@@ -1,59 +0,0 @@
-//
-// Copyright (C) 2015 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/libcros_proxy.h"
-
-#include "update_engine/dbus_connection.h"
-
-using org::chromium::LibCrosServiceInterfaceProxy;
-using org::chromium::LibCrosServiceInterfaceProxyInterface;
-using org::chromium::UpdateEngineLibcrosProxyResolvedInterfaceProxy;
-using org::chromium::UpdateEngineLibcrosProxyResolvedInterfaceProxyInterface;
-
-namespace {
-const char kLibCrosServiceName[] = "org.chromium.LibCrosService";
-}  // namespace
-
-namespace chromeos_update_engine {
-
-LibCrosProxy::LibCrosProxy(
-    std::unique_ptr<LibCrosServiceInterfaceProxyInterface>
-        service_interface_proxy,
-    std::unique_ptr<UpdateEngineLibcrosProxyResolvedInterfaceProxyInterface>
-        ue_proxy_resolved_interface)
-    : service_interface_proxy_(std::move(service_interface_proxy)),
-      ue_proxy_resolved_interface_(std::move(ue_proxy_resolved_interface)) {
-}
-
-LibCrosProxy::LibCrosProxy() {
-  const scoped_refptr<dbus::Bus>& bus = DBusConnection::Get()->GetDBus();
-  service_interface_proxy_.reset(
-      new LibCrosServiceInterfaceProxy(bus, kLibCrosServiceName));
-  ue_proxy_resolved_interface_.reset(
-      new UpdateEngineLibcrosProxyResolvedInterfaceProxy(bus,
-                                                         kLibCrosServiceName));
-}
-
-LibCrosServiceInterfaceProxyInterface* LibCrosProxy::service_interface_proxy() {
-  return service_interface_proxy_.get();
-}
-
-UpdateEngineLibcrosProxyResolvedInterfaceProxyInterface*
-LibCrosProxy::ue_proxy_resolved_interface() {
-  return ue_proxy_resolved_interface_.get();
-}
-
-}  // namespace chromeos_update_engine
diff --git a/libcros_proxy.h b/libcros_proxy.h
deleted file mode 100644
index 03bf312..0000000
--- a/libcros_proxy.h
+++ /dev/null
@@ -1,62 +0,0 @@
-//
-// Copyright (C) 2015 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_LIBCROS_PROXY_H_
-#define UPDATE_ENGINE_LIBCROS_PROXY_H_
-
-#include <memory>
-
-#include <base/macros.h>
-#include <dbus/bus.h>
-
-#include "libcros/dbus-proxies.h"
-
-namespace chromeos_update_engine {
-
-// This class handles the DBus connection with chrome to resolve proxies. This
-// is a thin class to just hold the generated proxies (real or mocked ones).
-class LibCrosProxy final {
- public:
-  LibCrosProxy();
-  LibCrosProxy(
-      std::unique_ptr<org::chromium::LibCrosServiceInterfaceProxyInterface>
-          service_interface_proxy,
-      std::unique_ptr<
-          org::chromium::
-              UpdateEngineLibcrosProxyResolvedInterfaceProxyInterface>
-          ue_proxy_resolved_interface);
-
-  ~LibCrosProxy() = default;
-
-  // Getters for the two proxies.
-  org::chromium::LibCrosServiceInterfaceProxyInterface*
-  service_interface_proxy();
-  org::chromium::UpdateEngineLibcrosProxyResolvedInterfaceProxyInterface*
-  ue_proxy_resolved_interface();
-
- private:
-  std::unique_ptr<org::chromium::LibCrosServiceInterfaceProxyInterface>
-      service_interface_proxy_;
-  std::unique_ptr<
-      org::chromium::UpdateEngineLibcrosProxyResolvedInterfaceProxyInterface>
-      ue_proxy_resolved_interface_;
-
-  DISALLOW_COPY_AND_ASSIGN(LibCrosProxy);
-};
-
-}  // namespace chromeos_update_engine
-
-#endif  // UPDATE_ENGINE_LIBCROS_PROXY_H_
diff --git a/libcurl_http_fetcher.cc b/libcurl_http_fetcher.cc
index f3d6a18..eac6ea0 100644
--- a/libcurl_http_fetcher.cc
+++ b/libcurl_http_fetcher.cc
@@ -52,9 +52,6 @@
 
 const int kNoNetworkRetrySeconds = 10;
 
-// Socket tag used by all network sockets. See qtaguid kernel module for stats.
-const int kUpdateEngineSocketTag = 0x55417243;  // "CrAU" in little-endian.
-
 // libcurl's CURLOPT_SOCKOPTFUNCTION callback function. Called after the socket
 // is created but before it is connected. This callback tags the created socket
 // so the network usage can be tracked in Android.
@@ -62,6 +59,9 @@
                            curl_socket_t curlfd,
                            curlsocktype /* purpose */) {
 #ifdef __ANDROID__
+  // Socket tag used by all network sockets. See qtaguid kernel module for
+  // stats.
+  const int kUpdateEngineSocketTag = 0x55417243;  // "CrAU" in little-endian.
   qtaguid_tagSocket(curlfd, kUpdateEngineSocketTag, AID_OTA_UPDATE);
 #endif  // __ANDROID__
   return CURL_SOCKOPT_OK;
@@ -346,11 +346,7 @@
   url_ = url;
   auto closure = base::Bind(&LibcurlHttpFetcher::ProxiesResolved,
                             base::Unretained(this));
-  if (!ResolveProxiesForUrl(url_, closure)) {
-    LOG(ERROR) << "Couldn't resolve proxies";
-    if (delegate_)
-      delegate_->TransferComplete(this, false);
-  }
+  ResolveProxiesForUrl(url_, closure);
 }
 
 void LibcurlHttpFetcher::ProxiesResolved() {
diff --git a/p2p_manager.cc b/p2p_manager.cc
index 127e5ff..1ee124d 100644
--- a/p2p_manager.cc
+++ b/p2p_manager.cc
@@ -16,6 +16,9 @@
 
 // This provides access to timestamps with nanosecond resolution in
 // struct stat, See NOTES in stat(2) for details.
+#ifndef _DEFAULT_SOURCE
+#define _DEFAULT_SOURCE
+#endif
 #ifndef _BSD_SOURCE
 #define _BSD_SOURCE
 #endif
diff --git a/p2p_manager_unittest.cc b/p2p_manager_unittest.cc
index 463c0e2..5ffb358 100644
--- a/p2p_manager_unittest.cc
+++ b/p2p_manager_unittest.cc
@@ -506,7 +506,18 @@
 
   // Emulate p2p-client exceeding its timeout.
   test_conf_->SetP2PClientCommand({
-      "sh", "-c", "echo http://1.2.3.4/; sleep 2"});
+      "sh", "-c",
+      // The 'sleep' launched below could be left behind as an orphaned
+      // process when the 'sh' process is terminated by SIGTERM. As a
+      // remedy, trap SIGTERM and kill the 'sleep' process, which requires
+      // launching 'sleep' in background and then waiting for it.
+      "cleanup() { kill \"${sleep_pid}\"; exit 0; }; "
+      "trap cleanup TERM; "
+      "sleep 5 & "
+      "sleep_pid=$!; "
+      "echo http://1.2.3.4/; "
+      "wait"
+  });
   manager_->LookupUrlForFile("foobar", 42, TimeDelta::FromMilliseconds(500),
                              base::Bind(ExpectUrl, ""));
   loop_.Run();
diff --git a/payload_consumer/delta_performer.cc b/payload_consumer/delta_performer.cc
index 5bd1a19..c406493 100644
--- a/payload_consumer/delta_performer.cc
+++ b/payload_consumer/delta_performer.cc
@@ -26,7 +26,6 @@
 #include <string>
 #include <vector>
 
-#include <applypatch/imgpatch.h>
 #include <base/files/file_util.h>
 #include <base/format_macros.h>
 #include <base/strings/string_number_conversions.h>
@@ -34,7 +33,7 @@
 #include <base/strings/stringprintf.h>
 #include <brillo/data_encoding.h>
 #include <brillo/make_unique_ptr.h>
-#include <bspatch.h>
+#include <bsdiff/bspatch.h>
 #include <google/protobuf/repeated_field.h>
 
 #include "update_engine/common/constants.h"
@@ -733,10 +732,11 @@
         op_result = PerformSourceBsdiffOperation(op, error);
         break;
       case InstallOperation::IMGDIFF:
-        op_result = PerformImgdiffOperation(op, error);
+        // TODO(deymo): Replace with PUFFIN operation.
+        op_result = false;
         break;
       default:
-       op_result = false;
+        op_result = false;
     }
     if (!HandleOpResult(op_result, InstallOperationTypeName(op.type()), error))
       return false;
@@ -1263,57 +1263,6 @@
   return true;
 }
 
-bool DeltaPerformer::PerformImgdiffOperation(const InstallOperation& operation,
-                                             ErrorCode* error) {
-  // Since we delete data off the beginning of the buffer as we use it,
-  // the data we need should be exactly at the beginning of the buffer.
-  TEST_AND_RETURN_FALSE(buffer_offset_ == operation.data_offset());
-  TEST_AND_RETURN_FALSE(buffer_.size() >= operation.data_length());
-
-  uint64_t src_blocks = GetBlockCount(operation.src_extents());
-  brillo::Blob src_data(src_blocks * block_size_);
-
-  ssize_t bytes_read = 0;
-  for (const Extent& extent : operation.src_extents()) {
-    ssize_t bytes_read_this_iteration = 0;
-    ssize_t bytes_to_read = extent.num_blocks() * block_size_;
-    TEST_AND_RETURN_FALSE(utils::PReadAll(source_fd_,
-                                          &src_data[bytes_read],
-                                          bytes_to_read,
-                                          extent.start_block() * block_size_,
-                                          &bytes_read_this_iteration));
-    TEST_AND_RETURN_FALSE(bytes_read_this_iteration == bytes_to_read);
-    bytes_read += bytes_read_this_iteration;
-  }
-
-  if (operation.has_src_sha256_hash()) {
-    brillo::Blob src_hash;
-    TEST_AND_RETURN_FALSE(HashCalculator::RawHashOfData(src_data, &src_hash));
-    TEST_AND_RETURN_FALSE(ValidateSourceHash(src_hash, operation, error));
-  }
-
-  vector<Extent> target_extents(operation.dst_extents().begin(),
-                                operation.dst_extents().end());
-  DirectExtentWriter writer;
-  TEST_AND_RETURN_FALSE(writer.Init(target_fd_, target_extents, block_size_));
-  TEST_AND_RETURN_FALSE(
-      ApplyImagePatch(src_data.data(),
-                      src_data.size(),
-                      buffer_.data(),
-                      operation.data_length(),
-                      [](const unsigned char* data, ssize_t len, void* token) {
-                        return reinterpret_cast<ExtentWriter*>(token)
-                                       ->Write(data, len)
-                                   ? len
-                                   : 0;
-                      },
-                      &writer) == 0);
-  TEST_AND_RETURN_FALSE(writer.End());
-
-  DiscardBuffer(true, buffer_.size());
-  return true;
-}
-
 bool DeltaPerformer::ExtractSignatureMessageFromOperation(
     const InstallOperation& operation) {
   if (operation.type() != InstallOperation::REPLACE ||
diff --git a/payload_consumer/delta_performer.h b/payload_consumer/delta_performer.h
index 74143e0..71d7178 100644
--- a/payload_consumer/delta_performer.h
+++ b/payload_consumer/delta_performer.h
@@ -254,8 +254,6 @@
                                   ErrorCode* error);
   bool PerformSourceBsdiffOperation(const InstallOperation& operation,
                                     ErrorCode* error);
-  bool PerformImgdiffOperation(const InstallOperation& operation,
-                               ErrorCode* error);
 
   // Extracts the payload signature message from the blob on the |operation| if
   // the offset matches the one specified by the manifest. Returns whether the
diff --git a/payload_consumer/delta_performer_unittest.cc b/payload_consumer/delta_performer_unittest.cc
index 47a95ec..ad0c301 100644
--- a/payload_consumer/delta_performer_unittest.cc
+++ b/payload_consumer/delta_performer_unittest.cc
@@ -87,60 +87,6 @@
     0x00, 0x00, 0x59, 0x5a,
 };
 
-// Gzipped 'abc', generated with:
-// echo -n abc | minigzip | hexdump -v -e '"    " 12/1 "0x%02x, " "\n"'
-const uint8_t kSourceGzippedData[] = {
-    0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x4b, 0x4c,
-    0x4a, 0x06, 0x00, 0xc2, 0x41, 0x24, 0x35, 0x03, 0x00, 0x00, 0x00,
-};
-
-// Gzipped 'def', generated with:
-// echo -n def | minigzip | hexdump -v -e '"    " 12/1 "0x%02x, " "\n"'
-const uint8_t kTargetGzippedData[] = {
-    0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x4b, 0x49,
-    0x4d, 0x03, 0x00, 0x61, 0xe1, 0xc4, 0x0c, 0x03, 0x00, 0x00, 0x00,
-};
-
-// Imgdiff data, generated with:
-// echo -n abc | minigzip > abc && truncate -s 4096 abc
-// echo -n def | minigzip > def && truncate -s 4096 def
-// imgdiff abc def patch && hexdump -v -e '"    " 12/1 "0x%02x, " "\n"' patch
-const uint8_t kImgdiffData[] = {
-    0x49, 0x4d, 0x47, 0x44, 0x49, 0x46, 0x46, 0x32, 0x03, 0x00, 0x00, 0x00,
-    0x03, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x1f, 0x8b, 0x08, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0x00, 0x0a, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0xf1, 0xff,
-    0xff, 0xff, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x0f,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x42, 0x53, 0x44, 0x49, 0x46, 0x46, 0x34, 0x30, 0x2a, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x5a,
-    0x68, 0x39, 0x31, 0x41, 0x59, 0x26, 0x53, 0x59, 0xc3, 0xc8, 0xfb, 0x1f,
-    0x00, 0x00, 0x01, 0x40, 0x00, 0x5c, 0x00, 0x20, 0x00, 0x30, 0xcd, 0x34,
-    0x12, 0x34, 0x54, 0x60, 0x5c, 0xce, 0x2e, 0xe4, 0x8a, 0x70, 0xa1, 0x21,
-    0x87, 0x91, 0xf6, 0x3e, 0x42, 0x5a, 0x68, 0x39, 0x17, 0x72, 0x45, 0x38,
-    0x50, 0x90, 0x00, 0x00, 0x00, 0x00, 0x42, 0x5a, 0x68, 0x39, 0x31, 0x41,
-    0x59, 0x26, 0x53, 0x59, 0x42, 0x3c, 0xb0, 0xf9, 0x00, 0x00, 0x00, 0x01,
-    0x00, 0x07, 0x00, 0x20, 0x00, 0x21, 0x98, 0x19, 0x84, 0x61, 0x77, 0x24,
-    0x53, 0x85, 0x09, 0x04, 0x23, 0xcb, 0x0f, 0x90, 0x42, 0x53, 0x44, 0x49,
-    0x46, 0x46, 0x34, 0x30, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x0f, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x42, 0x5a, 0x68, 0x39, 0x31, 0x41, 0x59, 0x26,
-    0x53, 0x59, 0x6f, 0x02, 0x77, 0xf3, 0x00, 0x00, 0x07, 0x40, 0x41, 0xe0,
-    0x10, 0xc0, 0x00, 0x00, 0x02, 0x20, 0x00, 0x20, 0x00, 0x21, 0x29, 0xa3,
-    0x10, 0x86, 0x03, 0x84, 0x04, 0xae, 0x5f, 0x17, 0x72, 0x45, 0x38, 0x50,
-    0x90, 0x6f, 0x02, 0x77, 0xf3, 0x42, 0x5a, 0x68, 0x39, 0x31, 0x41, 0x59,
-    0x26, 0x53, 0x59, 0x71, 0x62, 0xbd, 0xa7, 0x00, 0x00, 0x20, 0x40, 0x32,
-    0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x80, 0x00, 0x48, 0x20, 0x00,
-    0x30, 0xc0, 0x02, 0xa5, 0x19, 0xa5, 0x92, 0x6f, 0xc2, 0x5d, 0xac, 0x0e,
-    0x17, 0x72, 0x45, 0x38, 0x50, 0x90, 0x71, 0x62, 0xbd, 0xa7, 0x42, 0x5a,
-    0x68, 0x39, 0x17, 0x72, 0x45, 0x38, 0x50, 0x90, 0x00, 0x00, 0x00, 0x00,
-};
-
 }  // namespace
 
 class DeltaPerformerTest : public ::testing::Test {
@@ -534,33 +480,6 @@
   EXPECT_EQ(expected_data, ApplyPayload(payload_data, source_path, true));
 }
 
-TEST_F(DeltaPerformerTest, ImgdiffOperationTest) {
-  brillo::Blob imgdiff_data(std::begin(kImgdiffData), std::end(kImgdiffData));
-
-  AnnotatedOperation aop;
-  *(aop.op.add_src_extents()) = ExtentForRange(0, 1);
-  *(aop.op.add_dst_extents()) = ExtentForRange(0, 1);
-  aop.op.set_data_offset(0);
-  aop.op.set_data_length(imgdiff_data.size());
-  aop.op.set_type(InstallOperation::IMGDIFF);
-
-  brillo::Blob payload_data = GeneratePayload(imgdiff_data, {aop}, false);
-
-  string source_path;
-  EXPECT_TRUE(utils::MakeTempFile("Source-XXXXXX", &source_path, nullptr));
-  ScopedPathUnlinker path_unlinker(source_path);
-  brillo::Blob source_data(std::begin(kSourceGzippedData),
-                           std::end(kSourceGzippedData));
-  source_data.resize(4096);  // block size
-  EXPECT_TRUE(utils::WriteFile(
-      source_path.c_str(), source_data.data(), source_data.size()));
-
-  brillo::Blob target_data(std::begin(kTargetGzippedData),
-                           std::end(kTargetGzippedData));
-  target_data.resize(4096);  // block size
-  EXPECT_EQ(target_data, ApplyPayload(payload_data, source_path, true));
-}
-
 TEST_F(DeltaPerformerTest, SourceHashMismatchTest) {
   brillo::Blob expected_data = {'f', 'o', 'o'};
   brillo::Blob actual_data = {'b', 'a', 'r'};
diff --git a/payload_consumer/postinstall_runner_action.cc b/payload_consumer/postinstall_runner_action.cc
index 11eec34..27a9ed6 100644
--- a/payload_consumer/postinstall_runner_action.cc
+++ b/payload_consumer/postinstall_runner_action.cc
@@ -360,6 +360,8 @@
     return;
   if (kill(current_command_, SIGSTOP) != 0) {
     PLOG(ERROR) << "Couldn't pause child process " << current_command_;
+  } else {
+    is_current_command_suspended_ = true;
   }
 }
 
@@ -368,6 +370,8 @@
     return;
   if (kill(current_command_, SIGCONT) != 0) {
     PLOG(ERROR) << "Couldn't resume child process " << current_command_;
+  } else {
+    is_current_command_suspended_ = false;
   }
 }
 
@@ -377,6 +381,13 @@
   // Calling KillExec() will discard the callback we registered and therefore
   // the unretained reference to this object.
   Subprocess::Get().KillExec(current_command_);
+
+  // If the command has been suspended, resume it after KillExec() so that the
+  // process can process the SIGTERM sent by KillExec().
+  if (is_current_command_suspended_) {
+    ResumeAction();
+  }
+
   current_command_ = 0;
   Cleanup();
 }
diff --git a/payload_consumer/postinstall_runner_action.h b/payload_consumer/postinstall_runner_action.h
index 2bde3ca..2e48e11 100644
--- a/payload_consumer/postinstall_runner_action.h
+++ b/payload_consumer/postinstall_runner_action.h
@@ -134,6 +134,9 @@
   // Postinstall command currently running, or 0 if no program running.
   pid_t current_command_{0};
 
+  // True if |current_command_| has been suspended by SuspendAction().
+  bool is_current_command_suspended_{false};
+
   // The parent progress file descriptor used to watch for progress reports from
   // the postinstall program and the task watching for them.
   int progress_fd_{-1};
diff --git a/payload_generator/ab_generator.cc b/payload_generator/ab_generator.cc
index efb8ccf..3b0d012 100644
--- a/payload_generator/ab_generator.cc
+++ b/payload_generator/ab_generator.cc
@@ -88,14 +88,19 @@
                                      BlobFileWriter* blob_file) {
   vector<AnnotatedOperation> fragmented_aops;
   for (const AnnotatedOperation& aop : *aops) {
-    if (aop.op.type() == InstallOperation::SOURCE_COPY) {
-      TEST_AND_RETURN_FALSE(SplitSourceCopy(aop, &fragmented_aops));
-    } else if (IsAReplaceOperation(aop.op.type())) {
-      TEST_AND_RETURN_FALSE(SplitAReplaceOp(
-          version, aop, target_part_path, &fragmented_aops, blob_file));
-    } else {
-      fragmented_aops.push_back(aop);
+    // Only do split if the operation has more than one dst extents.
+    if (aop.op.dst_extents_size() > 1) {
+      if (aop.op.type() == InstallOperation::SOURCE_COPY) {
+        TEST_AND_RETURN_FALSE(SplitSourceCopy(aop, &fragmented_aops));
+        continue;
+      }
+      if (IsAReplaceOperation(aop.op.type())) {
+        TEST_AND_RETURN_FALSE(SplitAReplaceOp(
+            version, aop, target_part_path, &fragmented_aops, blob_file));
+        continue;
+      }
     }
+    fragmented_aops.push_back(aop);
   }
   *aops = std::move(fragmented_aops);
   return true;
@@ -139,8 +144,6 @@
     // Fix up our new operation and add it to the results.
     new_op.set_type(InstallOperation::SOURCE_COPY);
     *(new_op.add_dst_extents()) = dst_ext;
-    new_op.set_src_length(dst_ext.num_blocks() * kBlockSize);
-    new_op.set_dst_length(dst_ext.num_blocks() * kBlockSize);
 
     AnnotatedOperation new_aop;
     new_aop.op = new_op;
diff --git a/payload_generator/ab_generator_unittest.cc b/payload_generator/ab_generator_unittest.cc
index 3fd2323..ab4b164 100644
--- a/payload_generator/ab_generator_unittest.cc
+++ b/payload_generator/ab_generator_unittest.cc
@@ -354,11 +354,11 @@
   EXPECT_EQ("SplitSourceCopyTestOp:0", result_ops[0].name);
   InstallOperation first_op = result_ops[0].op;
   EXPECT_EQ(InstallOperation::SOURCE_COPY, first_op.type());
-  EXPECT_EQ(kBlockSize * 2, first_op.src_length());
+  EXPECT_FALSE(first_op.has_src_length());
   EXPECT_EQ(1, first_op.src_extents().size());
   EXPECT_EQ(2U, first_op.src_extents(0).start_block());
   EXPECT_EQ(2U, first_op.src_extents(0).num_blocks());
-  EXPECT_EQ(kBlockSize * 2, first_op.dst_length());
+  EXPECT_FALSE(first_op.has_dst_length());
   EXPECT_EQ(1, first_op.dst_extents().size());
   EXPECT_EQ(10U, first_op.dst_extents(0).start_block());
   EXPECT_EQ(2U, first_op.dst_extents(0).num_blocks());
@@ -366,7 +366,7 @@
   EXPECT_EQ("SplitSourceCopyTestOp:1", result_ops[1].name);
   InstallOperation second_op = result_ops[1].op;
   EXPECT_EQ(InstallOperation::SOURCE_COPY, second_op.type());
-  EXPECT_EQ(kBlockSize * 3, second_op.src_length());
+  EXPECT_FALSE(second_op.has_src_length());
   EXPECT_EQ(3, second_op.src_extents().size());
   EXPECT_EQ(4U, second_op.src_extents(0).start_block());
   EXPECT_EQ(1U, second_op.src_extents(0).num_blocks());
@@ -374,7 +374,7 @@
   EXPECT_EQ(1U, second_op.src_extents(1).num_blocks());
   EXPECT_EQ(8U, second_op.src_extents(2).start_block());
   EXPECT_EQ(1U, second_op.src_extents(2).num_blocks());
-  EXPECT_EQ(kBlockSize * 3, second_op.dst_length());
+  EXPECT_FALSE(second_op.has_dst_length());
   EXPECT_EQ(1, second_op.dst_extents().size());
   EXPECT_EQ(14U, second_op.dst_extents(0).start_block());
   EXPECT_EQ(3U, second_op.dst_extents(0).num_blocks());
@@ -382,11 +382,11 @@
   EXPECT_EQ("SplitSourceCopyTestOp:2", result_ops[2].name);
   InstallOperation third_op = result_ops[2].op;
   EXPECT_EQ(InstallOperation::SOURCE_COPY, third_op.type());
-  EXPECT_EQ(kBlockSize * 3, third_op.src_length());
+  EXPECT_FALSE(third_op.has_src_length());
   EXPECT_EQ(1, third_op.src_extents().size());
   EXPECT_EQ(9U, third_op.src_extents(0).start_block());
   EXPECT_EQ(3U, third_op.src_extents(0).num_blocks());
-  EXPECT_EQ(kBlockSize * 3, third_op.dst_length());
+  EXPECT_FALSE(third_op.has_dst_length());
   EXPECT_EQ(1, third_op.dst_extents().size());
   EXPECT_EQ(18U, third_op.dst_extents(0).start_block());
   EXPECT_EQ(3U, third_op.dst_extents(0).num_blocks());
@@ -445,8 +445,6 @@
   vector<AnnotatedOperation> aops;
   InstallOperation first_op;
   first_op.set_type(InstallOperation::SOURCE_COPY);
-  first_op.set_src_length(kBlockSize);
-  first_op.set_dst_length(kBlockSize);
   *(first_op.add_src_extents()) = ExtentForRange(1, 1);
   *(first_op.add_dst_extents()) = ExtentForRange(6, 1);
   AnnotatedOperation first_aop;
@@ -456,8 +454,6 @@
 
   InstallOperation second_op;
   second_op.set_type(InstallOperation::SOURCE_COPY);
-  second_op.set_src_length(3 * kBlockSize);
-  second_op.set_dst_length(3 * kBlockSize);
   *(second_op.add_src_extents()) = ExtentForRange(2, 2);
   *(second_op.add_src_extents()) = ExtentForRange(8, 2);
   *(second_op.add_dst_extents()) = ExtentForRange(7, 3);
@@ -469,8 +465,6 @@
 
   InstallOperation third_op;
   third_op.set_type(InstallOperation::SOURCE_COPY);
-  third_op.set_src_length(kBlockSize);
-  third_op.set_dst_length(kBlockSize);
   *(third_op.add_src_extents()) = ExtentForRange(11, 1);
   *(third_op.add_dst_extents()) = ExtentForRange(12, 1);
   AnnotatedOperation third_aop;
@@ -486,12 +480,12 @@
   EXPECT_EQ(1U, aops.size());
   InstallOperation first_result_op = aops[0].op;
   EXPECT_EQ(InstallOperation::SOURCE_COPY, first_result_op.type());
-  EXPECT_EQ(kBlockSize * 5, first_result_op.src_length());
+  EXPECT_FALSE(first_result_op.has_src_length());
   EXPECT_EQ(3, first_result_op.src_extents().size());
   EXPECT_TRUE(ExtentEquals(first_result_op.src_extents(0), 1, 3));
   EXPECT_TRUE(ExtentEquals(first_result_op.src_extents(1), 8, 2));
   EXPECT_TRUE(ExtentEquals(first_result_op.src_extents(2), 11, 1));
-  EXPECT_EQ(kBlockSize * 5, first_result_op.dst_length());
+  EXPECT_FALSE(first_result_op.has_dst_length());
   EXPECT_EQ(2, first_result_op.dst_extents().size());
   EXPECT_TRUE(ExtentEquals(first_result_op.dst_extents(0), 6, 4));
   EXPECT_TRUE(ExtentEquals(first_result_op.dst_extents(1), 11, 2));
diff --git a/payload_generator/delta_diff_utils.cc b/payload_generator/delta_diff_utils.cc
index 44aff7a..045d52f 100644
--- a/payload_generator/delta_diff_utils.cc
+++ b/payload_generator/delta_diff_utils.cc
@@ -22,7 +22,7 @@
 #pragma clang diagnostic ignored "-Wmacro-redefined"
 #include <ext2fs/ext2fs.h>
 #pragma clang diagnostic pop
-
+#include <unistd.h>
 
 #include <algorithm>
 #include <map>
@@ -30,6 +30,7 @@
 #include <base/files/file_util.h>
 #include <base/format_macros.h>
 #include <base/strings/stringprintf.h>
+#include <base/threading/simple_thread.h>
 
 #include "update_engine/common/hash_calculator.h"
 #include "update_engine/common/subprocess.h"
@@ -171,6 +172,81 @@
 
 namespace diff_utils {
 
+// This class encapsulates a file delta processing thread work. The
+// processor computes the delta between the source and target files;
+// and write the compressed delta to the blob.
+class FileDeltaProcessor : public base::DelegateSimpleThread::Delegate {
+ public:
+  FileDeltaProcessor(const string& old_part,
+                     const string& new_part,
+                     const PayloadVersion& version,
+                     const vector<Extent>& old_extents,
+                     const vector<Extent>& new_extents,
+                     const string& name,
+                     ssize_t chunk_blocks,
+                     BlobFileWriter* blob_file)
+      : old_part_(old_part),
+        new_part_(new_part),
+        version_(version),
+        old_extents_(old_extents),
+        new_extents_(new_extents),
+        name_(name),
+        chunk_blocks_(chunk_blocks),
+        blob_file_(blob_file) {}
+
+  FileDeltaProcessor(FileDeltaProcessor&& processor) = default;
+
+  ~FileDeltaProcessor() override = default;
+
+  // Overrides DelegateSimpleThread::Delegate.
+  // Calculate the list of operations and write their corresponding deltas to
+  // the blob_file.
+  void Run() override;
+
+  // Merge each file processor's ops list to aops.
+  void MergeOperation(vector<AnnotatedOperation>* aops);
+
+ private:
+  const string& old_part_;
+  const string& new_part_;
+  const PayloadVersion& version_;
+
+  // The block ranges of the old/new file within the src/tgt image
+  const vector<Extent> old_extents_;
+  const vector<Extent> new_extents_;
+  const string name_;
+  // Block limit of one aop.
+  ssize_t chunk_blocks_;
+  BlobFileWriter* blob_file_;
+
+  // The list of ops to reach the new file from the old file.
+  vector<AnnotatedOperation> file_aops_;
+
+  DISALLOW_COPY_AND_ASSIGN(FileDeltaProcessor);
+};
+
+void FileDeltaProcessor::Run() {
+  TEST_AND_RETURN(blob_file_ != nullptr);
+
+  if (!DeltaReadFile(&file_aops_,
+                     old_part_,
+                     new_part_,
+                     old_extents_,
+                     new_extents_,
+                     name_,
+                     chunk_blocks_,
+                     version_,
+                     blob_file_)) {
+    LOG(ERROR) << "Failed to generate delta for " << name_ << " ("
+               << BlocksInExtents(new_extents_) << " blocks)";
+  }
+}
+
+void FileDeltaProcessor::MergeOperation(vector<AnnotatedOperation>* aops) {
+  aops->reserve(aops->size() + file_aops_.size());
+  std::move(file_aops_.begin(), file_aops_.end(), std::back_inserter(*aops));
+}
+
 bool DeltaReadPartition(vector<AnnotatedOperation>* aops,
                         const PartitionConfig& old_part,
                         const PartitionConfig& new_part,
@@ -205,6 +281,8 @@
   vector<FilesystemInterface::File> new_files;
   new_part.fs_interface->GetFiles(&new_files);
 
+  vector<FileDeltaProcessor> file_delta_processors;
+
   // The processing is very straightforward here, we generate operations for
   // every file (and pseudo-file such as the metadata) in the new filesystem
   // based on the file with the same name in the old filesystem, if any.
@@ -239,16 +317,29 @@
         old_files_map[new_file.name], old_visited_blocks);
     old_visited_blocks.AddExtents(old_file_extents);
 
-    TEST_AND_RETURN_FALSE(DeltaReadFile(aops,
-                                        old_part.path,
-                                        new_part.path,
-                                        old_file_extents,
-                                        new_file_extents,
-                                        new_file.name,  // operation name
-                                        hard_chunk_blocks,
-                                        version,
-                                        blob_file));
+    file_delta_processors.emplace_back(old_part.path,
+                                       new_part.path,
+                                       version,
+                                       std::move(old_file_extents),
+                                       std::move(new_file_extents),
+                                       new_file.name,  // operation name
+                                       hard_chunk_blocks,
+                                       blob_file);
   }
+
+  size_t max_threads = GetMaxThreads();
+  base::DelegateSimpleThreadPool thread_pool("incremental-update-generator",
+                                             max_threads);
+  thread_pool.Start();
+  for (auto& processor : file_delta_processors) {
+    thread_pool.AddWork(&processor);
+  }
+  thread_pool.JoinAll();
+
+  for (auto& processor : file_delta_processors) {
+    processor.MergeOperation(aops);
+  }
+
   // Process all the blocks not included in any file. We provided all the unused
   // blocks in the old partition as available data.
   vector<Extent> new_unvisited = {
@@ -807,6 +898,11 @@
   return true;
 }
 
+// Return the number of CPUs on the machine, and 4 threads in minimum.
+size_t GetMaxThreads() {
+  return std::max(sysconf(_SC_NPROCESSORS_ONLN), 4L);
+}
+
 }  // namespace diff_utils
 
 }  // namespace chromeos_update_engine
diff --git a/payload_generator/delta_diff_utils.h b/payload_generator/delta_diff_utils.h
index 7254bca..c9fef17 100644
--- a/payload_generator/delta_diff_utils.h
+++ b/payload_generator/delta_diff_utils.h
@@ -143,6 +143,9 @@
 // false.
 bool IsExtFilesystem(const std::string& device);
 
+// Returns the max number of threads to process the files(chunks) in parallel.
+size_t GetMaxThreads();
+
 }  // namespace diff_utils
 
 }  // namespace chromeos_update_engine
diff --git a/payload_generator/full_update_generator.cc b/payload_generator/full_update_generator.cc
index 8fdb6ec..482a789 100644
--- a/payload_generator/full_update_generator.cc
+++ b/payload_generator/full_update_generator.cc
@@ -139,7 +139,7 @@
   TEST_AND_RETURN_FALSE(full_chunk_size % config.block_size == 0);
 
   size_t chunk_blocks = full_chunk_size / config.block_size;
-  size_t max_threads = std::max(sysconf(_SC_NPROCESSORS_ONLN), 4L);
+  size_t max_threads = diff_utils::GetMaxThreads();
   LOG(INFO) << "Compressing partition " << new_part.name
             << " from " << new_part.path << " splitting in chunks of "
             << chunk_blocks << " blocks (" << config.block_size
diff --git a/real_system_state.cc b/real_system_state.cc
index 5fc0b71..5cbf723 100644
--- a/real_system_state.cc
+++ b/real_system_state.cc
@@ -24,14 +24,19 @@
 #include <base/time/time.h>
 #include <brillo/make_unique_ptr.h>
 #include <brillo/message_loops/message_loop.h>
+#if USE_LIBCROS
+#include <chromeos/dbus/service_constants.h>
+#endif  // USE_LIBCROS
 
 #include "update_engine/common/boot_control.h"
 #include "update_engine/common/boot_control_stub.h"
 #include "update_engine/common/constants.h"
 #include "update_engine/common/hardware.h"
 #include "update_engine/common/utils.h"
+#if USE_DBUS
+#include "update_engine/dbus_connection.h"
+#endif  // USE_DBUS
 #include "update_engine/update_manager/state_factory.h"
-#include "update_engine/weave_service_factory.h"
 
 using brillo::MessageLoop;
 
@@ -60,6 +65,15 @@
     return false;
   }
 
+#if USE_LIBCROS
+  libcros_proxy_.reset(new org::chromium::LibCrosServiceInterfaceProxy(
+      DBusConnection::Get()->GetDBus(), chromeos::kLibCrosServiceName));
+  network_proxy_service_proxy_.reset(
+      new org::chromium::NetworkProxyServiceInterfaceProxy(
+          DBusConnection::Get()->GetDBus(),
+          chromeos::kNetworkProxyServiceName));
+#endif  // USE_LIBCROS
+
   LOG_IF(INFO, !hardware_->IsNormalBootMode()) << "Booted in dev mode.";
   LOG_IF(INFO, !hardware_->IsOfficialBuild()) << "Booted non-official build.";
 
@@ -130,20 +144,22 @@
   certificate_checker_->Init();
 
 #if USE_LIBCROS
-  LibCrosProxy* libcros_proxy = &libcros_proxy_;
+  org::chromium::NetworkProxyServiceInterfaceProxyInterface* net_proxy =
+      network_proxy_service_proxy_.get();
+  org::chromium::LibCrosServiceInterfaceProxyInterface* libcros_proxy =
+      libcros_proxy_.get();
 #else
-  LibCrosProxy* libcros_proxy = nullptr;
+  org::chromium::NetworkProxyServiceInterfaceProxyInterface* net_proxy =
+      nullptr;
+  org::chromium::LibCrosServiceInterfaceProxyInterface* libcros_proxy =
+      nullptr;
 #endif  // USE_LIBCROS
 
   // Initialize the UpdateAttempter before the UpdateManager.
-  update_attempter_.reset(
-      new UpdateAttempter(this, certificate_checker_.get(), libcros_proxy));
+  update_attempter_.reset(new UpdateAttempter(this, certificate_checker_.get(),
+                                              net_proxy));
   update_attempter_->Init();
 
-  weave_service_ = ConstructWeaveService(update_attempter_.get());
-  if (weave_service_)
-    update_attempter_->AddObserver(weave_service_.get());
-
   // Initialize the Update Manager using the default state factory.
   chromeos_update_manager::State* um_state =
       chromeos_update_manager::DefaultStateFactory(
diff --git a/real_system_state.h b/real_system_state.h
index 0964f10..64964cd 100644
--- a/real_system_state.h
+++ b/real_system_state.h
@@ -25,6 +25,11 @@
 #include <metrics/metrics_library.h>
 #include <policy/device_policy.h>
 
+#if USE_LIBCROS
+#include <libcros/dbus-proxies.h>
+#include <network_proxy/dbus-proxies.h>
+#endif  // USE_LIBCROS
+
 #include "update_engine/certificate_checker.h"
 #include "update_engine/common/boot_control_interface.h"
 #include "update_engine/common/clock.h"
@@ -37,7 +42,6 @@
 #include "update_engine/power_manager_interface.h"
 #include "update_engine/update_attempter.h"
 #include "update_engine/update_manager/update_manager.h"
-#include "update_engine/weave_service_interface.h"
 
 namespace chromeos_update_engine {
 
@@ -106,10 +110,6 @@
     return update_attempter_.get();
   }
 
-  inline WeaveServiceInterface* weave_service() override {
-    return weave_service_.get();
-  }
-
   inline OmahaRequestParams* request_params() override {
     return &request_params_;
   }
@@ -128,8 +128,10 @@
 
  private:
 #if USE_LIBCROS
-  // LibCros proxy using the DBus connection.
-  LibCrosProxy libcros_proxy_;
+  // Real DBus proxies using the DBus connection.
+  std::unique_ptr<org::chromium::LibCrosServiceInterfaceProxy> libcros_proxy_;
+  std::unique_ptr<org::chromium::NetworkProxyServiceInterfaceProxy>
+      network_proxy_service_proxy_;
 #endif  // USE_LIBCROS
 
   // Interface for the power manager.
@@ -176,8 +178,6 @@
 
   std::unique_ptr<P2PManager> p2p_manager_;
 
-  std::unique_ptr<WeaveServiceInterface> weave_service_;
-
   std::unique_ptr<chromeos_update_manager::UpdateManager> update_manager_;
 
   policy::PolicyProvider policy_provider_;
diff --git a/scripts/brillo_update_payload b/scripts/brillo_update_payload
index f7bb799..375c0df 100755
--- a/scripts/brillo_update_payload
+++ b/scripts/brillo_update_payload
@@ -463,6 +463,11 @@
       if [[ "${partitions_array}" == "SRC_PARTITIONS" ]]; then
         echo "Rounding DOWN partition ${part}.img to a multiple of 4 KiB."
         : $(( filesize = filesize & -4096 ))
+        if [[ ${filesize} == 0 ]]; then
+          echo "Source partition ${part}.img is empty after rounding down," \
+            "skipping."
+          continue
+        fi
       else
         echo "Rounding UP partition ${part}.img to a multiple of 4 KiB."
         : $(( filesize = (filesize + 4095) & -4096 ))
diff --git a/service_observer_interface.h b/service_observer_interface.h
index 75a739f..893df04 100644
--- a/service_observer_interface.h
+++ b/service_observer_interface.h
@@ -40,9 +40,6 @@
   // Called whenever an update attempt is completed.
   virtual void SendPayloadApplicationComplete(ErrorCode error_code) = 0;
 
-  // Called whenever the channel we are tracking changes.
-  virtual void SendChannelChangeUpdate(const std::string& tracking_channel) = 0;
-
  protected:
   ServiceObserverInterface() = default;
 };
diff --git a/sideload_main.cc b/sideload_main.cc
index d02af0e..574d062 100644
--- a/sideload_main.cc
+++ b/sideload_main.cc
@@ -112,8 +112,6 @@
     brillo::MessageLoop::current()->BreakLoop();
   }
 
-  void SendChannelChangeUpdate(const string& tracking_channel) override {}
-
   // Getters.
   UpdateStatus status() { return status_; }
   ErrorCode error_code() { return error_code_; }
diff --git a/system_state.h b/system_state.h
index 4d040ec..d538427 100644
--- a/system_state.h
+++ b/system_state.h
@@ -46,7 +46,6 @@
 class PowerManagerInterface;
 class PrefsInterface;
 class UpdateAttempter;
-class WeaveServiceInterface;
 
 // An interface to global system context, including platform resources,
 // the current state of the system, high-level objects whose lifetime is same
@@ -94,9 +93,6 @@
   // Returns a pointer to the update attempter object.
   virtual UpdateAttempter* update_attempter() = 0;
 
-  // Returns a pointer to the WeaveServiceInterface class or nullptr if none.
-  virtual WeaveServiceInterface* weave_service() = 0;
-
   // Returns a pointer to the object that stores the parameters that are
   // common to all Omaha requests.
   virtual OmahaRequestParams* request_params() = 0;
diff --git a/update_attempter.cc b/update_attempter.cc
index d36f7fd..8e25819 100644
--- a/update_attempter.cc
+++ b/update_attempter.cc
@@ -119,14 +119,16 @@
   return code;
 }
 
-UpdateAttempter::UpdateAttempter(SystemState* system_state,
-                                 CertificateChecker* cert_checker,
-                                 LibCrosProxy* libcros_proxy)
+UpdateAttempter::UpdateAttempter(
+    SystemState* system_state,
+    CertificateChecker* cert_checker,
+    org::chromium::NetworkProxyServiceInterfaceProxyInterface*
+        network_proxy_service_proxy)
     : processor_(new ActionProcessor()),
       system_state_(system_state),
 #if USE_LIBCROS
       cert_checker_(cert_checker),
-      chrome_proxy_resolver_(libcros_proxy) {
+      chrome_proxy_resolver_(network_proxy_service_proxy) {
 #else
       cert_checker_(cert_checker) {
 #endif  // USE_LIBCROS
@@ -157,10 +159,6 @@
     status_ = UpdateStatus::UPDATED_NEED_REBOOT;
   else
     status_ = UpdateStatus::IDLE;
-
-#if USE_LIBCROS
-  chrome_proxy_resolver_.Init();
-#endif  // USE_LIBCROS
 }
 
 void UpdateAttempter::ScheduleUpdates() {
@@ -371,9 +369,8 @@
   // Refresh the policy before computing all the update parameters.
   RefreshDevicePolicy();
 
-  // Set the target version prefix, if provided.
-  if (!target_version_prefix.empty())
-    omaha_request_params_->set_target_version_prefix(target_version_prefix);
+  // Update the target version prefix.
+  omaha_request_params_->set_target_version_prefix(target_version_prefix);
 
   CalculateScatteringParams(interactive);
 
@@ -409,8 +406,6 @@
                                                  &error_message)) {
       LOG(ERROR) << "Setting the channel failed: " << error_message;
     }
-    // Notify observers the target channel change.
-    BroadcastChannel();
 
     // Since this is the beginning of a new attempt, update the download
     // channel. The download channel won't be updated until the next attempt,
@@ -1066,44 +1061,6 @@
   system_state_->payload_state()->DownloadComplete();
 }
 
-bool UpdateAttempter::OnCheckForUpdates(brillo::ErrorPtr* error) {
-  CheckForUpdate(
-      "" /* app_version */, "" /* omaha_url */, true /* interactive */);
-  return true;
-}
-
-bool UpdateAttempter::OnTrackChannel(const string& channel,
-                                     brillo::ErrorPtr* error) {
-  LOG(INFO) << "Setting destination channel to: " << channel;
-  string error_message;
-  if (!system_state_->request_params()->SetTargetChannel(
-          channel, false /* powerwash_allowed */, &error_message)) {
-    brillo::Error::AddTo(error,
-                         FROM_HERE,
-                         brillo::errors::dbus::kDomain,
-                         "set_target_error",
-                         error_message);
-    return false;
-  }
-  // Notify observers the target channel change.
-  BroadcastChannel();
-  return true;
-}
-
-bool UpdateAttempter::GetWeaveState(int64_t* last_checked_time,
-                                    double* progress,
-                                    UpdateStatus* update_status,
-                                    string* current_channel,
-                                    string* tracking_channel) {
-  *last_checked_time = last_checked_time_;
-  *progress = download_progress_;
-  *update_status = status_;
-  OmahaRequestParams* rp = system_state_->request_params();
-  *current_channel = rp->current_channel();
-  *tracking_channel = rp->target_channel();
-  return true;
-}
-
 void UpdateAttempter::ProgressUpdate(double progress) {
   // Self throttle based on progress. Also send notifications if progress is
   // too slow.
@@ -1221,13 +1178,6 @@
   last_notify_time_ = TimeTicks::Now();
 }
 
-void UpdateAttempter::BroadcastChannel() {
-  for (const auto& observer : service_observers_) {
-    observer->SendChannelChangeUpdate(
-        system_state_->request_params()->target_channel());
-  }
-}
-
 uint32_t UpdateAttempter::GetErrorCodeFlags()  {
   uint32_t flags = 0;
 
diff --git a/update_attempter.h b/update_attempter.h
index 104975c..193e172 100644
--- a/update_attempter.h
+++ b/update_attempter.h
@@ -45,23 +45,26 @@
 #include "update_engine/system_state.h"
 #include "update_engine/update_manager/policy.h"
 #include "update_engine/update_manager/update_manager.h"
-#include "update_engine/weave_service_interface.h"
 
 class MetricsLibraryInterface;
 
+namespace org {
+namespace chromium {
+class NetworkProxyServiceInterfaceProxyInterface;
+}  // namespace chromium
+}  // namespace org
+
 namespace policy {
 class PolicyProvider;
 }
 
 namespace chromeos_update_engine {
 
-class LibCrosProxy;
 class UpdateEngineAdaptor;
 
 class UpdateAttempter : public ActionProcessorDelegate,
                         public DownloadActionDelegate,
                         public CertificateChecker::Observer,
-                        public WeaveServiceInterface::DelegateInterface,
                         public PostinstallRunnerAction::DelegateInterface {
  public:
   using UpdateStatus = update_engine::UpdateStatus;
@@ -69,7 +72,8 @@
 
   UpdateAttempter(SystemState* system_state,
                   CertificateChecker* cert_checker,
-                  LibCrosProxy* libcros_proxy);
+                  org::chromium::NetworkProxyServiceInterfaceProxyInterface*
+                      network_proxy_service_proxy);
   ~UpdateAttempter() override;
 
   // Further initialization to be done post construction.
@@ -100,16 +104,6 @@
                        AbstractAction* action,
                        ErrorCode code) override;
 
-  // WeaveServiceInterface::DelegateInterface overrides.
-  bool OnCheckForUpdates(brillo::ErrorPtr* error) override;
-  bool OnTrackChannel(const std::string& channel,
-                      brillo::ErrorPtr* error) override;
-  bool GetWeaveState(int64_t* last_checked_time,
-                     double* progress,
-                     UpdateStatus* update_status,
-                     std::string* current_channel,
-                     std::string* tracking_channel) override;
-
   // PostinstallRunnerAction::DelegateInterface
   void ProgressUpdate(double progress) override;
 
@@ -181,9 +175,6 @@
   // Broadcasts the current status to all observers.
   void BroadcastStatus();
 
-  // Broadcasts the current tracking channel to all observers.
-  void BroadcastChannel();
-
   // Returns the special flags to be added to ErrorCode values based on the
   // parameters used in the current update attempt.
   uint32_t GetErrorCodeFlags();
@@ -271,6 +262,7 @@
   FRIEND_TEST(UpdateAttempterTest, UpdateTest);
   FRIEND_TEST(UpdateAttempterTest, ReportDailyMetrics);
   FRIEND_TEST(UpdateAttempterTest, BootTimeInUpdateMarkerFile);
+  FRIEND_TEST(UpdateAttempterTest, TargetVersionPrefixSetAndReset);
 
   // CertificateChecker::Observer method.
   // Report metrics about the certificate being checked.
diff --git a/update_attempter_android.cc b/update_attempter_android.cc
index b80ee6e..da43b6a 100644
--- a/update_attempter_android.cc
+++ b/update_attempter_android.cc
@@ -209,7 +209,6 @@
   if (!headers[kPayloadPropertyUserAgent].empty())
     fetcher->SetHeader("User-Agent", headers[kPayloadPropertyUserAgent]);
 
-  cpu_limiter_.StartLimiter();
   SetStatusAndNotify(UpdateStatus::UPDATE_AVAILABLE);
   ongoing_update_ = true;
 
@@ -416,8 +415,6 @@
     return;
   }
 
-  // Reset cpu shares back to normal.
-  cpu_limiter_.StopLimiter();
   download_progress_ = 0;
   actions_.clear();
   UpdateStatus new_status =
diff --git a/update_attempter_android.h b/update_attempter_android.h
index 2617318..6a5c227 100644
--- a/update_attempter_android.h
+++ b/update_attempter_android.h
@@ -28,7 +28,6 @@
 #include "update_engine/client_library/include/update_engine/update_status.h"
 #include "update_engine/common/action_processor.h"
 #include "update_engine/common/boot_control_interface.h"
-#include "update_engine/common/cpu_limiter.h"
 #include "update_engine/common/hardware_interface.h"
 #include "update_engine/common/prefs_interface.h"
 #include "update_engine/daemon_state_interface.h"
@@ -160,9 +159,6 @@
   // Only direct proxy supported.
   DirectProxyResolver proxy_resolver_;
 
-  // 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_;
 
diff --git a/update_attempter_unittest.cc b/update_attempter_unittest.cc
index 94a1b3c..93bcc5c 100644
--- a/update_attempter_unittest.cc
+++ b/update_attempter_unittest.cc
@@ -32,9 +32,8 @@
 #include <policy/mock_device_policy.h>
 
 #if USE_LIBCROS
-#include "libcros/dbus-proxies.h"
-#include "libcros/dbus-proxy-mocks.h"
-#include "update_engine/libcros_proxy.h"
+#include "network_proxy/dbus-proxies.h"
+#include "network_proxy/dbus-proxy-mocks.h"
 #endif // USE_LIBCROS
 #include "update_engine/common/fake_clock.h"
 #include "update_engine/common/fake_prefs.h"
@@ -54,12 +53,16 @@
 #include "update_engine/payload_consumer/payload_constants.h"
 #include "update_engine/payload_consumer/postinstall_runner_action.h"
 
+namespace org {
+namespace chromium {
+class NetworkProxyServiceInterfaceProxyMock;
+}  // namespace chromium
+}  // namespace org
+
 using base::Time;
 using base::TimeDelta;
-#if USE_LIBCROS
-using org::chromium::LibCrosServiceInterfaceProxyMock;
-using org::chromium::UpdateEngineLibcrosProxyResolvedInterfaceProxyMock;
-#endif // USE_LIBCROS
+using org::chromium::NetworkProxyServiceInterfaceProxyInterface;
+using org::chromium::NetworkProxyServiceInterfaceProxyMock;
 using std::string;
 using std::unique_ptr;
 using testing::DoAll;
@@ -81,9 +84,10 @@
 // methods.
 class UpdateAttempterUnderTest : public UpdateAttempter {
  public:
-  UpdateAttempterUnderTest(SystemState* system_state,
-                           LibCrosProxy* libcros_proxy)
-      : UpdateAttempter(system_state, nullptr, libcros_proxy) {}
+  UpdateAttempterUnderTest(
+      SystemState* system_state,
+      NetworkProxyServiceInterfaceProxyInterface* network_proxy_service_proxy)
+      : UpdateAttempter(system_state, nullptr, network_proxy_service_proxy) {}
 
   // Wrap the update scheduling method, allowing us to opt out of scheduled
   // updates for testing purposes.
@@ -112,16 +116,7 @@
 class UpdateAttempterTest : public ::testing::Test {
  protected:
   UpdateAttempterTest()
-      :
-#if USE_LIBCROS
-        service_interface_mock_(new LibCrosServiceInterfaceProxyMock()),
-        ue_proxy_resolved_interface_mock_(
-            new NiceMock<UpdateEngineLibcrosProxyResolvedInterfaceProxyMock>()),
-        libcros_proxy_(
-            brillo::make_unique_ptr(service_interface_mock_),
-            brillo::make_unique_ptr(ue_proxy_resolved_interface_mock_)),
-#endif  // USE_LIBCROS
-        certificate_checker_(fake_system_state_.mock_prefs(),
+      : certificate_checker_(fake_system_state_.mock_prefs(),
                              &openssl_wrapper_) {
     // Override system state members.
     fake_system_state_.set_connection_manager(&mock_connection_manager);
@@ -193,11 +188,9 @@
 
   FakeSystemState fake_system_state_;
 #if USE_LIBCROS
-  LibCrosServiceInterfaceProxyMock* service_interface_mock_;
-  UpdateEngineLibcrosProxyResolvedInterfaceProxyMock*
-      ue_proxy_resolved_interface_mock_;
-  LibCrosProxy libcros_proxy_;
-  UpdateAttempterUnderTest attempter_{&fake_system_state_, &libcros_proxy_};
+  NetworkProxyServiceInterfaceProxyMock network_proxy_service_proxy_mock_;
+  UpdateAttempterUnderTest attempter_{&fake_system_state_,
+                                      &network_proxy_service_proxy_mock_};
 #else
   UpdateAttempterUnderTest attempter_{&fake_system_state_, nullptr};
 #endif  // USE_LIBCROS
@@ -978,4 +971,14 @@
   EXPECT_EQ(constants::kOmahaDefaultAUTestURL, attempter_.forced_omaha_url());
 }
 
+TEST_F(UpdateAttempterTest, TargetVersionPrefixSetAndReset) {
+  attempter_.CalculateUpdateParams("", "", "", "1234", false, false);
+  EXPECT_EQ("1234",
+            fake_system_state_.request_params()->target_version_prefix());
+
+  attempter_.CalculateUpdateParams("", "", "", "", false, false);
+  EXPECT_TRUE(
+      fake_system_state_.request_params()->target_version_prefix().empty());
+}
+
 }  // namespace chromeos_update_engine
diff --git a/update_engine.gyp b/update_engine.gyp
index 31296a5..6b7e5f4 100644
--- a/update_engine.gyp
+++ b/update_engine.gyp
@@ -23,13 +23,7 @@
       # The -DUSE_* flags are passed from platform2.py. We use sane defaults
       # here when these USE flags are not defined. You can set the default value
       # for the USE flag in the ebuild.
-      'USE_binder%': '0',
-      'USE_dbus%': '1',
       'USE_hwid_override%': '0',
-      'USE_libcros%': '1',
-      'USE_mtd%': '0',
-      'USE_power_management%': '0',
-      'USE_buffet%': '0',
     },
     'cflags': [
       '-g',
@@ -57,7 +51,6 @@
       'USE_MTD=<(USE_mtd)',
       'USE_OMAHA=1',
       'USE_SHILL=1',
-      'USE_WEAVE=<(USE_buffet)',
     ],
     'include_dirs': [
       # We need this include dir because we include all the local code as
@@ -119,6 +112,17 @@
           ],
           'includes': ['../../../platform2/common-mk/generate-dbus-proxies.gypi'],
         },
+        {
+          'action_name': 'update_engine-dbus-network_proxy-client',
+          'variables': {
+            'mock_output_file': 'include/network_proxy/dbus-proxy-mocks.h',
+            'proxy_output_file': 'include/network_proxy/dbus-proxies.h'
+          },
+          'sources': [
+            'dbus_bindings/org.chromium.NetworkProxyService.dbus-xml',
+          ],
+          'includes': ['../../../platform2/common-mk/generate-dbus-proxies.gypi'],
+        },
       ],
     },
     # The payload application component and common dependencies.
@@ -133,7 +137,6 @@
       'variables': {
         'exported_deps': [
           'libcrypto',
-          'libimgpatch',
           'xz-embedded',
         ],
         'deps': ['<@(exported_deps)'],
@@ -152,6 +155,7 @@
           ],
         },
         'libraries': [
+          '-lbspatch',
           '-lbz2',
           '-lrt',
         ],
@@ -257,7 +261,6 @@
         'dbus_service.cc',
         'hardware_chromeos.cc',
         'image_properties_chromeos.cc',
-        'libcros_proxy.cc',
         'libcurl_http_fetcher.cc',
         'metrics.cc',
         'metrics_utils.cc',
@@ -287,19 +290,8 @@
         'update_manager/state_factory.cc',
         'update_manager/update_manager.cc',
         'update_status_utils.cc',
-        'weave_service_factory.cc',
       ],
       'conditions': [
-        ['USE_buffet == 1', {
-          'sources': [
-            'weave_service.cc',
-          ],
-          'variables': {
-            'exported_deps': [
-              'libweave-<(libbase_ver)',
-            ],
-          },
-        }],
         ['USE_libcros == 1', {
           'dependencies': [
             'update_engine-other-dbus-proxies',
diff --git a/update_manager/chromeos_policy.cc b/update_manager/chromeos_policy.cc
index 80ff601..81a169f 100644
--- a/update_manager/chromeos_policy.cc
+++ b/update_manager/chromeos_policy.cc
@@ -246,9 +246,9 @@
       }
 
       result->target_version_prefix = *kiosk_required_platform_version_p;
-      LOG(INFO) << "Allow kiosk app to control Chrome version policy is set,"
-                << ", target version is "
-                << (kiosk_required_platform_version_p
+      LOG(INFO) << "Allow kiosk app to control Chrome version policy is set, "
+                << "target version is "
+                << (!kiosk_required_platform_version_p->empty()
                         ? *kiosk_required_platform_version_p
                         : std::string("latest"));
     } else {
diff --git a/update_manager/evaluation_context.cc b/update_manager/evaluation_context.cc
index 63f7d9b..98238f2 100644
--- a/update_manager/evaluation_context.cc
+++ b/update_manager/evaluation_context.cc
@@ -19,10 +19,12 @@
 #include <algorithm>
 #include <memory>
 #include <string>
+#include <utility>
 
 #include <base/bind.h>
 #include <base/json/json_writer.h>
 #include <base/location.h>
+#include <base/memory/ptr_util.h>
 #include <base/strings/string_util.h>
 #include <base/values.h>
 
@@ -227,13 +229,13 @@
 }
 
 string EvaluationContext::DumpContext() const {
-  base::DictionaryValue* variables = new base::DictionaryValue();
+  auto variables = base::MakeUnique<base::DictionaryValue>();
   for (auto& it : value_cache_) {
     variables->SetString(it.first->GetName(), it.second.ToString());
   }
 
   base::DictionaryValue value;
-  value.Set("variables", variables);  // Adopts |variables|.
+  value.Set("variables", std::move(variables));
   value.SetString(
       "evaluation_start_wallclock",
       chromeos_update_engine::utils::ToString(evaluation_start_wallclock_));
diff --git a/update_manager/real_system_provider.cc b/update_manager/real_system_provider.cc
index 44d5566..9b968ca 100644
--- a/update_manager/real_system_provider.cc
+++ b/update_manager/real_system_provider.cc
@@ -20,11 +20,11 @@
 #include <base/callback.h>
 #include <base/logging.h>
 #include <base/time/time.h>
+#if USE_LIBCROS
+#include <libcros/dbus-proxies.h>
+#endif
 
 #include "update_engine/common/utils.h"
-#if USE_LIBCROS
-#include "update_engine/libcros_proxy.h"
-#endif
 #include "update_engine/update_manager/generic_variables.h"
 #include "update_engine/update_manager/variable.h"
 
@@ -126,9 +126,8 @@
     string* required_platform_version) {
 #if USE_LIBCROS
   brillo::ErrorPtr error;
-  if (!libcros_proxy_->service_interface_proxy()
-           ->GetKioskAppRequiredPlatformVersion(required_platform_version,
-                                                &error)) {
+  if (!libcros_proxy_->GetKioskAppRequiredPlatformVersion(
+          required_platform_version, &error)) {
     LOG(WARNING) << "Failed to get kiosk required platform version";
     required_platform_version->clear();
     return false;
diff --git a/update_manager/real_system_provider.h b/update_manager/real_system_provider.h
index 083943b..a62e1ae 100644
--- a/update_manager/real_system_provider.h
+++ b/update_manager/real_system_provider.h
@@ -24,18 +24,21 @@
 #include "update_engine/common/hardware_interface.h"
 #include "update_engine/update_manager/system_provider.h"
 
-namespace chromeos_update_engine {
-class LibCrosProxy;
-}
+namespace org {
+namespace chromium {
+class LibCrosServiceInterfaceProxyInterface;
+}  // namespace chromium
+}  // namespace org
 
 namespace chromeos_update_manager {
 
 // SystemProvider concrete implementation.
 class RealSystemProvider : public SystemProvider {
  public:
-  RealSystemProvider(chromeos_update_engine::HardwareInterface* hardware,
-                     chromeos_update_engine::BootControlInterface* boot_control,
-                     chromeos_update_engine::LibCrosProxy* libcros_proxy)
+  RealSystemProvider(
+      chromeos_update_engine::HardwareInterface* hardware,
+      chromeos_update_engine::BootControlInterface* boot_control,
+      org::chromium::LibCrosServiceInterfaceProxyInterface* libcros_proxy)
       : hardware_(hardware),
         boot_control_(boot_control),
         libcros_proxy_(libcros_proxy) {}
@@ -75,7 +78,8 @@
 
   chromeos_update_engine::HardwareInterface* const hardware_;
   chromeos_update_engine::BootControlInterface* const boot_control_;
-  chromeos_update_engine::LibCrosProxy* const libcros_proxy_ ALLOW_UNUSED_TYPE;
+  org::chromium::LibCrosServiceInterfaceProxyInterface* const libcros_proxy_
+      ALLOW_UNUSED_TYPE;
 
   DISALLOW_COPY_AND_ASSIGN(RealSystemProvider);
 };
diff --git a/update_manager/real_system_provider_unittest.cc b/update_manager/real_system_provider_unittest.cc
index c997ad8..821a6cc 100644
--- a/update_manager/real_system_provider_unittest.cc
+++ b/update_manager/real_system_provider_unittest.cc
@@ -29,7 +29,6 @@
 #if USE_LIBCROS
 #include "libcros/dbus-proxies.h"
 #include "libcros/dbus-proxy-mocks.h"
-#include "update_engine/libcros_proxy.h"
 
 using org::chromium::LibCrosServiceInterfaceProxyMock;
 #endif  // USE_LIBCROS
@@ -51,19 +50,14 @@
  protected:
   void SetUp() override {
 #if USE_LIBCROS
-    service_interface_mock_ = new LibCrosServiceInterfaceProxyMock();
-    libcros_proxy_.reset(new chromeos_update_engine::LibCrosProxy(
-        brillo::make_unique_ptr(service_interface_mock_),
-        unique_ptr<
-            org::chromium::
-                UpdateEngineLibcrosProxyResolvedInterfaceProxyInterface>()));
-    ON_CALL(*service_interface_mock_,
+    libcros_proxy_mock_.reset(new LibCrosServiceInterfaceProxyMock());
+    ON_CALL(*libcros_proxy_mock_,
             GetKioskAppRequiredPlatformVersion(_, _, _))
         .WillByDefault(
             DoAll(SetArgPointee<0>(kRequiredPlatformVersion), Return(true)));
 
     provider_.reset(new RealSystemProvider(
-        &fake_hardware_, &fake_boot_control_, libcros_proxy_.get()));
+        &fake_hardware_, &fake_boot_control_, libcros_proxy_mock_.get()));
 #else
     provider_.reset(
         new RealSystemProvider(&fake_hardware_, &fake_boot_control_, nullptr));
@@ -76,11 +70,7 @@
   unique_ptr<RealSystemProvider> provider_;
 
 #if USE_LIBCROS
-  // Local pointers to the mocks. The instances are owned by the
-  // |libcros_proxy_|.
-  LibCrosServiceInterfaceProxyMock* service_interface_mock_;
-
-  unique_ptr<chromeos_update_engine::LibCrosProxy> libcros_proxy_;
+  unique_ptr<LibCrosServiceInterfaceProxyMock> libcros_proxy_mock_;
 #endif  // USE_LIBCROS
 };
 
@@ -109,7 +99,7 @@
 }
 
 TEST_F(UmRealSystemProviderTest, KioskRequiredPlatformVersionFailure) {
-  EXPECT_CALL(*service_interface_mock_,
+  EXPECT_CALL(*libcros_proxy_mock_,
               GetKioskAppRequiredPlatformVersion(_, _, _))
       .WillOnce(Return(false));
 
@@ -119,14 +109,14 @@
 
 TEST_F(UmRealSystemProviderTest,
        KioskRequiredPlatformVersionRecoveryFromFailure) {
-  EXPECT_CALL(*service_interface_mock_,
+  EXPECT_CALL(*libcros_proxy_mock_,
               GetKioskAppRequiredPlatformVersion(_, _, _))
       .WillOnce(Return(false));
   UmTestUtils::ExpectVariableNotSet(
       provider_->var_kiosk_required_platform_version());
-  testing::Mock::VerifyAndClearExpectations(service_interface_mock_);
+  testing::Mock::VerifyAndClearExpectations(libcros_proxy_mock_.get());
 
-  EXPECT_CALL(*service_interface_mock_,
+  EXPECT_CALL(*libcros_proxy_mock_,
               GetKioskAppRequiredPlatformVersion(_, _, _))
       .WillOnce(
           DoAll(SetArgPointee<0>(kRequiredPlatformVersion), Return(true)));
diff --git a/update_manager/state_factory.cc b/update_manager/state_factory.cc
index 2b3ce63..70fc80b 100644
--- a/update_manager/state_factory.cc
+++ b/update_manager/state_factory.cc
@@ -47,7 +47,7 @@
 
 State* DefaultStateFactory(
     policy::PolicyProvider* policy_provider,
-    chromeos_update_engine::LibCrosProxy* libcros_proxy,
+    org::chromium::LibCrosServiceInterfaceProxyInterface* libcros_proxy,
     chromeos_update_engine::SystemState* system_state) {
   chromeos_update_engine::ClockInterface* const clock = system_state->clock();
   unique_ptr<RealConfigProvider> config_provider(
diff --git a/update_manager/state_factory.h b/update_manager/state_factory.h
index f1b576c..689684a 100644
--- a/update_manager/state_factory.h
+++ b/update_manager/state_factory.h
@@ -20,9 +20,11 @@
 #include "update_engine/system_state.h"
 #include "update_engine/update_manager/state.h"
 
-namespace chromeos_update_engine {
-class LibCrosProxy;
-}
+namespace org {
+namespace chromium {
+class LibCrosServiceInterfaceProxyInterface;
+}  // namespace chromium
+}  // namespace org
 
 namespace chromeos_update_manager {
 
@@ -33,7 +35,7 @@
 // to initialize.
 State* DefaultStateFactory(
     policy::PolicyProvider* policy_provider,
-    chromeos_update_engine::LibCrosProxy* libcros_proxy,
+    org::chromium::LibCrosServiceInterfaceProxyInterface* libcros_proxy,
     chromeos_update_engine::SystemState* system_state);
 
 }  // namespace chromeos_update_manager
diff --git a/update_status_utils.cc b/update_status_utils.cc
index 9685853..ff039b8 100644
--- a/update_status_utils.cc
+++ b/update_status_utils.cc
@@ -20,21 +20,6 @@
 
 using update_engine::UpdateStatus;
 
-namespace {
-
-const char kWeaveStatusIdle[] = "idle";
-const char kWeaveStatusCheckingForUpdate[] = "checkingForUpdate";
-const char kWeaveStatusUpdateAvailable[] = "updateAvailable";
-const char kWeaveStatusDownloading[] = "downloading";
-const char kWeaveStatusVerifying[] = "verifying";
-const char kWeaveStatusFinalizing[] = "finalizing";
-const char kWeaveStatusUpdatedNeedReboot[] = "updatedNeedReboot";
-const char kWeaveStatusReportingErrorEvent[] = "reportingErrorEvent";
-const char kWeaveStatusAttemptingRollback[] = "attemptingRollback";
-const char kWeaveStatusDisabled[] = "disabled";
-
-}  // namespace
-
 namespace chromeos_update_engine {
 
 const char* UpdateStatusToString(const UpdateStatus& status) {
@@ -65,34 +50,6 @@
   return nullptr;
 }
 
-const char* UpdateStatusToWeaveStatus(const UpdateStatus& status) {
-  switch (status) {
-    case UpdateStatus::IDLE:
-      return kWeaveStatusIdle;
-    case UpdateStatus::CHECKING_FOR_UPDATE:
-      return kWeaveStatusCheckingForUpdate;
-    case UpdateStatus::UPDATE_AVAILABLE:
-      return kWeaveStatusUpdateAvailable;
-    case UpdateStatus::DOWNLOADING:
-      return kWeaveStatusDownloading;
-    case UpdateStatus::VERIFYING:
-      return kWeaveStatusVerifying;
-    case UpdateStatus::FINALIZING:
-      return kWeaveStatusFinalizing;
-    case UpdateStatus::UPDATED_NEED_REBOOT:
-      return kWeaveStatusUpdatedNeedReboot;
-    case UpdateStatus::REPORTING_ERROR_EVENT:
-      return kWeaveStatusReportingErrorEvent;
-    case UpdateStatus::ATTEMPTING_ROLLBACK:
-      return kWeaveStatusAttemptingRollback;
-    case UpdateStatus::DISABLED:
-      return kWeaveStatusDisabled;
-  }
-
-  NOTREACHED();
-  return nullptr;
-}
-
 bool StringToUpdateStatus(const std::string& s,
                           UpdateStatus* status) {
   if (s == update_engine::kUpdateStatusIdle) {
diff --git a/update_status_utils.h b/update_status_utils.h
index 9d85144..30ae53b 100644
--- a/update_status_utils.h
+++ b/update_status_utils.h
@@ -25,10 +25,6 @@
 
 const char* UpdateStatusToString(const update_engine::UpdateStatus& status);
 
-// Convert the UpdateStatus |status| to the string reported in the weave status.
-const char* UpdateStatusToWeaveStatus(
-    const update_engine::UpdateStatus& status);
-
 bool StringToUpdateStatus(const std::string& update_status_as_string,
                           update_engine::UpdateStatus* status);
 
diff --git a/weave_service.cc b/weave_service.cc
deleted file mode 100644
index 0a145e4..0000000
--- a/weave_service.cc
+++ /dev/null
@@ -1,133 +0,0 @@
-//
-// Copyright (C) 2015 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/weave_service.h"
-
-#include <cmath>
-#include <string>
-
-#include <base/bind.h>
-#include <brillo/errors/error.h>
-#include <brillo/message_loops/message_loop.h>
-
-#include "update_engine/update_status_utils.h"
-
-using std::string;
-
-namespace {
-
-const char kWeaveComponent[] = "updater";
-const char kWeaveTrait[] = "_updater";
-
-}  // namespace
-
-namespace chromeos_update_engine {
-
-bool WeaveService::Init(DelegateInterface* delegate) {
-  delegate_ = delegate;
-  weave_service_subscription_ = weaved::Service::Connect(
-      brillo::MessageLoop::current(),
-      base::Bind(&WeaveService::OnWeaveServiceConnected,
-                 base::Unretained(this)));
-  return true;
-}
-
-void WeaveService::OnWeaveServiceConnected(
-    const std::weak_ptr<weaved::Service>& service) {
-  weave_service_ = service;
-  auto weave_service = weave_service_.lock();
-  if (!weave_service)
-    return;
-
-  weave_service->AddComponent(kWeaveComponent, {kWeaveTrait}, nullptr);
-  weave_service->AddCommandHandler(
-      kWeaveComponent, kWeaveTrait, "checkForUpdates",
-      base::Bind(&WeaveService::OnCheckForUpdates, base::Unretained(this)));
-  weave_service->AddCommandHandler(
-      kWeaveComponent, kWeaveTrait, "trackChannel",
-      base::Bind(&WeaveService::OnTrackChannel, base::Unretained(this)));
-  UpdateWeaveState();
-}
-
-void WeaveService::SendStatusUpdate(int64_t /* last_checked_time */,
-                                    double /* progress */,
-                                    update_engine::UpdateStatus /* status */,
-                                    const string& /* new_version */,
-                                    int64_t /* new_size */) {
-  // We query the Weave
-  UpdateWeaveState();
-}
-
-void WeaveService::SendChannelChangeUpdate(
-    const string& /* tracking_channel */) {
-  UpdateWeaveState();
-}
-
-void WeaveService::UpdateWeaveState() {
-  auto weave_service = weave_service_.lock();
-  if (!weave_service || !delegate_)
-    return;
-
-  int64_t last_checked_time;
-  double progress;
-  update_engine::UpdateStatus update_status;
-  string current_channel;
-  string tracking_channel;
-
-  if (!delegate_->GetWeaveState(&last_checked_time,
-                                &progress,
-                                &update_status,
-                                &current_channel,
-                                &tracking_channel))
-    return;
-
-  // Round to progress to 1% (0.01) to avoid excessive and meaningless state
-  // changes.
-  progress = std::floor(progress * 100.) / 100.;
-
-  base::DictionaryValue state;
-  state.SetString("_updater.currentChannel", current_channel);
-  state.SetString("_updater.trackingChannel", tracking_channel);
-  state.SetString("_updater.status", UpdateStatusToWeaveStatus(update_status));
-  state.SetDouble("_updater.progress", progress);
-  state.SetDouble("_updater.lastUpdateCheckTimestamp",
-                  static_cast<double>(last_checked_time));
-
-  if (!weave_service->SetStateProperties(kWeaveComponent, state, nullptr)) {
-    LOG(ERROR) << "Failed to update _updater state.";
-  }
-}
-
-void WeaveService::OnCheckForUpdates(std::unique_ptr<weaved::Command> command) {
-  brillo::ErrorPtr error;
-  if (!delegate_->OnCheckForUpdates(&error)) {
-    command->AbortWithCustomError(error.get(), nullptr);
-    return;
-  }
-  command->Complete({}, nullptr);
-}
-
-void WeaveService::OnTrackChannel(std::unique_ptr<weaved::Command> command) {
-  string channel = command->GetParameter<string>("channel");
-  brillo::ErrorPtr error;
-  if (!delegate_->OnTrackChannel(channel, &error)) {
-    command->AbortWithCustomError(error.get(), nullptr);
-    return;
-  }
-  command->Complete({}, nullptr);
-}
-
-}  // namespace chromeos_update_engine
diff --git a/weave_service.h b/weave_service.h
deleted file mode 100644
index 5a3aff3..0000000
--- a/weave_service.h
+++ /dev/null
@@ -1,66 +0,0 @@
-//
-// Copyright (C) 2015 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_WEAVE_SERVICE_H_
-#define UPDATE_ENGINE_WEAVE_SERVICE_H_
-
-#include <memory>
-#include <string>
-
-#include <base/memory/weak_ptr.h>
-#include <libweaved/command.h>
-#include <libweaved/service.h>
-
-#include "update_engine/weave_service_interface.h"
-
-namespace chromeos_update_engine {
-
-class WeaveService : public WeaveServiceInterface {
- public:
-  WeaveService() = default;
-  ~WeaveService() override = default;
-
-  bool Init(DelegateInterface* delegate);
-
-  // ServiceObserverInterface overrides.
-  void SendStatusUpdate(int64_t last_checked_time,
-                        double progress,
-                        update_engine::UpdateStatus status,
-                        const std::string& new_version,
-                        int64_t new_size) override;
-  void SendChannelChangeUpdate(const std::string& tracking_channel) override;
-  void SendPayloadApplicationComplete(ErrorCode error_code) override {}
-
- private:
-  // Force a weave update.
-  void UpdateWeaveState();
-
-  void OnWeaveServiceConnected(const std::weak_ptr<weaved::Service>& service);
-
-  // Weave command handlers. These are called from the message loop whenever a
-  // command is received and dispatch the synchronous call to the |delegate_|.
-  void OnCheckForUpdates(std::unique_ptr<weaved::Command> cmd);
-  void OnTrackChannel(std::unique_ptr<weaved::Command> cmd);
-
-  WeaveServiceInterface::DelegateInterface* delegate_{nullptr};
-
-  std::unique_ptr<weaved::Service::Subscription> weave_service_subscription_;
-  std::weak_ptr<weaved::Service> weave_service_;
-};
-
-}  // namespace chromeos_update_engine
-
-#endif  // UPDATE_ENGINE_WEAVE_SERVICE_H_
diff --git a/weave_service_factory.cc b/weave_service_factory.cc
deleted file mode 100644
index 24b9b79..0000000
--- a/weave_service_factory.cc
+++ /dev/null
@@ -1,40 +0,0 @@
-//
-// Copyright (C) 2015 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/weave_service_factory.h"
-
-#if USE_WEAVE
-#include "update_engine/weave_service.h"
-#endif
-
-namespace chromeos_update_engine {
-
-std::unique_ptr<WeaveServiceInterface> ConstructWeaveService(
-    WeaveServiceInterface::DelegateInterface* delegate) {
-  std::unique_ptr<WeaveServiceInterface> result;
-  if (!delegate)
-    return result;
-
-#if USE_WEAVE
-  WeaveService* weave_service = new WeaveService();
-  result.reset(weave_service);
-  if (!weave_service->Init(delegate))
-    result.reset();
-#endif
-  return result;
-}
-
-}  // namespace chromeos_update_engine
diff --git a/weave_service_factory.h b/weave_service_factory.h
deleted file mode 100644
index 7b129ab..0000000
--- a/weave_service_factory.h
+++ /dev/null
@@ -1,35 +0,0 @@
-//
-// Copyright (C) 2015 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_WEAVE_SERVICE_FACTORY_H_
-#define UPDATE_ENGINE_WEAVE_SERVICE_FACTORY_H_
-
-#include <memory>
-
-#include <base/memory/ref_counted.h>
-
-#include "update_engine/weave_service_interface.h"
-
-namespace chromeos_update_engine {
-
-// Create a new WeaveServiceInterface instance. In case of error or when weaved
-// is disabled, returns an empty pointer.
-std::unique_ptr<WeaveServiceInterface> ConstructWeaveService(
-    WeaveServiceInterface::DelegateInterface* delegate);
-
-}  // namespace chromeos_update_engine
-
-#endif  // UPDATE_ENGINE_WEAVE_SERVICE_FACTORY_H_
diff --git a/weave_service_interface.h b/weave_service_interface.h
deleted file mode 100644
index a7e603e..0000000
--- a/weave_service_interface.h
+++ /dev/null
@@ -1,62 +0,0 @@
-//
-// Copyright (C) 2015 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_WEAVE_SERVICE_INTERFACE_H_
-#define UPDATE_ENGINE_WEAVE_SERVICE_INTERFACE_H_
-
-#include <string>
-
-#include <brillo/errors/error.h>
-
-#include "update_engine/client_library/include/update_engine/update_status.h"
-#include "update_engine/service_observer_interface.h"
-
-namespace chromeos_update_engine {
-
-// A WeaveServiceInterface instance allows to register the daemon with weaved,
-// handle commands and update the weave status. This class only handles the
-// registration with weaved and the connection, the actual work to handle the
-// commands is implemented by the DelegateInterface, which will be called from
-// this class.
-class WeaveServiceInterface : public ServiceObserverInterface {
- public:
-  // The delegate class that actually handles the command execution from
-  class DelegateInterface {
-   public:
-    virtual ~DelegateInterface() = default;
-
-    virtual bool OnCheckForUpdates(brillo::ErrorPtr* error) = 0;
-
-    virtual bool OnTrackChannel(const std::string& channel,
-                                brillo::ErrorPtr* error) = 0;
-
-    // Return the current status.
-    virtual bool GetWeaveState(int64_t* last_checked_time,
-                               double* progress,
-                               update_engine::UpdateStatus* update_status,
-                               std::string* current_channel,
-                               std::string* tracking_channel) = 0;
-  };
-
-  virtual ~WeaveServiceInterface() = default;
-
- protected:
-  WeaveServiceInterface() = default;
-};
-
-}  // namespace chromeos_update_engine
-
-#endif  // UPDATE_ENGINE_WEAVE_SERVICE_INTERFACE_H_
diff --git a/weaved/traits/updater.json b/weaved/traits/updater.json
deleted file mode 100644
index 52b1a55..0000000
--- a/weaved/traits/updater.json
+++ /dev/null
@@ -1,52 +0,0 @@
-{
-  "_updater": {
-    "commands": {
-      "checkForUpdates": {
-        "minimalRole": "manager",
-        "parameters": {}
-      },
-      "trackChannel": {
-        "minimalRole": "manager",
-        "parameters": {
-          "channel": {
-            "type": "string",
-            "enum": ["stable-channel", "beta-channel", "dev-channel", "canary-channel"]
-          }
-        }
-      }
-    },
-    "state": {
-      "currentChannel": {
-        "type": "string",
-        "enum": ["stable-channel", "beta-channel", "dev-channel", "canary-channel"]
-      },
-      "trackingChannel": {
-        "type": "string",
-        "enum": ["stable-channel", "beta-channel", "dev-channel", "canary-channel"]
-      },
-      "status": {
-        "type": "string",
-        "enum": [
-          "idle",
-          "checkingForUpdate",
-          "updateAvailable",
-          "downloading",
-          "verifying",
-          "finalizing",
-          "updatedNeedReboot",
-          "reportingErrorEvent",
-          "attemptingRollback",
-          "disabled"
-        ]
-      },
-      "progress": {
-        "type": "number",
-        "minimum": 0,
-        "maximum": 1
-      },
-      "lastUpdateCheckTimestamp": {
-        "type": "number"
-      }
-    }
-  }
-}