Skip to content

Commit

Permalink
Ensure cookies retrieved before setDataSource.
Browse files Browse the repository at this point in the history
When invoking MediaPlayer's setDataSource() API, cookies may not retrieved.
In some case the media will playback failed if the required cookies absent.

This CL will check whether the cookies are retrieved before call this
API. API call will be pending until cookies retrieved.

Bug: 1157376
Change-Id: I43f04461af86c83e53a169bb4df35cbe20419b6d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2584203
Commit-Queue: Thomas Guilbert <tguilbert@chromium.org>
Reviewed-by: Thomas Guilbert <tguilbert@chromium.org>
Cr-Commit-Position: refs/heads/master@{#836018}
  • Loading branch information
Lei Gao authored and Chromium LUCI CQ committed Dec 11, 2020
1 parent b1a39ac commit 447ade6
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 21 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,7 @@ Lavar Askew <open.hyperion@gmail.com>
Le Hoang Quyen <le.hoang.q@gmail.com>
Legend Lee <guanxian.li@intel.com>
Leith Bade <leith@leithalweapon.geek.nz>
Lei Gao <leigao@huawei.com>
Lei Li <lli.kernel.kvm@gmail.com>
Lenny Khazan <lenny.khazan@gmail.com>
Leo Wolf <jclw@ymail.com>
Expand Down
72 changes: 51 additions & 21 deletions media/base/android/media_player_bridge.cc
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ MediaPlayerBridge::MediaPlayerBridge(const GURL& url,
url_(url),
site_for_cookies_(site_for_cookies),
top_frame_origin_(top_frame_origin),
pending_retrieve_cookies_(false),
should_prepare_on_retrieved_cookies_(false),
user_agent_(user_agent),
hide_url_log_(hide_url_log),
width_(0),
Expand Down Expand Up @@ -127,6 +129,7 @@ void MediaPlayerBridge::Initialize() {
media::MediaResourceGetter* resource_getter =
client_->GetMediaResourceGetter();

pending_retrieve_cookies_ = true;
resource_getter->GetCookies(
url_, site_for_cookies_, top_frame_origin_,
base::BindOnce(&MediaPlayerBridge::OnCookiesRetrieved,
Expand Down Expand Up @@ -200,31 +203,52 @@ void MediaPlayerBridge::SetDataSource(const std::string& url) {
OnMediaError(MEDIA_ERROR_FORMAT);
return;
}
} else {
// Create a Java String for the URL.
ScopedJavaLocalRef<jstring> j_url_string =
ConvertUTF8ToJavaString(env, url);

const std::string data_uri_prefix("data:");
if (base::StartsWith(url, data_uri_prefix, base::CompareCase::SENSITIVE)) {
if (!Java_MediaPlayerBridge_setDataUriDataSource(
env, j_media_player_bridge_, j_url_string)) {
OnMediaError(MEDIA_ERROR_FORMAT);
}
return;
}

ScopedJavaLocalRef<jstring> j_cookies = ConvertUTF8ToJavaString(
env, cookies_);
ScopedJavaLocalRef<jstring> j_user_agent = ConvertUTF8ToJavaString(
env, user_agent_);
if (!Java_MediaPlayerBridge_prepareAsync(env, j_media_player_bridge_))
OnMediaError(MEDIA_ERROR_FORMAT);

return;
}

if (!Java_MediaPlayerBridge_setDataSource(env, j_media_player_bridge_,
j_url_string, j_cookies,
j_user_agent, hide_url_log_)) {
// Create a Java String for the URL.
ScopedJavaLocalRef<jstring> j_url_string = ConvertUTF8ToJavaString(env, url);

const std::string data_uri_prefix("data:");
if (base::StartsWith(url, data_uri_prefix, base::CompareCase::SENSITIVE)) {
if (!Java_MediaPlayerBridge_setDataUriDataSource(
env, j_media_player_bridge_, j_url_string)) {
OnMediaError(MEDIA_ERROR_FORMAT);
return;
}
return;
}

// Cookies may not have been retrieved yet, delay prepare until they are
// retrieved.
if (pending_retrieve_cookies_) {
should_prepare_on_retrieved_cookies_ = true;
return;
}
SetDataSourceInternal();
}

void MediaPlayerBridge::SetDataSourceInternal() {
DCHECK(!pending_retrieve_cookies_);

JNIEnv* env = base::android::AttachCurrentThread();
CHECK(env);

ScopedJavaLocalRef<jstring> j_cookies =
ConvertUTF8ToJavaString(env, cookies_);
ScopedJavaLocalRef<jstring> j_user_agent =
ConvertUTF8ToJavaString(env, user_agent_);
ScopedJavaLocalRef<jstring> j_url_string =
ConvertUTF8ToJavaString(env, url_.spec());

if (!Java_MediaPlayerBridge_setDataSource(env, j_media_player_bridge_,
j_url_string, j_cookies,
j_user_agent, hide_url_log_)) {
OnMediaError(MEDIA_ERROR_FORMAT);
return;
}

if (!Java_MediaPlayerBridge_prepareAsync(env, j_media_player_bridge_))
Expand Down Expand Up @@ -267,9 +291,15 @@ void MediaPlayerBridge::OnDidSetDataUriDataSource(

void MediaPlayerBridge::OnCookiesRetrieved(const std::string& cookies) {
cookies_ = cookies;
pending_retrieve_cookies_ = false;
client_->GetMediaResourceGetter()->GetAuthCredentials(
url_, base::BindOnce(&MediaPlayerBridge::OnAuthCredentialsRetrieved,
weak_factory_.GetWeakPtr()));

if (should_prepare_on_retrieved_cookies_) {
SetDataSourceInternal();
should_prepare_on_retrieved_cookies_ = false;
}
}

void MediaPlayerBridge::OnAuthCredentialsRetrieved(
Expand Down
7 changes: 7 additions & 0 deletions media/base/android/media_player_bridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ class MEDIA_EXPORT MediaPlayerBridge {

// Set the data source for the media player.
void SetDataSource(const std::string& url);
void SetDataSourceInternal();

// Functions that implements media player control.
void StartInternal();
Expand Down Expand Up @@ -220,6 +221,12 @@ class MEDIA_EXPORT MediaPlayerBridge {
// Used to check for cookie content settings.
url::Origin top_frame_origin_;

// Waiting to retrieve cookies for |url_|.
bool pending_retrieve_cookies_;

// Whether to prepare after cookies retrieved.
bool should_prepare_on_retrieved_cookies_;

// User agent string to be used for media player.
const std::string user_agent_;

Expand Down

0 comments on commit 447ade6

Please sign in to comment.