Commit acff9bd3 authored by Christian Dullweber's avatar Christian Dullweber Committed by Commit Bot

Pass top_frame_origin through media code

To correctly apply content settings, we need to know the
top_frame_origin any time cookies are used. Currently we only have
site_for_cookies, which is empty in third_party frames.

Bug: 988398
Change-Id: Icb724aaaf89c244aa7aebdbaceb1f9a8c3c3ec91
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1731900
Commit-Queue: Christian Dullweber <dullweber@chromium.org>
Reviewed-by: default avatarDominick Ng <dominickn@chromium.org>
Reviewed-by: default avatarJohn Rummell <jrummell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#688464}
parent 68944cab
...@@ -123,7 +123,8 @@ void MediaPlayerRenderer::CreateMediaPlayer( ...@@ -123,7 +123,8 @@ void MediaPlayerRenderer::CreateMediaPlayer(
base::android::SDK_VERSION_KITKAT; base::android::SDK_VERSION_KITKAT;
media_player_.reset(new media::MediaPlayerBridge( media_player_.reset(new media::MediaPlayerBridge(
url_params.media_url, url_params.site_for_cookies, user_agent, url_params.media_url, url_params.site_for_cookies,
url_params.top_frame_origin, user_agent,
false, // hide_url_log false, // hide_url_log
this, // MediaPlayerBridge::Client this, // MediaPlayerBridge::Client
allow_credentials, url_params.is_hls)); allow_credentials, url_params.is_hls));
......
...@@ -130,6 +130,7 @@ void MediaResourceGetterImpl::GetAuthCredentials( ...@@ -130,6 +130,7 @@ void MediaResourceGetterImpl::GetAuthCredentials(
void MediaResourceGetterImpl::GetCookies(const GURL& url, void MediaResourceGetterImpl::GetCookies(const GURL& url,
const GURL& site_for_cookies, const GURL& site_for_cookies,
const url::Origin& top_frame_origin,
GetCookieCB callback) { GetCookieCB callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
...@@ -147,11 +148,8 @@ void MediaResourceGetterImpl::GetCookies(const GURL& url, ...@@ -147,11 +148,8 @@ void MediaResourceGetterImpl::GetCookies(const GURL& url,
browser_context_, url, render_process_id_, render_frame_id_); browser_context_, url, render_process_id_, render_frame_id_);
network::mojom::RestrictedCookieManager* cookie_manager_ptr = network::mojom::RestrictedCookieManager* cookie_manager_ptr =
cookie_manager.get(); cookie_manager.get();
// TODO(crbug.com/988398): Same check as in mojo_renderer_service.cc. Is this
// correct?
DCHECK(!site_for_cookies.is_empty());
cookie_manager_ptr->GetCookiesString( cookie_manager_ptr->GetCookiesString(
url, site_for_cookies, url::Origin::Create(site_for_cookies), url, site_for_cookies, top_frame_origin,
base::BindOnce(&ReturnResultOnUIThreadAndClosePipe, base::BindOnce(&ReturnResultOnUIThreadAndClosePipe,
std::move(cookie_manager), std::move(callback))); std::move(cookie_manager), std::move(callback)));
} }
......
...@@ -46,6 +46,7 @@ class MediaResourceGetterImpl : public media::MediaResourceGetter { ...@@ -46,6 +46,7 @@ class MediaResourceGetterImpl : public media::MediaResourceGetter {
GetAuthCredentialsCB callback) override; GetAuthCredentialsCB callback) override;
void GetCookies(const GURL& url, void GetCookies(const GURL& url,
const GURL& site_for_cookies, const GURL& site_for_cookies,
const url::Origin& top_frame_origin,
GetCookieCB callback) override; GetCookieCB callback) override;
void GetPlatformPathFromURL(const GURL& url, void GetPlatformPathFromURL(const GURL& url,
GetPlatformPathCB callback) override; GetPlatformPathCB callback) override;
......
...@@ -191,6 +191,7 @@ jumbo_source_set("base") { ...@@ -191,6 +191,7 @@ jumbo_source_set("base") {
"media_types.h", "media_types.h",
"media_url_demuxer.cc", "media_url_demuxer.cc",
"media_url_demuxer.h", "media_url_demuxer.h",
"media_url_params.cc",
"media_url_params.h", "media_url_params.h",
"media_util.cc", "media_util.cc",
"media_util.h", "media_util.h",
......
...@@ -65,6 +65,7 @@ void RecordWatchTimeUMA(bool is_hls, bool has_video) { ...@@ -65,6 +65,7 @@ void RecordWatchTimeUMA(bool is_hls, bool has_video) {
MediaPlayerBridge::MediaPlayerBridge(const GURL& url, MediaPlayerBridge::MediaPlayerBridge(const GURL& url,
const GURL& site_for_cookies, const GURL& site_for_cookies,
const url::Origin& top_frame_origin,
const std::string& user_agent, const std::string& user_agent,
bool hide_url_log, bool hide_url_log,
Client* client, Client* client,
...@@ -75,6 +76,7 @@ MediaPlayerBridge::MediaPlayerBridge(const GURL& url, ...@@ -75,6 +76,7 @@ MediaPlayerBridge::MediaPlayerBridge(const GURL& url,
should_seek_on_prepare_(false), should_seek_on_prepare_(false),
url_(url), url_(url),
site_for_cookies_(site_for_cookies), site_for_cookies_(site_for_cookies),
top_frame_origin_(top_frame_origin),
user_agent_(user_agent), user_agent_(user_agent),
hide_url_log_(hide_url_log), hide_url_log_(hide_url_log),
width_(0), width_(0),
...@@ -123,7 +125,7 @@ void MediaPlayerBridge::Initialize() { ...@@ -123,7 +125,7 @@ void MediaPlayerBridge::Initialize() {
client_->GetMediaResourceGetter(); client_->GetMediaResourceGetter();
resource_getter->GetCookies( resource_getter->GetCookies(
url_, site_for_cookies_, url_, site_for_cookies_, top_frame_origin_,
base::BindOnce(&MediaPlayerBridge::OnCookiesRetrieved, base::BindOnce(&MediaPlayerBridge::OnCookiesRetrieved,
weak_factory_.GetWeakPtr())); weak_factory_.GetWeakPtr()));
} }
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "media/base/simple_watch_timer.h" #include "media/base/simple_watch_timer.h"
#include "ui/gl/android/scoped_java_surface.h" #include "ui/gl/android/scoped_java_surface.h"
#include "url/gurl.h" #include "url/gurl.h"
#include "url/origin.h"
namespace media { namespace media {
...@@ -78,6 +79,7 @@ class MEDIA_EXPORT MediaPlayerBridge { ...@@ -78,6 +79,7 @@ class MEDIA_EXPORT MediaPlayerBridge {
// the |manager| when needed. // the |manager| when needed.
MediaPlayerBridge(const GURL& url, MediaPlayerBridge(const GURL& url,
const GURL& site_for_cookies, const GURL& site_for_cookies,
const url::Origin& top_frame_origin,
const std::string& user_agent, const std::string& user_agent,
bool hide_url_log, bool hide_url_log,
Client* client, Client* client,
...@@ -209,9 +211,12 @@ class MEDIA_EXPORT MediaPlayerBridge { ...@@ -209,9 +211,12 @@ class MEDIA_EXPORT MediaPlayerBridge {
// Url for playback. // Url for playback.
GURL url_; GURL url_;
// First party url for cookies. // Used to determine if cookies are accessed in a third-party context.
GURL site_for_cookies_; GURL site_for_cookies_;
// Used to check for cookie content settings.
url::Origin top_frame_origin_;
// User agent string to be used for media player. // User agent string to be used for media player.
const std::string user_agent_; const std::string user_agent_;
......
...@@ -31,7 +31,14 @@ class MockMediaPlayerBridgeClient : public MediaPlayerBridge::Client { ...@@ -31,7 +31,14 @@ class MockMediaPlayerBridgeClient : public MediaPlayerBridge::Client {
class MediaPlayerBridgeTest : public testing::Test { class MediaPlayerBridgeTest : public testing::Test {
public: public:
MediaPlayerBridgeTest() MediaPlayerBridgeTest()
: bridge_(GURL(), GURL(), "", false, &client_, false, false) {} : bridge_(GURL(),
GURL(),
url::Origin(),
"",
false,
&client_,
false,
false) {}
protected: protected:
void SimulateDurationChange(base::TimeDelta duration) { void SimulateDurationChange(base::TimeDelta duration) {
......
...@@ -15,6 +15,10 @@ ...@@ -15,6 +15,10 @@
#include "media/base/media_export.h" #include "media/base/media_export.h"
#include "url/gurl.h" #include "url/gurl.h"
namespace url {
class Origin;
}
namespace media { namespace media {
// Class for asynchronously retrieving resources for a media URL. All callbacks // Class for asynchronously retrieving resources for a media URL. All callbacks
...@@ -44,6 +48,7 @@ class MEDIA_EXPORT MediaResourceGetter { ...@@ -44,6 +48,7 @@ class MEDIA_EXPORT MediaResourceGetter {
// Method for getting the cookies for a given URL. // Method for getting the cookies for a given URL.
virtual void GetCookies(const GURL& url, virtual void GetCookies(const GURL& url,
const GURL& site_for_cookies, const GURL& site_for_cookies,
const url::Origin& top_frame_origin,
GetCookieCB callback) = 0; GetCookieCB callback) = 0;
// Method for getting the platform path from a file system URL. // Method for getting the platform path from a file system URL.
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "media/base/media_resource.h" #include "media/base/media_resource.h"
#include "base/no_destructor.h"
#include "url/origin.h"
namespace media { namespace media {
...@@ -10,9 +12,11 @@ MediaResource::MediaResource() = default; ...@@ -10,9 +12,11 @@ MediaResource::MediaResource() = default;
MediaResource::~MediaResource() = default; MediaResource::~MediaResource() = default;
MediaUrlParams MediaResource::GetMediaUrlParams() const { const MediaUrlParams& MediaResource::GetMediaUrlParams() const {
NOTREACHED(); NOTREACHED();
return MediaUrlParams{GURL(), GURL(), false, false}; static base::NoDestructor<MediaUrlParams> instance{
GURL(), GURL(), url::Origin(), false, false};
return *instance;
} }
MediaResource::Type MediaResource::GetType() const { MediaResource::Type MediaResource::GetType() const {
......
...@@ -55,7 +55,7 @@ class MEDIA_EXPORT MediaResource { ...@@ -55,7 +55,7 @@ class MEDIA_EXPORT MediaResource {
// and should be handled appropriately by the caller. // and should be handled appropriately by the caller.
// Other types: // Other types:
// Should not be called. // Should not be called.
virtual MediaUrlParams GetMediaUrlParams() const; virtual const MediaUrlParams& GetMediaUrlParams() const;
// This method is only used with the MediaUrlDemuxer, to propagate duration // This method is only used with the MediaUrlDemuxer, to propagate duration
// changes coming from the MediaPlayerRendereClient. // changes coming from the MediaPlayerRendereClient.
......
...@@ -13,9 +13,11 @@ MediaUrlDemuxer::MediaUrlDemuxer( ...@@ -13,9 +13,11 @@ MediaUrlDemuxer::MediaUrlDemuxer(
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
const GURL& media_url, const GURL& media_url,
const GURL& site_for_cookies, const GURL& site_for_cookies,
const url::Origin& top_frame_origin,
bool allow_credentials, bool allow_credentials,
bool is_hls) bool is_hls)
: params_{media_url, site_for_cookies, allow_credentials, is_hls}, : params_{media_url, site_for_cookies, top_frame_origin, allow_credentials,
is_hls},
task_runner_(task_runner) {} task_runner_(task_runner) {}
MediaUrlDemuxer::~MediaUrlDemuxer() = default; MediaUrlDemuxer::~MediaUrlDemuxer() = default;
...@@ -26,7 +28,7 @@ std::vector<DemuxerStream*> MediaUrlDemuxer::GetAllStreams() { ...@@ -26,7 +28,7 @@ std::vector<DemuxerStream*> MediaUrlDemuxer::GetAllStreams() {
return std::vector<DemuxerStream*>(); return std::vector<DemuxerStream*>();
} }
MediaUrlParams MediaUrlDemuxer::GetMediaUrlParams() const { const MediaUrlParams& MediaUrlDemuxer::GetMediaUrlParams() const {
return params_; return params_;
} }
......
...@@ -36,13 +36,14 @@ class MEDIA_EXPORT MediaUrlDemuxer : public Demuxer { ...@@ -36,13 +36,14 @@ class MEDIA_EXPORT MediaUrlDemuxer : public Demuxer {
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
const GURL& media_url, const GURL& media_url,
const GURL& site_for_cookies, const GURL& site_for_cookies,
const url::Origin& top_frame_origin,
bool allow_credentials, bool allow_credentials,
bool is_hls); bool is_hls);
~MediaUrlDemuxer() override; ~MediaUrlDemuxer() override;
// MediaResource interface. // MediaResource interface.
std::vector<DemuxerStream*> GetAllStreams() override; std::vector<DemuxerStream*> GetAllStreams() override;
MediaUrlParams GetMediaUrlParams() const override; const MediaUrlParams& GetMediaUrlParams() const override;
MediaResource::Type GetType() const override; MediaResource::Type GetType() const override;
void ForwardDurationChangeToDemuxerHost(base::TimeDelta duration) override; void ForwardDurationChangeToDemuxerHost(base::TimeDelta duration) override;
......
...@@ -24,9 +24,9 @@ class MediaUrlDemuxerTest : public testing::Test { ...@@ -24,9 +24,9 @@ class MediaUrlDemuxerTest : public testing::Test {
void InitializeTest(const GURL& media_url, void InitializeTest(const GURL& media_url,
const GURL& first_party, const GURL& first_party,
bool allow_credentials) { bool allow_credentials) {
demuxer_.reset(new MediaUrlDemuxer(base::ThreadTaskRunnerHandle::Get(), demuxer_.reset(new MediaUrlDemuxer(
media_url, first_party, base::ThreadTaskRunnerHandle::Get(), media_url, first_party,
allow_credentials, false)); url::Origin::Create(first_party), allow_credentials, false));
} }
void InitializeTest() { void InitializeTest() {
...@@ -53,7 +53,7 @@ TEST_F(MediaUrlDemuxerTest, BaseCase) { ...@@ -53,7 +53,7 @@ TEST_F(MediaUrlDemuxerTest, BaseCase) {
EXPECT_EQ(MediaResource::Type::URL, demuxer_->GetType()); EXPECT_EQ(MediaResource::Type::URL, demuxer_->GetType());
MediaUrlParams params = demuxer_->GetMediaUrlParams(); const MediaUrlParams& params = demuxer_->GetMediaUrlParams();
EXPECT_EQ(default_media_url_, params.media_url); EXPECT_EQ(default_media_url_, params.media_url);
EXPECT_EQ(default_first_party_url_, params.site_for_cookies); EXPECT_EQ(default_first_party_url_, params.site_for_cookies);
EXPECT_EQ(true, params.allow_credentials); EXPECT_EQ(true, params.allow_credentials);
...@@ -62,7 +62,7 @@ TEST_F(MediaUrlDemuxerTest, BaseCase) { ...@@ -62,7 +62,7 @@ TEST_F(MediaUrlDemuxerTest, BaseCase) {
TEST_F(MediaUrlDemuxerTest, AcceptsEmptyStrings) { TEST_F(MediaUrlDemuxerTest, AcceptsEmptyStrings) {
InitializeTest(GURL(), GURL(), false); InitializeTest(GURL(), GURL(), false);
MediaUrlParams params = demuxer_->GetMediaUrlParams(); const MediaUrlParams& params = demuxer_->GetMediaUrlParams();
EXPECT_EQ(GURL::EmptyGURL(), params.media_url); EXPECT_EQ(GURL::EmptyGURL(), params.media_url);
EXPECT_EQ(GURL::EmptyGURL(), params.site_for_cookies); EXPECT_EQ(GURL::EmptyGURL(), params.site_for_cookies);
EXPECT_EQ(false, params.allow_credentials); EXPECT_EQ(false, params.allow_credentials);
......
// Copyright 2019 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 "media/base/media_url_params.h"
namespace media {
MediaUrlParams::MediaUrlParams(GURL media_url,
GURL site_for_cookies,
url::Origin top_frame_origin,
bool allow_credentials,
bool is_hls)
: media_url(std::move(media_url)),
site_for_cookies(std::move(site_for_cookies)),
top_frame_origin(std::move(top_frame_origin)),
allow_credentials(allow_credentials),
is_hls(is_hls) {}
MediaUrlParams::MediaUrlParams(const MediaUrlParams& other) = default;
MediaUrlParams::~MediaUrlParams() = default;
} // namespace media
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "media/base/media_export.h" #include "media/base/media_export.h"
#include "url/gurl.h" #include "url/gurl.h"
#include "url/origin.h"
namespace media { namespace media {
...@@ -14,17 +15,26 @@ namespace media { ...@@ -14,17 +15,26 @@ namespace media {
// playback (as opposed to stream based). // playback (as opposed to stream based).
// See MediaUrlDemuxer and MediaPlayerRenderer. // See MediaUrlDemuxer and MediaPlayerRenderer.
struct MEDIA_EXPORT MediaUrlParams { struct MEDIA_EXPORT MediaUrlParams {
MediaUrlParams(GURL media_url,
GURL site_for_cookies,
url::Origin top_frame_origin,
bool allow_credentials,
bool is_hls);
MediaUrlParams(const MediaUrlParams& other);
~MediaUrlParams();
// URL of the media to be played. // URL of the media to be played.
GURL media_url; GURL media_url;
// Used to play media in authenticated scenarios. // Used to play media in authenticated scenarios.
// NOTE: This URL is not the first party cookies, but the first party URL
// returned by blink::WebDocument::firstPartyForCookies().
// In the MediaPlayerRenderer case, it will ultimately be used in // In the MediaPlayerRenderer case, it will ultimately be used in
// MediaResourceGetterTask::CheckPolicyForCookies, to limit the scope of the // MediaResourceGetterTask::CheckPolicyForCookies, to limit the scope of the
// cookies that the MediaPlayerRenderer has access to. // cookies that the MediaPlayerRenderer has access to.
GURL site_for_cookies; GURL site_for_cookies;
// Used to check for cookie content settings.
url::Origin top_frame_origin;
// True when the crossorigin mode is unspecified or set to "use-credentials", // True when the crossorigin mode is unspecified or set to "use-credentials",
// false when it's "anonymous". // false when it's "anonymous".
// //
......
...@@ -141,7 +141,7 @@ class MockMediaResource : public MediaResource { ...@@ -141,7 +141,7 @@ class MockMediaResource : public MediaResource {
MOCK_CONST_METHOD0(GetType, MediaResource::Type()); MOCK_CONST_METHOD0(GetType, MediaResource::Type());
MOCK_METHOD0(GetAllStreams, std::vector<DemuxerStream*>()); MOCK_METHOD0(GetAllStreams, std::vector<DemuxerStream*>());
MOCK_METHOD1(GetFirstStream, DemuxerStream*(DemuxerStream::Type type)); MOCK_METHOD1(GetFirstStream, DemuxerStream*(DemuxerStream::Type type));
MOCK_CONST_METHOD0(GetMediaUrlParams, MediaUrlParams()); MOCK_CONST_METHOD0(GetMediaUrlParams, const MediaUrlParams&());
}; };
class MockDemuxer : public Demuxer { class MockDemuxer : public Demuxer {
......
...@@ -2662,6 +2662,7 @@ void WebMediaPlayerImpl::StartPipeline() { ...@@ -2662,6 +2662,7 @@ void WebMediaPlayerImpl::StartPipeline() {
demuxer_.reset(new MediaUrlDemuxer( demuxer_.reset(new MediaUrlDemuxer(
media_task_runner_, loaded_url_, frame_->GetDocument().SiteForCookies(), media_task_runner_, loaded_url_, frame_->GetDocument().SiteForCookies(),
frame_->GetDocument().TopFrameOrigin(),
allow_media_player_renderer_credentials_, demuxer_found_hls_)); allow_media_player_renderer_credentials_, demuxer_found_hls_));
pipeline_controller_->Start(Pipeline::StartType::kNormal, demuxer_.get(), pipeline_controller_->Start(Pipeline::StartType::kNormal, demuxer_.get(),
this, false, false); this, false, false);
......
...@@ -115,14 +115,15 @@ void MojoRenderer::InitializeRendererFromUrl(media::RendererClient* client) { ...@@ -115,14 +115,15 @@ void MojoRenderer::InitializeRendererFromUrl(media::RendererClient* client) {
mojom::RendererClientAssociatedPtrInfo client_ptr_info; mojom::RendererClientAssociatedPtrInfo client_ptr_info;
client_binding_.Bind(mojo::MakeRequest(&client_ptr_info)); client_binding_.Bind(mojo::MakeRequest(&client_ptr_info));
MediaUrlParams url_params = media_resource_->GetMediaUrlParams(); const MediaUrlParams& url_params = media_resource_->GetMediaUrlParams();
// Using base::Unretained(this) is safe because |this| owns // Using base::Unretained(this) is safe because |this| owns
// |remote_renderer_|, and the callback won't be dispatched if // |remote_renderer_|, and the callback won't be dispatched if
// |remote_renderer_| is destroyed. // |remote_renderer_| is destroyed.
mojom::MediaUrlParamsPtr media_url_params = mojom::MediaUrlParams::New( mojom::MediaUrlParamsPtr media_url_params = mojom::MediaUrlParams::New(
url_params.media_url, url_params.site_for_cookies, url_params.media_url, url_params.site_for_cookies,
url_params.allow_credentials, url_params.is_hls); url_params.top_frame_origin, url_params.allow_credentials,
url_params.is_hls);
remote_renderer_->Initialize( remote_renderer_->Initialize(
std::move(client_ptr_info), base::nullopt, std::move(media_url_params), std::move(client_ptr_info), base::nullopt, std::move(media_url_params),
base::Bind(&MojoRenderer::OnInitialized, base::Unretained(this), client)); base::Bind(&MojoRenderer::OnInitialized, base::Unretained(this), client));
......
...@@ -10,11 +10,13 @@ import "mojo/public/mojom/base/time.mojom"; ...@@ -10,11 +10,13 @@ import "mojo/public/mojom/base/time.mojom";
import "mojo/public/mojom/base/unguessable_token.mojom"; import "mojo/public/mojom/base/unguessable_token.mojom";
import "ui/gfx/geometry/mojom/geometry.mojom"; import "ui/gfx/geometry/mojom/geometry.mojom";
import "url/mojom/url.mojom"; import "url/mojom/url.mojom";
import "url/mojom/origin.mojom";
// See media/base/media_url_params.h for descriptions. // See media/base/media_url_params.h for descriptions.
struct MediaUrlParams { struct MediaUrlParams {
url.mojom.Url media_url; url.mojom.Url media_url;
url.mojom.Url site_for_cookies; url.mojom.Url site_for_cookies;
url.mojom.Origin top_frame_origin;
bool allow_credentials; bool allow_credentials;
bool is_hls; bool is_hls;
}; };
......
...@@ -83,10 +83,10 @@ void MojoRendererService::Initialize( ...@@ -83,10 +83,10 @@ void MojoRendererService::Initialize(
} }
DCHECK(!media_url_params->media_url.is_empty()); DCHECK(!media_url_params->media_url.is_empty());
DCHECK(!media_url_params->site_for_cookies.is_empty());
media_resource_.reset(new MediaUrlDemuxer( media_resource_.reset(new MediaUrlDemuxer(
nullptr, media_url_params->media_url, media_url_params->site_for_cookies, nullptr, media_url_params->media_url, media_url_params->site_for_cookies,
media_url_params->allow_credentials, media_url_params->is_hls)); media_url_params->top_frame_origin, media_url_params->allow_credentials,
media_url_params->is_hls));
renderer_->Initialize( renderer_->Initialize(
media_resource_.get(), this, media_resource_.get(), this,
base::Bind(&MojoRendererService::OnRendererInitializeDone, weak_this_, base::Bind(&MojoRendererService::OnRendererInitializeDone, weak_this_,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment