update_engine: Use org.chromium.NetworkProxyService.

Make update_engine call Chrome's new
org.chromium.NetworkProxyService D-Bus service to resolve
network proxies instead of using
org.chromium.LibCrosService. The new service supports
asynchronous replies instead of responding via D-Bus
signals.

BUG=chromium:446115,chromium:703217
TEST=unit tests pass; also added debug logging and verified
     that chrome's proxy settings are used

(cherry picked from commit 941cf235c5e56eddc6e4f2de2f38bee032a4dead)
Cherry-pick updated to resolve conflicts with existing code in AOSP.

Change-Id: I8c0704482e9988fe9ed14d32797b3a5b8da3d46a
Reviewed-on: https://chromium-review.googlesource.com/497491
Commit-Ready: Dan Erat <derat@chromium.org>
Tested-by: Dan Erat <derat@chromium.org>
Reviewed-by: Ben Chan <benchan@chromium.org>
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/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/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 cb038a5..eac6ea0 100644
--- a/libcurl_http_fetcher.cc
+++ b/libcurl_http_fetcher.cc
@@ -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/real_system_state.cc b/real_system_state.cc
index aab074f..5cbf723 100644
--- a/real_system_state.cc
+++ b/real_system_state.cc
@@ -24,12 +24,18 @@
 #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"
 
 using brillo::MessageLoop;
@@ -59,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.";
 
@@ -129,14 +144,20 @@
   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();
 
   // Initialize the Update Manager using the default state factory.
diff --git a/real_system_state.h b/real_system_state.h
index 270d8d2..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"
@@ -123,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.
diff --git a/update_attempter.cc b/update_attempter.cc
index 2cc5308..6a7853d 100644
--- a/update_attempter.cc
+++ b/update_attempter.cc
@@ -120,14 +120,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
@@ -158,10 +160,6 @@
     status_ = UpdateStatus::UPDATED_NEED_REBOOT;
   else
     status_ = UpdateStatus::IDLE;
-
-#if USE_LIBCROS
-  chrome_proxy_resolver_.Init();
-#endif  // USE_LIBCROS
 }
 
 void UpdateAttempter::ScheduleUpdates() {
diff --git a/update_attempter.h b/update_attempter.h
index c88e7ad..193e172 100644
--- a/update_attempter.h
+++ b/update_attempter.h
@@ -48,13 +48,18 @@
 
 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,
@@ -67,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.
diff --git a/update_attempter_unittest.cc b/update_attempter_unittest.cc
index 5224870..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
diff --git a/update_engine.gyp b/update_engine.gyp
index c0dec02..6b7e5f4 100644
--- a/update_engine.gyp
+++ b/update_engine.gyp
@@ -112,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.
@@ -250,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',
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