diff options
23 files changed, 669 insertions, 0 deletions
@@ -124,6 +124,13 @@ group("gn_all") { deps += [ "//ui/ozone" ] } + if (enable_media_router) { + deps += [ + "//chrome/browser/media/router/", + "//chrome/browser/media/router:unit_tests", + ] + } + if (is_win || is_mac || is_chromeos) { # RLZ works on these platforms. # TODO(GYP): Is this target needed, or pulled in automatically? diff --git a/chrome/browser/media/router/BUILD.gn b/chrome/browser/media/router/BUILD.gn new file mode 100644 index 0000000..81bc6a8 --- /dev/null +++ b/chrome/browser/media/router/BUILD.gn @@ -0,0 +1,52 @@ +# Copyright 2015 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. +# +import("//testing/test.gni") + +source_set("router") { + deps = [ + "//base", + "//url", + ] + sources = [ + "media_route.cc", + "media_route.h", + "media_route_id.h", + "media_sink.cc", + "media_sink.h", + "media_source.cc", + "media_source.h", + "media_source_helper.cc", + "media_source_helper.h", + "route_id_manager.cc", + "route_id_manager.h", + ] +} + +source_set("unit_tests") { + testonly = true + deps = [ + ":router", + "//base/test:test_support", + "//testing/gmock", + "//testing/gtest", + ] + sources = [ + "media_route_unittest.cc", + "media_sink_unittest.cc", + "media_source_unittest.cc", + "route_id_manager_unittest.cc", + ] +} + +# Optional standalone test binary, for faster isolated builds. +test("unit_tests_main") { + deps = [ + ":unit_tests", + "//testing/gmock:gmock_main", + ] + sources = [ + ":unittest_files", + ] +} diff --git a/chrome/browser/media/router/media_route.cc b/chrome/browser/media/router/media_route.cc new file mode 100644 index 0000000..f894761 --- /dev/null +++ b/chrome/browser/media/router/media_route.cc @@ -0,0 +1,32 @@ +// Copyright 2015 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/media/router/media_route.h" + +#include "base/logging.h" +#include "chrome/browser/media/router/media_source.h" + +namespace media_router { + +MediaRoute::MediaRoute(const MediaRouteId& media_route_id, + const MediaSource& media_source, + const MediaSink& media_sink, + const std::string& description, + bool is_local) + : media_route_id_(media_route_id), + media_source_(media_source), + media_sink_(media_sink), + description_(description), + is_local_(is_local), + state_(MEDIA_ROUTE_STATE_NEW) { +} + +MediaRoute::~MediaRoute() { +} + +bool MediaRoute::Equals(const MediaRoute& other) const { + return media_route_id_ == other.media_route_id_; +} + +} // namespace media_router diff --git a/chrome/browser/media/router/media_route.h b/chrome/browser/media/router/media_route.h new file mode 100644 index 0000000..a8564f6 --- /dev/null +++ b/chrome/browser/media/router/media_route.h @@ -0,0 +1,88 @@ +// Copyright 2015 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_MEDIA_ROUTER_MEDIA_ROUTE_H_ +#define CHROME_BROWSER_MEDIA_ROUTER_MEDIA_ROUTE_H_ + +#include <string> + +#include "base/gtest_prod_util.h" +#include "base/logging.h" +#include "base/values.h" +#include "chrome/browser/media/router/media_route_id.h" +#include "chrome/browser/media/router/media_sink.h" +#include "chrome/browser/media/router/media_source.h" +#include "url/gurl.h" + +namespace media_router { + +using RouteRequestId = int64; + +class MediaRouteFactory; + +// For now, a simple transition graph: NEW -> CONNECTED -> CLOSED. +enum MediaRouteState { + // The route is new and not yet connected to a sink. + MEDIA_ROUTE_STATE_NEW, + // The route is active and connected to a sink. + MEDIA_ROUTE_STATE_CONNECTED, + // The route has been disconnected. + MEDIA_ROUTE_STATE_CLOSED +}; + +// MediaRoute objects contain the status and metadata of a routing +// operation. The fields are immutable and reflect the route status +// only at the time of object creation. Updated route statuses must +// be retrieved as new MediaRoute objects from the Media Router. +class MediaRoute { + public: + // |media_route_id|: ID of the route. New route IDs should be created + // by the RouteIdManager class. + // |media_source|: Description of source of the route. + // |media_sink|: The sink that is receiving the media. + // |description|: Description of the route to be displayed. + // |is_local|: true if the route was created from this browser. + MediaRoute(const MediaRouteId& media_route_id, + const MediaSource& media_source, + const MediaSink& media_sink, + const std::string& description, + bool is_local); + + ~MediaRoute(); + + // The media route identifier. + const MediaRouteId& media_route_id() const { return media_route_id_; } + + // The state of the media route. + MediaRouteState state() const { return state_; } + + // The media source being routed. + const MediaSource& media_source() const { return media_source_; } + + // The sink being routed to. + const MediaSink& media_sink() const { return media_sink_; } + + // The description of the media route activity, for example + // "Playing Foo Bar Music All Access." + // TODO(kmarshall): Do we need to pass locale for bidi rendering? + const std::string& description() const { return description_; } + + // Returns |true| if the route is created locally (versus discovered + // by a media route provider.) + bool is_local() const { return is_local_; } + + bool Equals(const MediaRoute& other) const; + + private: + const MediaRouteId media_route_id_; + const MediaSource media_source_; + const MediaSink media_sink_; + const std::string description_; + const bool is_local_; + const MediaRouteState state_; +}; + +} // namespace media_router + +#endif // CHROME_BROWSER_MEDIA_ROUTER_MEDIA_ROUTE_H_ diff --git a/chrome/browser/media/router/media_route_id.h b/chrome/browser/media/router/media_route_id.h new file mode 100644 index 0000000..7bdfb57 --- /dev/null +++ b/chrome/browser/media/router/media_route_id.h @@ -0,0 +1,16 @@ +// Copyright 2015 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_MEDIA_ROUTER_MEDIA_ROUTE_ID_H_ +#define CHROME_BROWSER_MEDIA_ROUTER_MEDIA_ROUTE_ID_H_ + +#include <string> + +namespace media_router { + +using MediaRouteId = std::string; + +} // namespace media_router + +#endif // CHROME_BROWSER_MEDIA_ROUTER_MEDIA_ROUTE_ID_H_ diff --git a/chrome/browser/media/router/media_route_unittest.cc b/chrome/browser/media/router/media_route_unittest.cc new file mode 100644 index 0000000..7c42b6d --- /dev/null +++ b/chrome/browser/media/router/media_route_unittest.cc @@ -0,0 +1,43 @@ +// Copyright 2015 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/media/router/media_route.h" +#include "chrome/browser/media/router/media_sink.h" +#include "chrome/browser/media/router/media_source_helper.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace media_router { + +// Tests the == operator to ensure that only route ID equality is being checked. +TEST(MediaRouteTest, Equals) { + MediaRoute route1("routeId1", ForCastAppMediaSource("DialApp"), + MediaSink("sinkId", "sinkName"), + "Description", false); + + // Same as route1 with different sink ID. + MediaRoute route2("routeId1", ForCastAppMediaSource("DialApp"), + MediaSink("differentSinkId", "different sink"), + "Description", false); + EXPECT_TRUE(route1.Equals(route2)); + + // Same as route1 with different description. + MediaRoute route3("routeId1", ForCastAppMediaSource("DialApp"), + MediaSink("sinkId", "sinkName"), + "differentDescription", false); + EXPECT_TRUE(route1.Equals(route3)); + + // Same as route1 with different is_local. + MediaRoute route4("routeId1", ForCastAppMediaSource("DialApp"), + MediaSink("sinkId", "sinkName"), + "Description", true); + EXPECT_TRUE(route1.Equals(route4)); + + // The ID is different from route1's. + MediaRoute route5("routeId2", ForCastAppMediaSource("DialApp"), + MediaSink("sinkId", "sinkName"), + "Description", false); + EXPECT_FALSE(route1.Equals(route5)); +} + +} // namespace media_router diff --git a/chrome/browser/media/router/media_router.gyp b/chrome/browser/media/router/media_router.gyp new file mode 100644 index 0000000..6b9756c --- /dev/null +++ b/chrome/browser/media/router/media_router.gyp @@ -0,0 +1,33 @@ +# Copyright 2015 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. + +{ + 'targets': [ + { + 'target_name': 'media_router', + 'type': 'static_library', + 'include_dirs': [ + '<(DEPTH)', + ], + 'dependencies': [ + '<(DEPTH)/base/base.gyp:base', + '<(DEPTH)/url/url.gyp:url_lib', + ], + 'sources': [ + 'common.h', + 'media_route.cc', + 'media_route.h', + 'media_route_id.h', + 'media_sink.cc', + 'media_sink.h', + 'media_source.cc', + 'media_source.h', + 'media_source_helper.cc', + 'media_source_helper.h', + 'route_id_manager.cc', + 'route_id_manager.h', + ], + }, + ], +} diff --git a/chrome/browser/media/router/media_router_tests.gypi b/chrome/browser/media/router/media_router_tests.gypi new file mode 100644 index 0000000..1c74832 --- /dev/null +++ b/chrome/browser/media/router/media_router_tests.gypi @@ -0,0 +1,13 @@ +# Copyright 2015 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. + +{ + 'sources': [ + 'media_route_unittest.cc', + 'media_sink_unittest.cc', + 'media_source_helper_unittest.cc', + 'media_source_unittest.cc', + 'route_id_manager_unittest.cc', + ], +} diff --git a/chrome/browser/media/router/media_sink.cc b/chrome/browser/media/router/media_sink.cc new file mode 100644 index 0000000..87820f6 --- /dev/null +++ b/chrome/browser/media/router/media_sink.cc @@ -0,0 +1,21 @@ +// Copyright 2015 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/media/router/media_sink.h" + +namespace media_router { + +MediaSink::MediaSink(const MediaSinkId& sink_id, + const std::string& name) + : sink_id_(sink_id), name_(name) { +} + +MediaSink::~MediaSink() { +} + +bool MediaSink::Equals(const MediaSink& other) const { + return sink_id_ == other.sink_id_; +} + +} // namespace media_router diff --git a/chrome/browser/media/router/media_sink.h b/chrome/browser/media/router/media_sink.h new file mode 100644 index 0000000..af4e9a8 --- /dev/null +++ b/chrome/browser/media/router/media_sink.h @@ -0,0 +1,37 @@ +// Copyright 2015 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_MEDIA_ROUTER_MEDIA_SINK_H_ +#define CHROME_BROWSER_MEDIA_ROUTER_MEDIA_SINK_H_ + +#include <string> + +#include "chrome/browser/media/router/media_route_id.h" + +namespace media_router { + +using MediaSinkId = std::string; + +// Represents a sink to which media can be routed. +class MediaSink { + public: + // |sink_id|: Unique identifier for the MediaSink. + // |name|: Descriptive name of the MediaSink. + MediaSink(const MediaSinkId& sink_id, + const std::string& name); + ~MediaSink(); + + const MediaSinkId& sink_id() const { return sink_id_; } + const std::string& name() const { return name_; } + + bool Equals(const MediaSink& other) const; + + private: + const MediaSinkId sink_id_; + const std::string name_; +}; + +} // namespace media_router + +#endif // CHROME_BROWSER_MEDIA_ROUTER_MEDIA_SINK_H_ diff --git a/chrome/browser/media/router/media_sink_unittest.cc b/chrome/browser/media/router/media_sink_unittest.cc new file mode 100644 index 0000000..07c835a --- /dev/null +++ b/chrome/browser/media/router/media_sink_unittest.cc @@ -0,0 +1,26 @@ +// Copyright 2015 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/media/router/media_sink.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace media_router { + +TEST(MediaSinkTest, Equals) { + MediaSink sink1("sinkId", "Sink"); + + // Same as sink1. + MediaSink sink2("sinkId", "Sink"); + EXPECT_TRUE(sink1.Equals(sink2)); + + // Sink name is different from sink1's. + MediaSink sink3("sinkId", "Other Sink"); + EXPECT_TRUE(sink1.Equals(sink3)); + + // Sink ID is diffrent from sink1's. + MediaSink sink4("otherSinkId", "Sink"); + EXPECT_FALSE(sink1.Equals(sink4)); +} + +} // namespace media_router diff --git a/chrome/browser/media/router/media_source.cc b/chrome/browser/media/router/media_source.cc new file mode 100644 index 0000000..88fc284 --- /dev/null +++ b/chrome/browser/media/router/media_source.cc @@ -0,0 +1,21 @@ +// Copyright 2015 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/media/router/media_source.h" + +#include <string> + +namespace media_router { + +MediaSource::MediaSource(const std::string& source_id) + : id_(source_id) { +} + +MediaSource::~MediaSource() {} + +std::string MediaSource::id() const { + return id_; +} + +} // namespace media_router diff --git a/chrome/browser/media/router/media_source.h b/chrome/browser/media/router/media_source.h new file mode 100644 index 0000000..d90497f --- /dev/null +++ b/chrome/browser/media/router/media_source.h @@ -0,0 +1,26 @@ +// Copyright 2015 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_MEDIA_ROUTER_MEDIA_SOURCE_H_ +#define CHROME_BROWSER_MEDIA_ROUTER_MEDIA_SOURCE_H_ + +#include <string> + +namespace media_router { + +class MediaSource { + public: + explicit MediaSource(const std::string& id); + ~MediaSource(); + + // Gets the ID of the media source. + std::string id() const; + + private: + std::string id_; +}; + +} // namespace media_router + +#endif // CHROME_BROWSER_MEDIA_ROUTER_MEDIA_SOURCE_H_ diff --git a/chrome/browser/media/router/media_source_helper.cc b/chrome/browser/media/router/media_source_helper.cc new file mode 100644 index 0000000..305a00f --- /dev/null +++ b/chrome/browser/media/router/media_source_helper.cc @@ -0,0 +1,52 @@ +// Copyright 2015 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/media/router/media_source_helper.h" + +#include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" +#include "chrome/browser/media/router/media_source.h" +#include "url/gurl.h" + +namespace media_router { + +// Prefixes used to format and detect various protocols' media source URNs. +// See: https://www.ietf.org/rfc/rfc3406.txt +const char kTabMediaUrnPrefix[] = "urn:x-org.chromium.media:source:tab"; +const char kDesktopMediaUrn[] = "urn:x-org.chromium.media:source:desktop"; +const char kCastUrnPrefix[] = "urn:x-com.google.cast:application:"; + +MediaSource ForTabMediaSource(int tab_id) { + return MediaSource(base::StringPrintf("%s:%d", kTabMediaUrnPrefix, tab_id)); +} + +MediaSource ForDesktopMediaSource() { + return MediaSource(std::string(kDesktopMediaUrn)); +} + +// TODO(mfoltz): Remove when the TODO in +// MediaSourceManager::GetDefaultMediaSource is resolved. +MediaSource ForCastAppMediaSource(const std::string& app_id) { + return MediaSource(kCastUrnPrefix + app_id); +} + +MediaSource ForPresentationUrl(const std::string& presentation_url) { + return MediaSource(presentation_url); +} + +bool IsMirroringMediaSource(const MediaSource& source) { + return StartsWithASCII(source.id(), kDesktopMediaUrn, true) || + StartsWithASCII(source.id(), kTabMediaUrnPrefix, true); +} + +bool IsValidMediaSource(const MediaSource& source) { + if (IsMirroringMediaSource(source) || + StartsWithASCII(source.id(), kCastUrnPrefix, true)) { + return true; + } + GURL url(source.id()); + return url.is_valid() && url.SchemeIsHTTPOrHTTPS(); +} + +} // namespace media_router diff --git a/chrome/browser/media/router/media_source_helper.h b/chrome/browser/media/router/media_source_helper.h new file mode 100644 index 0000000..a46294f --- /dev/null +++ b/chrome/browser/media/router/media_source_helper.h @@ -0,0 +1,40 @@ +// Copyright 2015 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_MEDIA_ROUTER_MEDIA_SOURCE_HELPER_H_ +#define CHROME_BROWSER_MEDIA_ROUTER_MEDIA_SOURCE_HELPER_H_ + +#include <string> + +#include "chrome/browser/media/router/media_source.h" + +namespace media_router { + +// Helper library for protocol-specific media source object creation. + +// TODO(kmarshall): Should these creation methods be moved to the WebUI, which +// (excluding Presentation API) is their only caller? The MR base code can be +// Also, consider generating an is_mirroring state boolean at the time of URN +// creation so that the mirroring status does not have to be determined from a +// string prefix check. +// These changes would allow the MR to handle MediaSource objects in the same +// type agnostic fashion vs. having to format and parse URNs and track which +// MediaSource types are mirroring-enabled. + +// Returns MediaSource URI depending on the type of source. +MediaSource ForTabMediaSource(int tab_id); +MediaSource ForDesktopMediaSource(); +MediaSource ForCastAppMediaSource(const std::string& app_id); +MediaSource ForPresentationUrl(const std::string& presentation_url); + +// Returns true if |source| outputs its content via mirroring. +bool IsMirroringMediaSource(const MediaSource& source); + +// Checks that |source| is a parseable URN and is of a known type. +// Does not deeper protocol-level syntax checks. +bool IsValidMediaSource(const MediaSource& source); + +} // namespace media_router + +#endif // CHROME_BROWSER_MEDIA_ROUTER_MEDIA_SOURCE_HELPER_H_ diff --git a/chrome/browser/media/router/media_source_helper_unittest.cc b/chrome/browser/media/router/media_source_helper_unittest.cc new file mode 100644 index 0000000..fe36046 --- /dev/null +++ b/chrome/browser/media/router/media_source_helper_unittest.cc @@ -0,0 +1,44 @@ +// Copyright 2015 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/media/router/media_source.h" +#include "chrome/browser/media/router/media_source_helper.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace media_router { + +TEST(MediaSourcesTest, IsMirroringMediaSource) { + EXPECT_TRUE(IsMirroringMediaSource(ForTabMediaSource(123))); + EXPECT_TRUE(IsMirroringMediaSource(ForDesktopMediaSource())); + EXPECT_FALSE(IsMirroringMediaSource(ForCastAppMediaSource("CastApp"))); + EXPECT_FALSE(IsMirroringMediaSource(ForPresentationUrl("http://url"))); +} + +TEST(MediaSourcesTest, CreateMediaSource) { + EXPECT_EQ("urn:x-org.chromium.media:source:tab:123", + ForTabMediaSource(123).id()); + EXPECT_EQ("urn:x-org.chromium.media:source:desktop", + ForDesktopMediaSource().id()); + EXPECT_EQ("urn:x-com.google.cast:application:DEADBEEF", + ForCastAppMediaSource("DEADBEEF").id()); + EXPECT_EQ("http://example.com/", + ForPresentationUrl("http://example.com/").id()); +} + +TEST(MediaSourcesTest, IsValidMediaSource) { + EXPECT_TRUE(IsValidMediaSource(ForTabMediaSource(123))); + EXPECT_TRUE(IsValidMediaSource(ForDesktopMediaSource())); + EXPECT_TRUE(IsValidMediaSource(ForCastAppMediaSource("DEADBEEF"))); + EXPECT_TRUE(IsValidMediaSource(ForPresentationUrl("http://example.com/"))); + EXPECT_TRUE(IsValidMediaSource(ForPresentationUrl("https://example.com/"))); + + // Disallowed scheme + EXPECT_FALSE( + IsValidMediaSource(ForPresentationUrl("file:///some/local/path"))); + // Not a URL + EXPECT_FALSE(IsValidMediaSource(ForPresentationUrl("totally not a url"))); +} + +} // namespace media_router + diff --git a/chrome/browser/media/router/media_source_unittest.cc b/chrome/browser/media/router/media_source_unittest.cc new file mode 100644 index 0000000..470b572 --- /dev/null +++ b/chrome/browser/media/router/media_source_unittest.cc @@ -0,0 +1,16 @@ +// Copyright 2015 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/media/router/media_source.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace media_router { + +// Test that the object's getters match the constructor parameters. +TEST(MediaSourceTest, Constructor) { + MediaSource source1("urn:x-com.google.cast:application:DEADBEEF"); + EXPECT_EQ("urn:x-com.google.cast:application:DEADBEEF", source1.id()); +} + +} // namespace media_router diff --git a/chrome/browser/media/router/route_id_manager.cc b/chrome/browser/media/router/route_id_manager.cc new file mode 100644 index 0000000..9735257 --- /dev/null +++ b/chrome/browser/media/router/route_id_manager.cc @@ -0,0 +1,27 @@ +// Copyright 2015 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/media/router/route_id_manager.h" + +#include "base/memory/singleton.h" +#include "base/strings/string_number_conversions.h" +#include "chrome/browser/media/router/media_route.h" + +namespace media_router { + +const char kLocalRoutePrefix[] = "route-local-"; + +RouteIDManager::RouteIDManager() : next_local_id_(0) {} + +std::string RouteIDManager::ForLocalRoute() { + DCHECK(CalledOnValidThread()); + return kLocalRoutePrefix + base::Uint64ToString(next_local_id_++); +} + +// static +RouteIDManager* RouteIDManager::GetInstance() { + return Singleton<RouteIDManager>::get(); +} + +} // namespace media_router diff --git a/chrome/browser/media/router/route_id_manager.h b/chrome/browser/media/router/route_id_manager.h new file mode 100644 index 0000000..8497bd1 --- /dev/null +++ b/chrome/browser/media/router/route_id_manager.h @@ -0,0 +1,42 @@ +// Copyright 2015 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_MEDIA_ROUTER_ROUTE_ID_MANAGER_H_ +#define CHROME_BROWSER_MEDIA_ROUTER_ROUTE_ID_MANAGER_H_ + +#include <string> + +#include "base/basictypes.h" +#include "base/gtest_prod_util.h" +#include "base/memory/singleton.h" +#include "base/threading/non_thread_safe.h" + +namespace media_router { + +class MediaRoute; + +// Shared singleton which coordinates the assignment of unique IDs to +// MediaRoute objects. +// Class is not threadsafe; IDs should be created on the same thread. +class RouteIDManager : public base::NonThreadSafe { + public: + static RouteIDManager* GetInstance(); + + std::string ForLocalRoute(); + + private: + FRIEND_TEST_ALL_PREFIXES(RouteIDManagerTest, ForLocalRoute); + friend struct DefaultSingletonTraits<RouteIDManager>; + + RouteIDManager(); + + // Monotonically increasing ID number. + uint64 next_local_id_; + + DISALLOW_COPY_AND_ASSIGN(RouteIDManager); +}; + +} // namespace media_router + +#endif // CHROME_BROWSER_MEDIA_ROUTER_ROUTE_ID_MANAGER_H_ diff --git a/chrome/browser/media/router/route_id_manager_unittest.cc b/chrome/browser/media/router/route_id_manager_unittest.cc new file mode 100644 index 0000000..46da03e --- /dev/null +++ b/chrome/browser/media/router/route_id_manager_unittest.cc @@ -0,0 +1,20 @@ +// Copyright 2015 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/media/router/route_id_manager.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace media_router { + +TEST(RouteIDManagerTest, ForLocalRoute) { + // Singleton instance is left unused for better test isolation. + RouteIDManager manager1; + EXPECT_EQ("route-local-0", manager1.ForLocalRoute()); + EXPECT_EQ("route-local-1", manager1.ForLocalRoute()); + + RouteIDManager manager2; + EXPECT_EQ("route-local-0", manager2.ForLocalRoute()); +} + +} // namespace media_router diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 01263ef..ba7ed9f 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -3182,6 +3182,11 @@ ['enable_task_manager==1', { 'sources': [ '<@(chrome_browser_task_manager_sources)' ], }], + ['enable_media_router==1', { + 'dependencies': [ + 'browser/media/router/media_router.gyp:media_router', + ], + }], ['enable_spellcheck==1', { 'sources': [ '<@(chrome_browser_spellchecker_sources)' ], 'dependencies': [ diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi index cff9b65..03e2119 100644 --- a/chrome/chrome_tests_unit.gypi +++ b/chrome/chrome_tests_unit.gypi @@ -2327,6 +2327,11 @@ ['enable_print_preview==1', { 'sources': [ '<@(chrome_unit_tests_print_preview_sources)' ], }], + ['enable_media_router==1', { + 'includes': [ + 'browser/media/router/media_router_tests.gypi', + ], + }], ['enable_captive_portal_detection==1', { 'sources': [ '<@(chrome_unit_tests_captive_portal_sources)' ], }], diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 7fb1595..3a5eb10 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn @@ -1484,6 +1484,9 @@ if (!is_android) { ".", "//chrome") } + if (enable_media_router) { + deps += [ "//chrome/browser/media/router:unit_tests" ] + } if (is_chromeos) { sources += rebase_path(unit_gypi_values.chrome_unit_tests_chromeos_sources, |