Commit a52b017f authored by Gordon Seto's avatar Gordon Seto Committed by Chromium LUCI CQ

[CrOS Settings] Add pending eSIM profiles UI in internet_subpage

Update UI to show the name, provider and download button for pending
eSIM profiles in internet_subpage.

Screenshot:
https://screenshot.googleplex.com/C3FvRveeyNscFFY.png

Bug: 1093185
Change-Id: I84386bf9eb7bc8148b6ffa335143aa1da8f15d83
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2598146
Commit-Queue: Gordon Seto <gordonseto@google.com>
Reviewed-by: default avatarAzeem Arshad <azeemarshad@chromium.org>
Reviewed-by: default avatarKyle Horimoto <khorimoto@chromium.org>
Cr-Commit-Position: refs/heads/master@{#839205}
parent c216f2bc
......@@ -1626,6 +1626,15 @@
<message name="IDS_NETWORK_LIST_ITEM_LABEL_TETHER_WITH_CONNECTION_STATUS_AND_PROVIDER_NAME" desc="A11y label for a phone tether network in a list in settings and oobe. Includes connection status. Clicking the network navigates to the details page.">
Network <ph name="NETWORK_INDEX">$1<ex>1</ex></ph> of <ph name="NETWORK_COUNT">$2<ex>10</ex></ph>, <ph name="PHONE_NAME">$3<ex>Pixel 4</ex></ph>, <ph name="PROVIDER_NAME">$4<ex>Google Fi</ex></ph>, <ph name="CONNECTION_STATUS">$5<ex>Connecting...</ex></ph>, Signal Strength <ph name="SIGNAL_STRENGTH">$6<ex>80</ex></ph>%, Phone Battery <ph name="BATTERY_STATUS">$7<ex>80</ex></ph>%, Details
</message>
<message name="IDS_NETWORK_LIST_ITEM_LABEL_ESIM_PENDING_PROFILE" desc="A11y label for an eSIM profile that's ready to be installed, shown in a list in settings and oobe. Clicking the profile installs the eSIM profile so that the cellular network is available for connecting.">
Download mobile profile, Network <ph name="NETWORK_INDEX">$1<ex>1</ex></ph> of <ph name="NETWORK_COUNT">$2<ex>10</ex></ph>, <ph name="NETWORK_NAME">$3<ex>Verizon Wireless</ex></ph>
</message>
<message name="IDS_NETWORK_LIST_ITEM_LABEL_ESIM_PENDING_PROFILE_WITH_PROVIDER_NAME" desc="A11y label for an eSIM profile that's ready to be installed, shown in a list in settings and oobe. Includes the provider name. Clicking the profile installs the eSIM profile so that the cellular network is available for connecting.">
Download mobile profile, Network <ph name="NETWORK_INDEX">$1<ex>1</ex></ph> of <ph name="NETWORK_COUNT">$2<ex>10</ex></ph>, <ph name="NETWORK_NAME">$3<ex>Verizon Wireless</ex></ph>, <ph name="NETWORK_PROVIDER_NAME">$4<ex>Verizon LTE</ex></ph>
</message>
<message name="IDS_NETWORK_LIST_ITEM_DOWNLOAD" desc="Text for the button displayed for pending eSIM profiles that installs the profile when pressed.">
Download
</message>
<message name="IDS_WIFI_NETWORK_STATUS_SECURED" desc="a11y label used when a Wi-Fi network is secured.">
Secured
</message>
......
710d2238926a7c7036e60f6825f42ca4a59a95c9
\ No newline at end of file
99e38ce0156d6c556eddc26bea0550077ff20335
\ No newline at end of file
......@@ -114,6 +114,7 @@
var items = [];
if (this.isOfflineDemoModeSetup) {
items.push({
customItemType: NetworkList.CustomItemType.OOBE,
customItemName: 'offlineDemoSetupListItemName',
polymerIcon: 'oobe-network-20:offline-demo-setup',
showBeforeNetworksList: true,
......@@ -124,6 +125,7 @@
}
if (this.isNetworkConnected) {
items.push({
customItemType: NetworkList.CustomItemType.OOBE,
customItemName: 'proxySettingsListItemName',
polymerIcon: 'oobe-network-20:add-proxy',
showBeforeNetworksList: false,
......@@ -133,6 +135,7 @@
});
}
items.push({
customItemType: NetworkList.CustomItemType.OOBE,
customItemName: 'addWiFiListItemName',
polymerIcon: 'oobe-network-20:add-wifi',
showBeforeNetworksList: false,
......
......@@ -33,7 +33,7 @@
}
.cellular-network-content {
margin: 8px 0 8px 32px;
margin: 0 0 0 32px;
}
.cellular-not-setup {
......
......@@ -118,16 +118,25 @@ Polymer({
throw new Error('No EUICCs available.');
})
.then(profiles => {
this.eSimPendingProfiles_ = profiles.map(profile => {
const pendingProfilePromises = profiles.map(profile => {
return profile.getProperties().then(response => {
return {
// TODO(crbug.com/1093185) Populate with profile name and
// provider. Right now use any valid i18n string for
// customItemName so an error isn't thrown during test.
customItemName: 'cellularNetworkEsimLabel',
customItemType: NetworkList.CustomItemType.ESIM_PENDING_PROFILE,
customItemName:
String.fromCharCode(...response.properties.name.data),
customItemSubtitle: String.fromCharCode(
...response.properties.serviceProvider.data),
polymerIcon: 'network:cellular-0',
showBeforeNetworksList: false,
customData: {
iccid: response.properties.iccid,
},
};
});
});
Promise.all(pendingProfilePromises).then(profiles => {
this.eSimPendingProfiles_ = profiles;
});
})
.catch(error => {
console.error(error);
......
......@@ -78,6 +78,10 @@ constexpr webui::LocalizedString kElementLocalizedStrings[] = {
IDS_NETWORK_LIST_ITEM_LABEL_TETHER_WITH_CONNECTION_STATUS},
{"networkListItemLabelTetherWithConnectionStatusAndProviderName",
IDS_NETWORK_LIST_ITEM_LABEL_TETHER_WITH_CONNECTION_STATUS_AND_PROVIDER_NAME},
{"networkListItemLabelESimPendingProfile",
IDS_NETWORK_LIST_ITEM_LABEL_ESIM_PENDING_PROFILE},
{"networkListItemLabelESimPendingProfileWithProviderName",
IDS_NETWORK_LIST_ITEM_LABEL_ESIM_PENDING_PROFILE_WITH_PROVIDER_NAME},
{"wifiNetworkStatusSecured", IDS_WIFI_NETWORK_STATUS_SECURED},
{"wifiNetworkStatusUnsecured", IDS_WIFI_NETWORK_STATUS_UNSECURED},
{"networkListItemNotAvailable", IDS_NETWORK_LIST_NOT_AVAILABLE},
......@@ -85,6 +89,7 @@ constexpr webui::LocalizedString kElementLocalizedStrings[] = {
{"networkListItemSimCardLocked", IDS_NETWORK_LIST_SIM_CARD_LOCKED},
{"networkListItemNotConnected", IDS_NETWORK_LIST_NOT_CONNECTED},
{"networkListItemNoNetwork", IDS_NETWORK_LIST_NO_NETWORK},
{"networkListItemDownload", IDS_NETWORK_LIST_ITEM_DOWNLOAD},
{"vpnNameTemplate", IDS_NETWORK_LIST_THIRD_PARTY_VPN_NAME_TEMPLATE},
{"networkIconLabelEthernet", IDS_NETWORK_ICON_LABEL_ETHERNET},
{"networkIconLabelVpn", IDS_NETWORK_ICON_LABEL_VPN},
......
......@@ -17,6 +17,7 @@
// #import {FakeNetworkConfig} from 'chrome://test/chromeos/fake_network_config_mojom.m.js';
// #import {MojoInterfaceProviderImpl} from 'chrome://resources/cr_components/chromeos/network/mojo_interface_provider.m.js';
// #import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
// #import {NetworkList} from 'chrome://resources/cr_components/chromeos/network/network_list_types.m.js';
// clang-format on
suite('NetworkListItemTest', function() {
......@@ -71,7 +72,7 @@ suite('NetworkListItemTest', function() {
OncMojo.getDefaultNetworkState(mojom.NetworkType.kEthernet, 'eth0');
await flushAsync();
let providerName = listItem.$$('#networkProviderName');
let providerName = listItem.$$('#subtitle');
assertFalse(!!providerName.textContent.trim());
const cellular = OncMojo.getDefaultManagedProperties(
......@@ -87,8 +88,37 @@ suite('NetworkListItemTest', function() {
await flushAsync();
providerName = listItem.$$('#networkProviderName');
providerName = listItem.$$('#subtitle');
assertTrue(!!providerName);
assertEquals('Verizon Wireless', providerName.textContent.trim());
});
test(
'Pending eSIM profile name, provider, download button visibilty',
async () => {
const itemName = 'Item Name';
const itemSubtitle = 'Item Subtitle';
listItem.item = {
customItemType: NetworkList.CustomItemType.ESIM_PENDING_PROFILE,
customItemName: itemName,
customItemSubtitle: itemSubtitle,
polymerIcon: 'network:cellular-0',
showBeforeNetworksList: false,
customData: {
iccid: 'iccid',
},
};
await flushAsync();
let networkName = listItem.$$('#networkName');
assertTrue(!!networkName);
assertEquals(itemName, networkName.textContent.trim());
let subtitle = listItem.$$('#subtitle');
assertTrue(!!subtitle);
assertEquals(itemSubtitle, subtitle.textContent.trim());
let downloadButton = listItem.$$('#downloadButton');
assertTrue(!!downloadButton);
});
});
......@@ -24,6 +24,8 @@
and migrate the rest of the icons used by network_icon
into this iconset. -->
<g id="cellular-0"><path fill-rule="evenodd" clip-rule="evenodd" d="M15.002 15.002V7.41622L7.41622 15.002H15.002ZM16.002 17.002C16.5543 17.002 17.002 16.5543 17.002 16.002V5.002C17.002 4.1111 15.9249 3.66493 15.2949 4.2949L4.2949 15.2949C3.66493 15.9249 4.1111 17.002 5.002 17.002H16.002Z" ></g>
<g id="download" viewBox="0 0 20 20"><path d="M11 9.2L13.5 6.5L15 8L10 13L5 8L6.5 6.5L9 9.2V3H11V9.2Z"></path><path d="M6 15V13H4V15.375C4 16.2688 4.73125 17 5.625 17H14.375C15.2688 17 16 16.2688 16 15.375V13H14V15H6Z"></path></g>
</defs>
</svg>
</iron-iconset-svg>
......
......@@ -14,7 +14,6 @@
network-list-item {
align-items: center;
height: 48px;
}
#container {
......
......@@ -23,7 +23,10 @@
}
#divOuter {
height: 100%;
margin-bottom: 8px;
margin-top: 8px;
min-height: 48px;
overflow: auto;
padding-inline-end: var(--cr-icon-ripple-padding);
}
......@@ -49,18 +52,32 @@
color: var(--google-green-500);
}
iron-icon {
iron-icon :not(.esim-pending-profile) {
height: 24px;
width: 24px;
}
iron-icon .esim-pending-profile {
height: 20px;
width: 20px;
}
cr-policy-indicator {
padding: 0 var(--cr-controlled-by-spacing);
}
.esim-pending-profile {
opacity: 0.4;
}
#wrapper {
height: 100%;
}
cr-button iron-icon {
--iron-icon-fill-color: #1A73E8;
margin-inline-end: 8px;
}
</style>
<div id="wrapper" focus-row-container
class="layout horizontal center flex">
......@@ -82,14 +99,16 @@
</network-icon>
</template>
<template is="dom-if" if="[[item.polymerIcon]]">
<iron-icon icon="[[item.polymerIcon]]"></iron-icon>
<iron-icon icon="[[item.polymerIcon]]" class$="[[getItemClassName_(item)]]"></iron-icon>
</template>
<div id="divText" class="layout horizontal flex">
<div aria-hidden="true">[[getItemName_(item)]]</div>
<div id="networkProviderName"
hidden$="[[!isProviderNameVisible_(providerName_)]]"
<div id="divText" class$="layout horizontal flex [[getItemClassName_(item)]]">
<div id="networkName" aria-hidden="true">
[[getItemName_(item)]]
</div>
<div id="subtitle"
hidden$="[[!isSubtitleVisible_(subtitle_)]]"
aria-hidden="true">
[[getProviderName_(providerName_)]]
[[getSubtitle(subtitle_)]]
</div>
<div id="networkStateText"
class="cr-secondary-text"
......@@ -116,6 +135,14 @@
</cr-icon-button>
</div>
</template>
<template is="dom-if" if="[[isESimPendingProfile_(item)]]" restamp>
<!-- TODO(crbug.com/1093185): Download profile when clicked. -->
<cr-button id="downloadButton"
aria-label$="[[getItemName_(item)]], $i18n{networkListItemDownload}">
<iron-icon icon="network:download"></iron-icon>
$i18n{networkListItemDownload}
</cr-button>
</template>
</div>
</div>
</template>
......
......@@ -56,7 +56,7 @@ Polymer({
rowLabel: {
type: String,
notify: true,
computed: 'getRowLabel_(item, networkState, providerName_)',
computed: 'getRowLabel_(item, networkState, subtitle_)',
},
buttonLabel: {
......@@ -97,10 +97,10 @@ Polymer({
deviceState: Object,
/**
* Cellular/Tether network provider name
* Subtitle for item.
* @private {string}
*/
providerName_: {
subtitle_: {
type: String,
value: '',
},
......@@ -135,19 +135,31 @@ Polymer({
/** @private */
itemChanged_() {
if (this.item && !this.item.hasOwnProperty('customItemName')) {
if (this.item && !this.item.hasOwnProperty('customItemType')) {
this.networkState =
/** @type {!OncMojo.NetworkStateProperties} */ (this.item);
this.setProviderName_();
} else if (this.networkState) {
} else {
this.networkState = undefined;
}
this.setSubtitle_();
},
/** @private */
setProviderName_() {
setSubtitle_() {
const mojom = chromeos.networkConfig.mojom;
if (this.item.hasOwnProperty('customItemSubtitle') &&
this.item.customItemSubtitle) {
// Item is a custom OOBE network or pending eSIM profile.
const item = /** @type {!NetworkList.CustomItemState} */ (this.item);
this.subtitle_ = item.customItemSubtitle;
return;
}
if (!this.networkState) {
return;
}
if (this.networkState.type !== mojom.NetworkType.kCellular ||
!this.isUpdatedCellularUiEnabled_) {
return;
......@@ -162,7 +174,7 @@ Polymer({
const managedProperty = response.result;
if (managedProperty.typeProperties.cellular.homeProvider) {
this.providerName_ =
this.subtitle_ =
managedProperty.typeProperties.cellular.homeProvider.name;
}
});
......@@ -189,10 +201,9 @@ Polymer({
getItemName_() {
if (this.item.hasOwnProperty('customItemName')) {
const item = /** @type {!NetworkList.CustomItemState} */ (this.item);
const name = item.customItemName || '';
const customName = this.i18n(item.customItemName);
return customName ? customName : name;
return this.i18nExists(item.customItemName) ?
this.i18n(item.customItemName) :
item.customItemName;
}
return OncMojo.getNetworkStateDisplayName(
/** @type {!OncMojo.NetworkStateProperties} */ (this.item));
......@@ -242,10 +253,10 @@ Polymer({
case NetworkType.kCellular:
if (isManaged) {
if (status) {
if (this.providerName_) {
if (this.subtitle_) {
return this.i18n(
'networkListItemLabelCellularManagedWithConnectionStatusAndProviderName',
index, total, this.getItemName_(), this.providerName_, status,
index, total, this.getItemName_(), this.subtitle_, status,
this.item.typeState.cellular.signalStrength);
}
return this.i18n(
......@@ -253,10 +264,10 @@ Polymer({
index, total, this.getItemName_(), status,
this.item.typeState.cellular.signalStrength);
}
if (this.providerName_) {
if (this.subtitle_) {
return this.i18n(
'networkListItemLabelCellularManagedWithProviderName', index,
total, this.getItemName_(), this.providerName_,
total, this.getItemName_(), this.subtitle_,
this.item.typeState.cellular.signalStrength);
}
return this.i18n(
......@@ -264,10 +275,10 @@ Polymer({
this.getItemName_(), this.item.typeState.cellular.signalStrength);
}
if (status) {
if (this.providerName_) {
if (this.subtitle_) {
return this.i18n(
'networkListItemLabelCellularWithConnectionStatusAndProviderName',
index, total, this.getItemName_(), this.providerName_, status,
index, total, this.getItemName_(), this.subtitle_, status,
this.item.typeState.cellular.signalStrength);
}
return this.i18n(
......@@ -276,10 +287,10 @@ Polymer({
this.item.typeState.cellular.signalStrength);
}
if (this.providerName_) {
if (this.subtitle_) {
return this.i18n(
'networkListItemLabelCellularWithProviderName', index, total,
this.getItemName_(), this.providerName_,
this.getItemName_(), this.subtitle_,
this.item.typeState.cellular.signalStrength);
}
return this.i18n(
......@@ -306,10 +317,10 @@ Polymer({
case NetworkType.kTether:
// Tether networks will never be controlled by policy (only disabled).
if (status) {
if (this.providerName_) {
if (this.subtitle_) {
return this.i18n(
'networkListItemLabelTetherWithConnectionStatusAndProviderName',
index, total, this.getItemName_(), this.providerName_, status,
index, total, this.getItemName_(), this.subtitle_, status,
this.item.typeState.tether.signalStrength,
this.item.typeState.tether.batteryPercentage);
}
......@@ -319,10 +330,10 @@ Polymer({
this.item.typeState.tether.signalStrength,
this.item.typeState.tether.batteryPercentage);
}
if (this.providerName_) {
if (this.subtitle_) {
return this.i18n(
'networkListItemLabelTetherWithProviderName', index, total,
this.getItemName_(), this.providerName_,
this.getItemName_(), this.subtitle_,
this.item.typeState.tether.signalStrength,
this.item.typeState.tether.batteryPercentage);
}
......@@ -357,6 +368,16 @@ Polymer({
'networkListItemLabelWifi', index, total, this.getItemName_(),
secured, this.item.typeState.wifi.signalStrength);
default:
if (this.isESimPendingProfile_()) {
if (this.subtitle_) {
return this.i18n(
'networkListItemLabelESimPendingProfileWithProviderName', index,
total, this.getItemName_(), this.subtitle_);
}
return this.i18n(
'networkListItemLabelESimPendingProfile', index, total,
this.getItemName_());
}
return this.i18n(
'networkListItemLabel', index, total, this.getItemName_());
}
......@@ -409,16 +430,16 @@ Polymer({
* @return {string}
* @private
*/
getProviderName_() {
return this.providerName_ ? this.providerName_ : '';
getSubtitle() {
return this.subtitle_ ? this.subtitle_ : '';
},
/**
* @return {boolean}
* @private
*/
isProviderNameVisible_() {
return !!this.providerName_;
isSubtitleVisible_() {
return !!this.subtitle_;
},
/**
......@@ -530,4 +551,22 @@ Polymer({
// isFocused is supplied by FocusRowBehavior.
return this.isFocused ? 'polite' : 'off';
},
/**
* @return {boolean}
* @private
*/
isESimPendingProfile_() {
return this.item.hasOwnProperty('customItemType') &&
this.item.customItemType ===
NetworkList.CustomItemType.ESIM_PENDING_PROFILE;
},
/**
* @return {string}
* @private
*/
getItemClassName_() {
return this.isESimPendingProfile_() ? 'esim-pending-profile' : '';
},
});
......@@ -10,10 +10,18 @@
/* #export */ const NetworkList = {};
/** @enum {number} */
NetworkList.CustomItemType = {
OOBE: 1,
ESIM_PENDING_PROFILE: 2,
};
/**
* Custom data for implementation specific network list items.
* @typedef {{
* customItemType: NetworkList.CustomItemType,
* customItemName: string,
* customItemSubtitle: string,
* polymerIcon: (string|undefined),
* customData: (!Object|undefined),
* showBeforeNetworksList: boolean,
......
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