Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3522)

Unified Diff: chrome/browser/ui/webui/vr_shell/vr_shell_ui_ui.cc

Issue 2341803003: Add chrome://vr-shell-ui internal page (Closed)
Patch Set: More clean up Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/webui/vr_shell/vr_shell_ui_ui.cc
diff --git a/chrome/browser/ui/webui/vr_shell/vr_shell_ui_ui.cc b/chrome/browser/ui/webui/vr_shell/vr_shell_ui_ui.cc
new file mode 100644
index 0000000000000000000000000000000000000000..d2c28c4669024a4f1541b61fd8addd84bfb473c7
--- /dev/null
+++ b/chrome/browser/ui/webui/vr_shell/vr_shell_ui_ui.cc
@@ -0,0 +1,194 @@
+// Copyright 2016 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/ui/webui/vr_shell/vr_shell_ui_ui.h"
+
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/webui/vr_shell/vr_shell_ui_message_handler.h"
+#include "chrome/common/url_constants.h"
+#include "content/public/browser/web_ui.h"
+#if !defined(ENABLE_VR_SHELL_UI_DEV)
xiyuan 2016/09/15 22:58:47 nit: insert an empty line before to make it easier
bshe 2016/09/16 18:27:53 Done.
+#include "chrome/grit/browser_resources.h"
+#include "content/public/browser/web_ui_data_source.h"
+#else
+#include <map>
+#include "base/macros.h"
+#include "base/memory/ref_counted_memory.h"
+#include "base/strings/string_util.h"
+#include "content/public/browser/url_data_source.h"
+#include "net/url_request/url_fetcher.h"
+#include "net/url_request/url_fetcher_delegate.h"
+#include "net/url_request/url_request_context_getter.h"
+#endif
+
+namespace {
+
+#if defined(ENABLE_VR_SHELL_UI_DEV)
+std::string PathWithoutParams(const std::string& path) {
+ return GURL(std::string("chrome://vr-shell-ui/") + path).path().substr(1);
+}
+
+const char kRemoteBase[] = "http://localhost:8080/";
+const char kRemoteBaseAlt[] = "https://jcarpenter.github.io/hoverboard-ui/";
+const char kRemoteDefaultPath[] = "vr_shell_ui.html";
+const char kHttpNotFound[] = "HTTP/1.1 404 Not Found\n\n";
+
+// RemoteDataSource ---------------------------------------------------------
+
+std::string GetMimeTypeForPath(const std::string& path) {
+ std::string filename = PathWithoutParams(path);
+ if (base::EndsWith(filename, ".html", base::CompareCase::INSENSITIVE_ASCII)) {
+ return "text/html";
+ } else if (base::EndsWith(filename, ".css",
+ base::CompareCase::INSENSITIVE_ASCII)) {
+ return "text/css";
+ } else if (base::EndsWith(filename, ".js",
+ base::CompareCase::INSENSITIVE_ASCII)) {
+ return "application/javascript";
+ } else if (base::EndsWith(filename, ".png",
+ base::CompareCase::INSENSITIVE_ASCII)) {
+ return "image/png";
+ } else if (base::EndsWith(filename, ".gif",
+ base::CompareCase::INSENSITIVE_ASCII)) {
+ return "image/gif";
+ } else if (base::EndsWith(filename, ".svg",
+ base::CompareCase::INSENSITIVE_ASCII)) {
+ return "image/svg+xml";
+ } else if (base::EndsWith(filename, ".manifest",
+ base::CompareCase::INSENSITIVE_ASCII)) {
+ return "text/cache-manifest";
+ }
+ return "text/html";
+}
+
+class RemoteDataSource : public content::URLDataSource,
+ public net::URLFetcherDelegate {
+ public:
+ using GotDataCallback = content::URLDataSource::GotDataCallback;
+
+ explicit RemoteDataSource(net::URLRequestContextGetter* request_context);
+
+ // content::URLDataSource implementation.
+ std::string GetSource() const override;
+ void StartDataRequest(const std::string& path,
+ int render_process_id,
+ int render_frame_id,
+ const GotDataCallback& callback) override;
+
+ private:
+ // content::URLDataSource overrides.
+ std::string GetMimeType(const std::string& path) const override;
+ bool ShouldAddContentSecurityPolicy() const override;
+ bool ShouldDenyXFrameOptions() const override;
+ bool ShouldServeMimeTypeAsContentTypeHeader() const override;
+
+ // net::URLFetcherDelegate overrides.
+ void OnURLFetchComplete(const net::URLFetcher* source) override;
+
+ ~RemoteDataSource() override;
+
+ scoped_refptr<net::URLRequestContextGetter> request_context_;
+
+ using PendingRequestsMap = std::map<const net::URLFetcher*, GotDataCallback>;
+ PendingRequestsMap pending_;
+ bool localhost_failed_;
+
+ DISALLOW_COPY_AND_ASSIGN(RemoteDataSource);
+};
+
+RemoteDataSource::RemoteDataSource(
+ net::URLRequestContextGetter* request_context)
+ : request_context_(request_context), localhost_failed_(false) {}
+
+RemoteDataSource::~RemoteDataSource() {
+ for (const auto& pair : pending_) {
+ delete pair.first;
+ pair.second.Run(
+ new base::RefCountedStaticMemory(kHttpNotFound, strlen(kHttpNotFound)));
+ }
+}
+
+std::string RemoteDataSource::GetSource() const {
+ return chrome::kChromeUIVrShellUIHost;
+}
+
+void RemoteDataSource::StartDataRequest(
+ const std::string& path,
+ int render_process_id,
+ int render_frame_id,
+ const content::URLDataSource::GotDataCallback& callback) {
+ GURL url = GURL((localhost_failed_ ? kRemoteBaseAlt : kRemoteBase) +
+ (path.empty() ? std::string(kRemoteDefaultPath) : path));
+ if (!url.is_valid()) {
+ callback.Run(
+ new base::RefCountedStaticMemory(kHttpNotFound, strlen(kHttpNotFound)));
+ return;
+ }
+ net::URLFetcher* fetcher =
+ net::URLFetcher::Create(url, net::URLFetcher::GET, this).release();
+ pending_[fetcher] = callback;
+ fetcher->SetRequestContext(request_context_.get());
+ fetcher->Start();
+}
+
+std::string RemoteDataSource::GetMimeType(const std::string& path) const {
+ return GetMimeTypeForPath(path);
+}
+
+bool RemoteDataSource::ShouldAddContentSecurityPolicy() const {
+ return false;
+}
+
+bool RemoteDataSource::ShouldDenyXFrameOptions() const {
+ return false;
+}
+
+bool RemoteDataSource::ShouldServeMimeTypeAsContentTypeHeader() const {
+ return true;
+}
+
+void RemoteDataSource::OnURLFetchComplete(const net::URLFetcher* source) {
+ DCHECK(source);
+ PendingRequestsMap::iterator it = pending_.find(source);
+ DCHECK(it != pending_.end());
+ std::string response;
+ source->GetResponseAsString(&response);
+
+ delete source;
+ if (response.empty() && !localhost_failed_) {
+ localhost_failed_ = true;
+ content::URLDataSource::GotDataCallback callback = it->second;
+ pending_.erase(it);
+ StartDataRequest("", 0, 0, callback);
xiyuan 2016/09/15 22:58:47 nit: Don't we lose path info with "" ?
mthiesse 2016/09/16 15:04:07 No, an empty string is what URL fetching passes to
mthiesse 2016/09/16 15:07:24 Actually, we should be checking here that the path
bshe 2016/09/16 18:27:53 It is easy to make mistakes(such as use a resource
+ } else {
+ it->second.Run(base::RefCountedString::TakeString(&response));
+ pending_.erase(it);
+ }
+}
+#else
+content::WebUIDataSource* CreateVrShellUIHTMLSource() {
+ content::WebUIDataSource* source =
+ content::WebUIDataSource::Create(chrome::kChromeUIVrShellUIHost);
+ source->AddResourcePath("vr_shell_ui.js", IDR_VR_SHELL_UI_JS);
+ source->AddResourcePath("vr_shell_ui.css", IDR_VR_SHELL_UI_CSS);
+ source->SetDefaultResource(IDR_VR_SHELL_UI_HTML);
+ source->DisableI18nAndUseGzipForAllPaths();
+ return source;
+}
+#endif
+
+} // namespace
+
+VrShellUIUI::VrShellUIUI(content::WebUI* web_ui) : WebUIController(web_ui) {
+ Profile* profile = Profile::FromWebUI(web_ui);
+#if !defined(ENABLE_VR_SHELL_UI_DEV)
+ content::WebUIDataSource::Add(profile, CreateVrShellUIHTMLSource());
+#else
+ RemoteDataSource* source = new RemoteDataSource(profile->GetRequestContext());
xiyuan 2016/09/15 22:58:47 nit: Get rid of |source| and fold into the next li
bshe 2016/09/16 18:27:53 Done.
+ content::URLDataSource::Add(profile, source);
+#endif
+ web_ui->AddMessageHandler(new VrShellUIMessageHandler);
+}
+
+VrShellUIUI::~VrShellUIUI() {}

Powered by Google App Engine
This is Rietveld 408576698