Skip to content

Commit

Permalink
[CrOS Hotspot] Add enable toggle in hotspot subpage
Browse files Browse the repository at this point in the history
This CL adds a toggle button and on/off state text in the hotspot
subpage.

Screenshot:
https://screenshot.googleplex.com/AirbDf3NPLVQCZC.png
https://screenshot.googleplex.com/9kfoqgCTyJyGDg7.png

Bug: b/239477916
Change-Id: I08768e363e4fcf2d1b58ef88d63da999f225295e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4104111
Reviewed-by: Chad Duffin <chadduffin@chromium.org>
Commit-Queue: Jason Zhang <jiajunz@google.com>
Reviewed-by: Wes Okuhara <wesokuhara@google.com>
Cr-Commit-Position: refs/heads/main@{#1085176}
  • Loading branch information
Jason Zhang authored and Chromium LUCI CQ committed Dec 19, 2022
1 parent d12cb52 commit 22c44ae
Show file tree
Hide file tree
Showing 8 changed files with 336 additions and 31 deletions.
Expand Up @@ -173,6 +173,7 @@ js_library("internet_page") {
"//chrome/browser/resources/settings/chromeos:os_route",
"//chrome/browser/resources/settings/chromeos:route_observer_behavior",
"//chrome/browser/resources/settings/chromeos:router",
"//chromeos/ash/services/hotspot_config/public/mojom:mojom_webui_js",
"//third_party/polymer/v3_0/components-chromium/iron-icon:iron-icon",
"//third_party/polymer/v3_0/components-chromium/paper-tooltip:paper-tooltip",
"//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
Expand Down Expand Up @@ -214,9 +215,11 @@ js_library("internet_subpage") {

js_library("hotspot_subpage") {
deps = [
"//ash/webui/common/resources:i18n_behavior",
"//chromeos/ash/services/hotspot_config/public/mojom:mojom_webui_js",
"//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
]
externs_list = []
externs_list = [ "//ui/webui/resources/cr_elements/cr_a11y_announcer/cr_a11y_announcer_externs.js" ]
}

html_to_js("web_components") {
Expand Down
@@ -1,5 +1,32 @@
<style include="settings-shared">
.separator-line {
border-top: var(--cr-separator-line);
padding: 0;
}

#hotspotToggleText {
font-weight: 500;
}

#hotspotToggleText[on] {
color: var(--cros-text-color-prominent);
}

#hotspotToggleText:not([on]) {
color: var(--cros-text-color-secondary);
}
</style>
<div id="container">
<!-- TODO(b/239477916): add implementation -->
</div>
<div class="settings-box first">
<div id="hotspotToggleText" class="start" on$="[[isHotspotToggleOn_]]"
aria-hidden="true">
[[getOnOffString_(isHotspotToggleOn_)]]
</div>
<cr-toggle id="enableHotspotToggle"
checked="{{isHotspotToggleOn_}}"
disabled="[[isToggleDisabled_(hotspotInfo.allowStatus,
hotspotInfo.state)]]"
on-change="announceHotspotToggleChange_"
aria-label="$i18n{hotspotToggleA11yLabel}">
</cr-toggle>
</div>
<div class="separator-line"></div>
Expand Up @@ -4,22 +4,128 @@

/**
* @fileoverview
* Settings subpage for managing Hotspot.
* Settings subpage for managing and configuring Hotspot.
*/

import './internet_shared.css.js';
import '../../settings_shared.css.js';

import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
import {assert} from 'chrome://resources/ash/common/assert.js';
import {getHotspotConfig} from 'chrome://resources/ash/common/hotspot/cros_hotspot_config.js';
import {I18nBehavior, I18nBehaviorInterface} from 'chrome://resources/ash/common/i18n_behavior.js';
import {getInstance as getAnnouncerInstance} from 'chrome://resources/cr_elements/cr_a11y_announcer/cr_a11y_announcer.js';
import {HotspotAllowStatus, HotspotControlResult, HotspotInfo, HotspotState} from 'chrome://resources/mojo/chromeos/ash/services/hotspot_config/public/mojom/cros_hotspot_config.mojom-webui.js';
import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';

/**
* @constructor
* @extends {PolymerElement}
* @implements {I18nBehaviorInterface}
*/
const SettingsHotspotSubpageElementBase =
mixinBehaviors([I18nBehavior], PolymerElement);

/** @polymer */
class SettingsHotspotSubpageElement extends PolymerElement {
class SettingsHotspotSubpageElement extends SettingsHotspotSubpageElementBase {
static get is() {
return 'settings-hotspot-subpage';
}

static get template() {
return html`{__html_template__}`;
}

static get properties() {
return {
/** @type {!HotspotInfo|undefined} */
hotspotInfo: {
type: Object,
observer: 'onHotspotInfoChanged_',
},

/**
* Reflects the current state of the toggle button. This will be set when
* the |HotspotInfo| state changes or when the user presses the toggle.
* @private
*/
isHotspotToggleOn_: {
type: Boolean,
observer: 'onHotspotToggleChanged_',
},
};
}

/** @private */
onHotspotInfoChanged_() {
assert(this.hotspotInfo);
this.isHotspotToggleOn_ =
this.hotspotInfo.state === HotspotState.kEnabled ||
this.hotspotInfo.state === HotspotState.kEnabling;
}

/**
* Observer for isHotspotToggleOn_ that returns early until the previous
* value was not undefined to avoid wrongly toggling the HotspotInfo state.
* @param {boolean} newValue
* @param {boolean|undefined} oldValue
* @private
*/
onHotspotToggleChanged_(newValue, oldValue) {
if (oldValue === undefined) {
return;
}
// If the toggle value changed but the toggle is disabled, the change came
// from CrosHotspotConfig, not the user. Don't attempt to turn the hotspot
// on or off.
if (this.isToggleDisabled_()) {
return;
}

this.setHotspotEnabledState_(this.isHotspotToggleOn_);
}

/**
* @return {boolean}
* @private
*/
isToggleDisabled_() {
if (!this.hotspotInfo) {
return true;
}
if (this.hotspotInfo.allowStatus !== HotspotAllowStatus.kAllowed) {
return true;
}
return this.hotspotInfo.state === HotspotState.kEnabling ||
this.hotspotInfo.state === HotspotState.kDisabling;
}

/**
* @return {string}
* @private
*/
getOnOffString_() {
return this.isHotspotToggleOn_ ? this.i18n('hotspotSummaryStateOn') :
this.i18n('hotspotSummaryStateOff');
}

/**
* Enables or disables hotspot.
* @param {boolean} enabled
* @private
*/
setHotspotEnabledState_(enabled) {
if (enabled) {
getHotspotConfig().enableHotspot();
return;
}
getHotspotConfig().disableHotspot();
}

/** @private */
announceHotspotToggleChange_() {
getAnnouncerInstance().announce(
this.isHotspotToggleOn_ ? this.i18n('hotspotEnabledA11yLabel') :
this.i18n('hotspotDisabledA11yLabel'));
}
}

customElements.define(
Expand Down
Expand Up @@ -40,6 +40,7 @@
<div route-path="default">
<network-summary default-network="{{defaultNetwork}}"
device-states="{{deviceStates}}"
hotspot-info="{{hotspotInfo}}"
on-active-networks-updated="attemptDeepLink">
</network-summary>
<template is="dom-if" if="[[allowAddConnection_(globalPolicy_,
Expand Down Expand Up @@ -181,7 +182,8 @@
localized-string="[[i18nAdvanced('hotspotSubpageSubtitle')]]">
</localized-link>
</div>
<settings-hotspot-subpage></settings-hotspot-subpage>
<settings-hotspot-subpage hotspot-info="[[hotspotInfo]]">
</settings-hotspot-subpage>
</os-settings-subpage>
</template>

Expand Down
Expand Up @@ -41,6 +41,7 @@ import {MojoInterfaceProvider, MojoInterfaceProviderImpl} from 'chrome://resourc
import {NetworkListenerBehavior, NetworkListenerBehaviorInterface} from 'chrome://resources/ash/common/network/network_listener_behavior.js';
import {OncMojo} from 'chrome://resources/ash/common/network/onc_mojo.js';
import {WebUIListenerBehavior, WebUIListenerBehaviorInterface} from 'chrome://resources/ash/common/web_ui_listener_behavior.js';
import {HotspotInfo} from 'chrome://resources/mojo/chromeos/ash/services/hotspot_config/public/mojom/cros_hotspot_config.mojom-webui.js';
import {CrosNetworkConfigRemote, GlobalPolicy, NetworkStateProperties, StartConnectResult, VpnProvider} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/cros_network_config.mojom-webui.js';
import {DeviceStateType, NetworkType} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/network_types.mojom-webui.js';
import {afterNextRender, html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
Expand Down Expand Up @@ -138,6 +139,15 @@ class SettingsInternetPageElement extends SettingsInternetPageElementBase {
notify: true,
},

/**
* Hotspot information. Set by network-summary.
* @type {!HotspotInfo|undefined}
*/
hotspotInfo: {
type: Object,
notify: true,
},

/**
* Set by internet-subpage. Controls spinner visibility in subpage header.
* @private
Expand Down
Expand Up @@ -14,8 +14,8 @@
</network-summary-item>
</template>
<template is="dom-if" if="[[shouldShowHotspotSummary_(
isHotspotFeatureEnabled_, hotspotInfo_, hotspotInfo_.allowStatus)]]">
<hotspot-summary-item hotspot-info="[[hotspotInfo_]]">
isHotspotFeatureEnabled_, hotspotInfo, hotspotInfo.allowStatus)]]">
<hotspot-summary-item hotspot-info="[[hotspotInfo]]">
</hotspot-summary-item>
</template>
</div>
Expand Up @@ -69,6 +69,16 @@ class NetworkSummaryElement extends NetworkSummaryElementBase {
notify: true,
},

/**
* Hotspot information including state, active connected client count,
* allow status and hotspot configuration. Set here to update
* internet-page which updates hotspot-subpage.
*/
hotspotInfo: {
type: Object,
notify: true,
},

/**
* Array of active network states, one per device type. Initialized to
* include a default WiFi state (see deviceStates comment).
Expand All @@ -94,8 +104,6 @@ class NetworkSummaryElement extends NetworkSummaryElementBase {

globalPolicy_: Object,

hotspotInfo_: Object,

/**
* Return true if hotspot feature flag is enabled.
*/
Expand All @@ -110,13 +118,13 @@ class NetworkSummaryElement extends NetworkSummaryElementBase {
}

defaultNetwork: OncMojo.NetworkStateProperties|null;
hotspotInfo: HotspotInfo|undefined;
deviceStates: Record<NetworkType, OncMojo.DeviceStateProperties>;
private activeNetworkIds_: Set<string>|null;
private activeNetworkStates_: OncMojo.NetworkStateProperties[];
private crosHotspotConfig_: CrosHotspotConfigInterface;
private crosHotspotConfigObserverReceiver_: CrosHotspotConfigObserverReceiver;
private globalPolicy_: GlobalPolicy|undefined;
private hotspotInfo_: HotspotInfo;
private isHotspotFeatureEnabled_: boolean;
private networkConfig_: CrosNetworkConfigRemote;
private networkStateLists_:
Expand Down Expand Up @@ -164,7 +172,7 @@ class NetworkSummaryElement extends NetworkSummaryElementBase {

async onHotspotInfoChanged(): Promise<void> {
const response = await this.crosHotspotConfig_.getHotspotInfo();
this.hotspotInfo_ = response.hotspotInfo;
this.hotspotInfo = response.hotspotInfo;
}

/**
Expand Down Expand Up @@ -372,13 +380,13 @@ class NetworkSummaryElement extends NetworkSummaryElementBase {
* Return whether hotspot row should be shown in network summary.
*/
private shouldShowHotspotSummary_(): boolean {
if (!this.isHotspotFeatureEnabled_ || !this.hotspotInfo_) {
if (!this.isHotspotFeatureEnabled_ || !this.hotspotInfo) {
return false;
}
// Hide the hotspot summary row if the device doesn't support hotspot.
return this.hotspotInfo_.allowStatus !==
return this.hotspotInfo.allowStatus !==
HotspotAllowStatus.kDisallowedNoCellularUpstream &&
this.hotspotInfo_.allowStatus !==
this.hotspotInfo.allowStatus !==
HotspotAllowStatus.kDisallowedNoWiFiDownstream;
}
}
Expand Down

0 comments on commit 22c44ae

Please sign in to comment.