| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 |
| 4 /** | 5 /** |
| 5 * @unrestricted | 6 * @implements {SDK.SDKModelObserver<!SDK.EmulationModel>} |
| 6 */ | 7 */ |
| 7 MobileThrottling.NetworkConditionsSelector = class { | 8 MobileThrottling.ThrottlingManager = class extends Common.Object { |
| 8 /** | 9 constructor() { |
| 9 * @param {function(!Array<!MobileThrottling.NetworkConditionsGroup>):!Array<?
SDK.NetworkManager.Conditions>} populateCallback | 10 super(); |
| 10 * @param {function(number)} selectCallback | 11 /** @type {!MobileThrottling.CPUThrottlingRates} */ |
| 11 */ | 12 this._cpuThrottlingRate = MobileThrottling.CPUThrottlingRates.NoThrottling; |
| 12 constructor(populateCallback, selectCallback) { | 13 /** @type {!Set<!UI.ToolbarComboBox>} */ |
| 13 this._populateCallback = populateCallback; | 14 this._cpuThrottlingControls = new Set(); |
| 14 this._selectCallback = selectCallback; | 15 this._cpuThrottlingRates = MobileThrottling.cpuThrottlingPresets; |
| 15 this._customSetting = Common.moduleSetting('customNetworkConditions'); | 16 /** @type {!Common.Setting<!Array<!SDK.NetworkManager.Conditions>>} */ |
| 16 this._customSetting.addChangeListener(this._populateOptions, this); | 17 this._customNetworkConditionsSetting = Common.moduleSetting('customNetworkCo
nditions'); |
| 17 this._manager = SDK.multitargetNetworkManager; | 18 /** @type {!SDK.NetworkManager.Conditions} */ |
| 18 this._manager.addEventListener( | 19 this._currentNetworkThrottlingConditions = SDK.NetworkManager.NoThrottlingCo
nditions; |
| 19 SDK.MultitargetNetworkManager.Events.ConditionsChanged, this._conditions
Changed, this); | 20 /** @type {!SDK.NetworkManager.Conditions} */ |
| 20 this._populateOptions(); | 21 this._lastNetworkThrottlingConditions; |
| 22 |
| 23 SDK.multitargetNetworkManager.addEventListener(SDK.MultitargetNetworkManager
.Events.ConditionsChanged, () => { |
| 24 this._lastNetworkThrottlingConditions = this._currentNetworkThrottlingCond
itions; |
| 25 this._currentNetworkThrottlingConditions = SDK.multitargetNetworkManager.n
etworkConditions(); |
| 26 }); |
| 27 |
| 28 SDK.targetManager.observeModels(SDK.EmulationModel, this); |
| 21 } | 29 } |
| 22 | 30 |
| 23 /** | |
| 24 * @param {number} throughput | |
| 25 * @param {boolean=} plainText | |
| 26 * @return {string} | |
| 27 */ | |
| 28 static throughputText(throughput, plainText) { | |
| 29 if (throughput < 0) | |
| 30 return ''; | |
| 31 var throughputInKbps = throughput / (1024 / 8); | |
| 32 var delimiter = plainText ? '' : ' '; | |
| 33 if (throughputInKbps < 1024) | |
| 34 return Common.UIString('%d%skb/s', throughputInKbps, delimiter); | |
| 35 if (throughputInKbps < 1024 * 10) | |
| 36 return Common.UIString('%.1f%sMb/s', throughputInKbps / 1024, delimiter); | |
| 37 return Common.UIString('%d%sMb/s', (throughputInKbps / 1024) | 0, delimiter)
; | |
| 38 } | |
| 39 | 31 |
| 40 /** | 32 /** |
| 41 * @param {!HTMLSelectElement} selectElement | 33 * @param {!HTMLSelectElement} selectElement |
| 34 * @return {!MobileThrottling.NetworkThrottlingSelector} |
| 42 */ | 35 */ |
| 43 static decorateSelect(selectElement) { | 36 decorateSelectWithNetworkThrottling(selectElement) { |
| 44 var options = []; | 37 var options = []; |
| 45 var selector = new MobileThrottling.NetworkConditionsSelector(populate, sele
ct); | 38 var selector = |
| 39 new MobileThrottling.NetworkThrottlingSelector(populate, select, this._c
ustomNetworkConditionsSetting); |
| 46 selectElement.addEventListener('change', optionSelected, false); | 40 selectElement.addEventListener('change', optionSelected, false); |
| 41 return selector; |
| 47 | 42 |
| 48 /** | 43 /** |
| 49 * @param {!Array.<!MobileThrottling.NetworkConditionsGroup>} groups | 44 * @param {!Array.<!MobileThrottling.NetworkThrottlingConditionsGroup>} grou
ps |
| 50 * @return {!Array<?SDK.NetworkManager.Conditions>} | 45 * @return {!Array<?SDK.NetworkManager.Conditions>} |
| 51 */ | 46 */ |
| 52 function populate(groups) { | 47 function populate(groups) { |
| 53 selectElement.removeChildren(); | 48 selectElement.removeChildren(); |
| 54 options = []; | 49 options = []; |
| 55 for (var i = 0; i < groups.length; ++i) { | 50 for (var i = 0; i < groups.length; ++i) { |
| 56 var group = groups[i]; | 51 var group = groups[i]; |
| 57 var groupElement = selectElement.createChild('optgroup'); | 52 var groupElement = selectElement.createChild('optgroup'); |
| 58 groupElement.label = group.title; | 53 groupElement.label = group.title; |
| 59 for (var conditions of group.items) { | 54 for (var conditions of group.items) { |
| 60 var title = Common.UIString(conditions.title); | 55 var title = conditions.title; |
| 61 var option = new Option(title, title); | 56 var option = new Option(title, title); |
| 62 groupElement.appendChild(option); | 57 groupElement.appendChild(option); |
| 63 options.push(conditions); | 58 options.push(conditions); |
| 64 } | 59 } |
| 65 if (i === groups.length - 1) { | 60 if (i === groups.length - 1) { |
| 66 groupElement.appendChild(new Option(Common.UIString('Add\u2026'), Comm
on.UIString('Add\u2026'))); | 61 groupElement.appendChild(new Option(Common.UIString('Add\u2026'), Comm
on.UIString('Add\u2026'))); |
| 67 options.push(null); | 62 options.push(null); |
| 68 } | 63 } |
| 69 } | 64 } |
| 70 return options; | 65 return options; |
| 71 } | 66 } |
| 72 | 67 |
| 73 function optionSelected() { | 68 function optionSelected() { |
| 74 if (selectElement.selectedIndex === selectElement.options.length - 1) | 69 if (selectElement.selectedIndex === selectElement.options.length - 1) |
| 75 selector.revealAndUpdate(); | 70 selector.revealAndUpdate(); |
| 76 else | 71 else |
| 77 selector.optionSelected(options[selectElement.selectedIndex]); | 72 selector.optionSelected(options[selectElement.selectedIndex]); |
| 78 } | 73 } |
| 79 | 74 |
| 80 /** | 75 /** |
| 81 * @param {number} index | 76 * @param {number} index |
| 82 */ | 77 */ |
| 83 function select(index) { | 78 function select(index) { |
| 84 if (selectElement.selectedIndex !== index) | 79 if (selectElement.selectedIndex !== index) |
| 85 selectElement.selectedIndex = index; | 80 selectElement.selectedIndex = index; |
| 86 } | 81 } |
| 87 } | 82 } |
| 88 | 83 |
| 89 /** | 84 /** |
| 85 * @return {!UI.ToolbarCheckbox} |
| 86 */ |
| 87 createOfflineToolbarCheckbox() { |
| 88 var checkbox = new UI.ToolbarCheckbox( |
| 89 Common.UIString('Offline'), Common.UIString('Force disconnected from net
work'), forceOffline.bind(this)); |
| 90 SDK.multitargetNetworkManager.addEventListener( |
| 91 SDK.MultitargetNetworkManager.Events.ConditionsChanged, networkCondition
sChanged); |
| 92 checkbox.setChecked(SDK.multitargetNetworkManager.networkConditions() === SD
K.NetworkManager.OfflineConditions); |
| 93 |
| 94 /** |
| 95 * @this {!MobileThrottling.ThrottlingManager} |
| 96 */ |
| 97 function forceOffline() { |
| 98 if (checkbox.checked()) |
| 99 SDK.multitargetNetworkManager.setNetworkConditions(SDK.NetworkManager.Of
flineConditions); |
| 100 else |
| 101 SDK.multitargetNetworkManager.setNetworkConditions(this._lastNetworkThro
ttlingConditions); |
| 102 } |
| 103 |
| 104 function networkConditionsChanged() { |
| 105 checkbox.setChecked(SDK.multitargetNetworkManager.networkConditions() ===
SDK.NetworkManager.OfflineConditions); |
| 106 } |
| 107 |
| 108 return checkbox; |
| 109 } |
| 110 |
| 111 |
| 112 /** |
| 90 * @return {!UI.ToolbarMenuButton} | 113 * @return {!UI.ToolbarMenuButton} |
| 91 */ | 114 */ |
| 92 static createToolbarMenuButton() { | 115 createMobileThrottlingButton() { |
| 93 var button = new UI.ToolbarMenuButton(appendItems); | 116 var button = new UI.ToolbarMenuButton(appendItems); |
| 117 button.setTitle(Common.UIString('Throttling')); |
| 94 button.setGlyph(''); | 118 button.setGlyph(''); |
| 95 button.turnIntoSelect(); | 119 button.turnIntoSelect(); |
| 96 | 120 |
| 97 /** @type {!Array<?SDK.NetworkManager.Conditions>} */ | 121 /** @type {!MobileThrottling.ConditionsList} */ |
| 98 var options = []; | 122 var options = []; |
| 99 var selectedIndex = -1; | 123 var selectedIndex = -1; |
| 100 var selector = new MobileThrottling.NetworkConditionsSelector(populate, sele
ct); | 124 var selector = new MobileThrottling.MobileThrottlingSelector(populate, selec
t); |
| 101 return button; | 125 return button; |
| 102 | 126 |
| 103 /** | 127 /** |
| 104 * @param {!UI.ContextMenu} contextMenu | 128 * @param {!UI.ContextMenu} contextMenu |
| 105 */ | 129 */ |
| 106 function appendItems(contextMenu) { | 130 function appendItems(contextMenu) { |
| 107 for (var index = 0; index < options.length; ++index) { | 131 for (var index = 0; index < options.length; ++index) { |
| 108 var conditions = options[index]; | 132 var conditions = options[index]; |
| 109 if (!conditions) { | 133 if (!conditions) { |
| 110 contextMenu.appendSeparator(); | 134 contextMenu.appendSeparator(); |
| 111 } else { | 135 continue; |
| 112 contextMenu.appendCheckboxItem( | |
| 113 Common.UIString(conditions.title), selector.optionSelected.bind(se
lector, conditions), | |
| 114 selectedIndex === index); | |
| 115 } | 136 } |
| 137 if (conditions.title === MobileThrottling.CustomConditions.title && |
| 138 conditions.description === MobileThrottling.CustomConditions.descrip
tion) |
| 139 continue; |
| 140 contextMenu.appendCheckboxItem( |
| 141 Common.UIString(conditions.title), |
| 142 selector.optionSelected.bind(selector, /** @type {!MobileThrottling.
Conditions} */ (conditions)), |
| 143 selectedIndex === index); |
| 116 } | 144 } |
| 117 contextMenu.appendItem(Common.UIString('Edit\u2026'), selector.revealAndUp
date.bind(selector)); | |
| 118 } | 145 } |
| 119 | 146 |
| 120 /** | 147 /** |
| 121 * @param {!Array.<!MobileThrottling.NetworkConditionsGroup>} groups | 148 * @param {!Array.<!MobileThrottling.MobileThrottlingConditionsGroup>} group
s |
| 122 * @return {!Array<?SDK.NetworkManager.Conditions>} | 149 * @return {!MobileThrottling.ConditionsList} |
| 123 */ | 150 */ |
| 124 function populate(groups) { | 151 function populate(groups) { |
| 125 options = []; | 152 options = []; |
| 126 for (var group of groups) { | 153 for (var group of groups) { |
| 127 for (var conditions of group.items) | 154 for (var conditions of group.items) |
| 128 options.push(conditions); | 155 options.push(conditions); |
| 129 options.push(null); | 156 options.push(null); |
| 130 } | 157 } |
| 131 return options; | 158 return options; |
| 132 } | 159 } |
| 133 | 160 |
| 134 /** | 161 /** |
| 135 * @param {number} index | 162 * @param {number} index |
| 136 */ | 163 */ |
| 137 function select(index) { | 164 function select(index) { |
| 138 selectedIndex = index; | 165 selectedIndex = index; |
| 139 button.setText(options[index].title); | 166 button.setText(options[index].title); |
| 167 button.setTitle(options[index].description); |
| 140 } | 168 } |
| 141 } | 169 } |
| 142 | 170 |
| 143 /** | 171 /** |
| 144 * @return {!UI.ToolbarCheckbox} | 172 * @return {number} |
| 145 */ | 173 */ |
| 146 static createOfflineToolbarCheckbox() { | 174 cpuThrottlingRate() { |
| 147 var checkbox = new UI.ToolbarCheckbox( | 175 return this._cpuThrottlingRate; |
| 148 Common.UIString('Offline'), Common.UIString('Force disconnected from net
work'), forceOffline); | |
| 149 SDK.multitargetNetworkManager.addEventListener( | |
| 150 SDK.MultitargetNetworkManager.Events.ConditionsChanged, networkCondition
sChanged); | |
| 151 checkbox.setChecked(SDK.multitargetNetworkManager.networkConditions() === SD
K.NetworkManager.OfflineConditions); | |
| 152 | |
| 153 function forceOffline() { | |
| 154 if (checkbox.checked()) { | |
| 155 MobileThrottling.NetworkConditionsSelector._lastNetworkConditions = | |
| 156 SDK.multitargetNetworkManager.networkConditions(); | |
| 157 SDK.multitargetNetworkManager.setNetworkConditions(SDK.NetworkManager.Of
flineConditions); | |
| 158 } else { | |
| 159 SDK.multitargetNetworkManager.setNetworkConditions( | |
| 160 MobileThrottling.NetworkConditionsSelector._lastNetworkConditions); | |
| 161 } | |
| 162 } | |
| 163 | |
| 164 function networkConditionsChanged() { | |
| 165 var conditions = SDK.multitargetNetworkManager.networkConditions(); | |
| 166 checkbox.setChecked(conditions === SDK.NetworkManager.OfflineConditions); | |
| 167 } | |
| 168 return checkbox; | |
| 169 } | |
| 170 | |
| 171 _populateOptions() { | |
| 172 var customGroup = {title: Common.UIString('Custom'), items: this._customSett
ing.get()}; | |
| 173 var presetsGroup = {title: Common.UIString('Presets'), items: MobileThrottli
ng.NetworkConditionsSelector.presets}; | |
| 174 var disabledGroup = {title: Common.UIString('Disabled'), items: [SDK.Network
Manager.NoThrottlingConditions]}; | |
| 175 this._options = this._populateCallback([disabledGroup, presetsGroup, customG
roup]); | |
| 176 if (!this._conditionsChanged()) { | |
| 177 for (var i = this._options.length - 1; i >= 0; i--) { | |
| 178 if (this._options[i]) { | |
| 179 this.optionSelected(/** @type {!SDK.NetworkManager.Conditions} */ (thi
s._options[i])); | |
| 180 break; | |
| 181 } | |
| 182 } | |
| 183 } | |
| 184 } | |
| 185 | |
| 186 revealAndUpdate() { | |
| 187 Common.Revealer.reveal(this._customSetting); | |
| 188 this._conditionsChanged(); | |
| 189 } | 176 } |
| 190 | 177 |
| 191 /** | 178 /** |
| 192 * @param {!SDK.NetworkManager.Conditions} conditions | 179 * @param {!MobileThrottling.CPUThrottlingRates} rate |
| 193 */ | 180 */ |
| 194 optionSelected(conditions) { | 181 setCPUThrottlingRate(rate) { |
| 195 this._manager.setNetworkConditions(conditions); | 182 this._cpuThrottlingRate = rate; |
| 183 for (var emulationModel of SDK.targetManager.models(SDK.EmulationModel)) |
| 184 emulationModel.setCPUThrottlingRate(this._cpuThrottlingRate); |
| 185 var icon = null; |
| 186 if (this._cpuThrottlingRate !== MobileThrottling.CPUThrottlingRates.NoThrott
ling) { |
| 187 Host.userMetrics.actionTaken(Host.UserMetrics.Action.CpuThrottlingEnabled)
; |
| 188 icon = UI.Icon.create('smallicon-warning'); |
| 189 icon.title = Common.UIString('CPU throttling is enabled'); |
| 190 } |
| 191 var index = this._cpuThrottlingRates.indexOf(this._cpuThrottlingRate); |
| 192 for (var control of this._cpuThrottlingControls) |
| 193 control.setSelectedIndex(index); |
| 194 UI.inspectorView.setPanelIcon('timeline', icon); |
| 195 this.dispatchEventToListeners(MobileThrottling.ThrottlingManager.Events.Rate
Changed, this._cpuThrottlingRate); |
| 196 } | 196 } |
| 197 | 197 |
| 198 /** | 198 /** |
| 199 * @return {boolean} | 199 * @override |
| 200 * @param {!SDK.EmulationModel} emulationModel |
| 200 */ | 201 */ |
| 201 _conditionsChanged() { | 202 modelAdded(emulationModel) { |
| 202 var value = this._manager.networkConditions(); | 203 if (this._cpuThrottlingRate !== MobileThrottling.CPUThrottlingRates.NoThrott
ling) |
| 203 for (var index = 0; index < this._options.length; ++index) { | 204 emulationModel.setCPUThrottlingRate(this._cpuThrottlingRate); |
| 204 var option = this._options[index]; | 205 } |
| 205 if (option && option.download === value.download && option.upload === valu
e.upload && | 206 |
| 206 option.latency === value.latency && option.title === value.title) { | 207 /** |
| 207 this._selectCallback(index); | 208 * @override |
| 208 return true; | 209 * @param {!SDK.EmulationModel} emulationModel |
| 209 } | 210 */ |
| 211 modelRemoved(emulationModel) { |
| 212 } |
| 213 |
| 214 /** |
| 215 * @return {!UI.ToolbarComboBox} |
| 216 */ |
| 217 createCPUThrottlingSelector() { |
| 218 var control = new UI.ToolbarComboBox( |
| 219 event => this.setCPUThrottlingRate(this._cpuThrottlingRates[event.target
.selectedIndex])); |
| 220 this._cpuThrottlingControls.add(control); |
| 221 var currentRate = this._cpuThrottlingRate; |
| 222 |
| 223 for (var i = 0; i < this._cpuThrottlingRates.length; ++i) { |
| 224 var rate = this._cpuThrottlingRates[i]; |
| 225 var title = rate === 1 ? Common.UIString('No throttling') : Common.UIStrin
g('%d\xD7 slowdown', rate); |
| 226 var option = control.createOption(title); |
| 227 control.addOption(option); |
| 228 if (currentRate === rate) |
| 229 control.setSelectedIndex(i); |
| 210 } | 230 } |
| 211 return false; | 231 return control; |
| 212 } | 232 } |
| 213 }; | 233 }; |
| 214 | 234 |
| 215 /** @typedef {!{title: string, items: !Array<!SDK.NetworkManager.Conditions>}} *
/ | 235 /** @enum {symbol} */ |
| 216 MobileThrottling.NetworkConditionsGroup; | 236 MobileThrottling.ThrottlingManager.Events = { |
| 217 | 237 RateChanged: Symbol('RateChanged') |
| 218 | 238 }; |
| 219 /** @type {!Array.<!SDK.NetworkManager.Conditions>} */ | |
| 220 MobileThrottling.NetworkConditionsSelector.presets = [ | |
| 221 SDK.NetworkManager.OfflineConditions, | |
| 222 {title: 'Slow 3G', download: 500 * 1024 / 8 * .8, upload: 500 * 1024 / 8 * .8,
latency: 400 * 5}, | |
| 223 {title: 'Fast 3G', download: 1.6 * 1024 * 1024 / 8 * .9, upload: 750 * 1024 /
8 * .9, latency: 150 * 3.75} | |
| 224 ]; | |
| 225 | 239 |
| 226 /** | 240 /** |
| 227 * @implements {UI.ActionDelegate} | 241 * @implements {UI.ActionDelegate} |
| 228 * @unrestricted | |
| 229 */ | 242 */ |
| 230 MobileThrottling.NetworkConditionsActionDelegate = class { | 243 MobileThrottling.ThrottlingManager.ActionDelegate = class { |
| 231 /** | 244 /** |
| 232 * @override | 245 * @override |
| 233 * @param {!UI.Context} context | 246 * @param {!UI.Context} context |
| 234 * @param {string} actionId | 247 * @param {string} actionId |
| 235 * @return {boolean} | 248 * @return {boolean} |
| 236 */ | 249 */ |
| 237 handleAction(context, actionId) { | 250 handleAction(context, actionId) { |
| 238 if (actionId === 'network-conditions.network-online') { | 251 if (actionId === 'network-conditions.network-online') { |
| 239 SDK.multitargetNetworkManager.setNetworkConditions(SDK.NetworkManager.NoTh
rottlingConditions); | 252 SDK.multitargetNetworkManager.setNetworkConditions(SDK.NetworkManager.NoTh
rottlingConditions); |
| 240 return true; | 253 return true; |
| 241 } | 254 } |
| 242 if (actionId === 'network-conditions.network-offline') { | 255 if (actionId === 'network-conditions.network-offline') { |
| 243 SDK.multitargetNetworkManager.setNetworkConditions(SDK.NetworkManager.Offl
ineConditions); | 256 SDK.multitargetNetworkManager.setNetworkConditions(SDK.NetworkManager.Offl
ineConditions); |
| 244 return true; | 257 return true; |
| 245 } | 258 } |
| 246 return false; | 259 return false; |
| 247 } | 260 } |
| 248 }; | 261 }; |
| 262 |
| 263 /** |
| 264 * @return {!MobileThrottling.ThrottlingManager} |
| 265 */ |
| 266 MobileThrottling.throttlingManager = function() { |
| 267 return self.singleton(MobileThrottling.ThrottlingManager); |
| 268 }; |
| OLD | NEW |