0

Basic frontend for App Management supported link settings.

App Management's new settings for changing whether an app is preferred
for its supported links have been produced, and displayed behind a flag
(AppManagementIntentSettings).

Deck: go/apps-intent-url
Design doc: go/am-intent-settings
Screenshot: go/supported-links-screenshot

Bug: 1204324
Change-Id: Id01f34304a1b6da6773470c62dc54d37491f4df0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2944326
Reviewed-by: Avi Drissman <avi@chromium.org>
Reviewed-by: Jimmy Gong <jimmyxgong@chromium.org>
Reviewed-by: Jeevan Shikaram <jshikaram@chromium.org>
Reviewed-by: calamity <calamity@chromium.org>
Commit-Queue: Echo Linker <ajlinker@chromium.org>
Cr-Commit-Position: refs/heads/master@{#894426}
This commit is contained in:
echo linker
2021-06-21 22:10:26 +00:00
committed by Chromium LUCI CQ
parent aa16a2092d
commit 151242065b
20 changed files with 311 additions and 27 deletions

@ -49,4 +49,13 @@
<message name="IDS_APP_MANAGEMENT_POLICY_APP_POLICY_STRING" desc="Tooltip label explaining that an app cannot be uninstalled as it has been installed by an adminstrator.">
This app has been installed by your administrator.
</message>
<message name="IDS_APP_MANAGEMENT_INTENT_SHARING" desc="Label for the intent sharing settings section.">
Opening supported links
</message>
<message name="IDS_APP_MANAGEMENT_INTENT_SHARING_APP_OPEN" desc="Label for the intent sharing option to open in a specified app.">
Open in <ph name="APP_NAME">$1<ex>Chrome browser</ex></ph>
</message>
<message name="IDS_APP_MANAGEMENT_INTENT_SHARING_BROWSER_OPEN" desc="Label for the intent sharing option to open in the browser.">
Open in Chrome browser
</message>
</grit-part>

@ -0,0 +1 @@
b214f07ca2ca58b7fd17c63f1df6513ed77075a1

@ -0,0 +1 @@
12fa43d7254174c720bca4ccd9f35a11a78b47e2

@ -0,0 +1 @@
b214f07ca2ca58b7fd17c63f1df6513ed77075a1

@ -397,6 +397,7 @@ preprocess_if_expr("preprocess_gen_v3") {
"chromeos/os_apps_page/app_management_page/shared_vars.m.js",
"chromeos/os_apps_page/app_management_page/store.m.js",
"chromeos/os_apps_page/app_management_page/store_client.m.js",
"chromeos/os_apps_page/app_management_page/supported_links_item.m.js",
"chromeos/os_apps_page/app_management_page/toggle_row.m.js",
"chromeos/os_apps_page/app_management_page/types.m.js",
"chromeos/os_apps_page/app_management_page/uninstall_button.m.js",

@ -33,6 +33,7 @@ js_type_check("closure_compile_module") {
":shared_vars.m",
":store.m",
":store_client.m",
":supported_links_item.m",
":toggle_row.m",
":types.m",
":uninstall_button.m",
@ -107,6 +108,7 @@ js_library("arc_detail_view.m") {
":permission_item.m",
":pin_to_shelf_item.m",
":store_client.m",
":supported_links_item.m",
":util.m",
]
extra_deps = [ ":arc_detail_view_module" ]
@ -212,6 +214,7 @@ js_library("pwa_detail_view.m") {
":permission_item.m",
":pin_to_shelf_item.m",
":store_client.m",
":supported_links_item.m",
":util.m",
]
extra_deps = [ ":pwa_detail_view_module" ]
@ -240,15 +243,6 @@ js_library("resize_lock_item.m") {
extra_deps = [ ":resize_lock_item_module" ]
}
js_library("store.m") {
sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/store.m.js" ]
deps = [
"//ui/webui/resources/js:cr.m",
"//ui/webui/resources/js/cr/ui:store.m",
]
extra_deps = [ ":modulize" ]
}
js_library("shared_style.m") {
sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/shared_style.m.js" ]
deps = []
@ -261,6 +255,15 @@ js_library("shared_vars.m") {
extra_deps = [ ":shared_vars_module" ]
}
js_library("store.m") {
sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/store.m.js" ]
deps = [
"//ui/webui/resources/js:cr.m",
"//ui/webui/resources/js/cr/ui:store.m",
]
extra_deps = [ ":modulize" ]
}
js_library("store_client.m") {
sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/store_client.m.js" ]
deps = [
@ -273,6 +276,20 @@ js_library("store_client.m") {
extra_deps = [ ":modulize" ]
}
js_library("supported_links_item.m") {
sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/supported_links_item.m.js" ]
deps = [
":browser_proxy.m",
":constants.m",
":store_client.m",
":types.m",
":util.m",
"//ui/webui/resources/cr_elements/cr_radio_button:cr_radio_button.m",
"//ui/webui/resources/cr_elements/cr_radio_group:cr_radio_group.m",
]
extra_deps = [ ":supported_links_item_module" ]
}
js_library("toggle_row.m") {
sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/toggle_row.m.js" ]
deps = [
@ -330,6 +347,7 @@ group("polymer3_elements") {
":resize_lock_item_module",
":shared_style_module",
":shared_vars_module",
":supported_links_item_module",
":toggle_row_module",
":uninstall_button_module",
]
@ -452,6 +470,15 @@ polymer_modulizer("shared_vars") {
html_type = "custom-style"
}
polymer_modulizer("supported_links_item") {
js_file = "supported_links_item.js"
html_file = "supported_links_item.html"
html_type = "dom-module"
migrated_imports = os_settings_migrated_imports
namespace_rewrites = os_settings_namespace_rewrites
auto_imports = os_settings_auto_imports
}
polymer_modulizer("toggle_row") {
js_file = "toggle_row.js"
html_file = "toggle_row.html"

@ -7,6 +7,7 @@
<link rel="import" href="permission_item.html">
<link rel="import" href="shared_style.html">
<link rel="import" href="store_client.html">
<link rel="import" href="supported_links_item.html">
<link rel="import" href="pin_to_shelf_item.html">
<link rel="import" href="resize_lock_item.html">
<link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html">
@ -87,6 +88,10 @@
</cr-icon-button>
</div>
</div>
<app-management-supported-links-item
id="supportedLinksSetting"
class="permission-card-row">
</app-management-supported-links-item>
</div>
</template>
<script src="arc_detail_view.js"></script>

@ -58,6 +58,8 @@
/* #export */ const InstallSource = apps.mojom.InstallSource;
/* #export */ const WindowMode = apps.mojom.WindowMode;
// This histogram is also declared and used at chrome/browser/ui/webui/settings/
// chromeos/app_management/app_management_uma.h.
/* #export */ const AppManagementEntryPointsHistogramName =
@ -110,4 +112,6 @@
PrintingTurnedOff: 18,
ResizeLockTurnedOn: 19,
ResizeLockTurnedOff: 20,
PreferredAppTurnedOn: 21,
PreferredAppTurnedOff: 22,
};

@ -8,6 +8,7 @@
<link rel="import" href="pin_to_shelf_item.html">
<link rel="import" href="shared_style.html">
<link rel="import" href="store_client.html">
<link rel="import" href="supported_links_item.html">
<link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html">
<link rel="import" href="chrome://resources/cr_elements/icons.html">
@ -60,6 +61,10 @@
</cr-icon-button>
</div>
</div>
<app-management-supported-links-item
id="supportedLinksSetting"
class="permission-card-row">
</app-management-supported-links-item>
</div>
</template>
<script src="pwa_detail_view.js"></script>

@ -0,0 +1,37 @@
<link rel="import" href="chrome://resources/html/polymer.html">
<link rel="import" href="chrome://resources/html/assert.html">
<link rel="import" href="browser_proxy.html">
<link rel="import" href="constants.html">
<link rel="import" href="store_client.html">
<link rel="import" href="util.html">
<link rel="import" href="chrome://resources/cr_elements/cr_radio_group/cr_radio_group.html">
<link rel="import" href="chrome://resources/cr_elements/cr_radio_button/cr_radio_button.html">
<link rel="import" href="../../metrics_recorder.html">
<dom-module id="app-management-supported-links-item">
<template>
<style include="app-management-shared-css settings-shared"></style>
<template is="dom-if" if="[[appManagementIntentSettingsEnabled_]]">
<div class="permission-section-header">
<div class="header-text">
$i18n{appManagementIntentSharingLabel}
</div>
</div>
<div class="list-frame">
<cr-radio-group id="isSupportedRadioGroup"
selected="[[getSelectedRadioButtonName_(app)]]">
<cr-radio-button id="preferred"
name="preferred"
label="[[getAppNameRadioButtonLabel_(app)]]">
</cr-radio-button>
<cr-radio-button id="browser"
name="browser"
label="$i18n{appManagementIntentSharingOpenBrowserLabel}">
</cr-radio-button>
</cr-radio-group>
</div>
</template>
</template>
<script src="supported_links_item.js"></script>
</dom-module>

@ -0,0 +1,67 @@
// Copyright 2021 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 {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js';
import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
Polymer({
is: 'app-management-supported-links-item',
behaviors: [
app_management.AppManagementStoreClient,
I18nBehavior,
],
properties: {
/** @type {!App} */
app: Object,
appManagementIntentSettingsEnabled_: {
type: Boolean,
value: () =>
loadTimeData.getBoolean('appManagementIntentSettingsEnabled'),
},
},
listeners: {
click: 'onClick_',
},
attached() {
this.watch('app', state => app_management.util.getSelectedApp(state));
this.updateFromStore();
},
/**
* @private
* @param {App} app
* @return {string} Supported or not for radio buttons.
*/
getSelectedRadioButtonName_(app) {
return app.isPreferredApp ? 'preferred' : 'browser';
},
/**
* @private
* @param {App} app
* @return {string} label for app name radio button
*/
getAppNameRadioButtonLabel_(app) {
return this.i18n(
'appManagementIntentSharingOpenAppLabel', String(app.title));
},
/** @private */
onClick_() {
const newState = !this.app.isPreferredApp;
app_management.BrowserProxy.getInstance().handler.setPreferredApp(
this.app.id,
newState,
);
const userAction = newState ? AppManagementUserAction.PreferredAppTurnedOn :
AppManagementUserAction.PreferredAppTurnedOff;
app_management.util.recordAppManagementUserAction(
this.app.type, userAction);
}
});

@ -34,3 +34,8 @@ let AppMap;
* }}
*/
let AppManagementPageState;
/**
* @typedef {apps.mojom.WindowMode}
*/
let WindowMode;

@ -8,7 +8,7 @@
// #import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
// #import {Route, Router} from '../../../router.js';
// #import {routes} from '../../os_route.m.js';
// #import {AppType, AppManagementUserAction, ArcPermissionType, OptionalBool, PermissionValueType, Bool, PwaPermissionType, TriState, PluginVmPermissionType} from "./constants.m.js";
// #import {AppType, AppManagementUserAction, ArcPermissionType, OptionalBool, PermissionValueType, Bool, PwaPermissionType, TriState, PluginVmPermissionType, WindowMode} from "./constants.m.js";
// clang-format on
/**

@ -60,6 +60,7 @@ import './os_apps_page/app_management_page/plugin_vm_page/plugin_vm_detail_view.
import './os_apps_page/app_management_page/pwa_detail_view.m.js';
import './os_apps_page/app_management_page/shared_style.m.js';
import './os_apps_page/app_management_page/shared_vars.m.js';
import './os_apps_page/app_management_page/supported_links_item.m.js';
import './os_apps_page/app_management_page/toggle_row.m.js';
import './os_apps_page/app_management_page/uninstall_button.m.js';
import './os_apps_page/os_apps_page.m.js';
@ -117,7 +118,7 @@ export {DeviceNameBrowserProxy, DeviceNameBrowserProxyImpl} from './os_about_pag
export {AndroidAppsBrowserProxyImpl} from './os_apps_page/android_apps_browser_proxy.m.js';
export {addApp, changeApp, removeApp, updateSelectedAppId} from './os_apps_page/app_management_page/actions.m.js';
export {BrowserProxy} from './os_apps_page/app_management_page/browser_proxy.m.js';
export {ArcPermissionType, Bool, PageType, PermissionValueType, PluginVmPermissionType, PwaPermissionType, TriState} from './os_apps_page/app_management_page/constants.m.js';
export {ArcPermissionType, Bool, PageType, PermissionValueType, PluginVmPermissionType, PwaPermissionType, TriState, WindowMode} from './os_apps_page/app_management_page/constants.m.js';
export {FakePageHandler} from './os_apps_page/app_management_page/fake_page_handler.m.js';
export {PluginVmBrowserProxyImpl} from './os_apps_page/app_management_page/plugin_vm_page/plugin_vm_browser_proxy.m.js';
export {AppState, reduceAction} from './os_apps_page/app_management_page/reducers.m.js';

@ -132,6 +132,11 @@ void AddAppManagementStrings(content::WebUIDataSource* html_source) {
{"appManagementCameraPermissionLabel", IDS_APP_MANAGEMENT_CAMERA},
{"appManagementContactsPermissionLabel", IDS_APP_MANAGEMENT_CONTACTS},
{"appManagementLocationPermissionLabel", IDS_APP_MANAGEMENT_LOCATION},
{"appManagementIntentSharingOpenBrowserLabel",
IDS_APP_MANAGEMENT_INTENT_SHARING_BROWSER_OPEN},
{"appManagementIntentSharingLabel", IDS_APP_MANAGEMENT_INTENT_SHARING},
{"appManagementIntentSharingOpenAppLabel",
IDS_APP_MANAGEMENT_INTENT_SHARING_APP_OPEN},
{"appManagementMicrophonePermissionLabel", IDS_APP_MANAGEMENT_MICROPHONE},
{"appManagementMoreSettingsLabel", IDS_APP_MANAGEMENT_MORE_SETTINGS},
{"appManagementNoAppsFound", IDS_APP_MANAGEMENT_NO_APPS_FOUND},

@ -23,6 +23,7 @@
#include "chrome/browser/ui/webui/settings/browser_lifetime_handler.h"
#include "chrome/browser/ui/webui/settings/chromeos/os_settings_features_util.h"
#include "chrome/browser/ui/webui/webui_util.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/url_constants.h"
#include "chrome/common/webui_url_constants.h"
#include "chrome/grit/browser_resources.h"
@ -173,6 +174,10 @@ void MainSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
html_source->AddBoolean("isDeepLinkingEnabled",
chromeos::features::IsDeepLinkingEnabled());
html_source->AddBoolean(
"appManagementIntentSettingsEnabled",
base::FeatureList::IsEnabled(::features::kAppManagementIntentSettings));
// Add the System Web App resources for Settings.
html_source->AddResourcePath("icon-192.png", IDR_SETTINGS_LOGO_192);

@ -305,6 +305,7 @@ if (include_js_tests) {
"$root_gen_dir/chrome/test/data/webui/settings/chromeos/permission_item_test.m.js",
"$root_gen_dir/chrome/test/data/webui/settings/chromeos/pin_to_shelf_item_test.m.js",
"$root_gen_dir/chrome/test/data/webui/settings/chromeos/pwa_detail_view_test.m.js",
"$root_gen_dir/chrome/test/data/webui/settings/chromeos/supported_links_item_test.m.js",
"$root_gen_dir/chrome/test/data/webui/settings/chromeos/toggle_row_test.m.js",
"$root_gen_dir/chrome/test/data/webui/settings/chromeos/managed_apps_test.m.js",
"$root_gen_dir/chrome/test/data/webui/settings/chromeos/test_plugin_vm_browser_proxy.m.js",

@ -50,6 +50,7 @@ js_modulizer("modulize") {
"app_management/managed_apps_test.js",
"app_management/reducers_test.js",
"app_management/resize_lock_item_test.js",
"app_management/supported_links_item_test.js",
"app_management/test_plugin_vm_browser_proxy.js",
"app_management/toggle_row_test.js",
"app_management/test_store.js",
@ -165,20 +166,21 @@ js_modulizer("modulize") {
"tts_subpage_test.js",
"user_page_tests.js",
]
namespace_rewrites = os_settings_namespace_rewrites +
os_test_namespace_rewrites +
nearby_shared_namespace_rewrites + [
"nearby_share.FakeNearbyShareSettings|FakeNearbyShareSettings",
"nearby_share.setReceiveManagerForTesting|setReceiveManagerForTesting",
"nearby_share.FakeReceiveManager|FakeReceiveManager",
"nearby_share.FakeContactManager|FakeContactManager",
"test_util.isVisible|isVisible",
"test_util.waitAfterNextRender|waitAfterNextRender",
"app_management.TestAppManagementStore|TestAppManagementStore",
"cr.ui.TestStore|TestStore",
"app_management.util.conveapp_management.convertOptionalBoolToBool|convertOptionalBoolToBool",
"app_management.actions.changePage|changePage",
"settings.FakeSystemDisplay|FakeSystemDisplay",
"settings.setDisplayApiForTesting|setDisplayApiForTesting",
]
namespace_rewrites =
os_settings_namespace_rewrites + os_test_namespace_rewrites +
nearby_shared_namespace_rewrites +
[
"nearby_share.FakeNearbyShareSettings|FakeNearbyShareSettings",
"nearby_share.setReceiveManagerForTesting|setReceiveManagerForTesting",
"nearby_share.FakeReceiveManager|FakeReceiveManager",
"nearby_share.FakeContactManager|FakeContactManager",
"test_util.isVisible|isVisible",
"test_util.waitAfterNextRender|waitAfterNextRender",
"app_management.TestAppManagementStore|TestAppManagementStore",
"cr.ui.TestStore|TestStore",
"app_management.convertOptionalBoolToBool|convertOptionalBoolToBool",
"app_management.actions.changePage|changePage",
"settings.FakeSystemDisplay|FakeSystemDisplay",
"settings.setDisplayApiForTesting|setDisplayApiForTesting",
]
}

@ -0,0 +1,106 @@
// Copyright 2021 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.
// clang-format off
// #import 'chrome://os-settings/chromeos/os_settings.js';
// #import {AppManagementStore, FakePageHandler, updateSelectedAppId} from 'chrome://os-settings/chromeos/os_settings.js';
// #import {setupFakeHandler, replaceStore, replaceBody} from './test_util.m.js';
// #import {flushTasks} from 'chrome://test/test_util.m.js';
// clang-format on
'use strict';
suite('<app-management-supported-links-item>', () => {
let supportedLinksItem;
let fakeHandler;
setup(async function() {
fakeHandler = setupFakeHandler();
replaceStore();
supportedLinksItem =
document.createElement('app-management-supported-links-item');
// TODO(ajlinker): Remove this line when the feature flag is removed.
supportedLinksItem.appManagementIntentSettingsEnabled_ = true;
});
test(
'PWA - preferred -> browser',
async function() {
const pwaOptions = {
type: apps.mojom.AppType.kWeb,
isPreferredApp: true,
};
// Add PWA app, and make it the currently selected app.
const app = await fakeHandler.addApp('app1', pwaOptions);
app_management.AppManagementStore.getInstance().dispatch(
app_management.actions.updateSelectedAppId(app.id));
await fakeHandler.flushPipesForTesting();
assertTrue(!!app_management.AppManagementStore.getInstance()
.data.apps[app.id]);
supportedLinksItem.app = app;
replaceBody(supportedLinksItem);
fakeHandler.flushPipesForTesting();
test_util.flushTasks();
expectEquals(
supportedLinksItem.$$('cr-radio-group').selected, 'preferred');
await supportedLinksItem.$$('#browser').click();
await fakeHandler.flushPipesForTesting();
await test_util.flushTasks();
expectFalse(app_management.AppManagementStore.getInstance()
.data.apps[app.id]
.isPreferredApp);
expectEquals(
supportedLinksItem.$$('cr-radio-group').selected, 'browser');
}),
test('ARC - browser -> preferred', async function() {
const arcOptions = {
type: apps.mojom.AppType.kArc,
isPreferredApp: false,
};
// Add ARC app, and make it the currently selected app.
const app = await fakeHandler.addApp('app1', arcOptions);
app_management.AppManagementStore.getInstance().dispatch(
app_management.actions.updateSelectedAppId(app.id));
await fakeHandler.flushPipesForTesting();
assertTrue(!!app_management.AppManagementStore.getInstance()
.data.apps[app.id]);
supportedLinksItem.app = app;
replaceBody(supportedLinksItem);
fakeHandler.flushPipesForTesting();
test_util.flushTasks();
expectEquals(
supportedLinksItem.$$('cr-radio-group').selected, 'browser');
await supportedLinksItem.$$('#preferred').click();
await fakeHandler.flushPipesForTesting();
await test_util.flushTasks();
expectTrue(app_management.AppManagementStore.getInstance()
.data.apps[app.id]
.isPreferredApp);
expectEquals(
supportedLinksItem.$$('cr-radio-group').selected, 'preferred');
});
});

@ -286,6 +286,7 @@ TEST_F(
['AppManagementPwaDetailView', 'pwa_detail_view_test.m.js'],
['AppManagementReducers', 'reducers_test.m.js'],
['AppManagementResizeLockItem', 'resize_lock_item_test.m.js'],
['AppManagementSupportedLinksItem', 'supported_links_item_test.m.js'],
['AppManagementToggleRow', 'toggle_row_test.m.js'],
['AppManagementUninstallButton', 'uninstall_button_test.m.js'],
['BluetoothPage', 'bluetooth_page_tests.m.js'],