Introduce chrome.displaySource API
This patch introduces the 'chrome.displaySource' API including the idl file and the permission string and feature. The patch also provides bindings code and the implementation delegate interface for the 'getAvailableSinks', 'requestAuthentication' methods and for the 'onSinksUpdated' event. The API tests are included. The API proposal doc: https://docs.google.com/document/d/1svs0p_b6KAIiBrKjaORsA2D8Pd84u8ksnTCfubYVVWA BUG=242107 Review URL: https://codereview.chromium.org/1410093008 Cr-Commit-Position: refs/heads/master@{#360299}
This commit is contained in:

committed by
Commit bot

parent
30b0f37300
commit
d19c83ee78
chrome
extensions
browser
api
display_source
OWNERSdisplay_source_api.ccdisplay_source_api.hdisplay_source_apitest.ccdisplay_source_connection_delegate.ccdisplay_source_connection_delegate.hdisplay_source_connection_delegate_factory.ccdisplay_source_connection_delegate_factory.hdisplay_source_event_router.ccdisplay_source_event_router.hdisplay_source_event_router_factory.ccdisplay_source_event_router_factory.h
common
api
permissions
test
data
api_test
display_source
tools/metrics/histograms
@@ -4215,6 +4215,9 @@ Even if you have downloaded files from this website before, the website might ha
|
||||
<message name="IDS_EXTENSION_PROMPT_WARNING_USERS_PRIVATE" desc="Permission string for access to user accounts.">
|
||||
Read and change whitelisted users
|
||||
</message>
|
||||
<message name="IDS_EXTENSION_PROMPT_WARNING_DISPLAY_SOURCE" desc="Permission string for access to Display Source API.">
|
||||
Send audio and video to displays on the local network
|
||||
</message>
|
||||
</if>
|
||||
|
||||
<!-- Extension/App error messages -->
|
||||
|
@@ -633,6 +633,9 @@ ChromePermissionMessageRule::GetAllRules() {
|
||||
{IDS_EXTENSION_PROMPT_WARNING_USERS_PRIVATE,
|
||||
{APIPermission::kUsersPrivate},
|
||||
{}},
|
||||
{IDS_EXTENSION_PROMPT_WARNING_DISPLAY_SOURCE,
|
||||
{APIPermission::kDisplaySource},
|
||||
{}},
|
||||
};
|
||||
|
||||
return std::vector<ChromePermissionMessageRule>(
|
||||
|
2
extensions/browser/api/display_source/OWNERS
Normal file
2
extensions/browser/api/display_source/OWNERS
Normal file
@@ -0,0 +1,2 @@
|
||||
alexander.shalamov@intel.com
|
||||
mikhail.pozdnyakov@intel.com
|
97
extensions/browser/api/display_source/display_source_api.cc
Normal file
97
extensions/browser/api/display_source/display_source_api.cc
Normal file
@@ -0,0 +1,97 @@
|
||||
// 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 "extensions/browser/api/display_source/display_source_api.h"
|
||||
#include "extensions/browser/api/display_source/display_source_connection_delegate_factory.h"
|
||||
#include "extensions/common/api/display_source.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
namespace {
|
||||
|
||||
const char kErrorNotSupported[] = "Not supported";
|
||||
const char kErrorInvalidArguments[] = "Invalid arguments";
|
||||
|
||||
} // namespace
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// DisplaySourceGetAvailableSinksFunction
|
||||
|
||||
DisplaySourceGetAvailableSinksFunction::
|
||||
~DisplaySourceGetAvailableSinksFunction() {}
|
||||
|
||||
ExtensionFunction::ResponseAction
|
||||
DisplaySourceGetAvailableSinksFunction::Run() {
|
||||
DisplaySourceConnectionDelegate* delegate =
|
||||
DisplaySourceConnectionDelegateFactory::GetForBrowserContext(
|
||||
browser_context());
|
||||
if (!delegate) {
|
||||
return RespondNow(Error(kErrorNotSupported));
|
||||
}
|
||||
|
||||
auto success_callback = base::Bind(
|
||||
&DisplaySourceGetAvailableSinksFunction::OnGetSinksCompleted, this);
|
||||
auto failure_callback = base::Bind(
|
||||
&DisplaySourceGetAvailableSinksFunction::OnGetSinksFailed, this);
|
||||
delegate->GetAvailableSinks(success_callback, failure_callback);
|
||||
|
||||
return RespondLater();
|
||||
}
|
||||
|
||||
void DisplaySourceGetAvailableSinksFunction::OnGetSinksCompleted(
|
||||
const DisplaySourceSinkInfoList& sinks) {
|
||||
scoped_ptr<base::ListValue> result =
|
||||
api::display_source::GetAvailableSinks::Results::Create(sinks);
|
||||
Respond(ArgumentList(result.Pass()));
|
||||
}
|
||||
|
||||
void DisplaySourceGetAvailableSinksFunction::OnGetSinksFailed(
|
||||
const std::string& reason) {
|
||||
Respond(Error(reason));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// DisplaySourceRequestAuthenticationFunction
|
||||
|
||||
DisplaySourceRequestAuthenticationFunction::
|
||||
~DisplaySourceRequestAuthenticationFunction() {}
|
||||
|
||||
ExtensionFunction::ResponseAction
|
||||
DisplaySourceRequestAuthenticationFunction::Run() {
|
||||
scoped_ptr<api::display_source::RequestAuthentication::Params> params(
|
||||
api::display_source::RequestAuthentication::Params::Create(*args_));
|
||||
if (!params) {
|
||||
return RespondNow(Error(kErrorInvalidArguments));
|
||||
}
|
||||
|
||||
DisplaySourceConnectionDelegate* delegate =
|
||||
DisplaySourceConnectionDelegateFactory::GetForBrowserContext(
|
||||
browser_context());
|
||||
if (!delegate) {
|
||||
return RespondNow(Error(kErrorNotSupported));
|
||||
}
|
||||
|
||||
auto success_callback = base::Bind(
|
||||
&DisplaySourceRequestAuthenticationFunction::OnRequestAuthCompleted,
|
||||
this);
|
||||
auto failure_callback = base::Bind(
|
||||
&DisplaySourceRequestAuthenticationFunction::OnRequestAuthFailed, this);
|
||||
delegate->RequestAuthentication(params->sink_id, success_callback,
|
||||
failure_callback);
|
||||
return RespondLater();
|
||||
}
|
||||
|
||||
void DisplaySourceRequestAuthenticationFunction::OnRequestAuthCompleted(
|
||||
const DisplaySourceAuthInfo& auth_info) {
|
||||
scoped_ptr<base::ListValue> result =
|
||||
api::display_source::RequestAuthentication::Results::Create(auth_info);
|
||||
Respond(ArgumentList(result.Pass()));
|
||||
}
|
||||
|
||||
void DisplaySourceRequestAuthenticationFunction::OnRequestAuthFailed(
|
||||
const std::string& reason) {
|
||||
Respond(Error(reason));
|
||||
}
|
||||
|
||||
} // namespace extensions
|
52
extensions/browser/api/display_source/display_source_api.h
Normal file
52
extensions/browser/api/display_source/display_source_api.h
Normal file
@@ -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.
|
||||
|
||||
#ifndef EXTENSIONS_BROWSER_API_DISPLAY_SOURCE_DISPLAY_SOURCE_API_H_
|
||||
#define EXTENSIONS_BROWSER_API_DISPLAY_SOURCE_DISPLAY_SOURCE_API_H_
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "extensions/browser/api/display_source/display_source_connection_delegate.h"
|
||||
#include "extensions/browser/extension_function.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
class DisplaySourceGetAvailableSinksFunction
|
||||
: public UIThreadExtensionFunction {
|
||||
public:
|
||||
DECLARE_EXTENSION_FUNCTION("displaySource.getAvailableSinks",
|
||||
DISPLAYSOURCE_GETAVAILABLESINKS);
|
||||
DisplaySourceGetAvailableSinksFunction() = default;
|
||||
|
||||
protected:
|
||||
~DisplaySourceGetAvailableSinksFunction() override;
|
||||
ResponseAction Run() final;
|
||||
|
||||
private:
|
||||
void OnGetSinksCompleted(const DisplaySourceSinkInfoList& sinks);
|
||||
void OnGetSinksFailed(const std::string& reason);
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(DisplaySourceGetAvailableSinksFunction);
|
||||
};
|
||||
|
||||
class DisplaySourceRequestAuthenticationFunction
|
||||
: public UIThreadExtensionFunction {
|
||||
public:
|
||||
DECLARE_EXTENSION_FUNCTION("displaySource.requestAuthentication",
|
||||
DISPLAYSOURCE_REQUESTAUTHENTICATION);
|
||||
DisplaySourceRequestAuthenticationFunction() = default;
|
||||
|
||||
protected:
|
||||
~DisplaySourceRequestAuthenticationFunction() override;
|
||||
ResponseAction Run() final;
|
||||
|
||||
private:
|
||||
void OnRequestAuthCompleted(const DisplaySourceAuthInfo& auth_info);
|
||||
void OnRequestAuthFailed(const std::string& reason);
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(DisplaySourceRequestAuthenticationFunction);
|
||||
};
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // EXTENSIONS_BROWSER_API_DISPLAY_SOURCE_DISPLAY_SOURCE_API_H_
|
@@ -0,0 +1,99 @@
|
||||
// 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 "base/memory/scoped_ptr.h"
|
||||
#include "content/public/test/test_utils.h"
|
||||
#include "extensions/browser/api/display_source/display_source_connection_delegate.h"
|
||||
#include "extensions/browser/api/display_source/display_source_connection_delegate_factory.h"
|
||||
#include "extensions/shell/test/shell_apitest.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
using api::display_source::SinkInfo;
|
||||
using api::display_source::SinkState;
|
||||
using api::display_source::SINK_STATE_DISCONNECTED;
|
||||
using api::display_source::AUTHENTICATION_METHOD_PBC;
|
||||
|
||||
namespace {
|
||||
|
||||
DisplaySourceSinkInfoPtr CreateSinkInfoPtr(int id,
|
||||
const std::string& name,
|
||||
SinkState state) {
|
||||
DisplaySourceSinkInfoPtr ptr(new SinkInfo());
|
||||
ptr->id = id;
|
||||
ptr->name = name;
|
||||
ptr->state = state;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
class MockDisplaySourceConnectionDelegate
|
||||
: public DisplaySourceConnectionDelegate {
|
||||
public:
|
||||
DisplaySourceSinkInfoList last_found_sinks() const override { return sinks_; }
|
||||
const Connection* connection() const override { return nullptr; }
|
||||
void GetAvailableSinks(const SinkInfoListCallback& sinks_callback,
|
||||
const FailureCallback& failure_callback) override {
|
||||
AddSink(CreateSinkInfoPtr(1, "sink 1", SINK_STATE_DISCONNECTED));
|
||||
sinks_callback.Run(sinks_);
|
||||
}
|
||||
|
||||
void RequestAuthentication(int sink_id,
|
||||
const AuthInfoCallback& auth_info_callback,
|
||||
const FailureCallback& failure_callback) override {
|
||||
DisplaySourceAuthInfo info;
|
||||
info.method = AUTHENTICATION_METHOD_PBC;
|
||||
auth_info_callback.Run(info);
|
||||
}
|
||||
|
||||
void Connect(int sink_id,
|
||||
const DisplaySourceAuthInfo& auth_info,
|
||||
const base::Closure& connected_callback,
|
||||
const FailureCallback& failure_callback) override {}
|
||||
|
||||
void Disconnect(const base::Closure& disconnected_callback,
|
||||
const FailureCallback& failure_callback) override {}
|
||||
|
||||
void StartWatchingSinks() override {
|
||||
AddSink(CreateSinkInfoPtr(2, "sink 2", SINK_STATE_DISCONNECTED));
|
||||
}
|
||||
|
||||
void StopWatchingSinks() override {}
|
||||
|
||||
private:
|
||||
void AddSink(DisplaySourceSinkInfoPtr sink) {
|
||||
sinks_.push_back(sink);
|
||||
FOR_EACH_OBSERVER(DisplaySourceConnectionDelegate::Observer, observers_,
|
||||
OnSinksUpdated(sinks_));
|
||||
}
|
||||
|
||||
DisplaySourceSinkInfoList sinks_;
|
||||
};
|
||||
|
||||
class DisplaySourceApiTest : public ShellApiTest {
|
||||
public:
|
||||
DisplaySourceApiTest() = default;
|
||||
|
||||
private:
|
||||
static scoped_ptr<KeyedService> CreateMockDelegate(
|
||||
content::BrowserContext* profile) {
|
||||
return make_scoped_ptr<KeyedService>(
|
||||
new MockDisplaySourceConnectionDelegate());
|
||||
}
|
||||
|
||||
void SetUpOnMainThread() override {
|
||||
ShellApiTest::SetUpOnMainThread();
|
||||
DisplaySourceConnectionDelegateFactory::GetInstance()->SetTestingFactory(
|
||||
browser_context(), &CreateMockDelegate);
|
||||
content::RunAllPendingInMessageLoop();
|
||||
}
|
||||
};
|
||||
|
||||
IN_PROC_BROWSER_TEST_F(DisplaySourceApiTest, DisplaySourceExtension) {
|
||||
ASSERT_TRUE(RunAppTest("api_test/display_source/api")) << message_;
|
||||
}
|
||||
|
||||
} // namespace extensions
|
@@ -0,0 +1,25 @@
|
||||
// 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 "extensions/browser/api/display_source/display_source_connection_delegate.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
DisplaySourceConnectionDelegate::Connection::Connection() {}
|
||||
|
||||
DisplaySourceConnectionDelegate::Connection::~Connection() {}
|
||||
|
||||
DisplaySourceConnectionDelegate::DisplaySourceConnectionDelegate() {}
|
||||
|
||||
DisplaySourceConnectionDelegate::~DisplaySourceConnectionDelegate() {}
|
||||
|
||||
void DisplaySourceConnectionDelegate::AddObserver(Observer* observer) {
|
||||
observers_.AddObserver(observer);
|
||||
}
|
||||
|
||||
void DisplaySourceConnectionDelegate::RemoveObserver(Observer* observer) {
|
||||
observers_.RemoveObserver(observer);
|
||||
}
|
||||
|
||||
} // namespace extensions
|
@@ -0,0 +1,103 @@
|
||||
// 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 EXTENSIONS_BROWSER_API_DISPLAY_SOURCE_DISPLAY_SOURCE_CONNECTION_DELEGATE_H_
|
||||
#define EXTENSIONS_BROWSER_API_DISPLAY_SOURCE_DISPLAY_SOURCE_CONNECTION_DELEGATE_H_
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "base/observer_list.h"
|
||||
#include "components/keyed_service/core/keyed_service.h"
|
||||
#include "extensions/common/api/display_source.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
using DisplaySourceSinkInfoPtr = linked_ptr<api::display_source::SinkInfo>;
|
||||
using DisplaySourceSinkInfoList = std::vector<DisplaySourceSinkInfoPtr>;
|
||||
using DisplaySourceAuthInfo = api::display_source::AuthenticationInfo;
|
||||
|
||||
// The DisplaySourceConnectionDelegate interface should be implemented
|
||||
// to provide sinks search and connection functionality for
|
||||
// 'chrome.displaySource'
|
||||
// API.
|
||||
class DisplaySourceConnectionDelegate : public KeyedService {
|
||||
public:
|
||||
using AuthInfoCallback = base::Callback<void(const DisplaySourceAuthInfo&)>;
|
||||
using FailureCallback = base::Callback<void(const std::string&)>;
|
||||
using SinkInfoListCallback =
|
||||
base::Callback<void(const DisplaySourceSinkInfoList&)>;
|
||||
|
||||
struct Connection {
|
||||
Connection();
|
||||
~Connection();
|
||||
DisplaySourceSinkInfoPtr connected_sink;
|
||||
std::string local_ip;
|
||||
std::string sink_ip;
|
||||
};
|
||||
|
||||
class Observer {
|
||||
public:
|
||||
// This method is called each tiome the list of available
|
||||
// sinks is updated whether after 'GetAvailableSinks' call
|
||||
// or while the implementation is constantly watching the sinks
|
||||
// (after 'StartWatchingSinks' was called).
|
||||
virtual void OnSinksUpdated(const DisplaySourceSinkInfoList& sinks) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~Observer() {}
|
||||
};
|
||||
|
||||
DisplaySourceConnectionDelegate();
|
||||
~DisplaySourceConnectionDelegate() override;
|
||||
|
||||
virtual void AddObserver(Observer* observer);
|
||||
virtual void RemoveObserver(Observer* observer);
|
||||
|
||||
// Returns the list of last found available sinks
|
||||
// this list may contain outdated data if the delegate
|
||||
// is not watching the sinks (via 'StartWatchingSinks'
|
||||
// method). The list is refreshed after 'GetAvailableSinks'
|
||||
// call.
|
||||
virtual DisplaySourceSinkInfoList last_found_sinks() const = 0;
|
||||
|
||||
// Returns the Connection object representing the current
|
||||
// connection to the sink or NULL if there is no curent connection.
|
||||
virtual const Connection* connection() const = 0;
|
||||
|
||||
// Queries the list of currently available sinks.
|
||||
virtual void GetAvailableSinks(const SinkInfoListCallback& sinks_callback,
|
||||
const FailureCallback& failure_callback) = 0;
|
||||
|
||||
// Queries the authentication method required by the sink for connection.
|
||||
// If the used authentication method requires authentication data to be
|
||||
// visible on the sink's display (e.g. PIN) the implementation should
|
||||
// request the sink to show it.
|
||||
virtual void RequestAuthentication(
|
||||
int sink_id,
|
||||
const AuthInfoCallback& auth_info_callback,
|
||||
const FailureCallback& failure_callback) = 0;
|
||||
|
||||
// Connects to a sink by given id and auth info.
|
||||
virtual void Connect(int sink_id,
|
||||
const DisplaySourceAuthInfo& auth_info,
|
||||
const base::Closure& connected_callback,
|
||||
const FailureCallback& failure_callback) = 0;
|
||||
|
||||
// Disconnects the current connection to sink, the 'failure_callback'
|
||||
// is called if there is no current connection.
|
||||
virtual void Disconnect(const base::Closure& disconnected_callback,
|
||||
const FailureCallback& failure_callback) = 0;
|
||||
|
||||
// Implementation should start watching the sinks updates.
|
||||
virtual void StartWatchingSinks() = 0;
|
||||
|
||||
// Implementation should stop watching the sinks updates.
|
||||
virtual void StopWatchingSinks() = 0;
|
||||
|
||||
protected:
|
||||
base::ObserverList<Observer> observers_;
|
||||
};
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // EXTENSIONS_BROWSER_API_DISPLAY_SOURCE_DISPLAY_SOURCE_CONNECTION_DELEGATE_H_
|
@@ -0,0 +1,60 @@
|
||||
// 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 "extensions/browser/api/display_source/display_source_connection_delegate_factory.h"
|
||||
|
||||
#include "components/keyed_service/content/browser_context_dependency_manager.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "extensions/browser/extensions_browser_client.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
using content::BrowserContext;
|
||||
|
||||
// static
|
||||
DisplaySourceConnectionDelegate*
|
||||
DisplaySourceConnectionDelegateFactory::GetForBrowserContext(
|
||||
BrowserContext* browser_context) {
|
||||
return static_cast<DisplaySourceConnectionDelegate*>(
|
||||
GetInstance()->GetServiceForBrowserContext(browser_context, true));
|
||||
}
|
||||
|
||||
// static
|
||||
DisplaySourceConnectionDelegateFactory*
|
||||
DisplaySourceConnectionDelegateFactory::GetInstance() {
|
||||
return base::Singleton<DisplaySourceConnectionDelegateFactory>::get();
|
||||
}
|
||||
|
||||
DisplaySourceConnectionDelegateFactory::DisplaySourceConnectionDelegateFactory()
|
||||
: BrowserContextKeyedServiceFactory(
|
||||
"DisplaySourceConnectionDelegate",
|
||||
BrowserContextDependencyManager::GetInstance()) {}
|
||||
|
||||
DisplaySourceConnectionDelegateFactory::
|
||||
~DisplaySourceConnectionDelegateFactory() {}
|
||||
|
||||
KeyedService* DisplaySourceConnectionDelegateFactory::BuildServiceInstanceFor(
|
||||
BrowserContext* browser_context) const {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||
|
||||
DisplaySourceConnectionDelegate* delegate = nullptr;
|
||||
// TODO(mikhail): Add implementation.
|
||||
return delegate;
|
||||
}
|
||||
|
||||
BrowserContext* DisplaySourceConnectionDelegateFactory::GetBrowserContextToUse(
|
||||
BrowserContext* context) const {
|
||||
return ExtensionsBrowserClient::Get()->GetOriginalContext(context);
|
||||
}
|
||||
|
||||
bool DisplaySourceConnectionDelegateFactory::
|
||||
ServiceIsCreatedWithBrowserContext() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DisplaySourceConnectionDelegateFactory::ServiceIsNULLWhileTesting() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace extensions
|
@@ -0,0 +1,47 @@
|
||||
// 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 EXTENSIONS_BROWSER_API_DISPLAY_SOURCE_DISPLAY_SOURCE_CONNECTION_DELEGATE_FACTORY_H_
|
||||
#define EXTENSIONS_BROWSER_API_DISPLAY_SOURCE_DISPLAY_SOURCE_CONNECTION_DELEGATE_FACTORY_H_
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "base/memory/singleton.h"
|
||||
#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
|
||||
#include "extensions/browser/api/display_source/display_source_connection_delegate.h"
|
||||
|
||||
namespace context {
|
||||
class BrowserContext;
|
||||
}
|
||||
|
||||
namespace extensions {
|
||||
|
||||
class DisplaySourceConnectionDelegateFactory
|
||||
: public BrowserContextKeyedServiceFactory {
|
||||
public:
|
||||
static DisplaySourceConnectionDelegate* GetForBrowserContext(
|
||||
content::BrowserContext* browser_context);
|
||||
static DisplaySourceConnectionDelegateFactory* GetInstance();
|
||||
|
||||
private:
|
||||
friend struct base::DefaultSingletonTraits<
|
||||
DisplaySourceConnectionDelegateFactory>;
|
||||
|
||||
DisplaySourceConnectionDelegateFactory();
|
||||
~DisplaySourceConnectionDelegateFactory() override;
|
||||
|
||||
// BrowserContextKeyedServiceFactory:
|
||||
KeyedService* BuildServiceInstanceFor(
|
||||
content::BrowserContext* browser_context) const override;
|
||||
content::BrowserContext* GetBrowserContextToUse(
|
||||
content::BrowserContext* context) const override;
|
||||
bool ServiceIsCreatedWithBrowserContext() const override;
|
||||
bool ServiceIsNULLWhileTesting() const override;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(DisplaySourceConnectionDelegateFactory);
|
||||
};
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // EXTENSIONS_BROWSER_API_DISPLAY_SOURCE_DISPLAY_SOURCE_CONNECTION_DELEGATE_FACTORY_H_
|
@@ -0,0 +1,100 @@
|
||||
// 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 "extensions/browser/api/display_source/display_source_event_router.h"
|
||||
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "extensions/browser/api/display_source/display_source_api.h"
|
||||
#include "extensions/browser/api/display_source/display_source_connection_delegate_factory.h"
|
||||
#include "extensions/common/api/display_source.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
DisplaySourceEventRouter::DisplaySourceEventRouter(
|
||||
content::BrowserContext* browser_context)
|
||||
: browser_context_(browser_context), listening_(false) {
|
||||
EventRouter* event_router = EventRouter::Get(browser_context_);
|
||||
if (!event_router)
|
||||
return;
|
||||
event_router->RegisterObserver(
|
||||
this, api::display_source::OnSinksUpdated::kEventName);
|
||||
}
|
||||
|
||||
DisplaySourceEventRouter::~DisplaySourceEventRouter() {
|
||||
DCHECK(!listening_);
|
||||
}
|
||||
|
||||
void DisplaySourceEventRouter::Shutdown() {
|
||||
EventRouter* event_router = EventRouter::Get(browser_context_);
|
||||
if (event_router)
|
||||
event_router->UnregisterObserver(this);
|
||||
|
||||
if (!listening_)
|
||||
return;
|
||||
listening_ = false;
|
||||
DisplaySourceConnectionDelegate* delegate =
|
||||
DisplaySourceConnectionDelegateFactory::GetForBrowserContext(
|
||||
browser_context_);
|
||||
if (delegate)
|
||||
delegate->RemoveObserver(this);
|
||||
}
|
||||
|
||||
void DisplaySourceEventRouter::OnListenerAdded(
|
||||
const EventListenerInfo& details) {
|
||||
StartOrStopListeningForSinksChanges();
|
||||
}
|
||||
|
||||
void DisplaySourceEventRouter::OnListenerRemoved(
|
||||
const EventListenerInfo& details) {
|
||||
StartOrStopListeningForSinksChanges();
|
||||
}
|
||||
|
||||
void DisplaySourceEventRouter::StartOrStopListeningForSinksChanges() {
|
||||
EventRouter* event_router = EventRouter::Get(browser_context_);
|
||||
if (!event_router)
|
||||
return;
|
||||
|
||||
bool should_listen = event_router->HasEventListener(
|
||||
api::display_source::OnSinksUpdated::kEventName);
|
||||
if (should_listen && !listening_) {
|
||||
DisplaySourceConnectionDelegate* delegate =
|
||||
DisplaySourceConnectionDelegateFactory::GetForBrowserContext(
|
||||
browser_context_);
|
||||
if (delegate) {
|
||||
delegate->AddObserver(this);
|
||||
delegate->StartWatchingSinks();
|
||||
}
|
||||
}
|
||||
if (!should_listen && listening_) {
|
||||
DisplaySourceConnectionDelegate* delegate =
|
||||
DisplaySourceConnectionDelegateFactory::GetForBrowserContext(
|
||||
browser_context_);
|
||||
if (delegate) {
|
||||
delegate->RemoveObserver(this);
|
||||
delegate->StopWatchingSinks();
|
||||
}
|
||||
}
|
||||
|
||||
listening_ = should_listen;
|
||||
}
|
||||
|
||||
void DisplaySourceEventRouter::OnSinksUpdated(
|
||||
const DisplaySourceSinkInfoList& sinks) {
|
||||
EventRouter* event_router = EventRouter::Get(browser_context_);
|
||||
if (!event_router)
|
||||
return;
|
||||
scoped_ptr<base::ListValue> args(
|
||||
api::display_source::OnSinksUpdated::Create(sinks));
|
||||
scoped_ptr<Event> sinks_updated_event(
|
||||
new Event(events::DISPLAY_SOURCE_ON_SINKS_UPDATED,
|
||||
api::display_source::OnSinksUpdated::kEventName, args.Pass()));
|
||||
event_router->BroadcastEvent(sinks_updated_event.Pass());
|
||||
}
|
||||
|
||||
DisplaySourceEventRouter* DisplaySourceEventRouter::Create(
|
||||
content::BrowserContext* browser_context) {
|
||||
return new DisplaySourceEventRouter(browser_context);
|
||||
}
|
||||
|
||||
} // namespace extensions
|
@@ -0,0 +1,54 @@
|
||||
// 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 EXTENSIONS_BROWSER_API_DISPLAY_SOURCE_DISPLAY_SOURCE_EVENT_ROUTER_H_
|
||||
#define EXTENSIONS_BROWSER_API_DISPLAY_SOURCE_DISPLAY_SOURCE_EVENT_ROUTER_H_
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "components/keyed_service/core/keyed_service.h"
|
||||
#include "extensions/browser/api/display_source/display_source_connection_delegate.h"
|
||||
#include "extensions/browser/event_router.h"
|
||||
|
||||
namespace content {
|
||||
class BrowserContext;
|
||||
}
|
||||
|
||||
namespace extensions {
|
||||
|
||||
// Observe listeners to 'onSinksUpdated' events.
|
||||
class DisplaySourceEventRouter
|
||||
: public KeyedService,
|
||||
public EventRouter::Observer,
|
||||
public DisplaySourceConnectionDelegate::Observer {
|
||||
public:
|
||||
static DisplaySourceEventRouter* Create(
|
||||
content::BrowserContext* browser_context);
|
||||
|
||||
~DisplaySourceEventRouter() override;
|
||||
|
||||
private:
|
||||
explicit DisplaySourceEventRouter(content::BrowserContext* browser_context);
|
||||
|
||||
// KeyedService overrides:
|
||||
void Shutdown() override;
|
||||
|
||||
// EventRouter::Observer overrides:
|
||||
void OnListenerAdded(const EventListenerInfo& details) override;
|
||||
void OnListenerRemoved(const EventListenerInfo& details) override;
|
||||
|
||||
// DisplaySourceConnectionDelegate::Observer overrides:
|
||||
void OnSinksUpdated(const DisplaySourceSinkInfoList& sinks) override;
|
||||
|
||||
private:
|
||||
void StartOrStopListeningForSinksChanges();
|
||||
|
||||
content::BrowserContext* browser_context_;
|
||||
bool listening_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(DisplaySourceEventRouter);
|
||||
};
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // EXTENSIONS_BROWSER_API_DISPLAY_SOURCE_DISPLAY_SOURCE_EVENT_ROUTER_H_
|
@@ -0,0 +1,59 @@
|
||||
// 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 "extensions/browser/api/display_source/display_source_event_router_factory.h"
|
||||
|
||||
#include "components/keyed_service/content/browser_context_dependency_manager.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "extensions/browser/api/display_source/display_source_connection_delegate_factory.h"
|
||||
#include "extensions/browser/api/display_source/display_source_event_router.h"
|
||||
#include "extensions/browser/extension_system_provider.h"
|
||||
#include "extensions/browser/extensions_browser_client.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
// static
|
||||
DisplaySourceEventRouter* DisplaySourceEventRouterFactory::GetForProfile(
|
||||
content::BrowserContext* context) {
|
||||
return static_cast<DisplaySourceEventRouter*>(
|
||||
GetInstance()->GetServiceForBrowserContext(context, true));
|
||||
}
|
||||
|
||||
// static
|
||||
DisplaySourceEventRouterFactory*
|
||||
DisplaySourceEventRouterFactory::GetInstance() {
|
||||
return base::Singleton<DisplaySourceEventRouterFactory>::get();
|
||||
}
|
||||
|
||||
DisplaySourceEventRouterFactory::DisplaySourceEventRouterFactory()
|
||||
: BrowserContextKeyedServiceFactory(
|
||||
"DisplaySourceEventRouter",
|
||||
BrowserContextDependencyManager::GetInstance()) {
|
||||
DependsOn(ExtensionsBrowserClient::Get()->GetExtensionSystemFactory());
|
||||
DependsOn(DisplaySourceConnectionDelegateFactory::GetInstance());
|
||||
}
|
||||
|
||||
DisplaySourceEventRouterFactory::~DisplaySourceEventRouterFactory() {}
|
||||
|
||||
KeyedService* DisplaySourceEventRouterFactory::BuildServiceInstanceFor(
|
||||
content::BrowserContext* context) const {
|
||||
return DisplaySourceEventRouter::Create(context);
|
||||
}
|
||||
|
||||
content::BrowserContext*
|
||||
DisplaySourceEventRouterFactory::GetBrowserContextToUse(
|
||||
content::BrowserContext* context) const {
|
||||
return ExtensionsBrowserClient::Get()->GetOriginalContext(context);
|
||||
}
|
||||
|
||||
bool DisplaySourceEventRouterFactory::ServiceIsCreatedWithBrowserContext()
|
||||
const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DisplaySourceEventRouterFactory::ServiceIsNULLWhileTesting() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace extensions
|
@@ -0,0 +1,48 @@
|
||||
// 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 EXTENSIONS_BROWSER_API_DISPLAY_SOURCE_DISPLAY_SOURCE_EVENT_ROUTER_FACTORY_H_
|
||||
#define EXTENSIONS_BROWSER_API_DISPLAY_SOURCE_DISPLAY_SOURCE_EVENT_ROUTER_FACTORY_H_
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "base/memory/singleton.h"
|
||||
#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
class DisplaySourceEventRouter;
|
||||
|
||||
class DisplaySourceEventRouterFactory
|
||||
: public BrowserContextKeyedServiceFactory {
|
||||
public:
|
||||
// Returns the DisplaySourceEventRouter for |profile|, creating it if
|
||||
// it is not yet created.
|
||||
static DisplaySourceEventRouter* GetForProfile(
|
||||
content::BrowserContext* context);
|
||||
|
||||
static DisplaySourceEventRouterFactory* GetInstance();
|
||||
|
||||
protected:
|
||||
// BrowserContextKeyedBaseFactory overrides:
|
||||
content::BrowserContext* GetBrowserContextToUse(
|
||||
content::BrowserContext* context) const override;
|
||||
bool ServiceIsCreatedWithBrowserContext() const override;
|
||||
bool ServiceIsNULLWhileTesting() const override;
|
||||
|
||||
private:
|
||||
friend struct base::DefaultSingletonTraits<DisplaySourceEventRouterFactory>;
|
||||
|
||||
DisplaySourceEventRouterFactory();
|
||||
~DisplaySourceEventRouterFactory() override;
|
||||
|
||||
// BrowserContextKeyedServiceFactory:
|
||||
KeyedService* BuildServiceInstanceFor(
|
||||
content::BrowserContext* profile) const override;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(DisplaySourceEventRouterFactory);
|
||||
};
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // EXTENSIONS_BROWSER_API_DISPLAY_SOURCE_DISPLAY_SOURCE_EVENT_ROUTER_FACTORY_H_
|
@@ -10,6 +10,7 @@
|
||||
#include "extensions/browser/api/bluetooth/bluetooth_api.h"
|
||||
#include "extensions/browser/api/bluetooth/bluetooth_private_api.h"
|
||||
#include "extensions/browser/api/bluetooth_socket/bluetooth_socket_event_dispatcher.h"
|
||||
#include "extensions/browser/api/display_source/display_source_event_router_factory.h"
|
||||
#include "extensions/browser/api/hid/hid_device_manager.h"
|
||||
#include "extensions/browser/api/idle/idle_manager_factory.h"
|
||||
#include "extensions/browser/api/management/management_api.h"
|
||||
@@ -61,6 +62,7 @@ void EnsureBrowserContextKeyedServiceFactoriesBuilt() {
|
||||
api::TCPSocketEventDispatcher::GetFactoryInstance();
|
||||
api::UDPSocketEventDispatcher::GetFactoryInstance();
|
||||
DeclarativeUserScriptManagerFactory::GetInstance();
|
||||
DisplaySourceEventRouterFactory::GetInstance();
|
||||
EventRouterFactory::GetInstance();
|
||||
ExtensionMessageFilter::EnsureShutdownNotifierFactoryBuilt();
|
||||
ExtensionPrefsFactory::GetInstance();
|
||||
|
@@ -410,6 +410,7 @@ enum HistogramValue {
|
||||
EASY_UNLOCK_PRIVATE_ON_CONNECTION_STATUS_CHANGED,
|
||||
EASY_UNLOCK_PRIVATE_ON_DATA_RECEIVED,
|
||||
EASY_UNLOCK_PRIVATE_ON_SEND_COMPLETED,
|
||||
DISPLAY_SOURCE_ON_SINKS_UPDATED,
|
||||
// Last entry: Add new entries above, then run:
|
||||
// python tools/metrics/histograms/update_extension_histograms.py
|
||||
ENUM_BOUNDARY
|
||||
|
@@ -1156,6 +1156,8 @@ enum HistogramValue {
|
||||
SETTINGSPRIVATE_SETDEFAULTZOOMPERCENTFUNCTION,
|
||||
BLUETOOTHPRIVATE_CONNECT,
|
||||
BLUETOOTHPRIVATE_FORGETDEVICE,
|
||||
DISPLAYSOURCE_GETAVAILABLESINKS,
|
||||
DISPLAYSOURCE_REQUESTAUTHENTICATION,
|
||||
// Last entry: Add new entries above, then run:
|
||||
// python tools/metrics/histograms/update_extension_histograms.py
|
||||
ENUM_BOUNDARY
|
||||
|
@@ -127,6 +127,10 @@
|
||||
"extension_types": ["platform_app"],
|
||||
"contexts": ["blessed_extension"]
|
||||
},
|
||||
"displaySource": {
|
||||
"dependencies": ["permission:displaySource"],
|
||||
"contexts": ["blessed_extension"]
|
||||
},
|
||||
"dns": {
|
||||
"dependencies": ["permission:dns"],
|
||||
"contexts": ["blessed_extension"]
|
||||
|
@@ -184,6 +184,10 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"displaySource": {
|
||||
"channel": "dev",
|
||||
"extension_types": ["extension", "platform_app"]
|
||||
},
|
||||
"dns": [
|
||||
{
|
||||
"channel": "dev",
|
||||
|
152
extensions/common/api/display_source.idl
Normal file
152
extensions/common/api/display_source.idl
Normal file
@@ -0,0 +1,152 @@
|
||||
// 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.
|
||||
|
||||
// The <code>chrome.displaySource</code> API creates a Display
|
||||
// session using WebMediaStreamTrack as sources.
|
||||
namespace displaySource {
|
||||
enum ErrorType {
|
||||
// Cannot create media pipeline from the given media stream which could be
|
||||
// appropriate for a Display session (e.g., necessary codecs are missing
|
||||
// on the platform).
|
||||
create_media_pipeline_error,
|
||||
|
||||
// A new Display session cannot be started before the existing one is
|
||||
// terminated.
|
||||
exceeded_session_limit_error,
|
||||
|
||||
// Could not establish connection to the sink.
|
||||
establish_connection_error,
|
||||
|
||||
// The capabilities of this Display Source and the connected
|
||||
// sink do not fit (e.g. the sink cannot play the media content of
|
||||
// the formats given by the source).
|
||||
capabilities_negotiation_error,
|
||||
|
||||
// There was an error while packetizing and sending the media content.
|
||||
media_send_error,
|
||||
|
||||
// The TCP connection with sink has dropped unexpectedly.
|
||||
connection_error,
|
||||
|
||||
// An unexpected message has arrived from the sink.
|
||||
unexpected_message_error,
|
||||
|
||||
// The sink became unresponsive.
|
||||
timeout_error,
|
||||
|
||||
// Unspecified error.
|
||||
unknown_error
|
||||
};
|
||||
|
||||
dictionary ErrorInfo {
|
||||
ErrorType type;
|
||||
DOMString? description;
|
||||
};
|
||||
|
||||
enum SinkState {
|
||||
// Connected using this Display Source (i.e., there is an active session)
|
||||
Connected,
|
||||
// In process of connection to this Display Source
|
||||
Connecting,
|
||||
// Disconnected from this Display Source
|
||||
Disconnected
|
||||
};
|
||||
|
||||
dictionary SinkInfo {
|
||||
// Id of the sink. It is guaranteed to be unique during the browser session.
|
||||
long id;
|
||||
// Human readable name of the sink.
|
||||
DOMString name;
|
||||
// State of the sink.
|
||||
SinkState state;
|
||||
};
|
||||
|
||||
enum AuthenticationMethod {
|
||||
// Push Button Config authentication method.
|
||||
PBC,
|
||||
// PIN authentication method.
|
||||
PIN
|
||||
};
|
||||
|
||||
dictionary AuthenticationInfo {
|
||||
// Authentication method.
|
||||
AuthenticationMethod method;
|
||||
// Authentication data (e.g. PIN value).
|
||||
DOMString? data;
|
||||
};
|
||||
|
||||
dictionary StartSessionInfo {
|
||||
// Id of the sink to connect.
|
||||
long sinkId;
|
||||
// Authentication information.
|
||||
AuthenticationInfo? authenticationInfo;
|
||||
// The source audio track.
|
||||
[instanceOf=MediaStreamTrack] object? audioTrack;
|
||||
// The source audio track.
|
||||
[instanceOf=MediaStreamTrack] object? videoTrack;
|
||||
};
|
||||
|
||||
callback GetSinksCallback = void (SinkInfo[] result);
|
||||
callback RequestAuthenticationCallback = void (AuthenticationInfo result);
|
||||
callback TerminateSessionCallback = void ();
|
||||
|
||||
interface Functions {
|
||||
// Queries the list of the currently available Display sinks.
|
||||
//
|
||||
// |callback| : Called when the request is completed. The argument list
|
||||
// is empty if no available sinks were found.
|
||||
static void getAvailableSinks(GetSinksCallback callback);
|
||||
|
||||
// Queries authentication data from the sink device.
|
||||
//
|
||||
// |sinkId| : Id of the sink
|
||||
// |callback| : Called when authentication info retrieved from the sink.
|
||||
// The argument |method| field contains the authentication method required
|
||||
// by the sink for connection; the |data| field can be null or can contain
|
||||
// some supplementary data provided by the sink. If authentication info
|
||||
// cannot be retrieved from the sink the "chrome.runtime.lastError" property
|
||||
// is defined.
|
||||
static void requestAuthentication(long sinkId,
|
||||
RequestAuthenticationCallback callback);
|
||||
|
||||
// Creates a Display session using the provided StartSessionInfo instance.
|
||||
// The input argument fields must be initialized as described below:
|
||||
// The |sinkId| must be a valid id of a sink (obtained via
|
||||
// ‘getAvailableSinks’).
|
||||
//
|
||||
// The |audioTrack| or |videoTrack| must be of type MediaStreamTrack.
|
||||
// Either |audioTrack| or |videoTrack| can be null but not both. This
|
||||
// means creating a session with only audio or video.
|
||||
//
|
||||
// The |authenticationInfo| can be null if no additional authentication data
|
||||
// are required by the sink; otherwise its |data| field must contain the
|
||||
// required authentication data (e.g. PIN value) and its |method| field must
|
||||
// be the same as one obtained from ‘requestAuthentication’.
|
||||
[nocompile] static void startSession(StartSessionInfo sessionInfo);
|
||||
|
||||
// Terminates the active Display session.
|
||||
// |sinkId| : Id of the connected sink.
|
||||
// |callback| : Called when the session is terminated.
|
||||
[nocompile] static void terminateSession(
|
||||
long sinkId, optional TerminateSessionCallback callback);
|
||||
};
|
||||
|
||||
interface Events {
|
||||
// Event fired when the available sinks are modified (either their amount
|
||||
// or properties)
|
||||
// |sinks| the list of all currently available sinks
|
||||
static void onSinksUpdated(SinkInfo[] sinks);
|
||||
// Event fired when the Display session is started.
|
||||
// |sinkId| Id of the peer sink
|
||||
[nocompile] static void onSessionStarted(long sinkId);
|
||||
// Event fired when the Display session is terminated.
|
||||
// |sinkId| Id of the peer sink
|
||||
[nocompile] static void onSessionTerminated(long sinkId);
|
||||
// Event fired when an error occurs.
|
||||
// |sinkId| Id of the peer sink
|
||||
// |errorInfo| error description
|
||||
[nocompile] static void onSessionErrorOccured(long sinkId,
|
||||
ErrorInfo errorInfo);
|
||||
};
|
||||
};
|
@@ -20,6 +20,7 @@
|
||||
'bluetooth_socket.idl',
|
||||
'cast_channel.idl',
|
||||
'document_scan.idl',
|
||||
'display_source.idl',
|
||||
'dns.idl',
|
||||
'events.json',
|
||||
'extensions_manifest_types.json',
|
||||
|
@@ -243,6 +243,7 @@ class APIPermission {
|
||||
kEnterpriseDeviceAttributes,
|
||||
kCertificateProvider,
|
||||
kResourcesPrivate,
|
||||
kDisplaySource,
|
||||
// Last entry: Add new entries above and ensure to update the
|
||||
// "ExtensionPermission3" enum in tools/metrics/histograms/histograms.xml
|
||||
// (by running update_extension_permission.py).
|
||||
|
@@ -54,6 +54,7 @@ std::vector<APIPermissionInfo*> ExtensionsAPIPermissions::GetAllPermissions()
|
||||
{APIPermission::kDiagnostics,
|
||||
"diagnostics",
|
||||
APIPermissionInfo::kFlagCannotBeOptional},
|
||||
{APIPermission::kDisplaySource, "displaySource"},
|
||||
{APIPermission::kDns, "dns"},
|
||||
{APIPermission::kDocumentScan, "documentScan"},
|
||||
{APIPermission::kExtensionView,
|
||||
|
@@ -321,6 +321,16 @@
|
||||
'browser/api/device_permissions_manager.h',
|
||||
'browser/api/device_permissions_prompt.cc',
|
||||
'browser/api/device_permissions_prompt.h',
|
||||
'browser/api/display_source/display_source_api.cc',
|
||||
'browser/api/display_source/display_source_api.h',
|
||||
'browser/api/display_source/display_source_connection_delegate.cc',
|
||||
'browser/api/display_source/display_source_connection_delegate.h',
|
||||
'browser/api/display_source/display_source_connection_delegate_factory.cc',
|
||||
'browser/api/display_source/display_source_connection_delegate_factory.h',
|
||||
'browser/api/display_source/display_source_event_router.cc',
|
||||
'browser/api/display_source/display_source_event_router_factory.cc',
|
||||
'browser/api/display_source/display_source_event_router_factory.h',
|
||||
'browser/api/display_source/display_source_event_router.h',
|
||||
'browser/api/dns/dns_api.cc',
|
||||
'browser/api/dns/dns_api.h',
|
||||
'browser/api/dns/host_resolver_wrapper.cc',
|
||||
|
@@ -7,6 +7,7 @@
|
||||
'extensions_browsertests_sources': [
|
||||
'browser/api/audio/audio_apitest.cc',
|
||||
'browser/api/bluetooth_socket/bluetooth_socket_apitest.cc',
|
||||
'browser/api/display_source/display_source_apitest.cc',
|
||||
'browser/api/dns/dns_apitest.cc',
|
||||
'browser/api/hid/hid_apitest.cc',
|
||||
'browser/api/printer_provider/printer_provider_apitest.cc',
|
||||
|
@@ -0,0 +1,39 @@
|
||||
// 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.
|
||||
|
||||
var testGetAvailableSinks = function() {
|
||||
var callback = function(sinks) {
|
||||
chrome.test.assertEq(1, sinks.length);
|
||||
var sink = sinks[0];
|
||||
chrome.test.assertEq(1, sink.id);
|
||||
chrome.test.assertEq("Disconnected", sink.state);
|
||||
chrome.test.assertEq("sink 1", sink.name);
|
||||
chrome.test.succeed("GetAvailableSinks succeded");
|
||||
};
|
||||
chrome.displaySource.getAvailableSinks(callback);
|
||||
};
|
||||
|
||||
var testOnSinksUpdated = function() {
|
||||
var callback = function(sinks) {
|
||||
chrome.test.assertEq(2, sinks.length);
|
||||
var sink = sinks[1];
|
||||
chrome.test.assertEq(2, sink.id);
|
||||
chrome.test.assertEq("Disconnected", sink.state);
|
||||
chrome.test.assertEq("sink 2", sink.name);
|
||||
chrome.test.succeed("onSinksUpdated event delivered");
|
||||
};
|
||||
chrome.displaySource.onSinksUpdated.addListener(callback);
|
||||
};
|
||||
|
||||
var testRequestAuthentication = function() {
|
||||
var callback = function(auth_info) {
|
||||
chrome.test.assertEq("PBC", auth_info.method);
|
||||
chrome.test.succeed("RequestAuthentication succeded");
|
||||
};
|
||||
chrome.displaySource.requestAuthentication(1, callback);
|
||||
};
|
||||
|
||||
chrome.test.runTests([testGetAvailableSinks,
|
||||
testOnSinksUpdated,
|
||||
testRequestAuthentication]);
|
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "chrome.displaySource",
|
||||
"version": "0.1",
|
||||
"description": "end-to-end browser test for chrome.displaySource API",
|
||||
"app": {
|
||||
"background": {
|
||||
"scripts": ["background.js"]
|
||||
}
|
||||
},
|
||||
"permissions": ["displaySource"]
|
||||
}
|
||||
|
@@ -59445,6 +59445,7 @@ http://cs/file:chrome/histograms.xml - but prefer this file for new entries.
|
||||
<int value="389" label="EASY_UNLOCK_PRIVATE_ON_CONNECTION_STATUS_CHANGED"/>
|
||||
<int value="390" label="EASY_UNLOCK_PRIVATE_ON_DATA_RECEIVED"/>
|
||||
<int value="391" label="EASY_UNLOCK_PRIVATE_ON_SEND_COMPLETED"/>
|
||||
<int value="392" label="DISPLAY_SOURCE_ON_SINKS_UPDATED"/>
|
||||
</enum>
|
||||
|
||||
<enum name="ExtensionFileWriteResult" type="int">
|
||||
@@ -60588,6 +60589,8 @@ http://cs/file:chrome/histograms.xml - but prefer this file for new entries.
|
||||
<int value="1095" label="SETTINGSPRIVATE_SETDEFAULTZOOMPERCENTFUNCTION"/>
|
||||
<int value="1096" label="BLUETOOTHPRIVATE_CONNECT"/>
|
||||
<int value="1097" label="BLUETOOTHPRIVATE_FORGETDEVICE"/>
|
||||
<int value="1098" label="DISPLAYSOURCE_GETAVAILABLESINKS"/>
|
||||
<int value="1099" label="DISPLAYSOURCE_REQUESTAUTHENTICATION"/>
|
||||
</enum>
|
||||
|
||||
<enum name="ExtensionInstallCause" type="int">
|
||||
|
Reference in New Issue
Block a user