blob: d15a55e24ac3a24e1900d70e0407197fd5bb8f4d [file] [log] [blame]
/*
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "cobalt/browser/h5vcc_url_handler.h"
#include <string>
#include "base/bind.h"
#include "cobalt/base/localized_strings.h"
#include "cobalt/browser/browser_module.h"
namespace cobalt {
namespace browser {
namespace {
// Utility functions to get info from a GURL. Because our scheme is
// non-standard, the methods in GURL will not parse the components for us.
std::string GetH5vccUrlType(const GURL& url) {
const std::string path = url.path();
size_t start = path.find_first_not_of("/");
if (start == std::string::npos) {
DLOG(WARNING) << "Cannot determine type of URL.";
return "";
}
size_t end = path.find_first_of("/?&", start);
if (end != std::string::npos) {
end -= start;
}
return path.substr(start, end);
}
std::string GetH5vccUrlQuery(const GURL& url) {
const std::string path = url.path();
size_t start = path.find("?");
if (start == std::string::npos) {
DLOG(WARNING) << "Cannot find query string in URL.";
return "";
}
return path.substr(start + 1);
}
std::string GetH5vccUrlQueryParam(const GURL& url, const std::string& name) {
const std::string query = GetH5vccUrlQuery(url);
size_t name_start = query.find(name);
if (name_start == std::string::npos) {
DLOG(WARNING) << "Query parameter " << name << " not found in URL.";
return "";
}
size_t name_end = query.find("=", name_start);
if (name_end == std::string::npos) {
DLOG(WARNING) << "Value of " << name << " not found in URL.";
return "";
}
size_t value_start = name_end - name_start + 1;
size_t value_end = query.find_first_of("&", value_start);
if (value_end != std::string::npos) {
value_end -= value_start;
}
return query.substr(value_start, value_end);
}
const char kH5vccScheme[] = "h5vcc";
const char kNetworkFailure[] = "network-failure";
const char kSignedOut[] = "signed-out";
const char kAgeRestricted[] = "age-restricted";
const char kRetryParam[] = "retry-url";
const char kNetworkFailureMessageId[] = "UNABLE_TO_CONTACT_YOUTUBE";
const char kNetworkFailureMessageFallback[] = "Unable to contact YouTube";
const char kSignedOutMessageId[] = "OFFLINE_MESSAGE_1";
const char kSignedOutMessageFallback[] =
"You are signed out of PSN. To use YouTube, you need to sign in to PSN.";
const char kAgeRestrictedMessageId[] = "AGE_RESTRICTED";
const char kAgeRestrictedMessageFallback[] =
"YouTube is not intended for use by children under 13.";
} // namespace
H5vccURLHandler::H5vccURLHandler(BrowserModule* browser_module,
system_window::SystemWindow* system_window,
account::AccountManager* account_manager)
: ALLOW_THIS_IN_INITIALIZER_LIST(URLHandler(
browser_module,
base::Bind(&H5vccURLHandler::HandleURL, base::Unretained(this)))),
system_window_(system_window),
account_manager_(account_manager) {}
bool H5vccURLHandler::HandleURL(const GURL& url) {
bool was_handled = false;
if (url.SchemeIs(kH5vccScheme)) {
url_ = url;
const std::string type = GetH5vccUrlType(url);
if (type == kNetworkFailure) {
was_handled = HandleNetworkFailure();
} else if (type == kSignedOut) {
was_handled = HandleSignedOut();
} else if (type == kAgeRestricted) {
was_handled = HandleAgeRestricted();
} else {
LOG(WARNING) << "Unknown h5vcc URL type: " << type;
}
}
return was_handled;
}
bool H5vccURLHandler::HandleNetworkFailure() {
system_window::SystemWindow::DialogOptions dialog_options;
dialog_options.message = base::LocalizedStrings::GetInstance()->GetString(
kNetworkFailureMessageId, kNetworkFailureMessageFallback);
dialog_options.num_buttons = 1;
dialog_options.callback = base::Bind(
&H5vccURLHandler::OnNetworkFailureDialogResponse, base::Unretained(this));
system_window_->ShowDialog(dialog_options);
return true;
}
bool H5vccURLHandler::HandleSignedOut() {
system_window::SystemWindow::DialogOptions dialog_options;
dialog_options.message = base::LocalizedStrings::GetInstance()->GetString(
kSignedOutMessageId, kSignedOutMessageFallback);
dialog_options.num_buttons = 1;
dialog_options.callback = base::Bind(
&H5vccURLHandler::OnSignedOutDialogResponse, base::Unretained(this));
system_window_->ShowDialog(dialog_options);
return true;
}
bool H5vccURLHandler::HandleAgeRestricted() {
system_window::SystemWindow::DialogOptions dialog_options;
dialog_options.message = base::LocalizedStrings::GetInstance()->GetString(
kAgeRestrictedMessageId, kAgeRestrictedMessageFallback);
dialog_options.num_buttons = 0;
system_window_->ShowDialog(dialog_options);
return true;
}
void H5vccURLHandler::OnNetworkFailureDialogResponse(
system_window::SystemWindow::DialogResponse response) {
UNREFERENCED_PARAMETER(response);
const std::string retry_url = GetH5vccUrlQueryParam(url_, kRetryParam);
if (retry_url.length() > 0) {
GURL url(retry_url);
if (url.is_valid()) {
browser_module()->Navigate(GURL(retry_url));
}
}
}
void H5vccURLHandler::OnSignedOutDialogResponse(
system_window::SystemWindow::DialogResponse response) {
UNREFERENCED_PARAMETER(response);
account_manager_->StartSignIn();
}
} // namespace browser
} // namespace cobalt