[Device Discovery] Move files from browser/extensions/api/dial to browser/media/router/discovery/dial
DialMediaSinkService needs to reference DialRegistry and DeviceDescriptionFetcher class. Move them from extension to media router folder so DialMediaSinkService does not depend on files in extension folder. Files moved to media router folder:
chrome/browser/extensions/api/dial/device_description_fetcher.h
chrome/browser/extensions/api/dial/device_description_fetcher.cc
chrome/browser/extensions/api/dial/device_description_fetcher_unittest.cc
chrome/browser/extensions/api/dial/dial_device_data.h
chrome/browser/extensions/api/dial/dial_device_data.cc
chrome/browser/extensions/api/dial/dial_device_data_unittest.cc
chrome/browser/extensions/api/dial/dial_registry.h
chrome/browser/extensions/api/dial/dial_registry.cc
chrome/browser/extensions/api/dial/dial_registry_unittest.cc
chrome/browser/extensions/api/dial/dial_service.h
chrome/browser/extensions/api/dial/dial_service.cc
chrome/browser/extensions/api/dial/dial_service_unittest.cc
Changed namespace to media_router and updated unit tests.
BUG=687375
Review-Url: https://codereview.chromium.org/2756483007
Cr-Commit-Position: refs/heads/master@{#459253}
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn
index 514236c..9193a50 100644
--- a/chrome/browser/extensions/BUILD.gn
+++ b/chrome/browser/extensions/BUILD.gn
@@ -175,18 +175,10 @@
"api/developer_private/inspectable_views_finder.h",
"api/developer_private/show_permissions_dialog_helper.cc",
"api/developer_private/show_permissions_dialog_helper.h",
- "api/dial/device_description_fetcher.cc",
- "api/dial/device_description_fetcher.h ",
"api/dial/dial_api.cc",
"api/dial/dial_api.h",
"api/dial/dial_api_factory.cc",
"api/dial/dial_api_factory.h",
- "api/dial/dial_device_data.cc",
- "api/dial/dial_device_data.h",
- "api/dial/dial_registry.cc",
- "api/dial/dial_registry.h",
- "api/dial/dial_service.cc",
- "api/dial/dial_service.h",
"api/downloads/downloads_api.cc",
"api/downloads/downloads_api.h",
"api/downloads_internal/downloads_internal_api.cc",
@@ -829,6 +821,7 @@
"//chrome/app/theme:theme_resources",
"//chrome/app/vector_icons",
"//chrome/browser/devtools",
+ "//chrome/browser/media/router/discovery",
"//chrome/common",
"//chrome/common/extensions/api:api_registration",
"//chrome/common/extensions/api:extensions_features",
diff --git a/chrome/browser/extensions/api/dial/device_description_fetcher.cc b/chrome/browser/extensions/api/dial/device_description_fetcher.cc
deleted file mode 100644
index 6b60803..0000000
--- a/chrome/browser/extensions/api/dial/device_description_fetcher.cc
+++ /dev/null
@@ -1,182 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/extensions/api/dial/device_description_fetcher.h"
-
-#include "base/strings/string_util.h"
-#include "base/strings/stringprintf.h"
-#include "chrome/browser/extensions/api/dial/dial_device_data.h"
-#include "chrome/browser/profiles/profile.h"
-#include "content/public/browser/browser_thread.h"
-#include "net/base/load_flags.h"
-#include "net/http/http_response_headers.h"
-#include "net/http/http_status_code.h"
-#include "net/http/http_util.h"
-#include "net/traffic_annotation/network_traffic_annotation.h"
-#include "net/url_request/url_fetcher.h"
-#include "net/url_request/url_request_context_getter.h"
-
-using content::BrowserThread;
-
-constexpr char kApplicationUrlHeaderName[] = "Application-URL";
-constexpr int kMaxRetries = 3;
-// DIAL devices are unlikely to expose uPnP functions other than DIAL, so 256kb
-// should be more than sufficient.
-constexpr int kMaxDescriptionSizeBytes = 262144;
-
-namespace extensions {
-namespace api {
-namespace dial {
-
-DeviceDescriptionFetcher::DeviceDescriptionFetcher(
- const GURL& device_description_url,
- net::URLRequestContextGetter* request_context,
- base::OnceCallback<void(const DialDeviceDescriptionData&)> success_cb,
- base::OnceCallback<void(const std::string&)> error_cb)
- : device_description_url_(device_description_url),
- request_context_(request_context),
- success_cb_(std::move(success_cb)),
- error_cb_(std::move(error_cb)) {
- DCHECK(request_context_);
- DCHECK(device_description_url_.is_valid());
-}
-
-DeviceDescriptionFetcher::~DeviceDescriptionFetcher() {
- DCHECK(thread_checker_.CalledOnValidThread());
-}
-
-void DeviceDescriptionFetcher::Start() {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(!fetcher_);
-
- net::NetworkTrafficAnnotationTag traffic_annotation =
- net::DefineNetworkTrafficAnnotation("dial_get_device_description", R"(
- semantics {
- sender: "DIAL"
- description:
- "Chromium sends a request to a device (such as a smart TV) "
- "discovered via the DIAL (Disovery and Launch) protocol to obtain "
- "its device description. Chromium then uses the device description "
- "to determine the capabilities of the device to be used as a "
- "target for casting media content."
- trigger:
- "A new or updated device has been discovered via DIAL in the local "
- "network."
- data: "An HTTP GET request."
- destination: OTHER
- destination_other:
- "A device in the local network."
- }
- policy {
- cookies_allowed: false
- setting:
- "This feature cannot be disabled by settings and can only be "
- "disabled by media-router flag."
- chrome_policy {
- EnableMediaRouter {
- policy_options {mode: MANDATORY}
- EnableMediaRouter: false
- }
- }
- })");
- // DIAL returns device descriptions via GET request.
- fetcher_ =
- net::URLFetcher::Create(kURLFetcherIDForTest, device_description_url_,
- net::URLFetcher::GET, this, traffic_annotation);
-
- // net::LOAD_BYPASS_PROXY: Proxies almost certainly hurt more cases than they
- // help.
- // net::LOAD_DISABLE_CACHE: The request should not touch the cache.
- // net::LOAD_DO_NOT_{SAVE,SEND}_COOKIES: The request should not touch cookies.
- // net::LOAD_DO_NOT_SEND_AUTH_DATA: The request should not send auth data.
- fetcher_->SetLoadFlags(net::LOAD_BYPASS_PROXY | net::LOAD_DISABLE_CACHE |
- net::LOAD_DO_NOT_SAVE_COOKIES |
- net::LOAD_DO_NOT_SEND_COOKIES |
- net::LOAD_DO_NOT_SEND_AUTH_DATA);
-
- // Section 5.4 of the DIAL spec prohibits redirects.
- fetcher_->SetStopOnRedirect(true);
-
- // Allow the fetcher to retry on 5XX responses and ERR_NETWORK_CHANGED.
- fetcher_->SetMaxRetriesOn5xx(kMaxRetries);
- fetcher_->SetAutomaticallyRetryOnNetworkChanges(kMaxRetries);
-
- fetcher_->SetRequestContext(request_context_.get());
- fetcher_->Start();
-}
-
-void DeviceDescriptionFetcher::OnURLFetchComplete(
- const net::URLFetcher* source) {
- DCHECK_EQ(fetcher_.get(), source);
-
- if (source->GetResponseCode() != net::HTTP_OK) {
- ReportError(
- base::StringPrintf("HTTP %d: Unable to fetch device description",
- source->GetResponseCode()));
- return;
- }
-
- const net::HttpResponseHeaders* headers = source->GetResponseHeaders();
-
- // NOTE: The uPnP spec requires devices to set a Content-Type: header of
- // text/xml; charset="utf-8" (sec 2.11). However Chromecast (and possibly
- // other devices) do not comply, so specifically not checking this header.
- std::string app_url_header;
- if (!headers->GetNormalizedHeader(kApplicationUrlHeaderName,
- &app_url_header) ||
- app_url_header.empty()) {
- ReportError("Missing or empty Application-URL:");
- return;
- }
-
- // Section 5.4 of the DIAL spec implies that the Application URL should not
- // have path, query or fragment...unsure if that can be enforced.
- GURL app_url(app_url_header);
- if (!app_url.is_valid() || !app_url.SchemeIs("http") ||
- !app_url.HostIsIPAddress() ||
- app_url.host() != device_description_url_.host()) {
- ReportError(base::StringPrintf("Invalid Application-URL: %s",
- app_url_header.c_str()));
- return;
- }
-
- if (source->GetReceivedResponseContentLength() > kMaxDescriptionSizeBytes) {
- ReportError("Response too large");
- return;
- }
-
- std::string device_description;
- if (!source->GetResponseAsString(&device_description) ||
- device_description.empty()) {
- ReportError("Missing or empty response");
- return;
- }
-
- if (!base::IsStringUTF8(device_description)) {
- ReportError("Invalid response encoding");
- return;
- }
-
- std::move(success_cb_)
- .Run(DialDeviceDescriptionData(std::move(device_description), app_url));
-}
-
-void DeviceDescriptionFetcher::OnURLFetchDownloadProgress(
- const net::URLFetcher* source,
- int64_t current,
- int64_t total,
- int64_t current_network_bytes) {}
-
-void DeviceDescriptionFetcher::OnURLFetchUploadProgress(
- const net::URLFetcher* source,
- int64_t current,
- int64_t total) {}
-
-void DeviceDescriptionFetcher::ReportError(const std::string& message) {
- std::move(error_cb_).Run(message);
-}
-
-} // namespace dial
-} // namespace api
-} // namespace extensions
diff --git a/chrome/browser/extensions/api/dial/device_description_fetcher.h b/chrome/browser/extensions/api/dial/device_description_fetcher.h
deleted file mode 100644
index 8a4a8f56..0000000
--- a/chrome/browser/extensions/api/dial/device_description_fetcher.h
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_EXTENSIONS_API_DIAL_DEVICE_DESCRIPTION_FETCHER_H_
-#define CHROME_BROWSER_EXTENSIONS_API_DIAL_DEVICE_DESCRIPTION_FETCHER_H_
-
-#include <memory>
-#include <string>
-
-#include "base/callback.h"
-#include "base/threading/thread_checker.h"
-#include "content/public/browser/browser_thread.h"
-#include "net/url_request/url_fetcher_delegate.h"
-#include "url/gurl.h"
-
-namespace net {
-class URLFetcher;
-class URLRequestContextGetter;
-}
-
-namespace extensions {
-namespace api {
-namespace dial {
-
-struct DialDeviceDescriptionData;
-
-// Used to make a single HTTP GET request with |device_description_url| to fetch
-// a uPnP device description from a DIAL device. If successful, |success_cb| is
-// invoked with the result; otherwise, |error_cb| is invoked with an error
-// reason.
-// This class is not thread safe.
-class DeviceDescriptionFetcher : public net::URLFetcherDelegate {
- public:
- // Used to identify the net::URLFetcher instance for tests.
- static constexpr int kURLFetcherIDForTest = 1;
-
- // |request_context| is unowned; the caller must ensure that this object does
- // not outlive it.
- DeviceDescriptionFetcher(
- const GURL& device_description_url,
- net::URLRequestContextGetter* request_context,
- base::OnceCallback<void(const DialDeviceDescriptionData&)> success_cb,
- base::OnceCallback<void(const std::string&)> error_cb);
-
- ~DeviceDescriptionFetcher() override;
-
- void Start();
-
- private:
- // net::URLFetcherDelegate implementation.
- void OnURLFetchComplete(const net::URLFetcher* source) override;
- void OnURLFetchDownloadProgress(const net::URLFetcher* source,
- int64_t current,
- int64_t total,
- int64_t current_network_bytes) override;
- void OnURLFetchUploadProgress(const net::URLFetcher* source,
- int64_t current,
- int64_t total) override;
-
- // Runs |error_cb_| with |message| and clears it.
- void ReportError(const std::string& message);
-
- const GURL device_description_url_;
- const scoped_refptr<net::URLRequestContextGetter> request_context_;
- base::ThreadChecker thread_checker_;
-
- base::OnceCallback<void(const DialDeviceDescriptionData&)> success_cb_;
- base::OnceCallback<void(const std::string&)> error_cb_;
- std::unique_ptr<net::URLFetcher> fetcher_;
-};
-
-} // namespace dial
-} // namespace api
-} // namespace extensions
-
-#endif // CHROME_BROWSER_EXTENSIONS_API_DIAL_DEVICE_DESCRIPTION_FETCHER_H_
diff --git a/chrome/browser/extensions/api/dial/device_description_fetcher_unittest.cc b/chrome/browser/extensions/api/dial/device_description_fetcher_unittest.cc
deleted file mode 100644
index 7a64f4b8..0000000
--- a/chrome/browser/extensions/api/dial/device_description_fetcher_unittest.cc
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <memory>
-#include <string>
-
-#include "base/callback.h"
-#include "base/macros.h"
-#include "base/memory/ptr_util.h"
-#include "base/memory/ref_counted.h"
-#include "chrome/browser/extensions/api/dial/device_description_fetcher.h"
-#include "chrome/browser/extensions/api/dial/dial_device_data.h"
-#include "chrome/test/base/testing_profile.h"
-#include "content/public/test/test_browser_thread_bundle.h"
-#include "net/http/http_response_headers.h"
-#include "net/http/http_status_code.h"
-#include "net/url_request/test_url_fetcher_factory.h"
-#include "net/url_request/url_fetcher.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "url/gurl.h"
-
-namespace extensions {
-namespace api {
-namespace dial {
-
-class DeviceDescriptionFetcherTest : public testing::Test {
- public:
- DeviceDescriptionFetcherTest() : url_("http://127.0.0.1/description.xml") {}
-
- void TearDown() override {
- EXPECT_FALSE(error_cb_);
- EXPECT_FALSE(success_cb_);
- }
-
- void ExpectSuccess(const GURL& expected_app_url,
- const std::string& expected_description) {
- success_cb_ = base::BindOnce(&DeviceDescriptionFetcherTest::OnSuccess,
- base::Unretained(this), expected_app_url,
- expected_description);
- }
-
- void ExpectError(const std::string& expected_message) {
- error_cb_ = base::BindOnce(&DeviceDescriptionFetcherTest::OnError,
- base::Unretained(this), expected_message);
- }
-
- net::TestURLFetcher* StartRequest() {
- fetcher_ = base::MakeUnique<DeviceDescriptionFetcher>(
- url_, profile_.GetRequestContext(), std::move(success_cb_),
- std::move(error_cb_));
- fetcher_->Start();
- return factory_.GetFetcherByID(
- DeviceDescriptionFetcher::kURLFetcherIDForTest);
- }
-
- protected:
- const content::TestBrowserThreadBundle thread_bundle_;
- TestingProfile profile_;
- const net::TestURLFetcherFactory factory_;
- const GURL url_;
- base::OnceCallback<void(const DialDeviceDescriptionData&)> success_cb_;
- base::OnceCallback<void(const std::string&)> error_cb_;
- std::unique_ptr<DeviceDescriptionFetcher> fetcher_;
-
- private:
- void OnSuccess(const GURL& expected_app_url,
- const std::string& expected_description,
- const DialDeviceDescriptionData& description) {
- EXPECT_EQ(expected_app_url, description.app_url);
- EXPECT_EQ(expected_description, description.device_description);
- }
-
- void OnError(const std::string& expected_message,
- const std::string& message) {
- EXPECT_TRUE(message.find(expected_message) == 0);
- }
-
- DISALLOW_COPY_AND_ASSIGN(DeviceDescriptionFetcherTest);
-};
-
-TEST_F(DeviceDescriptionFetcherTest, FetchSuccessful) {
- ExpectSuccess(GURL("http://127.0.0.1/apps"), "<xml>description</xml>");
- net::TestURLFetcher* test_fetcher = StartRequest();
-
- test_fetcher->set_response_code(net::HTTP_OK);
- scoped_refptr<net::HttpResponseHeaders> headers =
- new net::HttpResponseHeaders("");
- headers->AddHeader("Application-URL: http://127.0.0.1/apps");
- test_fetcher->set_response_headers(headers);
- test_fetcher->SetResponseString("<xml>description</xml>");
- test_fetcher->delegate()->OnURLFetchComplete(test_fetcher);
-}
-
-TEST_F(DeviceDescriptionFetcherTest, FetchFailsOnMissingDescription) {
- ExpectError("HTTP 404:");
- net::TestURLFetcher* test_fetcher = StartRequest();
-
- test_fetcher->set_response_code(net::HTTP_NOT_FOUND);
- test_fetcher->delegate()->OnURLFetchComplete(test_fetcher);
-}
-
-TEST_F(DeviceDescriptionFetcherTest, FetchFailsOnMissingAppUrl) {
- ExpectError("Missing or empty Application-URL:");
- net::TestURLFetcher* test_fetcher = StartRequest();
-
- test_fetcher->set_response_code(net::HTTP_OK);
- scoped_refptr<net::HttpResponseHeaders> headers =
- new net::HttpResponseHeaders("");
- test_fetcher->set_response_headers(headers);
- test_fetcher->delegate()->OnURLFetchComplete(test_fetcher);
-}
-
-TEST_F(DeviceDescriptionFetcherTest, FetchFailsOnEmptyAppUrl) {
- ExpectError("Missing or empty Application-URL:");
- net::TestURLFetcher* test_fetcher = StartRequest();
-
- test_fetcher->set_response_code(net::HTTP_OK);
- scoped_refptr<net::HttpResponseHeaders> headers =
- new net::HttpResponseHeaders("");
- headers->AddHeader("Application-URL:");
- test_fetcher->set_response_headers(headers);
- test_fetcher->delegate()->OnURLFetchComplete(test_fetcher);
-}
-
-TEST_F(DeviceDescriptionFetcherTest, FetchFailsOnInvalidAppUrl) {
- ExpectError("Invalid Application-URL:");
- net::TestURLFetcher* test_fetcher = StartRequest();
-
- test_fetcher->set_response_code(net::HTTP_OK);
- scoped_refptr<net::HttpResponseHeaders> headers =
- new net::HttpResponseHeaders("");
- headers->AddHeader("Application-URL: http://www.example.com");
- test_fetcher->set_response_headers(headers);
- test_fetcher->delegate()->OnURLFetchComplete(test_fetcher);
-}
-
-TEST_F(DeviceDescriptionFetcherTest, FetchFailsOnEmptyDescription) {
- ExpectError("Missing or empty response");
- net::TestURLFetcher* test_fetcher = StartRequest();
-
- test_fetcher->set_response_code(net::HTTP_OK);
- scoped_refptr<net::HttpResponseHeaders> headers =
- new net::HttpResponseHeaders("");
- headers->AddHeader("Application-URL: http://127.0.0.1/apps");
- test_fetcher->set_response_headers(headers);
- test_fetcher->SetResponseString("");
- test_fetcher->delegate()->OnURLFetchComplete(test_fetcher);
-}
-
-TEST_F(DeviceDescriptionFetcherTest, FetchFailsOnBadDescription) {
- ExpectError("Invalid response encoding");
- net::TestURLFetcher* test_fetcher = StartRequest();
-
- test_fetcher->set_response_code(net::HTTP_OK);
- scoped_refptr<net::HttpResponseHeaders> headers =
- new net::HttpResponseHeaders("");
- headers->AddHeader("Application-URL: http://127.0.0.1/apps");
- test_fetcher->set_response_headers(headers);
- test_fetcher->SetResponseString("\xfc\x9c\xbf\x80\xbf\x80");
- test_fetcher->delegate()->OnURLFetchComplete(test_fetcher);
-}
-
-TEST_F(DeviceDescriptionFetcherTest, FetchFailsOnResponseTooLarge) {
- ExpectError("Response too large");
- net::TestURLFetcher* test_fetcher = StartRequest();
-
- test_fetcher->set_response_code(net::HTTP_OK);
- scoped_refptr<net::HttpResponseHeaders> headers =
- new net::HttpResponseHeaders("");
- headers->AddHeader("Application-URL: http://127.0.0.1/apps");
- test_fetcher->set_response_headers(headers);
- test_fetcher->SetResponseString(std::string(262145, 'd'));
- test_fetcher->delegate()->OnURLFetchComplete(test_fetcher);
-}
-
-} // namespace dial
-} // namespace api
-} // namespace extensions
diff --git a/chrome/browser/extensions/api/dial/dial_api.cc b/chrome/browser/extensions/api/dial/dial_api.cc
index e97f90fa..415ae15 100644
--- a/chrome/browser/extensions/api/dial/dial_api.cc
+++ b/chrome/browser/extensions/api/dial/dial_api.cc
@@ -11,8 +11,8 @@
#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/time/time.h"
-#include "chrome/browser/extensions/api/dial/device_description_fetcher.h"
#include "chrome/browser/extensions/api/dial/dial_api_factory.h"
+#include "chrome/browser/media/router/discovery/dial/device_description_fetcher.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/extensions/api/dial.h"
#include "content/public/browser/browser_thread.h"
@@ -22,10 +22,10 @@
using base::TimeDelta;
using content::BrowserThread;
-using extensions::api::dial::DeviceDescriptionFetcher;
-using extensions::api::dial::DialDeviceData;
-using extensions::api::dial::DialDeviceDescriptionData;
-using extensions::api::dial::DialRegistry;
+using media_router::DeviceDescriptionFetcher;
+using media_router::DialDeviceData;
+using media_router::DialDeviceDescriptionData;
+using media_router::DialRegistry;
namespace extensions {
@@ -92,6 +92,17 @@
dial_registry()->OnListenerRemoved();
}
+void DialAPI::FillDialDevice(const media_router::DialDeviceData& device_data,
+ api::dial::DialDevice* device) const {
+ DCHECK(!device_data.device_id().empty());
+ DCHECK(media_router::DialDeviceData::IsDeviceDescriptionUrl(
+ device_data.device_description_url()));
+ device->device_label = device_data.label();
+ device->device_description_url = device_data.device_description_url().spec();
+ if (device_data.has_config_id())
+ device->config_id.reset(new int(device_data.config_id()));
+}
+
void DialAPI::OnDialDeviceEvent(const DialRegistry::DeviceList& devices) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
@@ -110,7 +121,7 @@
std::vector<api::dial::DialDevice> args;
for (const DialDeviceData& device : devices) {
api::dial::DialDevice api_device;
- device.FillDialDevice(&api_device);
+ FillDialDevice(device, &api_device);
args.push_back(std::move(api_device));
}
std::unique_ptr<base::ListValue> results =
@@ -157,8 +168,8 @@
void DialAPI::ShutdownOnUIThread() {}
void DialAPI::SetDeviceForTest(
- const api::dial::DialDeviceData& device_data,
- const api::dial::DialDeviceDescriptionData& device_description) {
+ const media_router::DialDeviceData& device_data,
+ const media_router::DialDeviceDescriptionData& device_description) {
test_device_data_ = base::MakeUnique<DialDeviceData>(device_data);
test_device_description_ =
base::MakeUnique<DialDeviceDescriptionData>(device_description);
@@ -240,7 +251,7 @@
}
void DialFetchDeviceDescriptionFunction::OnFetchComplete(
- const api::dial::DialDeviceDescriptionData& result) {
+ const media_router::DialDeviceDescriptionData& result) {
// Destroy the DeviceDescriptionFetcher since it still contains a reference
// to |this| in its un-invoked callback.
device_description_fetcher_.reset();
diff --git a/chrome/browser/extensions/api/dial/dial_api.h b/chrome/browser/extensions/api/dial/dial_api.h
index 1aba1c7..7ee0d14e 100644
--- a/chrome/browser/extensions/api/dial/dial_api.h
+++ b/chrome/browser/extensions/api/dial/dial_api.h
@@ -8,20 +8,18 @@
#include <memory>
#include "base/macros.h"
-#include "chrome/browser/extensions/api/dial/dial_device_data.h"
-#include "chrome/browser/extensions/api/dial/dial_registry.h"
+#include "chrome/browser/media/router/discovery/dial/dial_device_data.h"
+#include "chrome/browser/media/router/discovery/dial/dial_registry.h"
#include "chrome/common/extensions/api/dial.h"
#include "components/keyed_service/core/refcounted_keyed_service.h"
#include "extensions/browser/api/async_api_function.h"
#include "extensions/browser/event_router.h"
-namespace extensions {
-
-namespace api {
-namespace dial {
+namespace media_router {
class DeviceDescriptionFetcher;
-} // namespace dial
-} // namespace api
+} // namespace media_router
+
+namespace extensions {
class DialFetchDeviceDescriptionFunction;
@@ -46,23 +44,25 @@
// real DialRegsitry.
class DialAPI : public RefcountedKeyedService,
public EventRouter::Observer,
- public api::dial::DialRegistry::Observer {
+ public media_router::DialRegistry::Observer {
public:
explicit DialAPI(Profile* profile);
// The DialRegistry for the API. This must always be used only from the IO
// thread.
- api::dial::DialRegistry* dial_registry();
+ media_router::DialRegistry* dial_registry();
// Called by the DialRegistry on the IO thread so that the DialAPI dispatches
// the event to listeners on the UI thread.
- void SendEventOnUIThread(const api::dial::DialRegistry::DeviceList& devices);
- void SendErrorOnUIThread(const api::dial::DialRegistry::DialErrorCode type);
+ void SendEventOnUIThread(
+ const media_router::DialRegistry::DeviceList& devices);
+ void SendErrorOnUIThread(
+ const media_router::DialRegistry::DialErrorCode type);
// Sets test device data.
void SetDeviceForTest(
- const api::dial::DialDeviceData& device_data,
- const api::dial::DialDeviceDescriptionData& device_description);
+ const media_router::DialDeviceData& device_data,
+ const media_router::DialDeviceDescriptionData& device_description);
private:
~DialAPI() override;
@@ -78,22 +78,26 @@
// DialRegistry::Observer:
void OnDialDeviceEvent(
- const api::dial::DialRegistry::DeviceList& devices) override;
- void OnDialError(api::dial::DialRegistry::DialErrorCode type) override;
+ const media_router::DialRegistry::DeviceList& devices) override;
+ void OnDialError(media_router::DialRegistry::DialErrorCode type) override;
// Methods to notify the DialRegistry on the correct thread of new/removed
// listeners.
void NotifyListenerAddedOnIOThread();
void NotifyListenerRemovedOnIOThread();
+ // Fills the |device| API struct from |device_data|.
+ void FillDialDevice(const media_router::DialDeviceData& device_data,
+ api::dial::DialDevice* device) const;
+
Profile* profile_;
// Created lazily on first access on the IO thread.
- std::unique_ptr<api::dial::DialRegistry> dial_registry_;
+ std::unique_ptr<media_router::DialRegistry> dial_registry_;
// Device data for testing.
- std::unique_ptr<api::dial::DialDeviceData> test_device_data_;
- std::unique_ptr<api::dial::DialDeviceDescriptionData>
+ std::unique_ptr<media_router::DialDeviceData> test_device_data_;
+ std::unique_ptr<media_router::DialDeviceDescriptionData>
test_device_description_;
DISALLOW_COPY_AND_ASSIGN(DialAPI);
@@ -145,11 +149,11 @@
void GetDeviceDescriptionUrlOnIOThread(const std::string& label);
void MaybeStartFetch(const GURL& url);
- void OnFetchComplete(const api::dial::DialDeviceDescriptionData& result);
+ void OnFetchComplete(const media_router::DialDeviceDescriptionData& result);
void OnFetchError(const std::string& result);
std::unique_ptr<api::dial::FetchDeviceDescription::Params> params_;
- std::unique_ptr<api::dial::DeviceDescriptionFetcher>
+ std::unique_ptr<media_router::DeviceDescriptionFetcher>
device_description_fetcher_;
DialAPI* dial_;
diff --git a/chrome/browser/extensions/api/dial/dial_apitest.cc b/chrome/browser/extensions/api/dial/dial_apitest.cc
index c3698c5..67049da 100644
--- a/chrome/browser/extensions/api/dial/dial_apitest.cc
+++ b/chrome/browser/extensions/api/dial/dial_apitest.cc
@@ -6,9 +6,9 @@
#include "build/build_config.h"
#include "chrome/browser/extensions/api/dial/dial_api.h"
#include "chrome/browser/extensions/api/dial/dial_api_factory.h"
-#include "chrome/browser/extensions/api/dial/dial_registry.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/media/router/discovery/dial/dial_registry.h"
#include "extensions/common/switches.h"
#include "extensions/test/extension_test_message_listener.h"
#include "extensions/test/result_catcher.h"
@@ -17,9 +17,9 @@
using extensions::Extension;
using extensions::ResultCatcher;
-using extensions::api::dial::DialDeviceData;
-using extensions::api::dial::DialDeviceDescriptionData;
-using extensions::api::dial::DialRegistry;
+using media_router::DialDeviceData;
+using media_router::DialDeviceDescriptionData;
+using media_router::DialRegistry;
namespace {
diff --git a/chrome/browser/extensions/api/dial/dial_device_data.cc b/chrome/browser/extensions/api/dial/dial_device_data.cc
deleted file mode 100644
index 1db2e5c..0000000
--- a/chrome/browser/extensions/api/dial/dial_device_data.cc
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/extensions/api/dial/dial_device_data.h"
-
-#include "chrome/common/extensions/api/dial.h"
-
-namespace extensions {
-namespace api {
-namespace dial {
-
-DialDeviceData::DialDeviceData() : max_age_(-1), config_id_(-1) { }
-
-DialDeviceData::DialDeviceData(const std::string& device_id,
- const GURL& device_description_url,
- const base::Time& response_time)
- : device_id_(device_id), device_description_url_(device_description_url),
- response_time_(response_time), max_age_(-1), config_id_(-1) {
-}
-
-DialDeviceData::DialDeviceData(const DialDeviceData& other) = default;
-
-DialDeviceData::~DialDeviceData() { }
-
-const GURL& DialDeviceData::device_description_url() const {
- return device_description_url_;
-}
-
-void DialDeviceData::set_device_description_url(const GURL& url) {
- device_description_url_ = url;
-}
-
-// static
-bool DialDeviceData::IsDeviceDescriptionUrl(const GURL& url) {
- return url.is_valid() && !url.is_empty() && url.SchemeIsHTTPOrHTTPS();
-}
-
-bool DialDeviceData::UpdateFrom(const DialDeviceData& new_data) {
- DCHECK(new_data.device_id() == device_id_);
- DCHECK(new_data.label().empty());
- std::string label_tmp(label_);
- bool updated_api_visible_field =
- (new_data.device_description_url() != device_description_url_) ||
- (new_data.config_id() != config_id_);
- *this = new_data;
- label_ = label_tmp;
- return updated_api_visible_field;
-}
-
-void DialDeviceData::FillDialDevice(api::dial::DialDevice* device) const {
- DCHECK(!device_id_.empty());
- DCHECK(IsDeviceDescriptionUrl(device_description_url_));
- device->device_label = label_;
- device->device_description_url = device_description_url_.spec();
- if (has_config_id())
- device->config_id.reset(new int(config_id_));
-}
-
-DialDeviceDescriptionData::DialDeviceDescriptionData(
- const std::string& device_description,
- const GURL& app_url)
- : device_description(device_description), app_url(app_url) {}
-
-} // namespace dial
-} // namespace api
-} // namespace extensions
diff --git a/chrome/browser/extensions/api/dial/dial_device_data.h b/chrome/browser/extensions/api/dial/dial_device_data.h
deleted file mode 100644
index 4706885..0000000
--- a/chrome/browser/extensions/api/dial/dial_device_data.h
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_EXTENSIONS_API_DIAL_DIAL_DEVICE_DATA_H_
-#define CHROME_BROWSER_EXTENSIONS_API_DIAL_DIAL_DEVICE_DATA_H_
-
-#include <string>
-#include <vector>
-
-#include "base/time/time.h"
-#include "base/values.h"
-#include "url/gurl.h"
-
-namespace extensions {
-namespace api {
-namespace dial {
-
-struct DialDevice;
-
-// Dial device information that is used within the DialService and Registry on
-// the IO thread. It is updated as new information arrives and a list of
-// DialDeviceData is copied and sent to event listeners on the UI thread.
-class DialDeviceData {
- public:
- DialDeviceData();
- DialDeviceData(const std::string& device_id,
- const GURL& device_description_url,
- const base::Time& response_time);
- DialDeviceData(const DialDeviceData& other);
- ~DialDeviceData();
-
- bool operator==(const DialDeviceData& other_data) const {
- return device_id_ == other_data.device_id_;
- }
-
- const std::string& device_id() const { return device_id_; }
- void set_device_id(const std::string& id) {
- device_id_ = id;
- }
-
- const std::string& label() const { return label_; }
- void set_label(const std::string& label) {
- label_ = label;
- }
-
- const GURL& device_description_url() const;
- void set_device_description_url(const GURL& url);
-
- const base::Time& response_time() const { return response_time_; }
- void set_response_time(const base::Time& response_time) {
- response_time_ = response_time;
- }
-
- int max_age() const { return max_age_; }
- void set_max_age(int max_age) { max_age_ = max_age; }
- bool has_max_age() const { return max_age_ >= 0; }
-
- int config_id() const { return config_id_; }
- void set_config_id(int config_id) { config_id_ = config_id; }
- bool has_config_id() const { return config_id_ >= 0; }
-
- // Fills the |device| API struct from this instance.
- void FillDialDevice(api::dial::DialDevice* device) const;
-
- // Updates this DeviceData based on information from a new response in
- // |new_data|. Returns |true| if a field was updated that is visible through
- // the DIAL API.
- bool UpdateFrom(const DialDeviceData& new_data);
-
- // Validates that the URL is valid for the device description.
- static bool IsDeviceDescriptionUrl(const GURL& url);
-
- private:
- // Hardware identifier from the DIAL response. Not exposed to API clients.
- std::string device_id_;
-
- // Identifies this device to clients of the API as a proxy for the hardware
- // identifier. Automatically generated by the DIAL registry.
- std::string label_;
-
- // The device description URL.
- GURL device_description_url_;
-
- // The time that the most recent response was received.
- base::Time response_time_;
-
- // Optional (-1 means unset).
- int max_age_;
-
- // Optional (-1 means unset).
- int config_id_;
-};
-
-struct DialDeviceDescriptionData {
- public:
- DialDeviceDescriptionData() = default;
- DialDeviceDescriptionData(const std::string& device_description,
- const GURL& app_url);
-
- std::string device_description;
- GURL app_url;
-};
-
-} // namespace dial
-} // namespace api
-} // namespace extensions
-
-#endif // CHROME_BROWSER_EXTENSIONS_API_DIAL_DIAL_DEVICE_DATA_H_
diff --git a/chrome/browser/extensions/api/dial/dial_device_data_unittest.cc b/chrome/browser/extensions/api/dial/dial_device_data_unittest.cc
deleted file mode 100644
index fc079a3..0000000
--- a/chrome/browser/extensions/api/dial/dial_device_data_unittest.cc
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/extensions/api/dial/dial_device_data.h"
-#include "chrome/common/extensions/api/dial.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace extensions {
-namespace api {
-namespace dial {
-
-namespace {
-
-// Asserts equality between the two objects.
-void ExpectEqual(const DialDeviceData& first, const DialDeviceData& second) {
- EXPECT_EQ(first.device_id(), second.device_id());
- EXPECT_EQ(first.label(), second.label());
- EXPECT_EQ(first.device_description_url(), second.device_description_url());
- EXPECT_EQ(first.response_time(), second.response_time());
- EXPECT_EQ(first.max_age(), second.max_age());
- EXPECT_EQ(first.config_id(), second.config_id());
-}
-
-} // namespace
-
-TEST(DialDeviceDataTest, TestFillDialDevice) {
- api::dial::DialDevice api_device;
-
- DialDeviceData device;
- device.set_device_id("device");
- device.set_label("label");
- device.set_device_description_url(GURL("http://127.0.0.1/dd.xml"));
- device.set_config_id(1);
-
- device.FillDialDevice(&api_device);
- EXPECT_EQ(api_device.device_label, device.label());
- EXPECT_EQ(api_device.device_description_url,
- device.device_description_url().spec());
- EXPECT_EQ(*(api_device.config_id), device.config_id());
-}
-
-TEST(DialDeviceDataTest, TestUpdateFrom) {
- DialDeviceData original;
- original.set_device_id("device_a");
- original.set_label("label_a");
- original.set_device_description_url(GURL("http://127.0.0.1/dd-a.xml"));
- original.set_response_time(base::Time::FromInternalValue(1000));
- original.set_max_age(100);
- original.set_config_id(1);
-
- DialDeviceData new_data;
- new_data.set_device_id("device_a");
- new_data.set_device_description_url(GURL("http://127.0.0.1/dd-a.xml"));
- new_data.set_response_time(base::Time::FromInternalValue(1000));
- new_data.set_max_age(100);
- new_data.set_config_id(1);
-
- DialDeviceData original_1(original);
- EXPECT_FALSE(original_1.UpdateFrom(new_data));
- ExpectEqual(original_1, original);
-
- DialDeviceData original_2(original);
- new_data.set_max_age(200);
- new_data.set_response_time(base::Time::FromInternalValue(2000));
- EXPECT_FALSE(original_2.UpdateFrom(new_data));
-
- EXPECT_EQ("device_a", original_2.device_id());
- EXPECT_EQ(GURL("http://127.0.0.1/dd-a.xml"),
- original_2.device_description_url());
- EXPECT_EQ("label_a", original_2.label());
- EXPECT_EQ(200, original_2.max_age());
- EXPECT_EQ(base::Time::FromInternalValue(2000), original_2.response_time());
- EXPECT_EQ(1, original_2.config_id());
-
- DialDeviceData original_3(original);
- new_data.set_device_description_url(GURL("http://127.0.0.2/dd-b.xml"));
- new_data.set_config_id(2);
- EXPECT_TRUE(original_3.UpdateFrom(new_data));
-
- EXPECT_EQ("device_a", original_3.device_id());
- EXPECT_EQ(GURL("http://127.0.0.2/dd-b.xml"),
- original_3.device_description_url());
- EXPECT_EQ("label_a", original_3.label());
- EXPECT_EQ(200, original_3.max_age());
- EXPECT_EQ(base::Time::FromInternalValue(2000), original_3.response_time());
- EXPECT_EQ(2, original_3.config_id());
-}
-
-TEST(DialDeviceDataTest, TestIsDeviceDescriptionUrl) {
- EXPECT_TRUE(DialDeviceData::IsDeviceDescriptionUrl(
- GURL("http://some.device.com/dd.xml")));
- EXPECT_TRUE(DialDeviceData::IsDeviceDescriptionUrl(
- GURL("https://some.device.com/dd.xml")));
- EXPECT_TRUE(DialDeviceData::IsDeviceDescriptionUrl(
- GURL("http://192.168.1.1:1234/dd.xml")));
- EXPECT_TRUE(DialDeviceData::IsDeviceDescriptionUrl(
- GURL("https://192.168.1.1:1234/dd.xml")));
-
- EXPECT_FALSE(DialDeviceData::IsDeviceDescriptionUrl(GURL()));
- EXPECT_FALSE(DialDeviceData::IsDeviceDescriptionUrl(GURL(std::string())));
- EXPECT_FALSE(
- DialDeviceData::IsDeviceDescriptionUrl(GURL("file://path/to/file")));
-}
-
-} // namespace dial
-} // namespace api
-} // namespace extensions
diff --git a/chrome/browser/extensions/api/dial/dial_registry.cc b/chrome/browser/extensions/api/dial/dial_registry.cc
deleted file mode 100644
index 280c6f0..0000000
--- a/chrome/browser/extensions/api/dial/dial_registry.cc
+++ /dev/null
@@ -1,377 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/extensions/api/dial/dial_registry.h"
-
-#include <memory>
-#include <utility>
-
-#include "base/memory/ptr_util.h"
-#include "base/stl_util.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/time/time.h"
-#include "base/values.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/extensions/api/dial/dial_api.h"
-#include "chrome/browser/extensions/api/dial/dial_device_data.h"
-#include "chrome/browser/extensions/api/dial/dial_service.h"
-#include "chrome/common/extensions/api/dial.h"
-#include "components/net_log/chrome_net_log.h"
-#include "content/public/browser/browser_thread.h"
-
-using base::Time;
-using base::TimeDelta;
-using content::BrowserThread;
-using net::NetworkChangeNotifier;
-
-namespace extensions {
-namespace api {
-namespace dial {
-
-DialRegistry::DialRegistry(base::TimeDelta refresh_interval,
- base::TimeDelta expiration,
- const size_t max_devices)
- : num_listeners_(0),
- registry_generation_(0),
- last_event_registry_generation_(0),
- label_count_(0),
- refresh_interval_delta_(refresh_interval),
- expiration_delta_(expiration),
- max_devices_(max_devices) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK_GT(max_devices_, 0U);
- NetworkChangeNotifier::AddNetworkChangeObserver(this);
-}
-
-DialRegistry::~DialRegistry() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
-}
-
-std::unique_ptr<DialService> DialRegistry::CreateDialService() {
- DCHECK(g_browser_process->net_log());
- return base::MakeUnique<DialServiceImpl>(g_browser_process->net_log());
-}
-
-void DialRegistry::ClearDialService() {
- dial_.reset();
-}
-
-base::Time DialRegistry::Now() const {
- return Time::Now();
-}
-
-void DialRegistry::OnListenerAdded() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (++num_listeners_ == 1) {
- VLOG(2) << "Listener added; starting periodic discovery.";
- StartPeriodicDiscovery();
- }
- // Event listeners with the current device list.
- // TODO(crbug.com/576817): Rework the DIAL API so we don't need to have extra
- // behaviors when adding listeners.
- SendEvent();
-}
-
-void DialRegistry::OnListenerRemoved() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK_GT(num_listeners_, 0);
- if (--num_listeners_ == 0) {
- VLOG(2) << "Listeners removed; stopping periodic discovery.";
- StopPeriodicDiscovery();
- }
-}
-
-void DialRegistry::RegisterObserver(Observer* observer) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- observers_.AddObserver(observer);
-}
-
-void DialRegistry::UnregisterObserver(Observer* observer) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- observers_.RemoveObserver(observer);
-}
-
-GURL DialRegistry::GetDeviceDescriptionURL(const std::string& label) const {
- const auto device_it = device_by_label_map_.find(label);
- if (device_it != device_by_label_map_.end())
- return device_it->second->device_description_url();
-
- return GURL();
-}
-
-void DialRegistry::AddDeviceForTest(const DialDeviceData& device_data) {
- std::unique_ptr<DialDeviceData> test_data =
- base::MakeUnique<DialDeviceData>(device_data);
- device_by_label_map_.insert(
- std::make_pair(device_data.label(), test_data.get()));
- device_by_id_map_.insert(
- std::make_pair(device_data.device_id(), std::move(test_data)));
-}
-
-bool DialRegistry::ReadyToDiscover() {
- if (num_listeners_ == 0) {
- OnDialError(DIAL_NO_LISTENERS);
- return false;
- }
- if (NetworkChangeNotifier::IsOffline()) {
- OnDialError(DIAL_NETWORK_DISCONNECTED);
- return false;
- }
- if (NetworkChangeNotifier::IsConnectionCellular(
- NetworkChangeNotifier::GetConnectionType())) {
- OnDialError(DIAL_CELLULAR_NETWORK);
- return false;
- }
- return true;
-}
-
-bool DialRegistry::DiscoverNow() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (!ReadyToDiscover()) {
- return false;
- }
- if (!dial_) {
- OnDialError(DIAL_UNKNOWN);
- return false;
- }
-
- if (!dial_->HasObserver(this))
- NOTREACHED() << "DiscoverNow() called without observing dial_";
-
- // Force increment |registry_generation_| to ensure an event is sent even if
- // the device list did not change.
- bool started = dial_->Discover();
- if (started)
- ++registry_generation_;
-
- return started;
-}
-
-void DialRegistry::StartPeriodicDiscovery() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (!ReadyToDiscover() || dial_)
- return;
-
- dial_ = CreateDialService();
- dial_->AddObserver(this);
- DoDiscovery();
- repeating_timer_.Start(FROM_HERE,
- refresh_interval_delta_,
- this,
- &DialRegistry::DoDiscovery);
-}
-
-void DialRegistry::DoDiscovery() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK(dial_);
- VLOG(2) << "About to discover!";
- dial_->Discover();
-}
-
-void DialRegistry::StopPeriodicDiscovery() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (!dial_)
- return;
-
- repeating_timer_.Stop();
- dial_->RemoveObserver(this);
- ClearDialService();
-}
-
-bool DialRegistry::PruneExpiredDevices() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- bool pruned_device = false;
- DeviceByLabelMap::iterator it = device_by_label_map_.begin();
- while (it != device_by_label_map_.end()) {
- auto* device = it->second;
- if (IsDeviceExpired(*device)) {
- VLOG(2) << "Device " << device->label() << " expired, removing";
-
- // Make a copy of the device ID here since |device| will be destroyed
- // during erase().
- std::string device_id = device->device_id();
- const size_t num_erased_by_id = device_by_id_map_.erase(device_id);
- DCHECK_EQ(1U, num_erased_by_id);
- device_by_label_map_.erase(it++);
- pruned_device = true;
- } else {
- ++it;
- }
- }
- return pruned_device;
-}
-
-bool DialRegistry::IsDeviceExpired(const DialDeviceData& device) const {
- Time now = Now();
-
- // Check against our default expiration timeout.
- Time default_expiration_time = device.response_time() + expiration_delta_;
- if (now > default_expiration_time)
- return true;
-
- // Check against the device's cache-control header, if set.
- if (device.has_max_age()) {
- Time max_age_expiration_time =
- device.response_time() + TimeDelta::FromSeconds(device.max_age());
- if (now > max_age_expiration_time)
- return true;
- }
- return false;
-}
-
-void DialRegistry::Clear() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- device_by_id_map_.clear();
- device_by_label_map_.clear();
- registry_generation_++;
-}
-
-void DialRegistry::MaybeSendEvent() {
- // Send an event if the device list has changed since the last event.
- bool needs_event = last_event_registry_generation_ < registry_generation_;
- VLOG(2) << "lerg = " << last_event_registry_generation_ << ", rg = "
- << registry_generation_ << ", needs_event = " << needs_event;
- if (needs_event)
- SendEvent();
-}
-
-void DialRegistry::SendEvent() {
- DeviceList device_list;
- for (DeviceByLabelMap::const_iterator it = device_by_label_map_.begin();
- it != device_by_label_map_.end(); ++it) {
- device_list.push_back(*(it->second));
- }
- OnDialDeviceEvent(device_list);
-
- // Reset watermark.
- last_event_registry_generation_ = registry_generation_;
-}
-
-std::string DialRegistry::NextLabel() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- return base::IntToString(++label_count_);
-}
-
-void DialRegistry::OnDiscoveryRequest(DialService* service) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- MaybeSendEvent();
-}
-
-void DialRegistry::OnDeviceDiscovered(DialService* service,
- const DialDeviceData& device) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- // Adds |device| to our list of devices or updates an existing device, unless
- // |device| is a duplicate. Returns true if the list was modified and
- // increments the list generation.
- auto device_data = base::MakeUnique<DialDeviceData>(device);
- DCHECK(!device_data->device_id().empty());
- DCHECK(device_data->label().empty());
-
- bool did_modify_list = false;
- DeviceByIdMap::iterator lookup_result =
- device_by_id_map_.find(device_data->device_id());
-
- if (lookup_result != device_by_id_map_.end()) {
- VLOG(2) << "Found device " << device_data->device_id() << ", merging";
-
- // Already have previous response. Merge in data from this response and
- // track if there were any API visible changes.
- did_modify_list = lookup_result->second->UpdateFrom(*device_data);
- } else {
- did_modify_list = MaybeAddDevice(std::move(device_data));
- }
-
- if (did_modify_list)
- registry_generation_++;
-
- VLOG(2) << "did_modify_list = " << did_modify_list
- << ", generation = " << registry_generation_;
-}
-
-bool DialRegistry::MaybeAddDevice(std::unique_ptr<DialDeviceData> device_data) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (device_by_id_map_.size() == max_devices_) {
- VLOG(1) << "Maximum registry size reached. Cannot add device.";
- return false;
- }
- device_data->set_label(NextLabel());
- DialDeviceData* device_data_ptr = device_data.get();
- device_by_id_map_[device_data_ptr->device_id()] = std::move(device_data);
- device_by_label_map_[device_data_ptr->label()] = device_data_ptr;
- VLOG(2) << "Added device, id = " << device_data_ptr->device_id()
- << ", label = " << device_data_ptr->label();
- return true;
-}
-
-void DialRegistry::OnDiscoveryFinished(DialService* service) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (PruneExpiredDevices())
- registry_generation_++;
- MaybeSendEvent();
-}
-
-void DialRegistry::OnError(DialService* service,
- const DialService::DialServiceErrorCode& code) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- switch (code) {
- case DialService::DIAL_SERVICE_SOCKET_ERROR:
- OnDialError(DIAL_SOCKET_ERROR);
- break;
- case DialService::DIAL_SERVICE_NO_INTERFACES:
- OnDialError(DIAL_NO_INTERFACES);
- break;
- default:
- NOTREACHED();
- OnDialError(DIAL_UNKNOWN);
- break;
- }
-}
-
-void DialRegistry::OnNetworkChanged(
- NetworkChangeNotifier::ConnectionType type) {
- switch (type) {
- case NetworkChangeNotifier::CONNECTION_NONE:
- if (dial_) {
- VLOG(2) << "Lost connection, shutting down discovery and clearing"
- << " list.";
- OnDialError(DIAL_NETWORK_DISCONNECTED);
-
- StopPeriodicDiscovery();
- // TODO(justinlin): As an optimization, we can probably keep our device
- // list around and restore it if we reconnected to the exact same
- // network.
- Clear();
- MaybeSendEvent();
- }
- break;
- case NetworkChangeNotifier::CONNECTION_2G:
- case NetworkChangeNotifier::CONNECTION_3G:
- case NetworkChangeNotifier::CONNECTION_4G:
- case NetworkChangeNotifier::CONNECTION_ETHERNET:
- case NetworkChangeNotifier::CONNECTION_WIFI:
- case NetworkChangeNotifier::CONNECTION_UNKNOWN:
- case NetworkChangeNotifier::CONNECTION_BLUETOOTH:
- if (!dial_) {
- VLOG(2) << "Connection detected, restarting discovery.";
- StartPeriodicDiscovery();
- }
- break;
- }
-}
-
-void DialRegistry::OnDialDeviceEvent(const DeviceList& devices) {
- for (auto& observer : observers_)
- observer.OnDialDeviceEvent(devices);
-}
-
-void DialRegistry::OnDialError(DialErrorCode type) {
- for (auto& observer : observers_)
- observer.OnDialError(type);
-}
-
-} // namespace dial
-} // namespace api
-} // namespace extensions
diff --git a/chrome/browser/extensions/api/dial/dial_registry.h b/chrome/browser/extensions/api/dial/dial_registry.h
deleted file mode 100644
index f0597e02..0000000
--- a/chrome/browser/extensions/api/dial/dial_registry.h
+++ /dev/null
@@ -1,210 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_EXTENSIONS_API_DIAL_DIAL_REGISTRY_H_
-#define CHROME_BROWSER_EXTENSIONS_API_DIAL_DIAL_REGISTRY_H_
-
-#include <stddef.h>
-
-#include <map>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/containers/hash_tables.h"
-#include "base/gtest_prod_util.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/observer_list.h"
-#include "base/time/time.h"
-#include "base/timer/timer.h"
-#include "chrome/browser/extensions/api/dial/dial_service.h"
-#include "chrome/browser/profiles/profile.h"
-#include "net/base/network_change_notifier.h"
-
-namespace extensions {
-namespace api {
-namespace dial {
-
-// Keeps track of devices that have responded to discovery requests and notifies
-// the observer with an updated, complete set of active devices. The registry's
-// observer (i.e., the Dial API) owns the registry instance.
-// DialRegistry lives on the IO thread.
-class DialRegistry : public DialService::Observer,
- public net::NetworkChangeNotifier::NetworkChangeObserver {
- public:
- using DeviceList = std::vector<DialDeviceData>;
-
- enum DialErrorCode {
- DIAL_NO_LISTENERS = 0,
- DIAL_NO_INTERFACES,
- DIAL_NETWORK_DISCONNECTED,
- DIAL_CELLULAR_NETWORK,
- DIAL_SOCKET_ERROR,
- DIAL_UNKNOWN
- };
-
- class Observer {
- public:
- // Methods invoked on the IO thread when a new device is discovered, an
- // update is triggered by dial.discoverNow or an error occured.
- virtual void OnDialDeviceEvent(const DeviceList& devices) = 0;
- virtual void OnDialError(DialErrorCode type) = 0;
-
- protected:
- virtual ~Observer() {}
- };
-
- // Create the DIAL registry and pass a reference to allow it to notify on
- // DIAL device events.
- DialRegistry(base::TimeDelta refresh_interval,
- base::TimeDelta expiration,
- const size_t max_devices);
-
- ~DialRegistry() override;
-
- // Called by the DIAL API when event listeners are added or removed. The dial
- // service is started after the first listener is added and stopped after the
- // last listener is removed.
- void OnListenerAdded();
- void OnListenerRemoved();
-
- // This class does not take ownership of observer.
- void RegisterObserver(Observer* observer);
- void UnregisterObserver(Observer* observer);
-
- // Called by the DIAL API to try to kickoff a discovery if there is not one
- // already active.
- bool DiscoverNow();
-
- // Returns the URL of the device description for the device identified by
- // |label|, or an empty GURL if no such device exists.
- GURL GetDeviceDescriptionURL(const std::string& label) const;
-
- // Adds a device directly to the registry as if it was discovered. For tests
- // only. Note that if discovery is actually started, this device will be
- // removed by PruneExpiredDevices().
- void AddDeviceForTest(const DialDeviceData& device_data);
-
- protected:
- // Returns a new instance of the DIAL service. Overridden by tests.
- virtual std::unique_ptr<DialService> CreateDialService();
- virtual void ClearDialService();
-
- // Returns the current time. Overridden by tests.
- virtual base::Time Now() const;
-
- // The DIAL service. Periodic discovery is active when this is not NULL.
- std::unique_ptr<DialService> dial_;
-
- private:
- using DeviceByIdMap =
- base::hash_map<std::string, std::unique_ptr<DialDeviceData>>;
- using DeviceByLabelMap = std::map<std::string, DialDeviceData*>;
-
- // DialService::Observer:
- void OnDiscoveryRequest(DialService* service) override;
- void OnDeviceDiscovered(DialService* service,
- const DialDeviceData& device) override;
- void OnDiscoveryFinished(DialService* service) override;
- void OnError(DialService* service,
- const DialService::DialServiceErrorCode& code) override;
-
- // net::NetworkChangeObserver:
- void OnNetworkChanged(
- net::NetworkChangeNotifier::ConnectionType type) override;
-
- // Notify all observers about DialDeviceEvent or DialError.
- void OnDialDeviceEvent(const DeviceList& devices);
- void OnDialError(DialErrorCode type);
-
- // Starts and stops periodic discovery. Periodic discovery is done when there
- // are registered event listeners.
- void StartPeriodicDiscovery();
- void StopPeriodicDiscovery();
-
- // Check whether we are in a state ready to discover and dispatch error
- // notifications if not.
- bool ReadyToDiscover();
-
- // Purge our whole registry. We may need to do this occasionally, e.g. when
- // the network status changes. Increments the registry generation.
- void Clear();
-
- // The repeating timer schedules discoveries with this method.
- void DoDiscovery();
-
- // Attempts to add a newly discovered device to the registry. Returns true if
- // successful.
- bool MaybeAddDevice(std::unique_ptr<DialDeviceData> device_data);
-
- // Remove devices from the registry that have expired, i.e. not responded
- // after some time. Returns true if the registry was modified.
- bool PruneExpiredDevices();
-
- // Returns true if the device has expired and should be removed from the
- // active set.
- bool IsDeviceExpired(const DialDeviceData& device) const;
-
- // Notify listeners with the current device list if the list has changed.
- void MaybeSendEvent();
-
- // Notify listeners with the current device list.
- void SendEvent();
-
- // Returns the next label to use for a newly-seen device.
- std::string NextLabel();
-
- // The current number of event listeners attached to this registry.
- int num_listeners_;
-
- // Incremented each time we modify the registry of active devices.
- int registry_generation_;
-
- // The registry generation associated with the last time we sent an event.
- // Used to suppress events with duplicate device lists.
- int last_event_registry_generation_;
-
- // Counter to generate device labels.
- int label_count_;
-
- // Registry parameters
- const base::TimeDelta refresh_interval_delta_;
- const base::TimeDelta expiration_delta_;
- const size_t max_devices_;
-
- // A map used to track known devices by their device_id.
- DeviceByIdMap device_by_id_map_;
-
- // A map used to track known devices sorted by label. We iterate over this to
- // construct the device list sent to API clients.
- DeviceByLabelMap device_by_label_map_;
-
- // Timer used to manage periodic discovery requests.
- base::RepeatingTimer repeating_timer_;
-
- // Interface from which the DIAL API is notified of DIAL device events. the
- // DIAL API owns this DIAL registry.
- base::ObserverList<Observer> observers_;
-
- FRIEND_TEST_ALL_PREFIXES(DialRegistryTest, TestAddRemoveListeners);
- FRIEND_TEST_ALL_PREFIXES(DialRegistryTest, TestNoDevicesDiscovered);
- FRIEND_TEST_ALL_PREFIXES(DialRegistryTest, TestDevicesDiscovered);
- FRIEND_TEST_ALL_PREFIXES(DialRegistryTest,
- TestDevicesDiscoveredWithTwoListeners);
- FRIEND_TEST_ALL_PREFIXES(DialRegistryTest, TestDeviceExpires);
- FRIEND_TEST_ALL_PREFIXES(DialRegistryTest, TestExpiredDeviceIsRediscovered);
- FRIEND_TEST_ALL_PREFIXES(DialRegistryTest,
- TestRemovingListenerDoesNotClearList);
- FRIEND_TEST_ALL_PREFIXES(DialRegistryTest, TestNetworkEventConnectionLost);
- FRIEND_TEST_ALL_PREFIXES(DialRegistryTest,
- TestNetworkEventConnectionRestored);
- DISALLOW_COPY_AND_ASSIGN(DialRegistry);
-};
-
-} // namespace dial
-} // namespace api
-} // namespace extensions
-
-#endif // CHROME_BROWSER_EXTENSIONS_API_DIAL_DIAL_REGISTRY_H_
diff --git a/chrome/browser/extensions/api/dial/dial_registry_unittest.cc b/chrome/browser/extensions/api/dial/dial_registry_unittest.cc
deleted file mode 100644
index bbe6a9d..0000000
--- a/chrome/browser/extensions/api/dial/dial_registry_unittest.cc
+++ /dev/null
@@ -1,382 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <stddef.h>
-
-#include "base/memory/ptr_util.h"
-#include "chrome/browser/extensions/api/dial/dial_device_data.h"
-#include "chrome/browser/extensions/api/dial/dial_registry.h"
-#include "chrome/browser/extensions/api/dial/dial_service.h"
-#include "chrome/test/base/testing_profile.h"
-#include "content/public/test/test_browser_thread_bundle.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "url/gurl.h"
-
-using base::Time;
-using base::TimeDelta;
-using ::testing::A;
-using ::testing::AtLeast;
-using ::testing::Return;
-using ::testing::InSequence;
-
-namespace extensions {
-namespace api {
-namespace dial {
-
-class MockDialObserver : public DialRegistry::Observer {
- public:
- ~MockDialObserver() override {}
-
- MOCK_METHOD1(OnDialDeviceEvent,
- void(const DialRegistry::DeviceList& devices));
- MOCK_METHOD1(OnDialError, void(DialRegistry::DialErrorCode type));
-};
-
-class MockDialService : public DialService {
- public:
- ~MockDialService() override {}
-
- MOCK_METHOD0(Discover, bool());
- MOCK_METHOD1(AddObserver, void(DialService::Observer*));
- MOCK_METHOD1(RemoveObserver, void(DialService::Observer*));
- MOCK_CONST_METHOD1(HasObserver, bool(const DialService::Observer*));
-};
-
-class MockDialRegistry : public DialRegistry {
- public:
- MockDialRegistry(const base::TimeDelta& refresh_interval,
- const base::TimeDelta& expiration,
- const size_t max_devices)
- : DialRegistry(refresh_interval, expiration, max_devices),
- time_(Time::Now()) {}
-
- ~MockDialRegistry() override {
- // Don't let the DialRegistry delete this.
- DialService* tmp = dial_.release();
- if (tmp)
- CHECK_EQ(&mock_service_, tmp);
- }
-
- // Returns the mock Dial service.
- MockDialService& mock_service() {
- return mock_service_;
- }
-
- void set_time(Time time) { time_ = time; }
-
- protected:
- base::Time Now() const override { return time_; }
-
- std::unique_ptr<DialService> CreateDialService() override {
- return base::WrapUnique(&mock_service_);
- }
-
- void ClearDialService() override {
- // Release the pointer but don't delete the object because the test owns it.
- CHECK_EQ(&mock_service_, dial_.release());
- }
-
- private:
- MockDialService mock_service_;
-
- // Set to mock out the current time.
- Time time_;
-};
-
-class DialRegistryTest : public testing::Test {
- public:
- DialRegistryTest()
- : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
- first_device_("first", GURL("http://127.0.0.1/dd.xml"), Time::Now()),
- second_device_("second", GURL("http://127.0.0.2/dd.xml"), Time::Now()),
- third_device_("third", GURL("http://127.0.0.3/dd.xml"), Time::Now()) {
- registry_ = base::MakeUnique<MockDialRegistry>(
- TimeDelta::FromSeconds(1000), TimeDelta::FromSeconds(10), 10);
- registry_->RegisterObserver(&mock_observer_);
- list_with_first_device_.push_back(first_device_);
- list_with_second_device_.push_back(second_device_);
- }
-
- protected:
- void SetListenerExpectations() {
- EXPECT_CALL(registry_->mock_service(),
- AddObserver(A<DialService::Observer*>()));
- EXPECT_CALL(registry_->mock_service(),
- RemoveObserver(A<DialService::Observer*>()));
- }
-
- content::TestBrowserThreadBundle thread_bundle_;
- std::unique_ptr<MockDialRegistry> registry_;
- MockDialObserver mock_observer_;
- const DialDeviceData first_device_;
- const DialDeviceData second_device_;
- const DialDeviceData third_device_;
-
- const DialRegistry::DeviceList empty_list_;
- DialRegistry::DeviceList list_with_first_device_;
- DialRegistry::DeviceList list_with_second_device_;
-};
-
-TEST_F(DialRegistryTest, TestAddRemoveListeners) {
- SetListenerExpectations();
- EXPECT_CALL(registry_->mock_service(), Discover());
- EXPECT_CALL(mock_observer_, OnDialDeviceEvent(empty_list_)).Times(2);
-
- EXPECT_FALSE(registry_->repeating_timer_.IsRunning());
- registry_->OnListenerAdded();
- EXPECT_TRUE(registry_->repeating_timer_.IsRunning());
- registry_->OnListenerAdded();
- EXPECT_TRUE(registry_->repeating_timer_.IsRunning());
- registry_->OnListenerRemoved();
- EXPECT_TRUE(registry_->repeating_timer_.IsRunning());
- registry_->OnListenerRemoved();
- EXPECT_FALSE(registry_->repeating_timer_.IsRunning());
-}
-
-TEST_F(DialRegistryTest, TestNoDevicesDiscovered) {
- SetListenerExpectations();
- EXPECT_CALL(mock_observer_, OnDialDeviceEvent(empty_list_));
- EXPECT_CALL(registry_->mock_service(), Discover());
-
- registry_->OnListenerAdded();
- registry_->OnDiscoveryRequest(nullptr);
- registry_->OnDiscoveryFinished(nullptr);
- registry_->OnListenerRemoved();
-}
-
-TEST_F(DialRegistryTest, TestDevicesDiscovered) {
- DialRegistry::DeviceList expected_list2;
- expected_list2.push_back(first_device_);
- expected_list2.push_back(second_device_);
-
- SetListenerExpectations();
- InSequence s;
- EXPECT_CALL(registry_->mock_service(), Discover());
- EXPECT_CALL(mock_observer_, OnDialDeviceEvent(empty_list_));
- EXPECT_CALL(mock_observer_, OnDialDeviceEvent(list_with_first_device_));
- EXPECT_CALL(registry_->mock_service(), Discover());
- EXPECT_CALL(mock_observer_, OnDialDeviceEvent(expected_list2));
-
- registry_->OnListenerAdded();
- registry_->OnDiscoveryRequest(nullptr);
- registry_->OnDeviceDiscovered(nullptr, first_device_);
- registry_->OnDiscoveryFinished(nullptr);
-
- registry_->DoDiscovery();
- registry_->OnDiscoveryRequest(nullptr);
- registry_->OnDeviceDiscovered(nullptr, second_device_);
- registry_->OnDiscoveryFinished(nullptr);
- registry_->OnListenerRemoved();
-}
-
-TEST_F(DialRegistryTest, TestDevicesDiscoveredWithTwoListeners) {
- DialRegistry::DeviceList expected_list2;
- expected_list2.push_back(first_device_);
- expected_list2.push_back(second_device_);
-
- SetListenerExpectations();
- InSequence s;
- EXPECT_CALL(registry_->mock_service(), Discover());
- EXPECT_CALL(mock_observer_, OnDialDeviceEvent(empty_list_));
- EXPECT_CALL(mock_observer_, OnDialDeviceEvent(list_with_first_device_))
- .Times(2);
- EXPECT_CALL(registry_->mock_service(), Discover());
- EXPECT_CALL(mock_observer_, OnDialDeviceEvent(expected_list2));
-
- registry_->OnListenerAdded();
- registry_->OnDiscoveryRequest(nullptr);
- registry_->OnDeviceDiscovered(nullptr, first_device_);
- registry_->OnDiscoveryFinished(nullptr);
-
- registry_->OnListenerAdded();
-
- registry_->DoDiscovery();
- registry_->OnDiscoveryRequest(nullptr);
- registry_->OnDeviceDiscovered(nullptr, second_device_);
- registry_->OnDiscoveryFinished(nullptr);
- registry_->OnListenerRemoved();
- registry_->OnListenerRemoved();
-}
-
-TEST_F(DialRegistryTest, TestDeviceExpires) {
- SetListenerExpectations();
- InSequence s;
- EXPECT_CALL(registry_->mock_service(), Discover());
- EXPECT_CALL(mock_observer_, OnDialDeviceEvent(empty_list_));
- EXPECT_CALL(mock_observer_, OnDialDeviceEvent(list_with_first_device_));
- EXPECT_CALL(registry_->mock_service(), Discover());
- EXPECT_CALL(mock_observer_, OnDialDeviceEvent(empty_list_));
-
- registry_->OnListenerAdded();
- registry_->OnDiscoveryRequest(nullptr);
- registry_->OnDeviceDiscovered(nullptr, first_device_);
- registry_->OnDiscoveryFinished(nullptr);
-
- registry_->set_time(Time::Now() + TimeDelta::FromSeconds(30));
-
- registry_->DoDiscovery();
- registry_->OnDiscoveryRequest(nullptr);
- registry_->OnDiscoveryFinished(nullptr);
- registry_->OnListenerRemoved();
-}
-
-TEST_F(DialRegistryTest, TestExpiredDeviceIsRediscovered) {
- std::vector<Time> discovery_times;
- discovery_times.push_back(Time::Now());
- discovery_times.push_back(discovery_times[0] + TimeDelta::FromSeconds(30));
- discovery_times.push_back(discovery_times[1] + TimeDelta::FromSeconds(30));
-
- DialDeviceData rediscovered_device("first",
- GURL("http://127.0.0.1/dd.xml"),
- discovery_times[2]);
-
- SetListenerExpectations();
-
- InSequence s;
- EXPECT_CALL(registry_->mock_service(), Discover());
- EXPECT_CALL(mock_observer_, OnDialDeviceEvent(empty_list_));
- EXPECT_CALL(mock_observer_, OnDialDeviceEvent(list_with_first_device_));
- EXPECT_CALL(registry_->mock_service(), Discover());
- EXPECT_CALL(mock_observer_, OnDialDeviceEvent(empty_list_));
- EXPECT_CALL(registry_->mock_service(), Discover());
- EXPECT_CALL(mock_observer_, OnDialDeviceEvent(list_with_first_device_));
-
- registry_->set_time(discovery_times[0]);
- registry_->OnListenerAdded();
- registry_->OnDiscoveryRequest(nullptr);
- registry_->OnDeviceDiscovered(nullptr, first_device_);
- registry_->OnDiscoveryFinished(nullptr);
-
- // Will expire "first" device as it is not discovered this time.
- registry_->set_time(discovery_times[1]);
- registry_->DoDiscovery();
- registry_->OnDiscoveryRequest(nullptr);
- registry_->OnDiscoveryFinished(nullptr);
-
- // "first" device is rediscovered 30 seconds later. We pass a device object
- // with a newer discovery time so it is not pruned immediately.
- registry_->set_time(discovery_times[2]);
- registry_->DoDiscovery();
- registry_->OnDiscoveryRequest(nullptr);
- registry_->OnDeviceDiscovered(nullptr, rediscovered_device);
- registry_->OnDiscoveryFinished(nullptr);
-
- registry_->OnListenerRemoved();
-}
-
-TEST_F(DialRegistryTest, TestRemovingListenerDoesNotClearList) {
- DialRegistry::DeviceList expected_list2;
- expected_list2.push_back(first_device_);
- expected_list2.push_back(second_device_);
-
- InSequence s;
- EXPECT_CALL(registry_->mock_service(),
- AddObserver(A<DialService::Observer*>()));
- EXPECT_CALL(registry_->mock_service(), Discover());
- EXPECT_CALL(mock_observer_, OnDialDeviceEvent(empty_list_));
- EXPECT_CALL(mock_observer_, OnDialDeviceEvent(expected_list2));
- EXPECT_CALL(registry_->mock_service(),
- RemoveObserver(A<DialService::Observer*>()));
-
- registry_->OnListenerAdded();
- registry_->OnDiscoveryRequest(nullptr);
- registry_->OnDeviceDiscovered(nullptr, first_device_);
- registry_->OnDeviceDiscovered(nullptr, second_device_);
- registry_->OnDiscoveryFinished(nullptr);
- registry_->OnListenerRemoved();
-
- // Removing and adding a listener again fires an event with the current device
- // list (even though no new devices were discovered).
- EXPECT_CALL(registry_->mock_service(),
- AddObserver(A<DialService::Observer*>()));
- EXPECT_CALL(registry_->mock_service(), Discover());
- EXPECT_CALL(mock_observer_, OnDialDeviceEvent(expected_list2));
- EXPECT_CALL(registry_->mock_service(),
- RemoveObserver(A<DialService::Observer*>()));
-
- registry_->OnListenerAdded();
- registry_->OnDiscoveryRequest(nullptr);
- registry_->OnDiscoveryFinished(nullptr);
- registry_->OnListenerRemoved();
-}
-
-TEST_F(DialRegistryTest, TestNetworkEventConnectionLost) {
- SetListenerExpectations();
-
- InSequence s;
- EXPECT_CALL(registry_->mock_service(), Discover());
- EXPECT_CALL(mock_observer_, OnDialDeviceEvent(empty_list_));
- EXPECT_CALL(mock_observer_, OnDialDeviceEvent(list_with_first_device_));
- EXPECT_CALL(mock_observer_,
- OnDialError(DialRegistry::DIAL_NETWORK_DISCONNECTED));
- EXPECT_CALL(mock_observer_, OnDialDeviceEvent(empty_list_));
-
- registry_->OnListenerAdded();
- registry_->OnDiscoveryRequest(nullptr);
- registry_->OnDeviceDiscovered(nullptr, first_device_);
- registry_->OnDiscoveryFinished(nullptr);
-
- registry_->OnNetworkChanged(net::NetworkChangeNotifier::CONNECTION_NONE);
-
- registry_->OnDiscoveryRequest(nullptr);
- registry_->OnDiscoveryFinished(nullptr);
- registry_->OnListenerRemoved();
-}
-
-TEST_F(DialRegistryTest, TestNetworkEventConnectionRestored) {
- DialRegistry::DeviceList expected_list3;
- expected_list3.push_back(second_device_);
- expected_list3.push_back(third_device_);
-
- // A disconnection should shutdown the DialService, so we expect the observer
- // to be added twice.
- EXPECT_CALL(registry_->mock_service(),
- AddObserver(A<DialService::Observer*>()))
- .Times(2);
- EXPECT_CALL(registry_->mock_service(),
- RemoveObserver(A<DialService::Observer*>()))
- .Times(2);
-
- InSequence s;
- EXPECT_CALL(registry_->mock_service(), Discover());
- EXPECT_CALL(mock_observer_, OnDialDeviceEvent(empty_list_));
- EXPECT_CALL(mock_observer_, OnDialDeviceEvent(list_with_first_device_));
-
- EXPECT_CALL(mock_observer_,
- OnDialError(DialRegistry::DIAL_NETWORK_DISCONNECTED));
- EXPECT_CALL(mock_observer_, OnDialDeviceEvent(empty_list_));
-
- EXPECT_CALL(registry_->mock_service(), Discover());
- EXPECT_CALL(mock_observer_, OnDialDeviceEvent(list_with_second_device_));
- EXPECT_CALL(mock_observer_, OnDialDeviceEvent(expected_list3));
-
- registry_->OnListenerAdded();
- registry_->OnDiscoveryRequest(nullptr);
- registry_->OnDeviceDiscovered(nullptr, first_device_);
- registry_->OnDiscoveryFinished(nullptr);
-
- registry_->OnNetworkChanged(net::NetworkChangeNotifier::CONNECTION_NONE);
-
- registry_->OnDiscoveryRequest(nullptr);
- registry_->OnDiscoveryFinished(nullptr);
-
- registry_->OnNetworkChanged(net::NetworkChangeNotifier::CONNECTION_WIFI);
-
- registry_->OnDiscoveryRequest(nullptr);
- registry_->OnDeviceDiscovered(nullptr, second_device_);
- registry_->OnDiscoveryFinished(nullptr);
-
- registry_->OnNetworkChanged(net::NetworkChangeNotifier::CONNECTION_ETHERNET);
-
- registry_->OnDiscoveryRequest(nullptr);
- registry_->OnDeviceDiscovered(nullptr, third_device_);
- registry_->OnDiscoveryFinished(nullptr);
-
- registry_->OnListenerRemoved();
-}
-
-} // namespace dial
-} // namespace api
-} // namespace extensions
diff --git a/chrome/browser/extensions/api/dial/dial_service.cc b/chrome/browser/extensions/api/dial/dial_service.cc
deleted file mode 100644
index 679b6b0d..0000000
--- a/chrome/browser/extensions/api/dial/dial_service.cc
+++ /dev/null
@@ -1,626 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/extensions/api/dial/dial_service.h"
-
-#include <stdint.h>
-
-#include <algorithm>
-#include <set>
-#include <utility>
-
-#include "base/callback.h"
-#include "base/location.h"
-#include "base/logging.h"
-#include "base/memory/ptr_util.h"
-#include "base/rand_util.h"
-#include "base/single_thread_task_runner.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/stringprintf.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/time/time.h"
-#include "build/build_config.h"
-#include "chrome/browser/extensions/api/dial/dial_device_data.h"
-#include "components/version_info/version_info.h"
-#include "content/public/browser/browser_thread.h"
-#include "net/base/address_family.h"
-#include "net/base/completion_callback.h"
-#include "net/base/io_buffer.h"
-#include "net/base/ip_endpoint.h"
-#include "net/base/net_errors.h"
-#include "net/base/network_interfaces.h"
-#include "net/http/http_response_headers.h"
-#include "net/http/http_util.h"
-#include "net/log/net_log.h"
-#include "net/log/net_log_source_type.h"
-#include "url/gurl.h"
-
-#if defined(OS_CHROMEOS)
-#include "chromeos/network/network_state.h"
-#include "chromeos/network/network_state_handler.h"
-#include "third_party/cros_system_api/dbus/service_constants.h"
-#endif
-
-using base::Time;
-using base::TimeDelta;
-using content::BrowserThread;
-using net::HttpResponseHeaders;
-using net::HttpUtil;
-using net::IOBufferWithSize;
-using net::IPAddress;
-using net::NetworkInterface;
-using net::NetworkInterfaceList;
-using net::StringIOBuffer;
-using net::UDPSocket;
-
-namespace extensions {
-namespace api {
-namespace dial {
-
-namespace {
-
-// The total number of requests to make per discovery cycle.
-const int kDialMaxRequests = 4;
-
-// The interval to wait between successive requests.
-const int kDialRequestIntervalMillis = 1000;
-
-// The maximum delay a device may wait before responding (MX).
-const int kDialMaxResponseDelaySecs = 1;
-
-// The maximum time a response is expected after a M-SEARCH request.
-const int kDialResponseTimeoutSecs = 2;
-
-// The multicast IP address for discovery.
-const char kDialRequestAddress[] = "239.255.255.250";
-
-// The UDP port number for discovery.
-const uint16_t kDialRequestPort = 1900;
-
-// The DIAL service type as part of the search request.
-const char kDialSearchType[] = "urn:dial-multiscreen-org:service:dial:1";
-
-// SSDP headers parsed from the response.
-const char kSsdpLocationHeader[] = "LOCATION";
-const char kSsdpCacheControlHeader[] = "CACHE-CONTROL";
-const char kSsdpConfigIdHeader[] = "CONFIGID.UPNP.ORG";
-const char kSsdpUsnHeader[] = "USN";
-
-// The receive buffer size, in bytes.
-const int kDialRecvBufferSize = 1500;
-
-// Gets a specific header from |headers| and puts it in |value|.
-bool GetHeader(HttpResponseHeaders* headers, const char* name,
- std::string* value) {
- return headers->EnumerateHeader(nullptr, std::string(name), value);
-}
-
-// Returns the request string.
-std::string BuildRequest() {
- // Extra line at the end to make UPnP lib happy.
- std::string request(base::StringPrintf(
- "M-SEARCH * HTTP/1.1\r\n"
- "HOST: %s:%u\r\n"
- "MAN: \"ssdp:discover\"\r\n"
- "MX: %d\r\n"
- "ST: %s\r\n"
- "USER-AGENT: %s/%s %s\r\n"
- "\r\n",
- kDialRequestAddress,
- kDialRequestPort,
- kDialMaxResponseDelaySecs,
- kDialSearchType,
- version_info::GetProductName().c_str(),
- version_info::GetVersionNumber().c_str(),
- version_info::GetOSType().c_str()));
- // 1500 is a good MTU value for most Ethernet LANs.
- DCHECK_LE(request.size(), 1500U);
- return request;
-}
-
-#if defined(OS_CHROMEOS)
-// Finds the IP address of the preferred interface of network type |type|
-// to bind the socket and inserts the address into |bind_address_list|. This
-// ChromeOS version can prioritize wifi and ethernet interfaces.
-void InsertBestBindAddressChromeOS(const chromeos::NetworkTypePattern& type,
- net::IPAddressList* bind_address_list) {
- const chromeos::NetworkState* state = chromeos::NetworkHandler::Get()
- ->network_state_handler()->ConnectedNetworkByType(type);
- IPAddress bind_ip_address;
- if (state && bind_ip_address.AssignFromIPLiteral(state->ip_address()) &&
- bind_ip_address.IsIPv4()) {
- VLOG(2) << "Found " << state->type() << ", " << state->name() << ": "
- << state->ip_address();
- bind_address_list->push_back(bind_ip_address);
- }
-}
-#else
-NetworkInterfaceList GetNetworkListOnFileThread() {
- NetworkInterfaceList list;
- bool success =
- net::GetNetworkList(&list, net::INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES);
- if (!success)
- VLOG(1) << "Could not retrieve network list!";
- return list;
-}
-#endif // defined(OS_CHROMEOS)
-
-} // namespace
-
-DialServiceImpl::DialSocket::DialSocket(
- const base::Closure& discovery_request_cb,
- const base::Callback<void(const DialDeviceData&)>& device_discovered_cb,
- const base::Closure& on_error_cb)
- : discovery_request_cb_(discovery_request_cb),
- device_discovered_cb_(device_discovered_cb),
- on_error_cb_(on_error_cb),
- is_writing_(false),
- is_reading_(false) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-}
-
-DialServiceImpl::DialSocket::~DialSocket() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-}
-
-bool DialServiceImpl::DialSocket::CreateAndBindSocket(
- const IPAddress& bind_ip_address,
- net::NetLog* net_log,
- net::NetLogSource net_log_source) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK(!socket_);
- DCHECK(bind_ip_address.IsIPv4());
-
- net::RandIntCallback rand_cb = base::Bind(&base::RandInt);
- socket_ = base::MakeUnique<UDPSocket>(net::DatagramSocket::RANDOM_BIND,
- rand_cb, net_log, net_log_source);
-
- // 0 means bind a random port
- net::IPEndPoint address(bind_ip_address, 0);
-
- if (socket_->Open(address.GetFamily()) != net::OK ||
- socket_->SetBroadcast(true) != net::OK ||
- !CheckResult("Bind", socket_->Bind(address))) {
- socket_.reset();
- return false;
- }
-
- recv_buffer_ = new IOBufferWithSize(kDialRecvBufferSize);
- return ReadSocket();
-}
-
-void DialServiceImpl::DialSocket::SendOneRequest(
- const net::IPEndPoint& send_address,
- const scoped_refptr<net::StringIOBuffer>& send_buffer) {
- if (!socket_) {
- VLOG(1) << "Socket not connected.";
- return;
- }
-
- if (is_writing_) {
- VLOG(1) << "Already writing.";
- return;
- }
-
- is_writing_ = true;
- int result = socket_->SendTo(
- send_buffer.get(), send_buffer->size(), send_address,
- base::Bind(&DialServiceImpl::DialSocket::OnSocketWrite,
- base::Unretained(this),
- send_buffer->size()));
- bool result_ok = CheckResult("SendTo", result);
- if (result_ok && result > 0) {
- // Synchronous write.
- OnSocketWrite(send_buffer->size(), result);
- }
-}
-
-bool DialServiceImpl::DialSocket::IsClosed() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- return !socket_;
-}
-
-bool DialServiceImpl::DialSocket::CheckResult(const char* operation,
- int result) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- VLOG(2) << "Operation " << operation << " result " << result;
- if (result < net::OK && result != net::ERR_IO_PENDING) {
- Close();
- std::string error_str(net::ErrorToString(result));
- VLOG(1) << "dial socket error: " << error_str;
- on_error_cb_.Run();
- return false;
- }
- return true;
-}
-
-void DialServiceImpl::DialSocket::Close() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- is_reading_ = false;
- is_writing_ = false;
- socket_.reset();
-}
-
-void DialServiceImpl::DialSocket::OnSocketWrite(int send_buffer_size,
- int result) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- is_writing_ = false;
- if (!CheckResult("OnSocketWrite", result))
- return;
- if (result != send_buffer_size) {
- VLOG(1) << "Sent " << result << " chars, expected "
- << send_buffer_size << " chars";
- }
- discovery_request_cb_.Run();
-}
-
-bool DialServiceImpl::DialSocket::ReadSocket() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (!socket_) {
- VLOG(1) << "Socket not connected.";
- return false;
- }
-
- if (is_reading_) {
- VLOG(1) << "Already reading.";
- return false;
- }
-
- int result = net::OK;
- bool result_ok = true;
- do {
- is_reading_ = true;
- result = socket_->RecvFrom(
- recv_buffer_.get(),
- kDialRecvBufferSize, &recv_address_,
- base::Bind(&DialServiceImpl::DialSocket::OnSocketRead,
- base::Unretained(this)));
- result_ok = CheckResult("RecvFrom", result);
- if (result != net::ERR_IO_PENDING)
- is_reading_ = false;
- if (result_ok && result > 0) {
- // Synchronous read.
- HandleResponse(result);
- }
- } while (result_ok && result != net::OK && result != net::ERR_IO_PENDING);
- return result_ok;
-}
-
-void DialServiceImpl::DialSocket::OnSocketRead(int result) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- is_reading_ = false;
- if (!CheckResult("OnSocketRead", result))
- return;
- if (result > 0)
- HandleResponse(result);
-
- // Await next response.
- ReadSocket();
-}
-
-void DialServiceImpl::DialSocket::HandleResponse(int bytes_read) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK_GT(bytes_read, 0);
- if (bytes_read > kDialRecvBufferSize) {
- VLOG(1) << bytes_read << " > " << kDialRecvBufferSize << "!?";
- return;
- }
- VLOG(2) << "Read " << bytes_read << " bytes from "
- << recv_address_.ToString();
-
- std::string response(recv_buffer_->data(), bytes_read);
- Time response_time = Time::Now();
-
- // Attempt to parse response, notify observers if successful.
- DialDeviceData parsed_device;
- if (ParseResponse(response, response_time, &parsed_device))
- device_discovered_cb_.Run(parsed_device);
-}
-
-// static
-bool DialServiceImpl::DialSocket::ParseResponse(
- const std::string& response,
- const base::Time& response_time,
- DialDeviceData* device) {
- int headers_end = HttpUtil::LocateEndOfHeaders(response.c_str(),
- response.size());
- if (headers_end < 1) {
- VLOG(1) << "Headers invalid or empty, ignoring: " << response;
- return false;
- }
- std::string raw_headers =
- HttpUtil::AssembleRawHeaders(response.c_str(), headers_end);
- VLOG(3) << "raw_headers: " << raw_headers << "\n";
- scoped_refptr<HttpResponseHeaders> headers =
- new HttpResponseHeaders(raw_headers);
-
- std::string device_url_str;
- if (!GetHeader(headers.get(), kSsdpLocationHeader, &device_url_str) ||
- device_url_str.empty()) {
- VLOG(1) << "No LOCATION header found.";
- return false;
- }
-
- GURL device_url(device_url_str);
- if (!DialDeviceData::IsDeviceDescriptionUrl(device_url)) {
- VLOG(1) << "URL " << device_url_str << " not valid.";
- return false;
- }
-
- std::string device_id;
- if (!GetHeader(headers.get(), kSsdpUsnHeader, &device_id) ||
- device_id.empty()) {
- VLOG(1) << "No USN header found.";
- return false;
- }
-
- device->set_device_id(device_id);
- device->set_device_description_url(device_url);
- device->set_response_time(response_time);
-
- // TODO(mfoltz): Parse the max-age value from the cache control header.
- // http://crbug.com/165289
- std::string cache_control;
- GetHeader(headers.get(), kSsdpCacheControlHeader, &cache_control);
-
- std::string config_id;
- int config_id_int;
- if (GetHeader(headers.get(), kSsdpConfigIdHeader, &config_id) &&
- base::StringToInt(config_id, &config_id_int)) {
- device->set_config_id(config_id_int);
- } else {
- VLOG(1) << "Malformed or missing " << kSsdpConfigIdHeader << ": "
- << config_id;
- }
-
- return true;
-}
-
-DialServiceImpl::DialServiceImpl(net::NetLog* net_log)
- : net_log_(net_log),
- discovery_active_(false),
- num_requests_sent_(0),
- max_requests_(kDialMaxRequests),
- finish_delay_(TimeDelta::FromMilliseconds((kDialMaxRequests - 1) *
- kDialRequestIntervalMillis) +
- TimeDelta::FromSeconds(kDialResponseTimeoutSecs)),
- request_interval_(
- TimeDelta::FromMilliseconds(kDialRequestIntervalMillis)),
- weak_factory_(this) {
- IPAddress address;
- bool success = address.AssignFromIPLiteral(kDialRequestAddress);
- DCHECK(success);
- send_address_ = net::IPEndPoint(address, kDialRequestPort);
- send_buffer_ = new StringIOBuffer(BuildRequest());
- net_log_source_.type = net::NetLogSourceType::UDP_SOCKET;
- net_log_source_.id = net_log_->NextID();
-}
-
-DialServiceImpl::~DialServiceImpl() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-}
-
-void DialServiceImpl::AddObserver(Observer* observer) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- observer_list_.AddObserver(observer);
-}
-
-void DialServiceImpl::RemoveObserver(Observer* observer) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- observer_list_.RemoveObserver(observer);
-}
-
-bool DialServiceImpl::HasObserver(const Observer* observer) const {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- return observer_list_.HasObserver(observer);
-}
-
-bool DialServiceImpl::Discover() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (discovery_active_) {
- VLOG(2) << "Discovery is already active - returning.";
- return false;
- }
- discovery_active_ = true;
-
- VLOG(2) << "Discovery started.";
-
- StartDiscovery();
- return true;
-}
-
-void DialServiceImpl::StartDiscovery() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK(discovery_active_);
- if (HasOpenSockets()) {
- VLOG(2) << "Calling StartDiscovery() with open sockets. Returning.";
- return;
- }
-
-#if defined(OS_CHROMEOS)
- // The ChromeOS specific version of getting network interfaces does not
- // require trampolining to another thread, and contains additional interface
- // information such as interface types (i.e. wifi vs cellular).
- net::IPAddressList chrome_os_address_list;
- InsertBestBindAddressChromeOS(chromeos::NetworkTypePattern::Ethernet(),
- &chrome_os_address_list);
- InsertBestBindAddressChromeOS(chromeos::NetworkTypePattern::WiFi(),
- &chrome_os_address_list);
- DiscoverOnAddresses(chrome_os_address_list);
-
-#else
- BrowserThread::PostTaskAndReplyWithResult(
- BrowserThread::FILE, FROM_HERE, base::Bind(&GetNetworkListOnFileThread),
- base::Bind(&DialServiceImpl::SendNetworkList,
- weak_factory_.GetWeakPtr()));
-#endif
-}
-
-void DialServiceImpl::SendNetworkList(const NetworkInterfaceList& networks) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- using InterfaceIndexAddressFamily = std::pair<uint32_t, net::AddressFamily>;
- std::set<InterfaceIndexAddressFamily> interface_index_addr_family_seen;
- net::IPAddressList ip_addresses;
-
- // Binds a socket to each IPv4 network interface found. Note that
- // there may be duplicates in |networks|, so address family + interface index
- // is used to identify unique interfaces.
- // TODO(mfoltz): Support IPV6 multicast. http://crbug.com/165286
- for (NetworkInterfaceList::const_iterator iter = networks.begin();
- iter != networks.end(); ++iter) {
- net::AddressFamily addr_family = net::GetAddressFamily(iter->address);
- VLOG(2) << "Found " << iter->name << ", " << iter->address.ToString()
- << ", address family: " << addr_family;
- if (addr_family == net::ADDRESS_FAMILY_IPV4) {
- InterfaceIndexAddressFamily interface_index_addr_family =
- std::make_pair(iter->interface_index, addr_family);
- bool inserted = interface_index_addr_family_seen
- .insert(interface_index_addr_family)
- .second;
- // We have not seen this interface before, so add its IP address to the
- // discovery list.
- if (inserted) {
- VLOG(2) << "Encountered "
- << "interface index: " << iter->interface_index << ", "
- << "address family: " << addr_family << " for the first time, "
- << "adding IP address " << iter->address.ToString()
- << " to list.";
- ip_addresses.push_back(iter->address);
- } else {
- VLOG(2) << "Already encountered "
- << "interface index: " << iter->interface_index << ", "
- << "address family: " << addr_family << " before, not adding.";
- }
- }
- }
-
- DiscoverOnAddresses(ip_addresses);
-}
-
-void DialServiceImpl::DiscoverOnAddresses(
- const net::IPAddressList& ip_addresses) {
- if (ip_addresses.empty()) {
- VLOG(1) << "Could not find a valid interface to bind. Finishing discovery";
- FinishDiscovery();
- return;
- }
-
- // Schedule a timer to finish the discovery process (and close the sockets).
- if (finish_delay_ > TimeDelta::FromSeconds(0)) {
- VLOG(2) << "Starting timer to finish discovery.";
- finish_timer_.Start(FROM_HERE,
- finish_delay_,
- this,
- &DialServiceImpl::FinishDiscovery);
- }
-
- for (const auto& address : ip_addresses) {
- BindAndAddSocket(address);
- }
-
- SendOneRequest();
-}
-
-void DialServiceImpl::BindAndAddSocket(const IPAddress& bind_ip_address) {
- std::unique_ptr<DialServiceImpl::DialSocket> dial_socket(CreateDialSocket());
- if (dial_socket->CreateAndBindSocket(bind_ip_address, net_log_,
- net_log_source_))
- dial_sockets_.push_back(std::move(dial_socket));
-}
-
-std::unique_ptr<DialServiceImpl::DialSocket>
-DialServiceImpl::CreateDialSocket() {
- return base::MakeUnique<DialServiceImpl::DialSocket>(
- base::Bind(&DialServiceImpl::NotifyOnDiscoveryRequest,
- weak_factory_.GetWeakPtr()),
- base::Bind(&DialServiceImpl::NotifyOnDeviceDiscovered,
- weak_factory_.GetWeakPtr()),
- base::Bind(&DialServiceImpl::NotifyOnError, weak_factory_.GetWeakPtr()));
-}
-
-void DialServiceImpl::SendOneRequest() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (num_requests_sent_ == max_requests_) {
- VLOG(2) << "Reached max requests; stopping request timer.";
- request_timer_.Stop();
- return;
- }
- num_requests_sent_++;
- VLOG(2) << "Sending request " << num_requests_sent_ << "/"
- << max_requests_;
- for (const auto& socket : dial_sockets_) {
- if (!socket->IsClosed())
- socket->SendOneRequest(send_address_, send_buffer_);
- }
-}
-
-void DialServiceImpl::NotifyOnDiscoveryRequest() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- // If discovery is inactive, no reason to notify observers.
- if (!discovery_active_) {
- VLOG(2) << "Request sent after discovery finished. Ignoring.";
- return;
- }
-
- VLOG(2) << "Notifying observers of discovery request";
- for (auto& observer : observer_list_)
- observer.OnDiscoveryRequest(this);
- // If we need to send additional requests, schedule a timer to do so.
- if (num_requests_sent_ < max_requests_ && num_requests_sent_ == 1) {
- VLOG(2) << "Scheduling timer to send additional requests";
- // TODO(imcheng): Move this to SendOneRequest() once the implications are
- // understood.
- request_timer_.Start(FROM_HERE,
- request_interval_,
- this,
- &DialServiceImpl::SendOneRequest);
- }
-}
-
-void DialServiceImpl::NotifyOnDeviceDiscovered(
- const DialDeviceData& device_data) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (!discovery_active_) {
- VLOG(2) << "Got response after discovery finished. Ignoring.";
- return;
- }
- for (auto& observer : observer_list_)
- observer.OnDeviceDiscovered(this, device_data);
-}
-
-void DialServiceImpl::NotifyOnError() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- // TODO(imcheng): Modify upstream so that the device list is not cleared
- // when it could still potentially discover devices on other sockets.
- for (auto& observer : observer_list_) {
- observer.OnError(this, HasOpenSockets() ? DIAL_SERVICE_SOCKET_ERROR
- : DIAL_SERVICE_NO_INTERFACES);
- }
-}
-
-void DialServiceImpl::FinishDiscovery() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK(discovery_active_);
- VLOG(2) << "Discovery finished.";
- // Close all open sockets.
- dial_sockets_.clear();
- finish_timer_.Stop();
- request_timer_.Stop();
- discovery_active_ = false;
- num_requests_sent_ = 0;
- for (auto& observer : observer_list_)
- observer.OnDiscoveryFinished(this);
-}
-
-bool DialServiceImpl::HasOpenSockets() {
- for (const auto& socket : dial_sockets_) {
- if (!socket->IsClosed())
- return true;
- }
- return false;
-}
-
-} // namespace dial
-} // namespace api
-} // namespace extensions
diff --git a/chrome/browser/extensions/api/dial/dial_service.h b/chrome/browser/extensions/api/dial/dial_service.h
deleted file mode 100644
index dfe56c19..0000000
--- a/chrome/browser/extensions/api/dial/dial_service.h
+++ /dev/null
@@ -1,299 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_EXTENSIONS_API_DIAL_DIAL_SERVICE_H_
-#define CHROME_BROWSER_EXTENSIONS_API_DIAL_DIAL_SERVICE_H_
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/gtest_prod_util.h"
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "base/observer_list.h"
-#include "base/timer/timer.h"
-#include "net/base/ip_address.h"
-#include "net/log/net_log_source.h"
-#include "net/socket/udp_socket.h"
-
-namespace net {
-class IPEndPoint;
-class StringIOBuffer;
-class NetLog;
-}
-
-namespace extensions {
-namespace api {
-namespace dial {
-
-class DialDeviceData;
-
-// DialService accepts requests to discover devices, sends multiple M-SEARCH
-// requests via UDP multicast, and notifies observers when a DIAL-compliant
-// device responds.
-//
-// Each time Discover() is called, kDialNumRequests M-SEARCH requests are sent
-// (with a delay of kDialRequestIntervalMillis in between):
-//
-// Time Action
-// ---- ------
-// T1 Request 1 sent, OnDiscoveryReqest() called
-// ...
-// Tk Request kDialNumRequests sent, OnDiscoveryReqest() called
-// Tf OnDiscoveryFinished() called
-//
-// Any time a valid response is received between T1 and Tf, it is parsed and
-// OnDeviceDiscovered() is called with the result. Tf is set to Tk +
-// kDialResponseTimeoutSecs (the response timeout passed in each request).
-//
-// Calling Discover() again between T1 and Tf has no effect.
-//
-// All relevant constants are defined in dial_service.cc.
-class DialService {
- public:
- enum DialServiceErrorCode {
- DIAL_SERVICE_NO_INTERFACES = 0,
- DIAL_SERVICE_SOCKET_ERROR
- };
-
- class Observer {
- public:
- // Called when a single discovery request was sent.
- virtual void OnDiscoveryRequest(DialService* service) = 0;
-
- // Called when a device responds to a request.
- virtual void OnDeviceDiscovered(DialService* service,
- const DialDeviceData& device) = 0;
-
- // Called when we have all responses from the last discovery request.
- virtual void OnDiscoveryFinished(DialService* service) = 0;
-
- // Called when an error occurs.
- virtual void OnError(DialService* service,
- const DialServiceErrorCode& code) = 0;
-
- protected:
- virtual ~Observer() {}
- };
-
- virtual ~DialService() {}
-
- // Starts a new round of discovery. Returns |true| if discovery was started
- // successfully or there is already one active. Returns |false| on error.
- virtual bool Discover() = 0;
-
- // Called by listeners to this service to add/remove themselves as observers.
- virtual void AddObserver(Observer* observer) = 0;
- virtual void RemoveObserver(Observer* observer) = 0;
- virtual bool HasObserver(const Observer* observer) const = 0;
-};
-
-// Implements DialService.
-//
-// NOTE(mfoltz): It would make this class cleaner to refactor most of the state
-// associated with a single discovery cycle into its own |DiscoveryOperation|
-// object. This would also simplify lifetime of the object w.r.t. DialRegistry;
-// the Registry would not need to create/destroy the Service on demand.
-// DialServiceImpl lives on the IO thread.
-class DialServiceImpl : public DialService {
- public:
- explicit DialServiceImpl(net::NetLog* net_log);
- ~DialServiceImpl() override;
-
- // DialService implementation
- bool Discover() override;
- void AddObserver(Observer* observer) override;
- void RemoveObserver(Observer* observer) override;
- bool HasObserver(const Observer* observer) const override;
-
- private:
- // Represents a socket binding to a single network interface.
- // DialSocket lives on the IO thread.
- class DialSocket {
- public:
- // TODO(imcheng): Consider writing a DialSocket::Delegate interface that
- // declares methods for these callbacks, and taking a ptr to the delegate
- // here.
- DialSocket(
- const base::Closure& discovery_request_cb,
- const base::Callback<void(const DialDeviceData&)>& device_discovered_cb,
- const base::Closure& on_error_cb);
- ~DialSocket();
-
- // Creates a socket using |net_log| and |net_log_source| and binds it to
- // |bind_ip_address|.
- bool CreateAndBindSocket(const net::IPAddress& bind_ip_address,
- net::NetLog* net_log,
- net::NetLogSource net_log_source);
-
- // Sends a single discovery request |send_buffer| to |send_address|
- // over the socket.
- void SendOneRequest(const net::IPEndPoint& send_address,
- const scoped_refptr<net::StringIOBuffer>& send_buffer);
-
- // Returns true if the socket is closed.
- bool IsClosed();
-
- private:
- // Checks the result of a socket operation. The name of the socket
- // operation is given by |operation| and the result of the operation is
- // given by |result|. If the result is an error, closes the socket,
- // calls |on_error_cb_|, and returns |false|. Returns
- // |true| otherwise. |operation| and |result| are logged.
- bool CheckResult(const char* operation, int result);
-
- // Closes the socket.
- void Close();
-
- // Callback invoked for socket writes.
- void OnSocketWrite(int buffer_size, int result);
-
- // Establishes the callback to read from the socket. Returns true if
- // successful.
- bool ReadSocket();
-
- // Callback invoked for socket reads.
- void OnSocketRead(int result);
-
- // Callback invoked for socket reads.
- void HandleResponse(int bytes_read);
-
- // Parses a response into a DialDeviceData object. If the DIAL response is
- // invalid or does not contain enough information, then the return
- // value will be false and |device| is not changed.
- static bool ParseResponse(const std::string& response,
- const base::Time& response_time,
- DialDeviceData* device);
-
- // The UDP socket.
- std::unique_ptr<net::UDPSocket> socket_;
-
- // Buffer for socket reads.
- scoped_refptr<net::IOBufferWithSize> recv_buffer_;
-
- // The source of of the last socket read.
- net::IPEndPoint recv_address_;
-
- // The callback to be invoked when a discovery request was made.
- base::Closure discovery_request_cb_;
-
- // The callback to be invoked when a device has been discovered.
- base::Callback<void(const DialDeviceData&)> device_discovered_cb_;
-
- // The callback to be invoked when there is an error with socket operations.
- base::Closure on_error_cb_;
-
- // Marks whether there is an active write callback.
- bool is_writing_;
-
- // Marks whether there is an active read callback.
- bool is_reading_;
-
- FRIEND_TEST_ALL_PREFIXES(DialServiceTest, TestNotifyOnError);
- FRIEND_TEST_ALL_PREFIXES(DialServiceTest, TestOnDeviceDiscovered);
- FRIEND_TEST_ALL_PREFIXES(DialServiceTest, TestOnDiscoveryRequest);
- FRIEND_TEST_ALL_PREFIXES(DialServiceTest, TestResponseParsing);
- DISALLOW_COPY_AND_ASSIGN(DialSocket);
- };
-
- // Starts the control flow for one discovery cycle.
- void StartDiscovery();
-
- // For each network interface in |list|, finds all unqiue IPv4 network
- // interfaces and call |DiscoverOnAddresses()| with their IP addresses.
- void SendNetworkList(const net::NetworkInterfaceList& list);
-
- // Calls |BindAndAddSocket()| for each address in |ip_addresses|, calls
- // |SendOneRequest()|, and start the timer to finish discovery if needed.
- // The (Address family, interface index) of each address in |ip_addresses|
- // must be unique. If |ip_address| is empty, calls |FinishDiscovery()|.
- void DiscoverOnAddresses(const net::IPAddressList& ip_addresses);
-
- // Creates a DialSocket, binds it to |bind_ip_address| and if
- // successful, add the DialSocket to |dial_sockets_|.
- void BindAndAddSocket(const net::IPAddress& bind_ip_address);
-
- // Creates a DialSocket with callbacks to this object.
- std::unique_ptr<DialSocket> CreateDialSocket();
-
- // Sends a single discovery request to every socket that are currently open.
- void SendOneRequest();
-
- // Notify observers that a discovery request was made.
- void NotifyOnDiscoveryRequest();
-
- // Notify observers a device has been discovered.
- void NotifyOnDeviceDiscovered(const DialDeviceData& device_data);
-
- // Notify observers that there has been an error with one of the DialSockets.
- void NotifyOnError();
-
- // Called from finish_timer_ when we are done with the current round of
- // discovery.
- void FinishDiscovery();
-
- // Returns |true| if there are open sockets.
- bool HasOpenSockets();
-
- // DialSockets for each network interface whose ip address was
- // successfully bound.
- std::vector<std::unique_ptr<DialSocket>> dial_sockets_;
-
- // The NetLog for this service.
- net::NetLog* const net_log_;
-
- // The NetLog source for this service.
- net::NetLogSource net_log_source_;
-
- // The multicast address:port for search requests.
- net::IPEndPoint send_address_;
-
- // Buffer for socket writes.
- scoped_refptr<net::StringIOBuffer> send_buffer_;
-
- // True when we are currently doing discovery.
- bool discovery_active_;
-
- // The number of requests that have been sent in the current discovery.
- int num_requests_sent_;
-
- // The maximum number of requests to send per discovery cycle.
- int max_requests_;
-
- // Timer for finishing discovery.
- base::OneShotTimer finish_timer_;
-
- // The delay for |finish_timer_|; how long to wait for discovery to finish.
- // Setting this to zero disables the timer.
- base::TimeDelta finish_delay_;
-
- // Timer for sending multiple requests at fixed intervals.
- base::RepeatingTimer request_timer_;
-
- // The delay for |request_timer_|; how long to wait between successive
- // requests.
- base::TimeDelta request_interval_;
-
- // List of observers.
- base::ObserverList<Observer> observer_list_;
-
- base::WeakPtrFactory<DialServiceImpl> weak_factory_;
-
- friend class DialServiceTest;
- FRIEND_TEST_ALL_PREFIXES(DialServiceTest, TestSendMultipleRequests);
- FRIEND_TEST_ALL_PREFIXES(DialServiceTest, TestMultipleNetworkInterfaces);
- FRIEND_TEST_ALL_PREFIXES(DialServiceTest, TestNotifyOnError);
- FRIEND_TEST_ALL_PREFIXES(DialServiceTest, TestOnDeviceDiscovered);
- FRIEND_TEST_ALL_PREFIXES(DialServiceTest, TestOnDiscoveryFinished);
- FRIEND_TEST_ALL_PREFIXES(DialServiceTest, TestOnDiscoveryRequest);
- FRIEND_TEST_ALL_PREFIXES(DialServiceTest, TestResponseParsing);
- DISALLOW_COPY_AND_ASSIGN(DialServiceImpl);
-};
-
-} // namespace dial
-} // namespace api
-} // namespace extensions
-
-#endif // CHROME_BROWSER_EXTENSIONS_API_DIAL_DIAL_SERVICE_H_
diff --git a/chrome/browser/extensions/api/dial/dial_service_unittest.cc b/chrome/browser/extensions/api/dial/dial_service_unittest.cc
deleted file mode 100644
index 9c46751..0000000
--- a/chrome/browser/extensions/api/dial/dial_service_unittest.cc
+++ /dev/null
@@ -1,239 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/extensions/api/dial/dial_service.h"
-
-#include <stddef.h>
-
-#include <memory>
-
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/run_loop.h"
-#include "chrome/browser/extensions/api/dial/dial_device_data.h"
-#include "content/public/test/test_browser_thread_bundle.h"
-#include "net/base/ip_address.h"
-#include "net/base/ip_endpoint.h"
-#include "net/base/network_interfaces.h"
-#include "net/log/test_net_log.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using base::Time;
-using base::TimeDelta;
-using ::testing::A;
-using ::testing::AtLeast;
-using ::testing::Return;
-
-namespace {
-
-const char kValidResponse[] =
- "HTTP/1.1 OK\r\n"
- "LOCATION: http://127.0.0.1/dd.xml\r\n"
- "USN: some_id\r\n"
- "CACHE-CONTROL: max-age=1800\r\n"
- "CONFIGID.UPNP.ORG: 1\r\n\r\n";
-
-} // namespace
-
-namespace extensions {
-namespace api {
-namespace dial {
-
-class MockObserver : public DialService::Observer {
- public:
- ~MockObserver() override {}
-
- MOCK_METHOD1(OnDiscoveryRequest, void(DialService*));
- MOCK_METHOD2(OnDeviceDiscovered, void(DialService*, const DialDeviceData&));
- MOCK_METHOD1(OnDiscoveryFinished, void(DialService*));
- MOCK_METHOD2(OnError, void(DialService*,
- const DialService::DialServiceErrorCode&));
-};
-
-class DialServiceTest : public testing::Test {
- public:
- DialServiceTest()
- : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
- mock_ip_(net::IPAddress::IPv4AllZeros()),
- dial_service_(&test_net_log_) {
- dial_service_.AddObserver(&mock_observer_);
- dial_socket_ = dial_service_.CreateDialSocket();
- }
- protected:
- content::TestBrowserThreadBundle thread_bundle_;
- net::TestNetLog test_net_log_;
- net::IPAddress mock_ip_;
- DialServiceImpl dial_service_;
- std::unique_ptr<DialServiceImpl::DialSocket> dial_socket_;
- MockObserver mock_observer_;
-};
-
-TEST_F(DialServiceTest, TestSendMultipleRequests) {
- // Setting the finish delay to zero disables the timer that invokes
- // FinishDiscovery().
- dial_service_.finish_delay_ = TimeDelta::FromSeconds(0);
- dial_service_.request_interval_ = TimeDelta::FromSeconds(0);
- dial_service_.max_requests_ = 4;
- dial_service_.discovery_active_ = true;
- EXPECT_CALL(mock_observer_, OnDiscoveryRequest(A<DialService*>())).Times(4);
- EXPECT_CALL(mock_observer_, OnDiscoveryFinished(A<DialService*>())).Times(1);
- dial_service_.BindAndAddSocket(mock_ip_);
- EXPECT_EQ(1u, dial_service_.dial_sockets_.size());
- dial_service_.SendOneRequest();
- base::RunLoop().RunUntilIdle();
- dial_service_.FinishDiscovery();
-}
-
-TEST_F(DialServiceTest, TestMultipleNetworkInterfaces) {
- // Setting the finish delay to zero disables the timer that invokes
- // FinishDiscovery().
- dial_service_.finish_delay_ = TimeDelta::FromSeconds(0);
- dial_service_.request_interval_ = TimeDelta::FromSeconds(0);
- dial_service_.max_requests_ = 4;
- dial_service_.discovery_active_ = true;
- net::NetworkInterfaceList interface_list;
- interface_list.push_back(
- net::NetworkInterface("network1",
- "network1",
- 0,
- net::NetworkChangeNotifier::CONNECTION_UNKNOWN,
- mock_ip_,
- 0,
- net::IP_ADDRESS_ATTRIBUTE_NONE));
- interface_list.push_back(
- net::NetworkInterface("network2",
- "network2",
- 1,
- net::NetworkChangeNotifier::CONNECTION_UNKNOWN,
- mock_ip_,
- 0,
- net::IP_ADDRESS_ATTRIBUTE_NONE));
- interface_list.push_back(
- net::NetworkInterface("network3",
- "network3",
- 2,
- net::NetworkChangeNotifier::CONNECTION_UNKNOWN,
- mock_ip_,
- 0,
- net::IP_ADDRESS_ATTRIBUTE_NONE));
-
- // "network4" is equivalent to "network2" because both the address family
- // and interface index are the same.
- interface_list.push_back(
- net::NetworkInterface("network4",
- "network4",
- 1,
- net::NetworkChangeNotifier::CONNECTION_UNKNOWN,
- mock_ip_,
- 0,
- net::IP_ADDRESS_ATTRIBUTE_NONE));
-
- // 3 sockets * 4 requests per socket = 12 requests
- EXPECT_CALL(mock_observer_, OnDiscoveryRequest(A<DialService*>())).Times(12);
- EXPECT_CALL(mock_observer_, OnDiscoveryFinished(A<DialService*>())).Times(1);
-
- dial_service_.SendNetworkList(interface_list);
- EXPECT_EQ(3u, dial_service_.dial_sockets_.size());
-
- base::RunLoop().RunUntilIdle();
- dial_service_.FinishDiscovery();
-}
-
-TEST_F(DialServiceTest, TestOnDiscoveryRequest) {
- dial_service_.discovery_active_ = true;
- dial_service_.num_requests_sent_ = 1;
- dial_service_.max_requests_ = 1;
- size_t num_bytes = dial_service_.send_buffer_->size();
- EXPECT_CALL(mock_observer_, OnDiscoveryRequest(A<DialService*>())).Times(1);
- dial_socket_->OnSocketWrite(num_bytes, num_bytes);
-}
-
-TEST_F(DialServiceTest, TestOnDeviceDiscovered) {
- dial_service_.discovery_active_ = true;
- int response_size = arraysize(kValidResponse) - 1;
- dial_socket_->recv_buffer_ =
- new net::IOBufferWithSize(response_size);
- strncpy(dial_socket_->recv_buffer_->data(),
- kValidResponse,
- response_size);
- dial_socket_->recv_address_ = net::IPEndPoint(mock_ip_, 12345);
-
- DialDeviceData expected_device;
- expected_device.set_device_id("some_id");
-
- EXPECT_CALL(mock_observer_,
- OnDeviceDiscovered(A<DialService*>(), expected_device))
- .Times(1);
- dial_socket_->OnSocketRead(response_size);
-}
-
-TEST_F(DialServiceTest, TestOnDiscoveryFinished) {
- dial_service_.discovery_active_ = true;
-
- EXPECT_CALL(mock_observer_, OnDiscoveryFinished(A<DialService*>())).Times(1);
- dial_service_.FinishDiscovery();
- EXPECT_FALSE(dial_service_.discovery_active_);
-}
-
-TEST_F(DialServiceTest, TestResponseParsing) {
- Time now = Time::Now();
-
- // Successful case
- DialDeviceData parsed;
- EXPECT_TRUE(DialServiceImpl::DialSocket::ParseResponse(
- kValidResponse, now, &parsed));
- EXPECT_EQ("some_id", parsed.device_id());
- EXPECT_EQ("http://127.0.0.1/dd.xml", parsed.device_description_url().spec());
- EXPECT_EQ(1, parsed.config_id());
- EXPECT_EQ(now, parsed.response_time());
-
- // Failure cases
- DialDeviceData not_parsed;
-
- // Empty, garbage
- EXPECT_FALSE(DialServiceImpl::DialSocket::ParseResponse(
- std::string(), now, ¬_parsed));
- EXPECT_FALSE(DialServiceImpl::DialSocket::ParseResponse(
- "\r\n\r\n",
- now, ¬_parsed));
- EXPECT_FALSE(DialServiceImpl::DialSocket::ParseResponse(
- "xyzzy",
- now, ¬_parsed));
-
- // No headers
- EXPECT_FALSE(DialServiceImpl::DialSocket::ParseResponse(
- "HTTP/1.1 OK\r\n\r\n",
- now, ¬_parsed));
-
- // Missing LOCATION
- EXPECT_FALSE(DialServiceImpl::DialSocket::ParseResponse(
- "HTTP/1.1 OK\r\n"
- "USN: some_id\r\n\r\n",
- now, ¬_parsed));
-
- // Empty LOCATION
- EXPECT_FALSE(DialServiceImpl::DialSocket::ParseResponse(
- "HTTP/1.1 OK\r\n"
- "LOCATION:\r\n"
- "USN: some_id\r\n\r\n",
- now, ¬_parsed));
-
- // Missing USN
- EXPECT_FALSE(DialServiceImpl::DialSocket::ParseResponse(
- "HTTP/1.1 OK\r\n"
- "LOCATION: http://127.0.0.1/dd.xml\r\n\r\n",
- now, ¬_parsed));
-
- // Empty USN
- EXPECT_FALSE(DialServiceImpl::DialSocket::ParseResponse(
- "HTTP/1.1 OK\r\n"
- "LOCATION: http://127.0.0.1/dd.xml\r\n"
- "USN:\r\n\r\n",
- now, ¬_parsed));
-}
-
-} // namespace dial
-} // namespace api
-} // namespace extensions