Commit 9231a22f authored by Christopher Lam's avatar Christopher Lam Committed by Commit Bot

[App Management] Add skeleton for App Management WebUI.

This CL adds a WebUI for App Management that replaces chrome://apps
when the feature NewAppManagement is enabled. This involves:
- adding the feature
- adding a new MojoWebUIController
- adding a mojom, and its C++ handler
- adding a skeleton HTML and Polymer 'app' element
- adding a BrowserProxy which connects the Renderer JS to the backend C++.

Bug: 906508
Change-Id: Iac5be9ce82dc2cb0b1c77301ca43ccf7a99f318f
Reviewed-on: https://chromium-review.googlesource.com/c/1309380
Commit-Queue: calamity <calamity@chromium.org>
Reviewed-by: default avatarDominick Ng <dominickn@chromium.org>
Cr-Commit-Position: refs/heads/master@{#609204}
parent 474c1c5b
......@@ -4980,6 +4980,7 @@ grit("resources") {
"//chrome/browser/engagement:mojo_bindings_js",
"//chrome/browser/media:mojo_bindings_js",
"//chrome/browser/resources/ssl/ssl_error_assistant:make_ssl_error_assistant_protobuf",
"//chrome/browser/ui/webui/app_management:mojo_bindings_js",
"//chrome/browser/ui/webui/bluetooth_internals:mojo_bindings_js",
"//chrome/browser/ui/webui/interventions_internals:mojo_bindings_js",
"//chrome/browser/ui/webui/omnibox:mojo_bindings_js",
......
......@@ -213,6 +213,14 @@
<include name="IDR_HANGOUT_SERVICES_MANIFEST" file="resources\hangout_services\manifest.json" type="BINDATA" />
</if>
<!-- App Management. -->
<include name="IDR_APP_MANAGEMENT_MOJO_LITE_JS" file="${root_gen_dir}\chrome\browser\ui\webui\app_management\app_management.mojom-lite.js" use_base_dir="false" type="BINDATA" />
<include name="IDR_APP_MANAGEMENT_APP_HTML" file="resources\app_management\app.html" type="BINDATA" />
<include name="IDR_APP_MANAGEMENT_APP_JS" file="resources\app_management\app.js" type="BINDATA" />
<include name="IDR_APP_MANAGEMENT_BROWSER_PROXY_HTML" file="resources\app_management\browser_proxy.html" type="BINDATA" />
<include name="IDR_APP_MANAGEMENT_BROWSER_PROXY_JS" file="resources\app_management\browser_proxy.js" type="BINDATA" />
<include name="IDR_APP_MANAGEMENT_INDEX_HTML" file="resources\app_management\index.html" type="BINDATA" />
<if expr="not is_android">
<!-- MD Bookmarks. -->
<include name="IDR_MD_BOOKMARKS_IMAGES_FOLDER_OPEN_SVG" file="resources\md_bookmarks\images\folder_open.svg" type="BINDATA" />
......
......@@ -106,6 +106,7 @@
"translate.mojom.ContentTranslateDriver",
// TODO(beng): These should be moved to a separate capability.
"app_management.mojom.PageHandlerFactory",
"eoc_internals.mojom.PageHandler",
"media.mojom.MediaEngagementScoreDetailsProvider",
"mojom.BluetoothInternalsHandler",
......
......@@ -46,6 +46,9 @@ if (closure_compile) {
"webapks:closure_compile",
]
}
if (!is_android) {
deps += [ "app_management:closure_compile" ]
}
}
}
......
# Copyright 2018 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.
import("../optimize_webui.gni")
import("//third_party/closure_compiler/compile_js.gni")
js_type_check("closure_compile") {
deps = [
":app",
":browser_proxy",
]
}
js_library("app") {
deps = [
":browser_proxy",
]
}
js_library("browser_proxy") {
deps = [
":externs",
"//ui/webui/resources/js:cr",
]
}
js_library("externs") {
sources = []
extra_deps = [ "//chrome/browser/ui/webui/app_management:mojo_bindings_js" ]
externs_list = [
"$root_gen_dir/chrome/browser/ui/webui/app_management/app_management.mojom-lite.externs.js",
"$externs_path/mojo.js",
]
}
calamity@chromium.org
dominickn@chromium.org
ericwilligers@chromium.org
<link rel="import" href="chrome://resources/html/polymer.html">
<link rel="import" href="chrome://apps/browser_proxy.html">
<dom-module id="app-management-app">
<template>
App Settings
</template>
<script src="chrome://apps/app.js"></script>
</dom-module>
// Copyright 2018 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.
Polymer({
is: 'app-management-app',
/** @override */
attached: function() {
app_management.BrowserProxy.getInstance().handler.getApps();
let callbackRouter =
app_management.BrowserProxy.getInstance().callbackRouter;
this.listenerIds_ =
[callbackRouter.onAppsAdded.addListener((id) => console.log(id))];
},
detached: function() {
let callbackRouter =
app_management.BrowserProxy.getInstance().callbackRouter;
this.listenerIds_.forEach((id) => callbackRouter.removeListener(id));
},
});
<link rel="import" href="chrome://resources/html/cr.html">
<script src="browser_proxy.js"></script>
<script src="chrome://resources/js/mojo_bindings_lite.js"></script>
<script src="app_management.mojom-lite.js"></script>
// Copyright 2018 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('app_management', function() {
class BrowserProxy {
constructor() {
/** @type {appManagement.mojom.PageCallbackRouter} */
this.callbackRouter = new appManagement.mojom.PageCallbackRouter();
/** @type {appManagement.mojom.PageHandlerProxy} */
this.handler = new appManagement.mojom.PageHandlerProxy();
const factory = appManagement.mojom.PageHandlerFactory.getProxy();
factory.createPageHandler(
this.callbackRouter.createProxy(), this.handler.createRequest());
}
}
cr.addSingletonGetter(BrowserProxy);
return {BrowserProxy: BrowserProxy};
});
<!doctype html>
<html dir="$i18n{textdirection}" lang="$i18n{language}">
<head>
<meta charset="utf8">
<link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css">
<link rel="stylesheet" href="chrome://resources/css/md_colors.css">
<style>
html {
/* Remove 300ms delay for 'click' event, when using touch interface. */
touch-action: manipulation;
}
html,
body {
background: var(--md-background-color);
height: 100%;
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<app-management-app></app-management-app>
<script src="chrome://resources/js/load_time_data.js"></script>
<script src="chrome://apps/strings.js"></script>
<link rel="import" href="chrome://apps/app.html">
</body>
</html>
......@@ -383,6 +383,7 @@ jumbo_split_static_library("ui") {
"//chrome/browser/profiling_host",
"//chrome/browser/safe_browsing",
"//chrome/browser/ssl:proto",
"//chrome/browser/ui/webui/app_management:mojo_bindings",
"//chrome/browser/ui/webui/bluetooth_internals",
"//chrome/browser/ui/webui/interventions_internals:mojo_bindings",
"//chrome/browser/ui/webui/omnibox:mojo_bindings",
......@@ -1059,6 +1060,10 @@ jumbo_split_static_library("ui") {
"unload_controller.h",
"webui/app_launcher_login_handler.cc",
"webui/app_launcher_login_handler.h",
"webui/app_management/app_management_page_handler.cc",
"webui/app_management/app_management_page_handler.h",
"webui/app_management/app_management_ui.cc",
"webui/app_management/app_management_ui.h",
"webui/browsing_history_handler.cc",
"webui/browsing_history_handler.h",
"webui/chrome_web_contents_handler.cc",
......
# Copyright 2018 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.
import("//mojo/public/tools/bindings/mojom.gni")
mojom("mojo_bindings") {
sources = [
"app_management.mojom",
]
}
per-file *.mojom=set noparent
per-file *.mojom=file://ipc/SECURITY_OWNERS
calamity@chromium.org
dominickn@chromium.org
ericwilligers@chromium.org
// Copyright 2018 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.
module app_management.mojom;
interface PageHandlerFactory {
CreatePageHandler(Page page, PageHandler& handler);
};
// Browser interface.
interface PageHandler {
GetApps();
};
// Frontend interface.
interface Page {
OnAppsAdded(array<string> ids);
};
// Copyright 2018 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/app_management/app_management_page_handler.h"
#include <utility>
#include <vector>
AppManagementPageHandler::AppManagementPageHandler(
app_management::mojom::PageHandlerRequest request,
app_management::mojom::PagePtr page,
content::WebUI* web_ui)
: binding_(this, std::move(request)), page_(std::move(page)) {}
AppManagementPageHandler::~AppManagementPageHandler() {}
void AppManagementPageHandler::GetApps() {
std::vector<std::string> ids = {"test_id"};
page_->OnAppsAdded(ids);
}
// Copyright 2018 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_APP_MANAGEMENT_APP_MANAGEMENT_PAGE_HANDLER_H_
#define CHROME_BROWSER_UI_WEBUI_APP_MANAGEMENT_APP_MANAGEMENT_PAGE_HANDLER_H_
#include "base/macros.h"
#include "chrome/browser/ui/webui/app_management/app_management.mojom.h"
#include "mojo/public/cpp/bindings/binding.h"
namespace content {
class WebUI;
}
class AppManagementPageHandler : public app_management::mojom::PageHandler {
public:
AppManagementPageHandler(app_management::mojom::PageHandlerRequest request,
app_management::mojom::PagePtr page,
content::WebUI* web_ui);
~AppManagementPageHandler() override;
// app_management::mojom::PageHandler:
void GetApps() override;
private:
mojo::Binding<app_management::mojom::PageHandler> binding_;
app_management::mojom::PagePtr page_;
DISALLOW_COPY_AND_ASSIGN(AppManagementPageHandler);
};
#endif // CHROME_BROWSER_UI_WEBUI_APP_MANAGEMENT_APP_MANAGEMENT_PAGE_HANDLER_H_
// Copyright 2018 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/app_management/app_management_ui.h"
#include <utility>
#include "base/bind.h"
#include "base/feature_list.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/webui/app_management/app_management_page_handler.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/url_constants.h"
#include "chrome/grit/browser_resources.h"
#include "chrome/grit/chromium_strings.h"
#include "chrome/grit/generated_resources.h"
#include "content/public/browser/web_ui.h"
#include "content/public/browser/web_ui_data_source.h"
#include "ui/base/resource/resource_bundle.h"
namespace {
content::WebUIDataSource* CreateAppManagementUIHTMLSource(Profile* profile) {
content::WebUIDataSource* source =
content::WebUIDataSource::Create(chrome::kChromeUIAppLauncherPageHost);
source->AddResourcePath("app_management.mojom-lite.js",
IDR_APP_MANAGEMENT_MOJO_LITE_JS);
source->AddResourcePath("app.html", IDR_APP_MANAGEMENT_APP_HTML);
source->AddResourcePath("app.js", IDR_APP_MANAGEMENT_APP_JS);
source->AddResourcePath("browser_proxy.html",
IDR_APP_MANAGEMENT_BROWSER_PROXY_HTML);
source->AddResourcePath("browser_proxy.js",
IDR_APP_MANAGEMENT_BROWSER_PROXY_JS);
source->SetDefaultResource(IDR_APP_MANAGEMENT_INDEX_HTML);
source->SetJsonPath("strings.js");
return source;
}
} // namespace
///////////////////////////////////////////////////////////////////////////////
//
// AppManagementUI
//
///////////////////////////////////////////////////////////////////////////////
AppManagementUI::AppManagementUI(content::WebUI* web_ui)
: ui::MojoWebUIController(web_ui, true), page_factory_binding_(this) {
Profile* profile = Profile::FromWebUI(web_ui);
// Set up the data source.
content::WebUIDataSource* source = CreateAppManagementUIHTMLSource(profile);
content::WebUIDataSource::Add(profile, source);
AddHandlerToRegistry(base::BindRepeating(
&AppManagementUI::BindPageHandlerFactory, base::Unretained(this)));
}
AppManagementUI::~AppManagementUI() = default;
bool AppManagementUI::IsEnabled() {
return base::FeatureList::IsEnabled(features::kAppManagement);
}
void AppManagementUI::BindPageHandlerFactory(
app_management::mojom::PageHandlerFactoryRequest request) {
if (page_factory_binding_.is_bound())
page_factory_binding_.Unbind();
page_factory_binding_.Bind(std::move(request));
}
void AppManagementUI::CreatePageHandler(
app_management::mojom::PagePtr page,
app_management::mojom::PageHandlerRequest request) {
DCHECK(page);
page_handler_.reset(new AppManagementPageHandler(std::move(request),
std::move(page), web_ui()));
}
// Copyright 2018 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_APP_MANAGEMENT_APP_MANAGEMENT_UI_H_
#define CHROME_BROWSER_UI_WEBUI_APP_MANAGEMENT_APP_MANAGEMENT_UI_H_
#include <memory>
#include "base/macros.h"
#include "chrome/browser/ui/webui/app_management/app_management.mojom.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "ui/webui/mojo_web_ui_controller.h"
class AppManagementPageHandler;
class AppManagementUI : public ui::MojoWebUIController,
public app_management::mojom::PageHandlerFactory {
public:
explicit AppManagementUI(content::WebUI* web_ui);
~AppManagementUI() override;
static bool IsEnabled();
private:
void BindPageHandlerFactory(
app_management::mojom::PageHandlerFactoryRequest request);
// app_management::mojom::PageHandlerFactory:
void CreatePageHandler(
app_management::mojom::PagePtr page,
app_management::mojom::PageHandlerRequest request) override;
std::unique_ptr<AppManagementPageHandler> page_handler_;
mojo::Binding<app_management::mojom::PageHandlerFactory>
page_factory_binding_;
DISALLOW_COPY_AND_ASSIGN(AppManagementUI);
};
#endif // CHROME_BROWSER_UI_WEBUI_APP_MANAGEMENT_APP_MANAGEMENT_UI_H_
......@@ -22,6 +22,7 @@
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/search/suggestions/suggestions_ui.h"
#include "chrome/browser/ui/webui/about_ui.h"
#include "chrome/browser/ui/webui/app_management/app_management_ui.h"
#include "chrome/browser/ui/webui/bluetooth_internals/bluetooth_internals_ui.h"
#include "chrome/browser/ui/webui/components_ui.h"
#include "chrome/browser/ui/webui/constrained_web_dialog_ui.h"
......@@ -415,6 +416,12 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI* web_ui,
* OS Specific #defines
***************************************************************************/
#if !defined(OS_ANDROID)
if (AppManagementUI::IsEnabled() &&
url.host_piece() == chrome::kChromeUIAppLauncherPageHost && profile &&
!profile->IsGuestSession()) {
return &NewWebUI<AppManagementUI>;
}
#if !defined(OS_CHROMEOS)
// AppLauncherPage is not needed on Android or ChromeOS.
if (url.host_piece() == chrome::kChromeUIAppLauncherPageHost && profile &&
......@@ -422,7 +429,7 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI* web_ui,
!profile->IsGuestSession()) {
return &NewWebUI<AppLauncherPageUI>;
}
#endif // defined(OS_CHROMEOS)
#endif // !defined(OS_CHROMEOS)
if (profile->IsGuestSession() &&
(url.host_piece() == chrome::kChromeUIAppLauncherPageHost ||
......
......@@ -576,6 +576,10 @@ const base::Feature kSysInternals{"SysInternals",
const base::Feature kSystemWebApps{"SystemWebApps",
base::FEATURE_DISABLED_BY_DEFAULT};
// Enables or disables the App Management UI.
const base::Feature kAppManagement{"AppManagement",
base::FEATURE_DISABLED_BY_DEFAULT};
// Enable TopSites to source and sort its site data using site engagement.
const base::Feature kTopSitesFromSiteEngagement{
"TopSitesFromSiteEngagement", base::FEATURE_DISABLED_BY_DEFAULT};
......
......@@ -379,6 +379,9 @@ extern const base::Feature kSysInternals;
COMPONENT_EXPORT(CHROME_FEATURES)
extern const base::Feature kSystemWebApps;
COMPONENT_EXPORT(CHROME_FEATURES)
extern const base::Feature kAppManagement;
#if !defined(OS_ANDROID)
COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kTabMetricsLogging;
#endif
......
......@@ -1091,6 +1091,7 @@ test("browser_tests") {
if (include_js_tests) {
deps += [
"//chrome/test/data/webui:browser_tests_js_mojo_lite_webui",
"//chrome/test/data/webui:browser_tests_js_mojo_webui",
"//chrome/test/data/webui:browser_tests_js_webui",
]
......
......@@ -156,6 +156,21 @@ js2gtest("browser_tests_js_mojo_webui") {
"//chrome/browser/ui",
"//skia",
]
defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ]
}
js2gtest("browser_tests_js_mojo_lite_webui") {
test_type = "mojo_lite_webui"
sources = [
"app_management/app_management_browsertest.js",
]
deps = [
"//chrome/browser/ui",
]
defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ]
}
......
// Copyright 2018 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.
/**
* @fileoverview Test suite for the App Management page.
*/
const ROOT_PATH = '../../../../../';
GEN_INCLUDE(
[ROOT_PATH + 'chrome/test/data/webui/polymer_browser_test_base.js']);
GEN('#include "chrome/common/chrome_features.h"');
function AppManagementBrowserTest() {}
AppManagementBrowserTest.prototype = {
__proto__: PolymerTest.prototype,
browsePreload: 'chrome://apps',
extraLibraries: PolymerTest.getLibraries(ROOT_PATH),
featureList: ['features::kAppManagement', ''],
/** override */
runAccessibilityChecks: true,
};
function AppManagementAppTest() {}
AppManagementAppTest.prototype = {
__proto__: AppManagementBrowserTest.prototype,
extraLibraries: AppManagementBrowserTest.prototype.extraLibraries.concat([
'app_test.js',
]),
};
TEST_F('AppManagementAppTest', 'All', function() {
mocha.run();
});
// Copyright 2018 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.
suite('<app-management-app>', function() {
test('loads', function(done) {
app_management.BrowserProxy.getInstance().handler.getApps();
let callbackRouter =
app_management.BrowserProxy.getInstance().callbackRouter;
callbackRouter.onAppsAdded.addListener(() => done());
});
});
......@@ -36,6 +36,7 @@
# failing tests.
ActiveDirectoryJoinTest.*
AppManagementAppTest.*
AudioPlayerBrowserTest.*
BluetoothInternalsTest.*
CertificateViewerModalUITest.*
......
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