Commit f85ba713 authored by bshe's avatar bshe Committed by Commit bot

Add chrome://vr-shell-ui internal page

See design doc in the following link on why we need this page:
https://docs.google.com/document/d/1V9_Xj3MYQ4d_MT30ZpXsdqFoFSJXEvQeMNgXcP5SXjU/edit
All the webui functions are NOTIMPLEMENTED at the moment.
They need some files in https://codereview.chromium.org/2335643002/
before they can be implemented.
To support fast prototyping that requested by UX, this CL
also support override the internal page with remote pages.
So UI can be developed without rebuild Chrome.
That feature is behind enable_vr_shell_ui_dev build flag. We
don't have plan to turn the build flag on.

BUG=
CQ_INCLUDE_TRYBOTS=master.tryserver.chromium.linux:closure_compilation

Review-Url: https://codereview.chromium.org/2341803003
Cr-Commit-Position: refs/heads/master@{#419431}
parent af7e0ce5
......@@ -198,6 +198,12 @@
<include name="IDR_SNIPPETS_INTERNALS_HTML" file="resources\snippets_internals.html" allowexternalscript="true" compress="gzip" type="BINDATA" />
<include name="IDR_SNIPPETS_INTERNALS_CSS" file="resources\snippets_internals.css" compress="gzip" type="BINDATA" />
<include name="IDR_SNIPPETS_INTERNALS_JS" file="resources\snippets_internals.js" compress="gzip" type="BINDATA" />
<!-- TODO: Enable only for VrShell, independent of Android. -->
<if expr="enable_vr_shell">
<include name="IDR_VR_SHELL_UI_HTML" file="resources\vr_shell\vr_shell_ui.html" allowexternalscript="true" flattenhtml="true" compress="gzip" type="BINDATA" />
<include name="IDR_VR_SHELL_UI_CSS" file="resources\vr_shell\vr_shell_ui.css" compress="gzip" type="BINDATA" />
<include name="IDR_VR_SHELL_UI_JS" file="resources\vr_shell\vr_shell_ui.js" compress="gzip" type="BINDATA" />
</if>
</if>
<include name="IDR_SUPERVISED_USER_INTERNALS_HTML" file="resources\supervised_user_internals.html" allowexternalscript="true" compress="gzip" type="BINDATA" />
<include name="IDR_SUPERVISED_USER_INTERNALS_CSS" file="resources\supervised_user_internals.css" compress="gzip" type="BINDATA" />
......
/* 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. */
html {
background-color: rgba(255, 255, 255, 0.2);
font-size: 20px;
}
.ui-button {
background: white;
border-radius: 6px;
overflow: hidden;
position: absolute;
text-align: center;
vertical-align: middle;
}
<!--
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.
-->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<if expr="is_android or is_ios">
<meta name="viewport" content="width=device-width, initial-scale=1.0,
maximum-scale=1.0, user-scalable=no">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="pragma" content="no-cache">
</if>
<title>Vr Shell UIs</title>
<link rel="stylesheet" href="vr_shell_ui.css">
</head>
<body>
</body>
<!-- Run script after creating body, to let it add its own elements. -->
<script src="vr_shell_ui.js"></script>
</html>
// 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.
var vrShellUi = (function() {
'use strict';
/**
* Enumeration of valid Anchroing for X axis.
* A mesh can either be anchored to the left, right, or center of the main
* content rect (or it can be absolutely positioned using NONE). Any
* translations applied will be relative to this anchoring.
* @enum {number}
* @const
*/
var XAnchoring = Object.freeze({
'XLEFT': 0,
'XRIGHT': 1,
'XCENTER': 2,
'XNONE': 3
});
/**
* Enumeration of valid Anchroing for Y axis.
* @enum {number}
* @const
*/
var YAnchoring = Object.freeze({
'YTOP': 0,
'YBOTTOM': 1,
'YCENTER': 2,
'YNONE': 3
});
/**
* Enumeration of animatable properties.
* @enum {number}
* @const
*/
var Property = Object.freeze({
'COPYRECT': 0,
'SIZE': 1,
'TRANSLATION': 2,
'ORIENTATION': 3,
'ROTATION': 4
});
/**
* Enumeration of easing type.
* @enum {number}
* @const
*/
var Easing = Object.freeze({
'LINEAR': 0,
'CUBICBEZIER': 1,
'EASEIN': 2,
'EASEOUT': 3
});
/**
* @type {number} Id generator.
*/
var idIndex = 1;
class UiElement {
/**
* Constructor of UiElement.
* pixelX and pixelY values indicate the left upper corner; pixelWidth and
* pixelHeight is width and height of the texture to be copied from the web
* contents. metersX and metersY indicate the size of the rectangle onto
* which the pixel region will be mapped.
*/
constructor(pixelX, pixelY, pixelWidth, pixelHeight, metersX, metersY) {
this.copyRect = {
x: pixelX,
y: pixelY,
width: pixelWidth,
height: pixelHeight
};
this.size = { x: metersX, y: metersY };
this.xAnchoring = XAnchoring.XNONE;
this.yAnchoring = YAnchoring.YNONE;
this.anchorZ = false;
this.translation = { x: 0, y: 0, z: 0 };
this.orientationAxisAngle = { x: 0, y: 0, z: 0, a: 0 };
this.rotationAxisAngle = { x: 0, y: 0, z: 0, a: 0 };
}
/**
* The rotation for the mesh in 3D, applied before translation. The
* rotation is axis-angle representation (rotated around unit vector [x, y,
* z] by 'a' radians).
*/
setRotation(x, y, z, a) {
this.rotationAxisAngle = { x: x, y: y, z: z, a: a };
}
/**
* The offset for the mesh in 3D. If anchoring is specified, the offset is
* applied to the anchoring position rather than the origin.
*/
setTranslation(x, y, z) {
this.translation = { x: x, y: y, z: z };
}
/**
* Anchoring allows a rectangle to be positioned relative to the content
* window. X and Y values should be XAnchoring and YAnchoring elements.
* anchorZ is a boolean.
* Example: rect.setAnchoring(XAnchoring.XCENTER, YAnchoring.YBOTTOM, true);
*/
setAnchoring(x, y, z) {
this.xAnchoring = x;
this.yAnchoring = y;
this.anchorZ = z;
}
};
class Animation {
constructor(meshId, durationMs) {
this.meshId = meshId;
this.easing = {};
this.from = {};
this.to = {};
this.easing.type = Easing.LINEAR;
// How many milliseconds in the future to start the animation.
this.startInMillis = 0.0;
// Duration of the animation (milliseconds).
this.durationMillis = durationMs;
}
setRotateTo(x, y, z, a) {
this.property = Property.ROTATION;
this.to.x = x;
this.to.y = y;
this.to.z = z;
this.to.a = a;
}
setResizeTo(newWidth, newHeight) {
this.property = Property.SIZE;
this.to.x = newWidth;
this.to.y = newHeight;
}
};
function initialize() {
domLoaded();
// Change the body background so that the transparency applies.
window.setTimeout(function() {
document.body.parentNode.style.backgroundColor = 'rgba(255,255,255,0)';
}, 100);
addControlButtons();
}
// Build a row of control buttons.
function addControlButtons() {
var buttons = [
// Button text, UI action passed down to native.
['<', 'HISTORY_BACK'],
['>', 'HISTORY_FORWARD'],
['R', 'RELOAD'],
['-', 'ZOOM_OUT'],
['+', 'ZOOM_IN']
];
var buttonWidth = 0.3;
var buttonHeight = 0.2;
var buttonSpacing = 0.5;
var buttonStartPosition = -buttonSpacing * (buttons.length / 2.0 - 0.5);
for (var i = 0; i < buttons.length; i++) {
var b = document.createElement('div');
b.position = 'absolute';
b.style.top = '200px';
b.style.left = 50 * i + 'px';
b.style.width = '50px';
b.style.height = '50px';
b.className = 'ui-button';
b.textContent = buttons[i][0];
// Add click behaviour.
b.addEventListener('click', function(action, e) {
chrome.send('doAction', [action]);
}.bind(undefined, buttons[i][1]));
document.body.appendChild(b);
// Add a UI rectangle for the button.
var el = new UiElement(50 * i, 200, 50, 50, buttonWidth, buttonHeight);
el.setAnchoring(XAnchoring.XCENTER, YAnchoring.YBOTTOM, true);
el.setTranslation(buttonStartPosition + buttonSpacing * i, -0.3, 0.0);
var id = idIndex++;
addMesh(id, el);
// Add transitions when the mouse hovers over (and leaves) the button.
b.addEventListener('mouseenter', function(buttonId, width, height, e) {
var resize = new Animation(buttonId, 250);
resize.id = idIndex++;
resize.setResizeTo(width, height);
chrome.send('addAnimations', [resize]);
}.bind(undefined, id, buttonWidth * 1.5, buttonHeight * 1.5));
b.addEventListener('mouseleave', function(buttonId, width, height) {
var resize = new Animation(buttonId, 250);
resize.id = idIndex++;
resize.setResizeTo(width, height);
chrome.send('addAnimations', [resize]);
}.bind(undefined, id, buttonWidth, buttonHeight));
}
}
function domLoaded() {
chrome.send('domLoaded', [window.innerWidth, window.innerHeight]);
}
function addAnimations(animations) {
chrome.send('addAnimations', animations);
}
function addMesh(id, mesh) {
chrome.send('addMesh', [id, mesh]);
}
return {
initialize: initialize,
};
})();
document.addEventListener('DOMContentLoaded', vrShellUi.initialize);
......@@ -2182,6 +2182,19 @@ split_static_library("ui") {
"webui/snippets_internals_ui.cc",
"webui/snippets_internals_ui.h",
]
if (enable_vr_shell) {
defines += [ "ENABLE_VR_SHELL" ]
sources += [
"webui/vr_shell/vr_shell_ui_message_handler.cc",
"webui/vr_shell/vr_shell_ui_message_handler.h",
"webui/vr_shell/vr_shell_ui_ui.cc",
"webui/vr_shell/vr_shell_ui_ui.h",
]
}
if (enable_vr_shell_ui_dev) {
assert(enable_vr_shell)
defines += [ "ENABLE_VR_SHELL_UI_DEV" ]
}
deps += [
"//chrome/browser:jni_headers",
"//components/web_contents_delegate_android",
......
......@@ -107,6 +107,9 @@
#include "chrome/browser/ui/webui/offline/offline_internals_ui.h"
#include "chrome/browser/ui/webui/popular_sites_internals_ui.h"
#include "chrome/browser/ui/webui/snippets_internals_ui.h"
#if defined(ENABLE_VR_SHELL)
#include "chrome/browser/ui/webui/vr_shell/vr_shell_ui_ui.h"
#endif
#else
#include "chrome/browser/signin/easy_unlock_service.h"
#include "chrome/browser/signin/easy_unlock_service_factory.h"
......@@ -521,6 +524,10 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI* web_ui,
if (url.host() == chrome::kChromeUISnippetsInternalsHost &&
!profile->IsOffTheRecord())
return &NewWebUI<SnippetsInternalsUI>;
#if defined(ENABLE_VR_SHELL)
if (url.host() == chrome::kChromeUIVrShellUIHost)
return &NewWebUI<VrShellUIUI>;
#endif // defined(ENABLE_VR_SHELL)
#else
if (url.SchemeIs(content::kChromeDevToolsScheme))
return &NewWebUI<DevToolsUI>;
......
// 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_message_handler.h"
#include <memory>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/values.h"
#include "content/public/browser/web_ui.h"
VrShellUIMessageHandler::VrShellUIMessageHandler() {}
VrShellUIMessageHandler::~VrShellUIMessageHandler() {}
void VrShellUIMessageHandler::RegisterMessages() {
web_ui()->RegisterMessageCallback(
"domLoaded", base::Bind(&VrShellUIMessageHandler::HandleDomLoaded,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"addMesh", base::Bind(&VrShellUIMessageHandler::HandleAddMesh,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"removeMesh", base::Bind(&VrShellUIMessageHandler::HandleRemoveMesh,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"doAction", base::Bind(&VrShellUIMessageHandler::HandleDoAction,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"addAnimations", base::Bind(&VrShellUIMessageHandler::HandleAddAnimations,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"setDevicePixelRatio",
base::Bind(&VrShellUIMessageHandler::HandleSetDevicePixelRatio,
base::Unretained(this)));
}
void VrShellUIMessageHandler::HandleDomLoaded(const base::ListValue* args) {
NOTIMPLEMENTED();
}
void VrShellUIMessageHandler::HandleSetDevicePixelRatio(
const base::ListValue* args) {
NOTIMPLEMENTED();
}
void VrShellUIMessageHandler::HandleAddMesh(const base::ListValue* args) {
NOTIMPLEMENTED();
}
void VrShellUIMessageHandler::HandleRemoveMesh(const base::ListValue* args) {
NOTIMPLEMENTED();
}
void VrShellUIMessageHandler::HandleAddAnimations(const base::ListValue* args) {
NOTIMPLEMENTED();
}
void VrShellUIMessageHandler::HandleDoAction(const base::ListValue* args) {
NOTIMPLEMENTED();
}
// 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.
#ifndef CHROME_BROWSER_UI_WEBUI_VR_SHELL_VR_SHELL_UI_MESSAGE_HANDLER_H_
#define CHROME_BROWSER_UI_WEBUI_VR_SHELL_VR_SHELL_UI_MESSAGE_HANDLER_H_
#include <string>
#include "base/macros.h"
#include "content/public/browser/web_ui_message_handler.h"
namespace base {
class ListValue;
}
namespace vr_shell {
class VrShell;
}
class VrShellUIMessageHandler : public content::WebUIMessageHandler {
public:
VrShellUIMessageHandler();
~VrShellUIMessageHandler() override;
private:
// content::WebUIMessageHandler:
void RegisterMessages() override;
void HandleDomLoaded(const base::ListValue* args);
void HandleSetDevicePixelRatio(const base::ListValue* args);
void HandleAddMesh(const base::ListValue* args);
void HandleRemoveMesh(const base::ListValue* args);
void HandleAddAnimations(const base::ListValue* args);
void HandleDoAction(const base::ListValue* args);
DISALLOW_COPY_AND_ASSIGN(VrShellUIMessageHandler);
};
#endif // CHROME_BROWSER_UI_WEBUI_VR_SHELL_VR_SHELL_UI_MESSAGE_HANDLER_H_
// 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)
#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 use_localhost_;
DISALLOW_COPY_AND_ASSIGN(RemoteDataSource);
};
RemoteDataSource::RemoteDataSource(
net::URLRequestContextGetter* request_context)
: request_context_(request_context), use_localhost_(true) {}
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((use_localhost_ ? kRemoteBase : kRemoteBaseAlt) +
(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);
if (response.empty() && use_localhost_) {
if (source->GetOriginalURL().path().substr(1) == kRemoteDefaultPath) {
// Failed to request default page from local host, try request default
// page from remote server. Empty string indicates default page.
use_localhost_ = false;
content::URLDataSource::GotDataCallback callback = it->second;
StartDataRequest("", 0, 0, callback);
}
} else {
it->second.Run(base::RefCountedString::TakeString(&response));
}
delete source;
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
content::URLDataSource::Add(
profile, new RemoteDataSource(profile->GetRequestContext()));
#endif
web_ui->AddMessageHandler(new VrShellUIMessageHandler);
}
VrShellUIUI::~VrShellUIUI() {}
// 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.
#ifndef CHROME_BROWSER_UI_WEBUI_VR_SHELL_VR_SHELL_UI_UI_H_
#define CHROME_BROWSER_UI_WEBUI_VR_SHELL_VR_SHELL_UI_UI_H_
#include "base/macros.h"
#include "content/public/browser/web_ui_controller.h"
// The implementation for the chrome://vr-shell-ui page.
class VrShellUIUI : public content::WebUIController {
public:
explicit VrShellUIUI(content::WebUI* web_ui);
~VrShellUIUI() override;
private:
DISALLOW_COPY_AND_ASSIGN(VrShellUIUI);
};
#endif // CHROME_BROWSER_UI_WEBUI_VR_SHELL_VR_SHELL_UI_UI_H_
......@@ -504,6 +504,10 @@ static_library("common") {
]
}
}
if (enable_vr_shell) {
defines += [ "ENABLE_VR_SHELL" ]
}
}
process_version("version_header") {
......
......@@ -39,6 +39,9 @@ declare_args() {
# Enables vr shell.
enable_vr_shell = false
# Enables vr shell UI development on local or remote page.
enable_vr_shell_ui_dev = false
# Enable native notifications via XPC services (mac only).
enable_xpc_notifications = false
......@@ -54,5 +57,6 @@ chrome_grit_defines = [
"enable_background=$enable_background",
"enable_google_now=$enable_google_now",
"enable_hotwording=$enable_hotwording",
"enable_vr_shell=$enable_vr_shell",
"use_vulcanize=$use_vulcanize",
]
......@@ -275,6 +275,10 @@ const char kChromeUIPopularSitesInternalsHost[] = "popular-sites-internals";
const char kChromeUISnippetsInternalsHost[] = "snippets-internals";
#endif
#if defined(ENABLE_VR_SHELL)
const char kChromeUIVrShellUIHost[] = "vr-shell-ui";
#endif
#if defined(OS_CHROMEOS)
const char kChromeUIActivationMessageHost[] = "activationmessage";
const char kChromeUIAppLaunchHost[] = "app-launch";
......
......@@ -258,6 +258,10 @@ extern const char kChromeUIPopularSitesInternalsHost[];
extern const char kChromeUISnippetsInternalsHost[];
#endif
#if defined(ENABLE_VR_SHELL)
extern const char kChromeUIVrShellUIHost[];
#endif
#if defined(OS_CHROMEOS)
extern const char kChromeUIActivationMessageHost[];
extern const char kChromeUIAppLaunchHost[];
......
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