0

Migrate Content WebUIs to Mojo JS modules

There are three WebUIs defined in Content which use Mojo:

- gpu
- process-internals
- conversion-internals

These are adapted here to use newer Mojo JS modules.

Bug: 1004256
Change-Id: If766eb81599d9311b79076011a8ac1d08f343927
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2555806
Reviewed-by: Charlie Harrison <csharrison@chromium.org>
Reviewed-by: Alex Gough <ajgo@chromium.org>
Reviewed-by: Zhenyao Mo <zmo@chromium.org>
Reviewed-by: Avi Drissman <avi@chromium.org>
Commit-Queue: Alex Gough <ajgo@chromium.org>
Auto-Submit: Ken Rockot <rockot@google.com>
Cr-Commit-Position: refs/heads/master@{#832130}
This commit is contained in:
Ken Rockot
2020-12-01 01:06:00 +00:00
committed by Chromium LUCI CQ
parent 84309f828f
commit 4acce46f02
25 changed files with 271 additions and 571 deletions

@ -118,8 +118,9 @@ grit("content_resources") {
"content_resources.pak",
]
deps = [
"//gpu/ipc/common:vulkan_interface_js",
"//gpu/ipc/common:vulkan_interface_webui_js",
"//url/mojom:url_mojom_origin_js",
"//url/mojom:url_mojom_origin_webui_js",
]
}
@ -131,8 +132,8 @@ grit("dev_ui_content_resources") {
"dev_ui_content_resources.pak",
]
deps = [
"//content/browser/conversions:mojo_bindings_js",
"//content/browser/process_internals:mojo_bindings_js",
"//content/browser/conversions:mojo_bindings_webui_js",
"//content/browser/process_internals:mojo_bindings_webui_js",
]
}

@ -7,4 +7,5 @@ import("//mojo/public/tools/bindings/mojom.gni")
mojom("mojo_bindings") {
sources = [ "conversion_internals.mojom" ]
public_deps = [ "//url/mojom:url_mojom_origin" ]
webui_module_path = "/"
}

@ -25,7 +25,7 @@ ConversionInternalsUI::ConversionInternalsUI(WebUI* web_ui)
WebUIDataSource* source =
WebUIDataSource::Create(kChromeUIConversionInternalsHost);
source->AddResourcePath("conversion_internals.mojom-lite.js",
source->AddResourcePath("conversion_internals.mojom-webui.js",
IDR_CONVERSION_INTERNALS_MOJOM_JS);
source->AddResourcePath("conversion_internals.js",
IDR_CONVERSION_INTERNALS_JS);

@ -98,9 +98,14 @@ WebUIDataSource* CreateGpuHTMLSource() {
"trusted-types jstemplate;");
source->UseStringsJs();
source->AddResourcePath("browser_bridge.js", IDR_GPU_BROWSER_BRIDGE_JS);
source->AddResourcePath("gpu_internals.js", IDR_GPU_INTERNALS_JS);
source->AddResourcePath("vulkan_info.mojom.js", IDR_VULKAN_INFO_MOJO_JS);
source->AddResourcePath("vulkan_types.mojom.js", IDR_VULKAN_TYPES_MOJO_JS);
source->AddResourcePath("info_view.js", IDR_GPU_INFO_VIEW_JS);
source->AddResourcePath("vulkan_info.js", IDR_GPU_VULKAN_INFO_JS);
source->AddResourcePath("vulkan_info.mojom-webui.js",
IDR_VULKAN_INFO_MOJO_JS);
source->AddResourcePath("vulkan_types.mojom-webui.js",
IDR_VULKAN_TYPES_MOJO_JS);
source->SetDefaultResource(IDR_GPU_INTERNALS_HTML);
return source;
}

@ -8,4 +8,5 @@ mojom("mojo_bindings") {
sources = [ "process_internals.mojom" ]
deps = [ "//url/mojom:url_mojom_gurl" ]
webui_module_path = "/"
}

@ -37,7 +37,7 @@ ProcessInternalsUI::ProcessInternalsUI(WebUI* web_ui)
source->AddResourcePath("process_internals.js", IDR_PROCESS_INTERNALS_JS);
source->AddResourcePath("process_internals.css", IDR_PROCESS_INTERNALS_CSS);
source->AddResourcePath("process_internals.mojom-lite.js",
source->AddResourcePath("process_internals.mojom-webui.js",
IDR_PROCESS_INTERNALS_MOJO_JS);
source->SetDefaultResource(IDR_PROCESS_INTERNALS_HTML);
source->OverrideContentSecurityPolicy(

@ -7,21 +7,9 @@
<meta charset="utf-8">
<link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
<link rel="stylesheet" href="chrome://resources/css/roboto.css">
<script src="chrome://resources/js/assert.js"></script>
<script src="chrome://resources/js/util.js"></script>
<script src="chrome://resources/js/cr.js"></script>
<script src="chrome://resources/js/cr/ui.js"></script>
<script src="chrome://resources/js/cr/ui/tree.js"></script>
<script src="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js">
</script>
<script src="chrome://resources/mojo/mojo/public/mojom/base/unguessable_token.mojom-lite.js"></script>
<script src="chrome://resources/mojo/url/mojom/url.mojom-lite.js"></script>
<script src="chrome://resources/mojo/url/mojom/origin.mojom-lite.js"></script>
<link rel="stylesheet" href="conversion_internals.css">
<script src="conversion_internals.mojom-lite.js"></script>
<script src="conversion_internals.js"></script>
<script type="module" src="conversion_internals.js"></script>
<title>Conversion Internals</title>
</head>
<body>

@ -2,24 +2,26 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
(function() {
'use strict';
import {$} from 'chrome://resources/js/util.m.js';
import {Origin} from 'chrome://resources/mojo/url/mojom/origin.mojom-webui.js';
import {ConversionInternalsHandler, ConversionInternalsHandlerRemote, WebUIImpression} from './conversion_internals.mojom-webui.js';
/**
* Reference to the backend providing all the data.
* @type {mojom.ConversionInternalsHandlerRemote}
* @type {ConversionInternalsHandlerRemote}
*/
let pageHandler = null;
/**
* All impressions held in storage at last update.
* @type {!Array<!mojom.Impression>}
* @type {!Array<!WebUIImpression>}
*/
let impressions = null;
/**
* All impressions held in storage at last update.
* @type {!Array<!mojom.Impression>}
* @type {!Array<!WebUIImpression>}
*/
let reports = null;
@ -33,7 +35,7 @@ function clearTable(table) {
/**
* Converts a mojo origin into a user-readable string, omitting default ports.
* @param {url.mojom.Origin} origin Origin to convert
* @param {Origin} origin Origin to convert
* @return {string}
*/
function UrlToText(origin) {
@ -52,7 +54,7 @@ function UrlToText(origin) {
/**
* Creates a single row for the impression table.
* @param {!mojom.Impression} impression The info to create the row.
* @param {!WebIUIImpression} impression The info to create the row.
* @return {!HTMLElement}
*/
function createImpressionRow(impression) {
@ -70,7 +72,7 @@ function createImpressionRow(impression) {
/**
* Creates a single row for the impression table.
* @param {!mojom.Impression} impression The info to create the row.
* @param {!WebUIImpression} impression The info to create the row.
* @return {!HTMLElement}
*/
function createReportRow(report) {
@ -175,7 +177,7 @@ function sendReports() {
document.addEventListener('DOMContentLoaded', function() {
// Setup the mojo interface.
pageHandler = mojom.ConversionInternalsHandler.getRemote();
pageHandler = ConversionInternalsHandler.getRemote();
$('refresh').addEventListener('click', updatePageData);
$('clear-data').addEventListener('click', clearStorage);
@ -185,4 +187,3 @@ document.addEventListener('DOMContentLoaded', function() {
setInterval(updatePageData, 2 * 60 * 1000);
updatePageData();
});
})();

@ -1,158 +1,139 @@
// Copyright (c) 2011 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.
cr.define('gpu', function() {
import {dispatchSimpleEvent} from 'chrome://resources/js/cr.m.js';
import {NativeEventTarget as EventTarget} from 'chrome://resources/js/cr/event_target.m.js';
/**
* This class provides a 'bridge' for communicating between javascript and the
* browser. When run outside of WebUI, e.g. as a regular webpage, it provides
* synthetic data to assist in testing.
*/
export class BrowserBridge extends EventTarget {
constructor() {
super();
this.nextRequestId_ = 0;
this.pendingCallbacks_ = [];
this.logMessages_ = [];
// Tell c++ code that we are ready to receive GPU Info.
chrome.send('browserBridgeInitialized');
this.beginRequestClientInfo_();
this.beginRequestLogMessages_();
}
applySimulatedData_(data) {
// set up things according to the simulated data
this.gpuInfo_ = data.gpuInfo;
this.clientInfo_ = data.clientInfo;
this.logMessages_ = data.logMessages;
dispatchSimpleEvent(this, 'gpuInfoUpdate');
dispatchSimpleEvent(this, 'clientInfoChange');
dispatchSimpleEvent(this, 'logMessagesChange');
}
/**
* This class provides a 'bridge' for communicating between javascript and the
* browser. When run outside of WebUI, e.g. as a regular webpage, it provides
* synthetic data to assist in testing.
* Sends a message to the browser with specified args. The
* browser will reply asynchronously via the provided callback.
*/
class BrowserBridge extends cr.EventTarget {
constructor() {
super();
// If we are not running inside WebUI, output chrome.send messages
// to the console to help with quick-iteration debugging.
this.debugMode_ = (chrome.send === undefined && console.log);
if (this.debugMode_) {
const browserBridgeTests = document.createElement('script');
browserBridgeTests.src = './gpu_internals/browser_bridge_tests.js';
document.body.appendChild(browserBridgeTests);
}
this.nextRequestId_ = 0;
this.pendingCallbacks_ = [];
this.logMessages_ = [];
// Tell c++ code that we are ready to receive GPU Info.
if (!this.debugMode_) {
chrome.send('browserBridgeInitialized');
this.beginRequestClientInfo_();
this.beginRequestLogMessages_();
}
}
applySimulatedData_(data) {
// set up things according to the simulated data
this.gpuInfo_ = data.gpuInfo;
this.clientInfo_ = data.clientInfo;
this.logMessages_ = data.logMessages;
cr.dispatchSimpleEvent(this, 'gpuInfoUpdate');
cr.dispatchSimpleEvent(this, 'clientInfoChange');
cr.dispatchSimpleEvent(this, 'logMessagesChange');
}
/**
* Returns true if the page is hosted inside Chrome WebUI
* Helps have behavior conditional to emulate_webui.py
*/
get debugMode() {
return this.debugMode_;
}
/**
* Sends a message to the browser with specified args. The
* browser will reply asynchronously via the provided callback.
*/
callAsync(submessage, args, callback) {
const requestId = this.nextRequestId_;
this.nextRequestId_ += 1;
this.pendingCallbacks_[requestId] = callback;
if (!args) {
chrome.send('callAsync', [requestId.toString(), submessage]);
} else {
const allArgs = [requestId.toString(), submessage].concat(args);
chrome.send('callAsync', allArgs);
}
}
/**
* Called by gpu c++ code when client info is ready.
*/
onCallAsyncReply(requestId, args) {
if (this.pendingCallbacks_[requestId] === undefined) {
throw new Error('requestId ' + requestId + ' is not pending');
}
const callback = this.pendingCallbacks_[requestId];
callback(args);
delete this.pendingCallbacks_[requestId];
}
/**
* Get gpuInfo data.
*/
get gpuInfo() {
return this.gpuInfo_;
}
/**
* Called from gpu c++ code when GPU Info is updated.
*/
onGpuInfoUpdate(gpuInfo) {
this.gpuInfo_ = gpuInfo;
cr.dispatchSimpleEvent(this, 'gpuInfoUpdate');
}
/**
* This function begins a request for the ClientInfo. If it comes back
* as undefined, then we will issue the request again in 250ms.
*/
beginRequestClientInfo_() {
this.callAsync(
'requestClientInfo', undefined,
(function(data) {
if (data === undefined) { // try again in 250 ms
window.setTimeout(this.beginRequestClientInfo_.bind(this), 250);
} else {
this.clientInfo_ = data;
cr.dispatchSimpleEvent(this, 'clientInfoChange');
}
}).bind(this));
}
/**
* Returns information about the currently running Chrome build.
*/
get clientInfo() {
return this.clientInfo_;
}
/**
* This function checks for new GPU_LOG messages.
* If any are found, a refresh is triggered.
*/
beginRequestLogMessages_() {
this.callAsync(
'requestLogMessages', undefined,
(function(messages) {
if (messages.length !== this.logMessages_.length) {
this.logMessages_ = messages;
cr.dispatchSimpleEvent(this, 'logMessagesChange');
}
// check again in 250 ms
window.setTimeout(this.beginRequestLogMessages_.bind(this), 250);
}).bind(this));
}
/**
* Returns an array of log messages issued by the GPU process, if any.
*/
get logMessages() {
return this.logMessages_;
}
/**
* Returns the value of the "Sandboxed" row.
*/
isSandboxedForTesting() {
for (i = 0; i < this.gpuInfo_.basicInfo.length; ++i) {
const info = this.gpuInfo_.basicInfo[i];
if (info.description === 'Sandboxed') {
return info.value;
}
}
return false;
callAsync(submessage, args, callback) {
const requestId = this.nextRequestId_;
this.nextRequestId_ += 1;
this.pendingCallbacks_[requestId] = callback;
if (!args) {
chrome.send('callAsync', [requestId.toString(), submessage]);
} else {
const allArgs = [requestId.toString(), submessage].concat(args);
chrome.send('callAsync', allArgs);
}
}
return {BrowserBridge: BrowserBridge};
});
/**
* Called by gpu c++ code when client info is ready.
*/
onCallAsyncReply(requestId, args) {
if (this.pendingCallbacks_[requestId] === undefined) {
throw new Error('requestId ' + requestId + ' is not pending');
}
const callback = this.pendingCallbacks_[requestId];
callback(args);
delete this.pendingCallbacks_[requestId];
}
/**
* Get gpuInfo data.
*/
get gpuInfo() {
return this.gpuInfo_;
}
/**
* Called from gpu c++ code when GPU Info is updated.
*/
onGpuInfoUpdate(gpuInfo) {
this.gpuInfo_ = gpuInfo;
dispatchSimpleEvent(this, 'gpuInfoUpdate');
}
/**
* This function begins a request for the ClientInfo. If it comes back
* as undefined, then we will issue the request again in 250ms.
*/
beginRequestClientInfo_() {
this.callAsync(
'requestClientInfo', undefined,
(function(data) {
if (data === undefined) { // try again in 250 ms
window.setTimeout(this.beginRequestClientInfo_.bind(this), 250);
} else {
this.clientInfo_ = data;
dispatchSimpleEvent(this, 'clientInfoChange');
}
}).bind(this));
}
/**
* Returns information about the currently running Chrome build.
*/
get clientInfo() {
return this.clientInfo_;
}
/**
* This function checks for new GPU_LOG messages.
* If any are found, a refresh is triggered.
*/
beginRequestLogMessages_() {
this.callAsync(
'requestLogMessages', undefined,
(function(messages) {
if (messages.length !== this.logMessages_.length) {
this.logMessages_ = messages;
dispatchSimpleEvent(this, 'logMessagesChange');
}
// check again in 250 ms
window.setTimeout(this.beginRequestLogMessages_.bind(this), 250);
}).bind(this));
}
/**
* Returns an array of log messages issued by the GPU process, if any.
*/
get logMessages() {
return this.logMessages_;
}
/**
* Returns the value of the "Sandboxed" row.
*/
isSandboxedForTesting() {
for (const info of this.gpuInfo_.basicInfo) {
if (info.description === 'Sandboxed') {
return info.value;
}
}
return false;
}
}

@ -1,297 +0,0 @@
// Copyright (c) 2012 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.
const commandLineFlags = [
'--flag-switches-begin', '--show-composited-layer-borders',
'--flag-switches-end'
];
const commandLineStr = './out/Debug/chrome ' + commandLineFlags.join(' ');
const glValueArray = [
'GL_ARB_compatibility',
'GL_ARB_copy_buffer',
'GL_ARB_depth_buffer_float',
'GL_ARB_depth_clamp',
'GL_ARB_depth_texture',
'GL_ARB_draw_buffers',
'GL_ARB_draw_elements_base_vertex',
'GL_ARB_draw_instanced',
'GL_ARB_fragment_coord_conventions',
'GL_ARB_fragment_program',
'GL_ARB_fragment_program_shadow',
'GL_ARB_fragment_shader',
'GL_ARB_framebuffer_object',
'GL_ARB_framebuffer_sRGB',
'GL_ARB_geometry_shader4',
'GL_ARB_half_float_pixel',
'GL_ARB_half_float_vertex',
'GL_ARB_imaging',
'GL_ARB_map_buffer_range',
'GL_ARB_multisample',
'GL_ARB_multitexture',
'GL_ARB_occlusion_query',
'GL_ARB_pixel_buffer_object',
'GL_ARB_point_parameters',
'GL_ARB_point_sprite',
'GL_ARB_provoking_vertex',
'GL_ARB_seamless_cube_map',
'GL_ARB_shader_objects',
'GL_ARB_shading_language_100',
'GL_ARB_shadow',
'GL_ARB_sync',
'GL_ARB_texture_border_clamp',
'GL_ARB_texture_buffer_object',
'GL_ARB_texture_compression',
'GL_ARB_texture_compression_rgtc',
'GL_ARB_texture_cube_map',
'GL_ARB_texture_env_add',
'GL_ARB_texture_env_combine',
'GL_ARB_texture_env_crossbar',
'GL_ARB_texture_env_dot3',
'GL_ARB_texture_float',
'GL_ARB_texture_mirrored_repeat',
'GL_ARB_texture_multisample',
'GL_ARB_texture_non_power_of_two',
'GL_ARB_texture_rectangle',
'GL_ARB_texture_rg',
'GL_ARB_transpose_matrix',
'GL_ARB_uniform_buffer_object',
'GL_ARB_vertex_array_bgra',
'GL_ARB_vertex_array_object',
'GL_ARB_vertex_buffer_object',
'GL_ARB_vertex_program',
'GL_ARB_vertex_shader',
'GL_ARB_window_pos',
'GL_ATI_draw_buffers',
'GL_ATI_texture_float',
'GL_ATI_texture_mirror_once',
'GL_S3_s3tc',
'GL_EXT_texture_env_add',
'GL_EXT_abgr',
'GL_EXT_bgra',
'GL_EXT_bindable_uniform',
'GL_EXT_blend_color',
'GL_EXT_blend_equation_separate',
'GL_EXT_blend_func_separate',
'GL_EXT_blend_minmax',
'GL_EXT_blend_subtract',
'GL_EXT_compiled_vertex_array',
'GL_EXT_Cg_shader',
'GL_EXT_depth_bounds_test',
'GL_EXT_direct_state_access',
'GL_EXT_draw_buffers2',
'GL_EXT_draw_instanced',
'GL_EXT_draw_range_elements',
'GL_EXT_fog_coord',
'GL_EXT_framebuffer_blit',
'GL_EXT_framebuffer_multisample',
'GL_EXTX_framebuffer_mixed_formats',
'GL_EXT_framebuffer_object',
'GL_EXT_framebuffer_sRGB',
'GL_EXT_geometry_shader4',
'GL_EXT_gpu_program_parameters',
'GL_EXT_gpu_shader4',
'GL_EXT_multi_draw_arrays',
'GL_EXT_packed_depth_stencil',
'GL_EXT_packed_float',
'GL_EXT_packed_pixels',
'GL_EXT_pixel_buffer_object',
'GL_EXT_point_parameters',
'GL_EXT_provoking_vertex',
'GL_EXT_rescale_normal',
'GL_EXT_secondary_color',
'GL_EXT_separate_shader_objects',
'GL_EXT_separate_specular_color',
'GL_EXT_shadow_funcs',
'GL_EXT_stencil_two_side',
'GL_EXT_stencil_wrap',
'GL_EXT_texture3D',
'GL_EXT_texture_array',
'GL_EXT_texture_buffer_object',
'GL_EXT_texture_compression_latc',
'GL_EXT_texture_compression_rgtc',
'GL_EXT_texture_compression_s3tc',
'GL_EXT_texture_cube_map',
'GL_EXT_texture_edge_clamp',
'GL_EXT_texture_env_combine',
'GL_EXT_texture_env_dot3',
'GL_EXT_texture_filter_anisotropic',
'GL_EXT_texture_integer',
'GL_EXT_texture_lod',
'GL_EXT_texture_lod_bias',
'GL_EXT_texture_mirror_clamp',
'GL_EXT_texture_object',
'GL_EXT_texture_shared_exponent',
'GL_EXT_texture_sRGB',
'GL_EXT_texture_swizzle',
'GL_EXT_timer_query',
'GL_EXT_vertex_array',
'GL_EXT_vertex_array_bgra',
'GL_IBM_rasterpos_clip',
'GL_IBM_texture_mirrored_repeat',
'GL_KTX_buffer_region',
'GL_NV_blend_square',
'GL_NV_conditional_render',
'GL_NV_copy_depth_to_color',
'GL_NV_copy_image',
'GL_NV_depth_buffer_float',
'GL_NV_depth_clamp',
'GL_NV_explicit_multisample',
'GL_NV_fence',
'GL_NV_float_buffer',
'GL_NV_fog_distance',
'GL_NV_fragment_program',
'GL_NV_fragment_program_option',
'GL_NV_fragment_program2',
'GL_NV_framebuffer_multisample_coverage',
'GL_NV_geometry_shader4',
'GL_NV_gpu_program4',
'GL_NV_half_float',
'GL_NV_light_max_exponent',
'GL_NV_multisample_coverage',
'GL_NV_multisample_filter_hint',
'GL_NV_occlusion_query',
'GL_NV_packed_depth_stencil',
'GL_NV_parameter_buffer_object',
'GL_NV_parameter_buffer_object2',
'GL_NV_pixel_data_range',
'GL_NV_point_sprite',
'GL_NV_primitive_restart',
'GL_NV_register_combiners',
'GL_NV_register_combiners2',
'GL_NV_shader_buffer_load',
'GL_NV_texgen_reflection',
'GL_NV_texture_barrier',
'GL_NV_texture_compression_vtc',
'GL_NV_texture_env_combine4',
'GL_NV_texture_expand_normal',
'GL_NV_texture_rectangle',
'GL_NV_texture_shader',
'GL_NV_texture_shader2',
'GL_NV_texture_shader3',
'GL_NV_transform_feedback',
'GL_NV_vertex_array_range',
'GL_NV_vertex_array_range2',
'GL_NV_vertex_buffer_unified_memory',
'GL_NV_vertex_program',
'GL_NV_vertex_program1_1',
'GL_NV_vertex_program2',
'GL_NV_vertex_program2_option',
'GL_NV_vertex_program3',
'GL_NVX_conditional_render',
'GL_NVX_gpu_memory_info',
'GL_SGIS_generate_mipmap',
'GL_SGIS_texture_lod',
'GL_SGIX_depth_texture',
'GL_SGIX_shadow',
'GL_SUN_slice_accum'
];
(function() {
const dataSets = [
{
name: 'full_data_linux',
gpuInfo: {
basic_info: [
{description: 'Initialization time', value: '111'},
{description: 'Vendor Id', value: '0x10de'},
{description: 'Device Id', value: '0x0658'},
{description: 'Driver vendor', value: 'NVIDIA'},
{description: 'Driver version', value: '195.36.24'},
{description: 'Driver date', value: ''},
{description: 'Pixel shader version', value: '1.50'},
{description: 'Vertex shader version', value: '1.50'},
{description: 'GL version', value: '3.2'},
{description: 'GL_VENDOR', value: 'NVIDIA Corporation'},
{description: 'GL_RENDERER', value: 'Quadro FX 380/PCI/SSE2'},
{description: 'GL_VERSION', value: '3.2.0 NVIDIA 195.36.24'}, {
description: 'GL_EXTENSIONS',
value: glValueArray.join(' '),
}
],
featureStatus: {
featureStatus: [
{'status': 'enabled', name: '2d_canvas'},
{'status': 'enabled', name: '3d_css'},
{'status': 'enabled', name: 'compositing'},
{'status': 'enabled', name: 'webgl'},
{'status': 'enabled', name: 'multisampling'}
],
problems: []
}
},
clientInfo: {
command_line: commandLineStr,
version: 'Chrome/12.0.729.0',
},
logMessages: []
},
{
name: 'no_data',
gpuInfo: undefined,
clientInfo: undefined,
logMessages: undefined
},
{
name: 'logs',
gpuInfo: undefined,
clientInfo: undefined,
logMessages: [{header: 'foo', message: 'Bar'}]
},
// tests for 'status'
{
name: 'feature_states',
gpuInfo: {
basic_info: undefined,
featureStatus: {
featureStatus: [
{'status': 'disabled_off', name: '2d_canvas'},
{'status': 'unavailable_software', name: '3d_css'},
{'status': 'disabled_software', name: 'compositing'},
{'status': 'software', name: 'compositing'},
{'status': 'unavailable_off', name: 'webgl'},
{'status': 'enabled', name: 'multisampling'}
],
problems: [
{description: 'Something wrong', crBugs: [], webkitBugs: []},
{description: 'SomethingElse', crBugs: [], webkitBugs: []}, {
description: 'WebKit and Chrome bug',
crBugs: [23456],
webkitBugs: [789, 2123]
}
]
}
},
clientInfo: undefined,
logMessages: []
}
];
const selectEl = document.createElement('select');
for (let i = 0; i < dataSets.length; ++i) {
const optionEl = document.createElement('option');
optionEl.textContent = dataSets[i].name;
optionEl.dataSet = dataSets[i];
selectEl.add(optionEl);
}
selectEl.addEventListener('change', function() {
browserBridge.applySimulatedData_(dataSets[selectEl.selectedIndex]);
});
selectEl.addEventListener('keydown', function() {
window.setTimeout(function() {
browserBridge.applySimulatedData_(dataSets[selectEl.selectedIndex]);
}, 0);
});
const controlEl = document.createElement('div');
const textEl = document.createElement('span');
textEl.textContent = 'GPU Info:';
controlEl.appendChild(textEl);
controlEl.appendChild(selectEl);
document.querySelector('#debug-div')
.appendChild(controlEl, document.body.firstChild);
browserBridge.applySimulatedData_(dataSets[0]);
})();

@ -31,18 +31,7 @@ body {
</style>
<link rel="stylesheet" href="info_view.css">
<link rel="stylesheet" href="chrome://resources/css/widgets.css">
<script src="chrome://resources/js/cr.js"></script>
<script src="chrome://resources/js/cr/event_target.js"></script>
<script src="chrome://resources/js/cr/ui.js"></script>
<script src="chrome://resources/js/cr/ui/focus_outline_manager.js"></script>
<script src="chrome://resources/js/load_time_data.js"></script>
<script src="chrome://resources/js/assert.js"></script>
<script src="chrome://resources/js/util.js"></script>
<script src="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js"></script>
<script src="chrome://resources/gpu/ipc/common/vulkan_types.mojom-lite.js"></script>
<script src="chrome://resources/gpu/ipc/common/vulkan_info.mojom-lite.js"></script>
<script src="gpu_internals.js"></script>
<script src="strings.js"></script>
<script type="module" src="gpu_internals.js"></script>
</head>
<body>
<div id="debug-div">

@ -2,20 +2,28 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// <include src="browser_bridge.js">
// <include src="info_view.js">
// <include src="vulkan_info.js">
import {decorate} from 'chrome://resources/js/cr/ui.m.js';
let browserBridge;
import {BrowserBridge} from './browser_bridge.js';
import {makeInfoView} from './info_view.js';
// Injected script from C++ or test environments may reference `browserBridge`
// as a property of the global object.
window.browserBridge = new BrowserBridge;
/**
* Main entry point. called once the page has loaded.
*/
function onLoad() {
browserBridge = new gpu.BrowserBridge();
// Create the views.
cr.ui.decorate('#info-view', gpu.InfoView);
decorate('#info-view', makeInfoView(window.browserBridge));
// Because of inherent raciness (between the deprecated DevTools API which
// telemtry uses to drive the relevant tests, and the asynchronous loading of
// JS modules like this one) it's possible for telemetry tests to inject code
// *before* `browserBridge` is set and the DOM is populated. This flag is used
// to synchronize script injection by tests to prevent such races.
window.gpuPagePopulated = true;
}
document.addEventListener('DOMContentLoaded', onLoad);

@ -2,18 +2,22 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import {define as crUiDefine} from 'chrome://resources/js/cr/ui.m.js';
import {$} from 'chrome://resources/js/util.m.js';
import {VulkanInfo} from './vulkan_info.js';
/**
* @fileoverview This view displays information on the current GPU
* hardware. Its primary usefulness is to allow users to copy-paste
* their data in an easy to read format for bug reports.
*/
cr.define('gpu', function() {
export function makeInfoView(browserBridge) {
/**
* Provides information on the GPU process and underlying graphics hardware.
* @constructor
*/
const InfoView = cr.ui.define('div');
const InfoView = crUiDefine('div');
InfoView.prototype = {
__proto__: HTMLDivElement.prototype,
@ -185,8 +189,7 @@ cr.define('gpu', function() {
if (gpuInfo.ANGLEFeatures.length) {
ANGLEFeaturesDiv.hidden = false;
ANGLEFeaturesList.textContent = '';
for (i = 0; i < gpuInfo.ANGLEFeatures.length; i++) {
const ANGLEFeature = gpuInfo.ANGLEFeatures[i];
for (const ANGLEFeature of gpuInfo.ANGLEFeatures) {
const ANGLEFeatureEl = this.createANGLEFeatureEl_(ANGLEFeature);
ANGLEFeaturesList.appendChild(ANGLEFeatureEl);
}
@ -210,7 +213,7 @@ cr.define('gpu', function() {
}
if (gpuInfo.vulkanInfo) {
const vulkanInfo = new gpu.VulkanInfo(gpuInfo.vulkanInfo);
const vulkanInfo = new VulkanInfo(gpuInfo.vulkanInfo);
const data = [{
'description': 'info',
'value': vulkanInfo.toString(),
@ -324,8 +327,7 @@ cr.define('gpu', function() {
if (featureInfo.problems.length) {
problemsDiv.hidden = false;
problemsList.textContent = '';
for (i = 0; i < featureInfo.problems.length; i++) {
const problem = featureInfo.problems[i];
for (const problem of featureInfo.problems) {
const problemEl = this.createProblemEl_(problem);
problemsList.appendChild(problemEl);
}
@ -337,9 +339,9 @@ cr.define('gpu', function() {
if (featureInfo.workarounds.length) {
workaroundsDiv.hidden = false;
workaroundsList.textContent = '';
for (i = 0; i < featureInfo.workarounds.length; i++) {
for (const workaround of featureInfo.workarounds) {
const workaroundEl = document.createElement('li');
workaroundEl.textContent = featureInfo.workarounds[i];
workaroundEl.textContent = workaround;
workaroundsList.appendChild(workaroundEl);
}
} else {
@ -536,5 +538,5 @@ cr.define('gpu', function() {
}
};
return {InfoView: InfoView};
});
return InfoView;
}

@ -2,18 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
cr.define('gpu', function() {
class VulkanInfo {
constructor(base64Data) {
const array = Uint8Array.from(atob(base64Data), c => c.charCodeAt(0));
const dataView = new DataView(array.buffer);
this.vulkanInfo_ = gpu.mojom.VulkanInfo_Deserialize(dataView);
}
import {VulkanInfo_Deserialize} from './vulkan_info.mojom-webui.js';
toString() {
return JSON.stringify(this.vulkanInfo_, null, 2);
}
export class VulkanInfo {
constructor(base64Data) {
const array = Uint8Array.from(atob(base64Data), c => c.charCodeAt(0));
const dataView = new DataView(array.buffer);
this.vulkanInfo_ = VulkanInfo_Deserialize(dataView);
}
return {VulkanInfo: VulkanInfo};
});
toString() {
return JSON.stringify(this.vulkanInfo_, null, 2);
}
}

@ -6,13 +6,21 @@ import("//third_party/closure_compiler/compile_js.gni")
js_type_check("closure_compile") {
deps = [ ":process_internals" ]
uses_js_modules = true
closure_flags =
default_closure_args + mojom_js_args + [
"js_module_root=" + rebase_path(".", root_build_dir),
"js_module_root=" + rebase_path(
"$root_gen_dir/mojom-webui/content/browser/process_internals",
root_build_dir),
]
}
js_library("process_internals") {
deps = [
"//content/browser/process_internals:mojo_bindings_js_library_for_compile",
"//ui/webui/resources/js:assert",
"//ui/webui/resources/js:util",
"//ui/webui/resources/js/cr/ui:tree",
"//content/browser/process_internals:mojo_bindings_webui_js",
"//ui/webui/resources/js:util.m",
"//ui/webui/resources/js/cr:ui.m",
"//ui/webui/resources/js/cr/ui:tree.m",
]
}

@ -6,20 +6,9 @@
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
<script src="chrome://resources/js/assert.js"></script>
<script src="chrome://resources/js/util.js"></script>
<script src="chrome://resources/js/cr.js"></script>
<script src="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js">
</script>
<script src="chrome://resources/mojo/url/mojom/url.mojom-lite.js"></script>
<link rel="stylesheet" href="chrome://resources/css/tree.css">
<script src="chrome://resources/js/cr/ui.js"></script>
<script src="chrome://resources/js/cr/ui/tree.js"></script>
<link rel="stylesheet" href="process_internals.css">
<script src="process_internals.mojom-lite.js"></script>
<script src='process_internals.js'></script>
<script type="module" src='process_internals.js'></script>
<title>Process Model Internals</title>
</head>
<body>

@ -2,12 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
(function() {
'use strict';
import {decorate} from 'chrome://resources/js/cr/ui.m.js';
import {Tree, TreeItem} from 'chrome://resources/js/cr/ui/tree.m.js';
import {$} from 'chrome://resources/js/util.m.js';
import {FrameInfo, ProcessInternalsHandler, ProcessInternalsHandlerRemote, WebContentsInfo} from './process_internals.mojom-webui.js';
/**
* Reference to the backend providing all the data.
* @type {mojom.ProcessInternalsHandlerRemote}
* @type {ProcessInternalsHandlerRemote}
*/
let pageHandler = null;
@ -61,19 +64,19 @@ function setupTabs() {
/**
* Root of the WebContents tree.
* @type {cr.ui.Tree|null}
* @type {Tree|null}
*/
let treeViewRoot = null;
/**
* Initialize and return |treeViewRoot|.
* @return {cr.ui.Tree} Initialized |treeViewRoot|.
* @return {Tree} Initialized |treeViewRoot|.
*/
function getTreeViewRoot() {
if (!treeViewRoot) {
cr.ui.decorate('#tree-view', cr.ui.Tree);
decorate('#tree-view', Tree);
treeViewRoot = /** @type {cr.ui.Tree} */ ($('tree-view'));
treeViewRoot = /** @type {Tree} */ ($('tree-view'));
treeViewRoot.detail = {payload: {}, children: {}};
}
return treeViewRoot;
@ -82,7 +85,7 @@ function getTreeViewRoot() {
/**
* Initialize and return a tree item representing a FrameInfo object and
* recursively creates its subframe objects.
* @param {mojom.FrameInfo} frame
* @param {FrameInfo} frame
* @return {Array}
*/
function frameToTreeItem(frame) {
@ -109,8 +112,8 @@ function frameToTreeItem(frame) {
itemLabel += ` | url: ${frame.lastCommittedUrl.url}`;
}
const item = new cr.ui.TreeItem(
{label: itemLabel, detail: {payload: {}, children: {}}});
const item =
new TreeItem({label: itemLabel, detail: {payload: {}, children: {}}});
item.mayHaveChildren_ = true;
item.expanded = true;
item.icon = '';
@ -131,8 +134,8 @@ function frameToTreeItem(frame) {
/**
* Initialize and return a tree item representing the WebContentsInfo object
* and contains all frames in it as a subtree.
* @param {mojom.WebContentsInfo} webContents
* @return {!cr.ui.TreeItem}
* @param {WebContentsInfo} webContents
* @return {!TreeItem}
*/
function webContentsToTreeItem(webContents) {
let itemLabel = 'WebContents: ';
@ -140,8 +143,8 @@ function webContentsToTreeItem(webContents) {
itemLabel += webContents.title + ', ';
}
const item = new cr.ui.TreeItem(
{label: itemLabel, detail: {payload: {}, children: {}}});
const item =
new TreeItem({label: itemLabel, detail: {payload: {}, children: {}}});
item.mayHaveChildren_ = true;
item.expanded = true;
item.icon = '';
@ -171,16 +174,15 @@ function webContentsToTreeItem(webContents) {
/**
* This is a callback which is invoked when the data for WebContents
* associated with the browser profile is received from the browser process.
* @param {mojom.ProcessInternalsHandler_GetAllWebContentsInfo_ResponseParams}
* input
* @param {!Array<!WebContentsInfo>} infos
*/
function populateWebContentsTab(input) {
function populateWebContentsTab(infos) {
const tree = getTreeViewRoot();
// Clear the tree first before populating it with the new content.
tree.innerText = '';
for (const webContents of input.infos) {
for (const webContents of infos) {
const item = webContentsToTreeItem(webContents);
tree.add(item);
}
@ -190,8 +192,9 @@ function populateWebContentsTab(input) {
* Function which retrieves the data for all WebContents associated with the
* current browser profile. The result is passed to populateWebContentsTab.
*/
function loadWebContentsInfo() {
pageHandler.getAllWebContentsInfo().then(populateWebContentsTab);
async function loadWebContentsInfo() {
const {infos} = await pageHandler.getAllWebContentsInfo();
populateWebContentsTab(infos);
}
/**
@ -252,7 +255,7 @@ function loadIsolatedOriginInfo() {
document.addEventListener('DOMContentLoaded', function() {
// Setup Mojo interface to the backend.
pageHandler = mojom.ProcessInternalsHandler.getRemote();
pageHandler = ProcessInternalsHandler.getRemote();
// Get the Site Isolation mode and populate it.
pageHandler.getIsolationMode().then((response) => {
@ -269,4 +272,3 @@ document.addEventListener('DOMContentLoaded', function() {
$('refresh-button').addEventListener('click', loadWebContentsInfo);
});
})();

@ -81,6 +81,7 @@ const std::map<int, std::string> CreateContentResourceIdToAliasMap() {
return std::map<int, std::string>{
{IDR_ORIGIN_MOJO_HTML, "mojo/url/mojom/origin.mojom.html"},
{IDR_ORIGIN_MOJO_JS, "mojo/url/mojom/origin.mojom-lite.js"},
{IDR_ORIGIN_MOJO_WEBUI_JS, "mojo/url/mojom/origin.mojom-webui.js"},
{IDR_UNGUESSABLE_TOKEN_MOJO_HTML,
"mojo/mojo/public/mojom/base/unguessable_token.mojom.html"},
{IDR_UNGUESSABLE_TOKEN_MOJO_JS,
@ -88,8 +89,8 @@ const std::map<int, std::string> CreateContentResourceIdToAliasMap() {
{IDR_URL_MOJO_HTML, "mojo/url/mojom/url.mojom.html"},
{IDR_URL_MOJO_JS, "mojo/url/mojom/url.mojom-lite.js"},
{IDR_URL_MOJOM_WEBUI_JS, "mojo/url/mojom/url.mojom-webui.js"},
{IDR_VULKAN_INFO_MOJO_JS, "gpu/ipc/common/vulkan_info.mojom-lite.js"},
{IDR_VULKAN_TYPES_MOJO_JS, "gpu/ipc/common/vulkan_types.mojom-lite.js"},
{IDR_VULKAN_INFO_MOJO_JS, "gpu/ipc/common/vulkan_info.mojom-webui.js"},
{IDR_VULKAN_TYPES_MOJO_JS, "gpu/ipc/common/vulkan_types.mojom-webui.js"},
};
}

@ -28,6 +28,7 @@ Other resources that belong in this file:
<include name="IDR_HISTOGRAMS_INTERNALS_JS" file="browser/resources/histograms/histograms_internals.js" type="BINDATA" />
<include name="IDR_ORIGIN_MOJO_HTML" file="${root_gen_dir}/url/mojom/origin.mojom.html" use_base_dir="false" type="BINDATA" />
<include name="IDR_ORIGIN_MOJO_JS" file="${root_gen_dir}/url/mojom/origin.mojom-lite.js" use_base_dir="false" type="BINDATA" />
<include name="IDR_ORIGIN_MOJO_WEBUI_JS" file="${root_gen_dir}/mojom-webui/url/mojom/origin.mojom-webui.js" use_base_dir="false" type="BINDATA" />
<include name="IDR_UKM_INTERNALS_HTML" file="../components/ukm/debug/ukm_internals.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
<include name="IDR_UKM_INTERNALS_JS" file="../components/ukm/debug/ukm_internals.js" type="BINDATA" />
<include name="IDR_UKM_INTERNALS_CSS" file="../components/ukm/debug/ukm_internals.css" type="BINDATA" />
@ -36,8 +37,8 @@ Other resources that belong in this file:
<include name="IDR_URL_MOJO_HTML" file="${root_gen_dir}/url/mojom/url.mojom.html" use_base_dir="false" type="BINDATA" />
<include name="IDR_URL_MOJO_JS" file="${root_gen_dir}/url/mojom/url.mojom-lite.js" use_base_dir="false" type="BINDATA" />
<include name="IDR_URL_MOJOM_WEBUI_JS" file="${root_gen_dir}/mojom-webui/url/mojom/url.mojom-webui.js" use_base_dir="false" type="BINDATA" />
<include name="IDR_VULKAN_INFO_MOJO_JS" file="${root_gen_dir}/gpu/ipc/common/vulkan_info.mojom-lite.js" use_base_dir="false" type="BINDATA" />
<include name="IDR_VULKAN_TYPES_MOJO_JS" file="${root_gen_dir}/gpu/ipc/common/vulkan_types.mojom-lite.js" use_base_dir="false" type="BINDATA" />
<include name="IDR_VULKAN_INFO_MOJO_JS" file="${root_gen_dir}/mojom-webui/gpu/ipc/common/vulkan_info.mojom-webui.js" use_base_dir="false" type="BINDATA" />
<include name="IDR_VULKAN_TYPES_MOJO_JS" file="${root_gen_dir}/mojom-webui/gpu/ipc/common/vulkan_types.mojom-webui.js" use_base_dir="false" type="BINDATA" />
</includes>
</release>
</grit>

@ -21,9 +21,12 @@ files that belong there instead.
<include name="IDR_CONVERSION_INTERNALS_HTML" file="browser/resources/conversions/conversion_internals.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
<include name="IDR_CONVERSION_INTERNALS_JS" file="browser/resources/conversions/conversion_internals.js" type="BINDATA" />
<include name="IDR_CONVERSION_INTERNALS_CSS" file="browser/resources/conversions/conversion_internals.css" type="BINDATA" />
<include name="IDR_CONVERSION_INTERNALS_MOJOM_JS" file="${root_gen_dir}/content/browser/conversions/conversion_internals.mojom-lite.js" use_base_dir="false" type="BINDATA" />
<include name="IDR_CONVERSION_INTERNALS_MOJOM_JS" file="${root_gen_dir}/mojom-webui/content/browser/conversions/conversion_internals.mojom-webui.js" use_base_dir="false" type="BINDATA" />
<include name="IDR_GPU_BROWSER_BRIDGE_JS" file="browser/resources/gpu/browser_bridge.js" type="BINDATA" />
<include name="IDR_GPU_INFO_VIEW_JS" file="browser/resources/gpu/info_view.js" type="BINDATA" />
<include name="IDR_GPU_INTERNALS_HTML" file="browser/resources/gpu/gpu_internals.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
<include name="IDR_GPU_INTERNALS_JS" file="browser/resources/gpu/gpu_internals.js" flattenhtml="true" type="BINDATA" />
<include name="IDR_GPU_INTERNALS_JS" file="browser/resources/gpu/gpu_internals.js" type="BINDATA" />
<include name="IDR_GPU_VULKAN_INFO_JS" file="browser/resources/gpu/vulkan_info.js" type="BINDATA" />
<include name="IDR_INDEXED_DB_INTERNALS_HTML" file="browser/resources/indexed_db/indexeddb_internals.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
<include name="IDR_INDEXED_DB_INTERNALS_JS" file="browser/resources/indexed_db/indexeddb_internals.js" type="BINDATA" />
<include name="IDR_INDEXED_DB_INTERNALS_CSS" file="browser/resources/indexed_db/indexeddb_internals.css" type="BINDATA" />
@ -31,7 +34,7 @@ files that belong there instead.
<include name="IDR_NETWORK_ERROR_LISTING_JS" file="browser/resources/net/network_errors_listing.js" type="BINDATA" />
<include name="IDR_NETWORK_ERROR_LISTING_CSS" file="browser/resources/net/network_errors_listing.css" type="BINDATA" />
<include name="IDR_PROCESS_INTERNALS_HTML" file="browser/resources/process/process_internals.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
<include name="IDR_PROCESS_INTERNALS_MOJO_JS" file="${root_gen_dir}/content/browser/process_internals/process_internals.mojom-lite.js" use_base_dir="false" type="BINDATA" />
<include name="IDR_PROCESS_INTERNALS_MOJO_JS" file="${root_gen_dir}/mojom-webui/content/browser/process_internals/process_internals.mojom-webui.js" use_base_dir="false" type="BINDATA" />
<include name="IDR_PROCESS_INTERNALS_CSS" file="browser/resources/process/process_internals.css" flattenhtml="true" type="BINDATA" />
<include name="IDR_PROCESS_INTERNALS_JS" file="browser/resources/process/process_internals.js" type="BINDATA" />
<include name="IDR_SERVICE_WORKER_INTERNALS_HTML" file="browser/resources/service_worker/serviceworker_internals.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />

@ -39,6 +39,14 @@ test_harness_script = r"""
"""
def _GetBrowserBridgeProperty(tab, path):
"""The GPU WebUI uses JS modules and may not have initialized the global
browserBridge object by the time we can start injecting JavaScript. This
ensures we don't have that problem."""
tab.WaitForJavaScriptCondition('window.gpuPagePopulated', timeout=10)
return tab.EvaluateJavaScript('browserBridge.' + path)
class GpuProcessIntegrationTest(gpu_integration_test.GpuIntegrationTest):
@classmethod
def Name(cls):
@ -211,7 +219,7 @@ class GpuProcessIntegrationTest(gpu_integration_test.GpuIntegrationTest):
'workarounds are not equal: %s != %s, diff: %s' %
(browser_list, gpu_list, list(diff)))
basic_infos = tab.EvaluateJavaScript('browserBridge.gpuInfo.basicInfo')
basic_infos = _GetBrowserBridgeProperty(tab, 'gpuInfo.basicInfo')
disabled_gl_extensions = None
for info in basic_infos:
if info['description'].startswith('Disabled Extensions'):
@ -276,8 +284,8 @@ class GpuProcessIntegrationTest(gpu_integration_test.GpuIntegrationTest):
cba.DISABLE_GPU_COMPOSITING,
])
self._Navigate(test_path)
feature_status_list = self.tab.EvaluateJavaScript(
'browserBridge.gpuInfo.featureStatus.featureStatus')
feature_status_list = _GetBrowserBridgeProperty(
self.tab, 'gpuInfo.featureStatus.featureStatus')
result = True
for name, status in feature_status_list.items():
if name == 'webgl':
@ -293,8 +301,8 @@ class GpuProcessIntegrationTest(gpu_integration_test.GpuIntegrationTest):
# Hit test group 2 with entry 153 from kSoftwareRenderingListEntries.
self.RestartBrowserIfNecessaryWithArgs(['--gpu-blocklist-test-group=2'])
self._Navigate(test_path)
feature_status_list = self.tab.EvaluateJavaScript(
'browserBridge.gpuInfo.featureStatus.featureStatus')
feature_status_list = _GetBrowserBridgeProperty(
self.tab, 'gpuInfo.featureStatus.featureStatus')
for name, status in feature_status_list.items():
if name == 'webgl' and status != 'unavailable_software':
self.fail('WebGL status for SwiftShader failed: %s' % status)
@ -307,8 +315,8 @@ class GpuProcessIntegrationTest(gpu_integration_test.GpuIntegrationTest):
if sys.platform.startswith('linux'):
return
feature_status_for_hardware_gpu_list = self.tab.EvaluateJavaScript(
'browserBridge.gpuInfo.featureStatusForHardwareGpu.featureStatus')
feature_status_for_hardware_gpu_list = _GetBrowserBridgeProperty(
self.tab, 'gpuInfo.featureStatusForHardwareGpu.featureStatus')
for name, status in feature_status_for_hardware_gpu_list.items():
if name == 'webgl' and status != 'unavailable_off':
self.fail('WebGL status for hardware GPU failed: %s' % status)

@ -64,6 +64,7 @@ class HardwareAcceleratedFeatureIntegrationTest(
feature = args[0]
self._Navigate(test_path)
tab = self.tab
tab.WaitForJavaScriptCondition('window.gpuPagePopulated', timeout=10)
if not tab.EvaluateJavaScript(
'VerifyHardwareAccelerated({{ feature }})', feature=feature):
print 'Test failed. Printing page contents:'

@ -546,6 +546,8 @@ mojom("vulkan_interface") {
traits_public_deps = [ ":vulkan_types_mojom_traits" ]
},
]
webui_module_path = "/"
}
mojom("test_interfaces") {

@ -80,6 +80,11 @@
use_base_dir="false"
resource_path="mojo/mojo/public/mojom/base/text_direction.mojom-lite.js"
type="BINDATA" />
<include name="IDR_MOJO_UNGUESSABLE_TOKEN_MOJOM_WEBUI_JS"
file="${root_gen_dir}/mojom-webui/mojo/public/mojom/base/unguessable_token.mojom-webui.js"
use_base_dir="false"
resource_path="mojo/mojo/public/mojom/base/unguessable_token.mojom-webui.js"
type="BINDATA" />
<if expr="is_win or is_macosx or is_linux or is_android">
<include name="IDR_MOJO_PROCESS_ID_MOJOM_WEBUI_JS"
file="${root_gen_dir}/mojom-webui/mojo/public/mojom/base/process_id.mojom-webui.js"

@ -84,6 +84,8 @@ mojom("url_mojom_origin") {
traits_public_deps = [ "//url" ]
},
]
webui_module_path = "chrome://resources/mojo/url/mojom"
}
mojom("test_url_mojom_gurl") {