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

[CrOS Settings] Install pending eSIM profile from network settings.

Update cellular_networks_list to install pending eSIM profiles when
their install button is clicked.

Screenshot:
https://screenshot.googleplex.com/72v5bZue5QTqeoA.png

Bug: 1093185
Change-Id: I36f9f51c66bdfde369060a3ea33d3c35416bc51d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2605399Reviewed-by: default avatarKyle Horimoto <khorimoto@chromium.org>
Reviewed-by: default avatarAzeem Arshad <azeemarshad@chromium.org>
Commit-Queue: Gordon Seto <gordonseto@google.com>
Cr-Commit-Position: refs/heads/master@{#841245}
parent ba4a68ee
...@@ -1632,9 +1632,18 @@ ...@@ -1632,9 +1632,18 @@
<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."> <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> 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>
<message name="IDS_NETWORK_LIST_ITEM_LABEL_ESIM_PENDING_PROFILE_INSTALLING" desc="A11y label for an eSIM profile that is currently installing, shown in a list in settings and oobe.">
Installing 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_INSTALLING" desc="A11y label for an eSIM profile that is currently installing, shown in a list in settings and oobe. Includes the provider name.">
Installing 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."> <message name="IDS_NETWORK_LIST_ITEM_DOWNLOAD" desc="Text for the button displayed for pending eSIM profiles that installs the profile when pressed.">
Download Download
</message> </message>
<message name="IDS_NETWORK_LIST_ITEM_ADDING_PROFILE" desc="Loading text indicating that an eSIM profile is currently installing.">
Adding Profile...
</message>
<message name="IDS_WIFI_NETWORK_STATUS_SECURED" desc="a11y label used when a Wi-Fi network is secured."> <message name="IDS_WIFI_NETWORK_STATUS_SECURED" desc="a11y label used when a Wi-Fi network is secured.">
Secured Secured
</message> </message>
......
185afb896fdb3fe2f34d173871deaba7e1037e09
\ No newline at end of file
...@@ -213,6 +213,7 @@ js_library("cellular_networks_list") { ...@@ -213,6 +213,7 @@ js_library("cellular_networks_list") {
deps = [ deps = [
":cellular_eid_popup", ":cellular_eid_popup",
"//ui/webui/resources/cr_components/chromeos/cellular_setup:cellular_types", "//ui/webui/resources/cr_components/chromeos/cellular_setup:cellular_types",
"//ui/webui/resources/cr_components/chromeos/cellular_setup:esim_manager_listener_behavior",
"//ui/webui/resources/cr_components/chromeos/cellular_setup:esim_manager_utils", "//ui/webui/resources/cr_components/chromeos/cellular_setup:esim_manager_utils",
"//ui/webui/resources/cr_components/chromeos/network:mojo_interface_provider", "//ui/webui/resources/cr_components/chromeos/network:mojo_interface_provider",
"//ui/webui/resources/cr_components/chromeos/network:network_list_types", "//ui/webui/resources/cr_components/chromeos/network:network_list_types",
...@@ -536,6 +537,7 @@ js_library("cellular_networks_list.m") { ...@@ -536,6 +537,7 @@ js_library("cellular_networks_list.m") {
"//chrome/browser/resources/settings/chromeos/localized_link:localized_link.m", "//chrome/browser/resources/settings/chromeos/localized_link:localized_link.m",
"//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
"//ui/webui/resources/cr_components/chromeos/cellular_setup:cellular_types.m", "//ui/webui/resources/cr_components/chromeos/cellular_setup:cellular_types.m",
"//ui/webui/resources/cr_components/chromeos/cellular_setup:esim_manager_listener_behavior.m",
"//ui/webui/resources/cr_components/chromeos/cellular_setup:esim_manager_utils.m", "//ui/webui/resources/cr_components/chromeos/cellular_setup:esim_manager_utils.m",
"//ui/webui/resources/cr_components/chromeos/network:network_list_types.m", "//ui/webui/resources/cr_components/chromeos/network:network_list_types.m",
"//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button.m", "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button.m",
......
<link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/html/polymer.html">
<link rel="import" href="chrome://resources/cr_components/chromeos/cellular_setup/mojo_interface_provider.html"> <link rel="import" href="chrome://resources/cr_components/chromeos/cellular_setup/mojo_interface_provider.html">
<link rel="import" href="chrome://resources/cr_components/chromeos/cellular_setup/esim_manager_listener_behavior.html">
<link rel="import" href="chrome://resources/cr_components/chromeos/cellular_setup/esim_manager_utils.html"> <link rel="import" href="chrome://resources/cr_components/chromeos/cellular_setup/esim_manager_utils.html">
<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_list_types.html"> <link rel="import" href="chrome://resources/cr_components/chromeos/network/network_list_types.html">
<link rel="import" href="chrome://resources/cr_components/chromeos/network/onc_mojo.html"> <link rel="import" href="chrome://resources/cr_components/chromeos/network/onc_mojo.html">
...@@ -84,19 +85,19 @@ ...@@ -84,19 +85,19 @@
</div> </div>
</div> </div>
<template is="dom-if" <template is="dom-if"
if="[[shouldShowNetworkSublist_(eSimNetworks_, eSimPendingProfiles_)]]" restamp> if="[[shouldShowNetworkSublist_(eSimNetworks_, eSimPendingProfileItems_)]]" restamp>
<div class="cellular-network-content"> <div class="cellular-network-content">
<network-list id="esimNetworkList" show-buttons <network-list id="esimNetworkList" show-buttons
show-technology-badge="[[showTechnologyBadge]]" show-technology-badge="[[showTechnologyBadge]]"
networks="[[eSimNetworks_]]" networks="[[eSimNetworks_]]"
custom-items="[[eSimPendingProfiles_]]" custom-items="[[eSimPendingProfileItems_]]"
device-state="[[deviceState]]"> device-state="[[deviceState]]">
</network-list> </network-list>
</div> </div>
</template> </template>
<template <template
is="dom-if" is="dom-if"
if="[[!shouldShowNetworkSublist_(eSimNetworks_, eSimPendingProfiles_)]]" restamp> if="[[!shouldShowNetworkSublist_(eSimNetworks_, eSimPendingProfileItems_)]]" restamp>
<div id="eSimNoNetworkFound" <div id="eSimNoNetworkFound"
class="cellular-network-content cellular-not-setup"> class="cellular-network-content cellular-not-setup">
<settings-localized-link <settings-localized-link
......
...@@ -11,6 +11,7 @@ Polymer({ ...@@ -11,6 +11,7 @@ Polymer({
is: 'cellular-networks-list', is: 'cellular-networks-list',
behaviors: [ behaviors: [
ESimManagerListenerBehavior,
I18nBehavior, I18nBehavior,
], ],
...@@ -50,12 +51,25 @@ Polymer({ ...@@ -50,12 +51,25 @@ Polymer({
}, },
}, },
/**
* Dictionary mapping pending eSIM profile iccids to pending eSIM profiles.
* @type {!Map<string, chromeos.cellularSetup.mojom.ESimProfileRemote>}
* @private
*/
profilesMap_: {
type: Object,
value() {
return new Map();
},
},
/** /**
* The list of pending eSIM profiles to display after the list of eSIM * The list of pending eSIM profiles to display after the list of eSIM
* networks. * networks.
* @type {!Array<NetworkList.CustomItemState>} * @type {!Array<NetworkList.CustomItemState>}
* @private
*/ */
eSimPendingProfiles_: { eSimPendingProfileItems_: {
type: Array, type: Array,
value() { value() {
return []; return [];
...@@ -95,6 +109,7 @@ Polymer({ ...@@ -95,6 +109,7 @@ Polymer({
listeners: { listeners: {
'close-eid-popup': 'toggleEidPopup_', 'close-eid-popup': 'toggleEidPopup_',
'install-profile': 'installProfile_',
}, },
/** @private {?chromeos.networkConfig.mojom.CrosNetworkConfigRemote} */ /** @private {?chromeos.networkConfig.mojom.CrosNetworkConfigRemote} */
...@@ -107,40 +122,103 @@ Polymer({ ...@@ -107,40 +122,103 @@ Polymer({
this.fetchESimPendingProfileList_(); this.fetchESimPendingProfileList_();
}, },
/**
* @param {!chromeos.cellularSetup.mojom.EuiccRemote} euicc
* ESimManagerListenerBehavior override
*/
onProfileListChanged(euicc) {
this.fetchESimPendingProfileListForEuicc_(euicc);
},
/**
* @param {!chromeos.cellularSetup.mojom.ESimProfileRemote} profile
* ESimManagerListenerBehavior override
*/
onProfileChanged(profile) {
profile.getProperties().then(response => {
const eSimPendingProfileItem =
this.eSimPendingProfileItems_.find(item => {
return item.customData.iccid === response.properties.iccid;
});
if (!eSimPendingProfileItem) {
return;
}
eSimPendingProfileItem.customItemType = response.properties.state ===
chromeos.cellularSetup.mojom.ProfileState.kInstalling ?
NetworkList.CustomItemType.ESIM_INSTALLING_PROFILE :
NetworkList.CustomItemType.ESIM_PENDING_PROFILE;
});
},
/** @private */ /** @private */
fetchESimPendingProfileList_() { fetchESimPendingProfileList_() {
cellular_setup.getESimManagerRemote() cellular_setup.getESimManagerRemote()
.getAvailableEuiccs() .getAvailableEuiccs()
.then(response => { .then(response => {
if (response.euiccs.length > 0) { if (response.euiccs.length > 0) {
return cellular_setup.getPendingESimProfiles(response.euiccs[0]); return this.fetchESimPendingProfileListForEuicc_(
response.euiccs[0]);
} }
throw new Error('No EUICCs available.'); throw new Error('No EUICCs available.');
}) })
.then(profiles => { .catch(error => {
const pendingProfilePromises = profiles.map(profile => { console.error(error);
});
},
/**
* @param {!chromeos.cellularSetup.mojom.EuiccRemote} euicc
* @private
*/
fetchESimPendingProfileListForEuicc_(euicc) {
cellular_setup.getPendingESimProfiles(euicc).then(
this.processESimPendingProfiles_.bind(this));
},
/**
* @param {Array<!chromeos.cellularSetup.mojom.ESimProfileRemote>} profiles
* @private
*/
processESimPendingProfiles_(profiles) {
this.profilesMap_ = new Map();
const eSimPendingProfilePromises =
profiles.map(this.createESimPendingProfilePromise_.bind(this));
Promise.all(eSimPendingProfilePromises).then(eSimPendingProfileItems => {
this.eSimPendingProfileItems_ = eSimPendingProfileItems;
});
},
/**
* @param {!chromeos.cellularSetup.mojom.ESimProfileRemote} profile
* @return {!Promise<NetworkList.CustomItemState>}
* @private
*/
createESimPendingProfilePromise_(profile) {
return profile.getProperties().then(response => { return profile.getProperties().then(response => {
this.profilesMap_.set(response.properties.iccid, profile);
return this.createESimPendingProfileItem_(response.properties);
});
},
/**
* @param {!chromeos.cellularSetup.mojom.ESimProfileProperties} properties
* @return {NetworkList.CustomItemState}
*/
createESimPendingProfileItem_(properties) {
return { return {
customItemType: NetworkList.CustomItemType.ESIM_PENDING_PROFILE, customItemType: properties.state ===
customItemName: chromeos.cellularSetup.mojom.ProfileState.kInstalling ?
String.fromCharCode(...response.properties.name.data), NetworkList.CustomItemType.ESIM_INSTALLING_PROFILE :
customItemSubtitle: String.fromCharCode( NetworkList.CustomItemType.ESIM_PENDING_PROFILE,
...response.properties.serviceProvider.data), customItemName: String.fromCharCode(...properties.name.data),
customItemSubtitle:
String.fromCharCode(...properties.serviceProvider.data),
polymerIcon: 'network:cellular-0', polymerIcon: 'network:cellular-0',
showBeforeNetworksList: false, showBeforeNetworksList: false,
customData: { customData: {
iccid: response.properties.iccid, iccid: properties.iccid,
}, },
}; };
});
});
Promise.all(pendingProfilePromises).then(profiles => {
this.eSimPendingProfiles_ = profiles;
});
})
.catch(error => {
console.error(error);
});
}, },
/** /**
...@@ -227,5 +305,19 @@ Polymer({ ...@@ -227,5 +305,19 @@ Polymer({
this.$$('.eid-popup').focus(); this.$$('.eid-popup').focus();
}); });
} }
} },
/**
* @param {Event} event
* @private
*/
installProfile_(event) {
const profileIccid = event.detail.iccid;
const profile = this.profilesMap_.get(profileIccid);
profile.installProfile('').then(
() => {
// TODO(crbug.com/1093185) Show error if install fails.
// Show confirmation code page if required.
});
},
}); });
...@@ -82,6 +82,10 @@ constexpr webui::LocalizedString kElementLocalizedStrings[] = { ...@@ -82,6 +82,10 @@ constexpr webui::LocalizedString kElementLocalizedStrings[] = {
IDS_NETWORK_LIST_ITEM_LABEL_ESIM_PENDING_PROFILE}, IDS_NETWORK_LIST_ITEM_LABEL_ESIM_PENDING_PROFILE},
{"networkListItemLabelESimPendingProfileWithProviderName", {"networkListItemLabelESimPendingProfileWithProviderName",
IDS_NETWORK_LIST_ITEM_LABEL_ESIM_PENDING_PROFILE_WITH_PROVIDER_NAME}, IDS_NETWORK_LIST_ITEM_LABEL_ESIM_PENDING_PROFILE_WITH_PROVIDER_NAME},
{"networkListItemLabelESimPendingProfileInstalling",
IDS_NETWORK_LIST_ITEM_LABEL_ESIM_PENDING_PROFILE_INSTALLING},
{"networkListItemLabelESimPendingProfileWithProviderNameInstalling",
IDS_NETWORK_LIST_ITEM_LABEL_ESIM_PENDING_PROFILE_WITH_PROVIDER_NAME_INSTALLING},
{"wifiNetworkStatusSecured", IDS_WIFI_NETWORK_STATUS_SECURED}, {"wifiNetworkStatusSecured", IDS_WIFI_NETWORK_STATUS_SECURED},
{"wifiNetworkStatusUnsecured", IDS_WIFI_NETWORK_STATUS_UNSECURED}, {"wifiNetworkStatusUnsecured", IDS_WIFI_NETWORK_STATUS_UNSECURED},
{"networkListItemNotAvailable", IDS_NETWORK_LIST_NOT_AVAILABLE}, {"networkListItemNotAvailable", IDS_NETWORK_LIST_NOT_AVAILABLE},
...@@ -90,6 +94,7 @@ constexpr webui::LocalizedString kElementLocalizedStrings[] = { ...@@ -90,6 +94,7 @@ constexpr webui::LocalizedString kElementLocalizedStrings[] = {
{"networkListItemNotConnected", IDS_NETWORK_LIST_NOT_CONNECTED}, {"networkListItemNotConnected", IDS_NETWORK_LIST_NOT_CONNECTED},
{"networkListItemNoNetwork", IDS_NETWORK_LIST_NO_NETWORK}, {"networkListItemNoNetwork", IDS_NETWORK_LIST_NO_NETWORK},
{"networkListItemDownload", IDS_NETWORK_LIST_ITEM_DOWNLOAD}, {"networkListItemDownload", IDS_NETWORK_LIST_ITEM_DOWNLOAD},
{"networkListItemAddingProfile", IDS_NETWORK_LIST_ITEM_ADDING_PROFILE},
{"vpnNameTemplate", IDS_NETWORK_LIST_THIRD_PARTY_VPN_NAME_TEMPLATE}, {"vpnNameTemplate", IDS_NETWORK_LIST_THIRD_PARTY_VPN_NAME_TEMPLATE},
{"networkIconLabelEthernet", IDS_NETWORK_ICON_LABEL_ETHERNET}, {"networkIconLabelEthernet", IDS_NETWORK_ICON_LABEL_ETHERNET},
{"networkIconLabelVpn", IDS_NETWORK_ICON_LABEL_VPN}, {"networkIconLabelVpn", IDS_NETWORK_ICON_LABEL_VPN},
......
...@@ -44,6 +44,10 @@ cr.define('cellular_setup', function() { ...@@ -44,6 +44,10 @@ cr.define('cellular_setup', function() {
* chromeos.cellularSetup.mojom.ProfileInstallResult},}>} * chromeos.cellularSetup.mojom.ProfileInstallResult},}>}
*/ */
installProfile(confirmationCode) { installProfile(confirmationCode) {
this.properties_.state =
chromeos.cellularSetup.mojom.ProfileState.kActive;
this.fakeEuicc_.notifyProfileChangedForTest(this);
this.fakeEuicc_.notifyProfileListChangedForTest();
return Promise.resolve({ return Promise.resolve({
result: this.profileInstallResult_ ? result: this.profileInstallResult_ ?
this.profileInstallResult_ : this.profileInstallResult_ :
...@@ -119,6 +123,7 @@ cr.define('cellular_setup', function() { ...@@ -119,6 +123,7 @@ cr.define('cellular_setup', function() {
/** @override */ /** @override */
uninstallProfile() { uninstallProfile() {
this.fakeEuicc_.notifyProfileChangedForTest(this);
this.defferedUninstallProfilePromise_ = this.deferredPromise_(); this.defferedUninstallProfilePromise_ = this.deferredPromise_();
return this.defferedUninstallProfilePromise_.promise; return this.defferedUninstallProfilePromise_.promise;
} }
...@@ -144,7 +149,8 @@ cr.define('cellular_setup', function() { ...@@ -144,7 +149,8 @@ cr.define('cellular_setup', function() {
/** @implements {chromeos.cellularSetup.mojom.Euicc} */ /** @implements {chromeos.cellularSetup.mojom.Euicc} */
class FakeEuicc { class FakeEuicc {
constructor(numProfiles) { constructor(numProfiles, fakeESimManager) {
this.fakeESimManager_ = fakeESimManager;
this.profiles_ = []; this.profiles_ = [];
for (let i = 0; i < numProfiles; i++) { for (let i = 0; i < numProfiles; i++) {
this.addProfileForTest_(); this.addProfileForTest_();
...@@ -180,6 +186,7 @@ cr.define('cellular_setup', function() { ...@@ -180,6 +186,7 @@ cr.define('cellular_setup', function() {
* chromeos.cellularSetup.mojom.ProfileInstallResult},}>} * chromeos.cellularSetup.mojom.ProfileInstallResult},}>}
*/ */
installProfileFromActivationCode(activationCode, confirmationCode) { installProfileFromActivationCode(activationCode, confirmationCode) {
this.notifyProfileListChangedForTest();
return Promise.resolve({ return Promise.resolve({
result: this.profileInstallResult_ ? result: this.profileInstallResult_ ?
this.profileInstallResult_ : this.profileInstallResult_ :
...@@ -218,6 +225,7 @@ cr.define('cellular_setup', function() { ...@@ -218,6 +225,7 @@ cr.define('cellular_setup', function() {
this.profiles_ = result; this.profiles_ = result;
if (profileRemoved) { if (profileRemoved) {
this.notifyProfileListChangedForTest();
return { return {
result: chromeos.cellularSetup.mojom.ESimOperationResult.kSuccess result: chromeos.cellularSetup.mojom.ESimOperationResult.kSuccess
}; };
...@@ -226,12 +234,24 @@ cr.define('cellular_setup', function() { ...@@ -226,12 +234,24 @@ cr.define('cellular_setup', function() {
result: chromeos.cellularSetup.mojom.ESimOperationResult.kFailure result: chromeos.cellularSetup.mojom.ESimOperationResult.kFailure
}; };
} }
/**
* @param {FakeProfile} profile
*/
notifyProfileChangedForTest(profile) {
this.fakeESimManager_.notifyProfileChangedForTest(profile);
}
notifyProfileListChangedForTest() {
this.fakeESimManager_.notifyProfileListChangedForTest(this);
}
} }
/** @implements {chromeos.cellularSetup.mojom.ESimManagerInterface} */ /** @implements {chromeos.cellularSetup.mojom.ESimManagerInterface} */
/* #export */ class FakeESimManagerRemote { /* #export */ class FakeESimManagerRemote {
constructor() { constructor() {
this.euiccs_ = []; this.euiccs_ = [];
this.observers_ = [];
} }
/** /**
...@@ -248,9 +268,35 @@ cr.define('cellular_setup', function() { ...@@ -248,9 +268,35 @@ cr.define('cellular_setup', function() {
* @param {number} numProfiles The number of profiles the EUICC has. * @param {number} numProfiles The number of profiles the EUICC has.
*/ */
addEuiccForTest(numProfiles) { addEuiccForTest(numProfiles) {
const euicc = new FakeEuicc(numProfiles); const euicc = new FakeEuicc(numProfiles, this);
this.euiccs_.push(euicc); this.euiccs_.push(euicc);
} }
/**
* @param {!chromeos.cellularSetup.mojom.ESimManagerObserverInterface}
* observer
*/
addObserver(observer) {
this.observers_.push(observer);
}
/**
* @param {FakeEuicc} euicc
*/
notifyProfileListChangedForTest(euicc) {
for (const observer of this.observers_) {
observer.onProfileListChanged(euicc);
}
}
/**
* @param {FakeProfile} profile
*/
notifyProfileChangedForTest(profile) {
for (const observer of this.observers_) {
observer.onProfileChanged(profile);
}
}
} }
// #cr_define_end // #cr_define_end
......
...@@ -94,7 +94,7 @@ suite('NetworkListItemTest', function() { ...@@ -94,7 +94,7 @@ suite('NetworkListItemTest', function() {
}); });
test( test(
'Pending eSIM profile name, provider, download button visibilty', 'Pending eSIM profile name, provider, install button visibilty',
async () => { async () => {
const itemName = 'Item Name'; const itemName = 'Item Name';
const itemSubtitle = 'Item Subtitle'; const itemSubtitle = 'Item Subtitle';
...@@ -118,7 +118,44 @@ suite('NetworkListItemTest', function() { ...@@ -118,7 +118,44 @@ suite('NetworkListItemTest', function() {
assertTrue(!!subtitle); assertTrue(!!subtitle);
assertEquals(itemSubtitle, subtitle.textContent.trim()); assertEquals(itemSubtitle, subtitle.textContent.trim());
let downloadButton = listItem.$$('#downloadButton'); let installButton = listItem.$$('#installButton');
assertTrue(!!downloadButton); assertTrue(!!installButton);
let installProfileEventIccid = null;
listItem.addEventListener('install-profile', (event) => {
installProfileEventIccid = event.detail.iccid;
});
installButton.click();
await flushAsync();
assertEquals(installProfileEventIccid, 'iccid');
});
test(
'Installing eSIM profile name, provider, spinner visibilty', async () => {
const itemName = 'Item Name';
const itemSubtitle = 'Item Subtitle';
listItem.item = {
customItemType: NetworkList.CustomItemType.ESIM_INSTALLING_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 spinner = listItem.$$('paper-spinner-lite');
assertTrue(!!spinner);
}); });
}); });
...@@ -152,4 +152,29 @@ suite('CellularNetworkList', function() { ...@@ -152,4 +152,29 @@ suite('CellularNetworkList', function() {
eidPopup = cellularNetworkList.$$('.eid-popup'); eidPopup = cellularNetworkList.$$('.eid-popup');
assertTrue(!!eidPopup); assertTrue(!!eidPopup);
}); });
test('Install pending eSIM profile', async () => {
eSimManagerRemote.addEuiccForTest(1);
await flushAsync();
let eSimNetworkList = cellularNetworkList.$$('#esimNetworkList');
assertTrue(!!eSimNetworkList);
assertEquals(1, cellularNetworkList.eSimPendingProfileItems_.length);
const listItem = eSimNetworkList.$$('network-list-item');
assertTrue(!!listItem);
const installButton = listItem.$$('#installButton');
assertTrue(!!installButton);
installButton.click();
await flushAsync();
// eSIM network list should now be hidden and link showing.
eSimNetworkList = cellularNetworkList.$$('#esimNetworkList');
assertFalse(!!eSimNetworkList);
const esimNoNetworkAnchor = cellularNetworkList.$$('#eSimNoNetworkFound')
.querySelector('settings-localized-link')
.shadowRoot.querySelector('a');
assertTrue(!!esimNoNetworkAnchor);
});
}); });
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// #import {getESimManagerRemote} from './mojo_interface_provider.m.js'; // #import {observeESimManager} from './mojo_interface_provider.m.js';
/** /**
* @fileoverview Polymer behavior for observing ESimManagerObserver * @fileoverview Polymer behavior for observing ESimManagerObserver
...@@ -16,10 +16,7 @@ ...@@ -16,10 +16,7 @@
/** @override */ /** @override */
attached() { attached() {
this.observer_ = cellular_setup.observeESimManager(this);
new chromeos.cellularSetup.mojom.ESimManagerObserverReceiver(this);
cellular_setup.getESimManagerRemote().addObserver(
this.observer_.$.bindNewPipeAndPassRemote());
}, },
// ESimManagerObserver methods. Override these in the implementation. // ESimManagerObserver methods. Override these in the implementation.
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
cr.define('cellular_setup', function() { cr.define('cellular_setup', function() {
let cellularRemote = null; let cellularRemote = null;
let eSimManagerRemote = null; let eSimManagerRemote = null;
let isTesting = false;
/** /**
* @param {?chromeos.cellularSetup.mojom.CellularSetupRemote} * @param {?chromeos.cellularSetup.mojom.CellularSetupRemote}
...@@ -21,6 +22,7 @@ cr.define('cellular_setup', function() { ...@@ -21,6 +22,7 @@ cr.define('cellular_setup', function() {
*/ */
/* #export */ function setCellularSetupRemoteForTesting(testCellularRemote) { /* #export */ function setCellularSetupRemoteForTesting(testCellularRemote) {
cellularRemote = testCellularRemote; cellularRemote = testCellularRemote;
isTesting = true;
} }
/** /**
...@@ -42,6 +44,7 @@ cr.define('cellular_setup', function() { ...@@ -42,6 +44,7 @@ cr.define('cellular_setup', function() {
*/ */
/* #export */ function setESimManagerRemoteForTesting(testESimManagerRemote) { /* #export */ function setESimManagerRemoteForTesting(testESimManagerRemote) {
eSimManagerRemote = testESimManagerRemote; eSimManagerRemote = testESimManagerRemote;
isTesting = true;
} }
/** /**
...@@ -57,11 +60,31 @@ cr.define('cellular_setup', function() { ...@@ -57,11 +60,31 @@ cr.define('cellular_setup', function() {
return eSimManagerRemote; return eSimManagerRemote;
} }
/**
* @param {!chromeos.cellularSetup.mojom.ESimManagerObserverInterface}
* observer
* @returns {?chromeos.cellularSetup.mojom.ESimManagerObserverReceiver}
*/
/* #export */ function observeESimManager(observer) {
if (isTesting) {
getESimManagerRemote().addObserver(
/** @type {!chromeos.cellularSetup.mojom.ESimManagerObserverRemote} */
(observer));
return null;
}
const receiver =
new chromeos.cellularSetup.mojom.ESimManagerObserverReceiver(observer);
getESimManagerRemote().addObserver(receiver.$.bindNewPipeAndPassRemote());
return receiver;
}
// #cr_define_end // #cr_define_end
return { return {
setCellularSetupRemoteForTesting, setCellularSetupRemoteForTesting,
getCellularSetupRemote, getCellularSetupRemote,
setESimManagerRemoteForTesting, setESimManagerRemoteForTesting,
getESimManagerRemote getESimManagerRemote,
observeESimManager
}; };
}); });
...@@ -454,6 +454,7 @@ js_library("network_list_item.m") { ...@@ -454,6 +454,7 @@ js_library("network_list_item.m") {
deps = [ deps = [
":mojo_interface_provider.m", ":mojo_interface_provider.m",
":network_list_types.m", ":network_list_types.m",
"//third_party/polymer/v3_0/components-chromium/paper-spinner:paper-spinner-lite",
"//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
"//ui/webui/resources/js/cr/ui:focus_row_behavior.m", "//ui/webui/resources/js/cr/ui:focus_row_behavior.m",
] ]
......
<link rel="import" href="../../../html/polymer.html"> <link rel="import" href="../../../html/polymer.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-spinner/paper-spinner-lite.html">
<link rel="import" href="../../../cr_elements/cr_icon_button/cr_icon_button.html"> <link rel="import" href="../../../cr_elements/cr_icon_button/cr_icon_button.html">
<link rel="import" href="../../../cr_elements/icons.html"> <link rel="import" href="../../../cr_elements/icons.html">
<link rel="import" href="../../../cr_elements/policy/cr_policy_indicator.html"> <link rel="import" href="../../../cr_elements/policy/cr_policy_indicator.html">
...@@ -78,6 +79,12 @@ ...@@ -78,6 +79,12 @@
--iron-icon-fill-color: #1A73E8; --iron-icon-fill-color: #1A73E8;
margin-inline-end: 8px; margin-inline-end: 8px;
} }
paper-spinner-lite {
height: 20px;
margin-inline-end: 16px;
width: 20px;
}
</style> </style>
<div id="wrapper" focus-row-container <div id="wrapper" focus-row-container
class="layout horizontal center flex"> class="layout horizontal center flex">
...@@ -99,9 +106,11 @@ ...@@ -99,9 +106,11 @@
</network-icon> </network-icon>
</template> </template>
<template is="dom-if" if="[[item.polymerIcon]]"> <template is="dom-if" if="[[item.polymerIcon]]">
<iron-icon icon="[[item.polymerIcon]]" class$="[[getItemClassName_(item)]]"></iron-icon> <iron-icon icon="[[item.polymerIcon]]"
class$="[[getItemClassName_(item, item.customItemType]]"></iron-icon>
</template> </template>
<div id="divText" class$="layout horizontal flex [[getItemClassName_(item)]]"> <div id="divText" class$="layout horizontal flex
[[getItemClassName_(item, item.customItemType)]]">
<div id="networkName" aria-hidden="true"> <div id="networkName" aria-hidden="true">
[[getItemName_(item)]] [[getItemName_(item)]]
</div> </div>
...@@ -135,14 +144,18 @@ ...@@ -135,14 +144,18 @@
</cr-icon-button> </cr-icon-button>
</div> </div>
</template> </template>
<template is="dom-if" if="[[isESimPendingProfile_(item)]]" restamp> <template is="dom-if" if="[[isESimPendingProfile_(item, item.customItemType)]]" restamp>
<!-- TODO(crbug.com/1093185): Download profile when clicked. --> <cr-button id="installButton"
<cr-button id="downloadButton" aria-label$="[[getItemName_(item)]], $i18n{networkListItemDownload}"
aria-label$="[[getItemName_(item)]], $i18n{networkListItemDownload}"> on-click="onInstallButtonClick_">
<iron-icon icon="network:download"></iron-icon> <iron-icon icon="network:download"></iron-icon>
$i18n{networkListItemDownload} $i18n{networkListItemDownload}
</cr-button> </cr-button>
</template> </template>
<template is="dom-if" if="[[isESimInstallingProfile_(item, item.customItemType)]]" restamp>
<paper-spinner-lite active></paper-spinner-lite>
$i18n{networkListItemAddingProfile}
</template>
</div> </div>
</div> </div>
</template> </template>
......
...@@ -377,6 +377,15 @@ Polymer({ ...@@ -377,6 +377,15 @@ Polymer({
return this.i18n( return this.i18n(
'networkListItemLabelESimPendingProfile', index, total, 'networkListItemLabelESimPendingProfile', index, total,
this.getItemName_()); this.getItemName_());
} else if (this.isESimInstallingProfile_()) {
if (this.subtitle_) {
return this.i18n(
'networkListItemLabelESimPendingProfileWithProviderNameInstalling',
index, total, this.getItemName_(), this.subtitle_);
}
return this.i18n(
'networkListItemLabelESimPendingProfileInstalling', index, total,
this.getItemName_());
} }
return this.i18n( return this.i18n(
'networkListItemLabel', index, total, this.getItemName_()); 'networkListItemLabel', index, total, this.getItemName_());
...@@ -495,6 +504,8 @@ Polymer({ ...@@ -495,6 +504,8 @@ Polymer({
if (this.isSubpageButtonVisible_(this.networkState, this.showButtons) && if (this.isSubpageButtonVisible_(this.networkState, this.showButtons) &&
this.$$('#subpage-button') === this.shadowRoot.activeElement) { this.$$('#subpage-button') === this.shadowRoot.activeElement) {
this.fireShowDetails_(event); this.fireShowDetails_(event);
} else if (this.isESimPendingProfile_()) {
this.onInstallButtonClick_();
} else if (this.item.hasOwnProperty('customItemName')) { } else if (this.item.hasOwnProperty('customItemName')) {
this.fire('custom-item-selected', this.item); this.fire('custom-item-selected', this.item);
} else { } else {
...@@ -552,12 +563,17 @@ Polymer({ ...@@ -552,12 +563,17 @@ Polymer({
return this.isFocused ? 'polite' : 'off'; return this.isFocused ? 'polite' : 'off';
}, },
/** @private */
onInstallButtonClick_() {
this.fire('install-profile', {iccid: this.item.customData.iccid});
},
/** /**
* @return {boolean} * @return {boolean}
* @private * @private
*/ */
isESimPendingProfile_() { isESimPendingProfile_() {
return this.item.hasOwnProperty('customItemType') && return !!this.item && this.item.hasOwnProperty('customItemType') &&
this.item.customItemType === this.item.customItemType ===
NetworkList.CustomItemType.ESIM_PENDING_PROFILE; NetworkList.CustomItemType.ESIM_PENDING_PROFILE;
}, },
...@@ -569,4 +585,14 @@ Polymer({ ...@@ -569,4 +585,14 @@ Polymer({
getItemClassName_() { getItemClassName_() {
return this.isESimPendingProfile_() ? 'esim-pending-profile' : ''; return this.isESimPendingProfile_() ? 'esim-pending-profile' : '';
}, },
/**
* @return {boolean}
* @private
*/
isESimInstallingProfile_() {
return !!this.item && this.item.hasOwnProperty('customItemType') &&
this.item.customItemType ===
NetworkList.CustomItemType.ESIM_INSTALLING_PROFILE;
},
}); });
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
NetworkList.CustomItemType = { NetworkList.CustomItemType = {
OOBE: 1, OOBE: 1,
ESIM_PENDING_PROFILE: 2, ESIM_PENDING_PROFILE: 2,
ESIM_INSTALLING_PROFILE: 3,
}; };
/** /**
......
...@@ -19,6 +19,7 @@ cr_components_chromeos_namespace_rewrites = [ ...@@ -19,6 +19,7 @@ cr_components_chromeos_namespace_rewrites = [
"cellular_setup.setCellularSetupRemoteForTesting|setCellularSetupRemoteForTesting", "cellular_setup.setCellularSetupRemoteForTesting|setCellularSetupRemoteForTesting",
"cellular_setup.getESimManagerRemote|getESimManagerRemote", "cellular_setup.getESimManagerRemote|getESimManagerRemote",
"cellular_setup.setESimManagerRemoteForTesting|setESimManagerRemoteForTesting", "cellular_setup.setESimManagerRemoteForTesting|setESimManagerRemoteForTesting",
"cellular_setup.observeESimManager|observeESimManager",
"cellular_setup.getPendingESimProfiles|getPendingESimProfiles", "cellular_setup.getPendingESimProfiles|getPendingESimProfiles",
"cellular_setup.CellularSetupDelegate|CellularSetupDelegate", "cellular_setup.CellularSetupDelegate|CellularSetupDelegate",
"network_config.MojoInterfaceProvider|MojoInterfaceProvider", "network_config.MojoInterfaceProvider|MojoInterfaceProvider",
...@@ -33,7 +34,7 @@ cr_components_chromeos_auto_imports = [ ...@@ -33,7 +34,7 @@ cr_components_chromeos_auto_imports = [
"ui/webui/resources/cr_components/chromeos/cellular_setup/cellular_types.html|ButtonState,Button,ButtonBarState,CellularSetupPageName", "ui/webui/resources/cr_components/chromeos/cellular_setup/cellular_types.html|ButtonState,Button,ButtonBarState,CellularSetupPageName",
"ui/webui/resources/cr_components/chromeos/cellular_setup/cellular_setup_delegate.html|CellularSetupDelegate", "ui/webui/resources/cr_components/chromeos/cellular_setup/cellular_setup_delegate.html|CellularSetupDelegate",
"ui/webui/resources/cr_components/chromeos/cellular_setup/subflow_behavior.html|SubflowBehavior", "ui/webui/resources/cr_components/chromeos/cellular_setup/subflow_behavior.html|SubflowBehavior",
"ui/webui/resources/cr_components/chromeos/cellular_setup/mojo_interface_provider.html|setCellularSetupRemoteForTesting,getCellularSetupRemote,setESimManagerRemoteForTesting,getESimManagerRemote", "ui/webui/resources/cr_components/chromeos/cellular_setup/mojo_interface_provider.html|setCellularSetupRemoteForTesting,getCellularSetupRemote,setESimManagerRemoteForTesting,getESimManagerRemote,observeESimManager",
"ui/webui/resources/cr_components/chromeos/cellular_setup/esim_manager_utils.html|getPendingESimProfiles", "ui/webui/resources/cr_components/chromeos/cellular_setup/esim_manager_utils.html|getPendingESimProfiles",
"ui/webui/resources/cr_components/chromeos/cellular_setup/esim_manager_listener_behavior.html|ESimManagerListenerBehavior", "ui/webui/resources/cr_components/chromeos/cellular_setup/esim_manager_listener_behavior.html|ESimManagerListenerBehavior",
"ui/webui/resources/cr_components/chromeos/network/cr_policy_network_behavior_mojo.html|CrPolicyNetworkBehaviorMojo", "ui/webui/resources/cr_components/chromeos/network/cr_policy_network_behavior_mojo.html|CrPolicyNetworkBehaviorMojo",
......
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