Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 * @unrestricted |
| 7 * @implements {SDK.SDKModelObserver<!SDK.EmulationModel>} | |
| 6 */ | 8 */ |
| 7 MobileThrottling.NetworkConditionsSelector = class { | 9 MobileThrottling.ThrottlingSelector = class extends Common.Object { |
| 8 /** | 10 /** |
| 9 * @param {function(!Array<!MobileThrottling.NetworkConditionsGroup>):!Array<? SDK.NetworkManager.Conditions>} populateCallback | 11 * @param {function(!Array<!MobileThrottling.ThrottlingConditionsGroup>):!Arra y<?SDK.MobileThrottling.Conditions>} populateCallback |
| 10 * @param {function(number)} selectCallback | 12 * @param {function(number)} selectCallback |
| 11 */ | 13 */ |
| 12 constructor(populateCallback, selectCallback) { | 14 constructor(populateCallback, selectCallback) { |
| 15 super(); | |
| 16 this._cpuThrottlingRate = 1; | |
| 17 SDK.targetManager.observeModels(SDK.EmulationModel, this); | |
| 13 this._populateCallback = populateCallback; | 18 this._populateCallback = populateCallback; |
| 14 this._selectCallback = selectCallback; | 19 this._selectCallback = selectCallback; |
| 15 this._customSetting = Common.moduleSetting('customNetworkConditions'); | 20 this._customSetting = Common.moduleSetting('customThrottlingConditions'); |
| 16 this._customSetting.addChangeListener(this._populateOptions, this); | 21 this._customSetting.addChangeListener(this._populateOptions, this); |
| 17 this._manager = SDK.multitargetNetworkManager; | 22 this._manager = SDK.multitargetNetworkManager; |
| 18 this._manager.addEventListener( | 23 this._manager.addEventListener( |
| 19 SDK.MultitargetNetworkManager.Events.ConditionsChanged, this._conditions Changed, this); | 24 SDK.MultitargetNetworkManager.Events.ConditionsChanged, this._conditions Changed, this); |
| 20 this._populateOptions(); | 25 this._populateOptions(); |
| 21 } | 26 } |
| 22 | 27 |
| 23 /** | 28 /** |
| 24 * @param {number} throughput | 29 * @param {number} throughput |
| 25 * @param {boolean=} plainText | 30 * @param {boolean=} plainText |
| 26 * @return {string} | 31 * @return {string} |
| 27 */ | 32 */ |
| 28 static throughputText(throughput, plainText) { | 33 static throughputText(throughput, plainText) { |
| 29 if (throughput < 0) | 34 if (throughput < 0) |
| 30 return ''; | 35 return ''; |
| 31 var throughputInKbps = throughput / (1024 / 8); | 36 var throughputInKbps = throughput / (1024 / 8); |
| 32 var delimiter = plainText ? '' : ' '; | 37 var delimiter = plainText ? '' : ' '; |
| 33 if (throughputInKbps < 1024) | 38 if (throughputInKbps < 1024) |
| 34 return Common.UIString('%d%skb/s', throughputInKbps, delimiter); | 39 return Common.UIString('%d%skb/s', throughputInKbps, delimiter); |
| 35 if (throughputInKbps < 1024 * 10) | 40 if (throughputInKbps < 1024 * 10) |
| 36 return Common.UIString('%.1f%sMb/s', throughputInKbps / 1024, delimiter); | 41 return Common.UIString('%.1f%sMb/s', throughputInKbps / 1024, delimiter); |
| 37 return Common.UIString('%d%sMb/s', (throughputInKbps / 1024) | 0, delimiter) ; | 42 return Common.UIString('%d%sMb/s', (throughputInKbps / 1024) | 0, delimiter) ; |
| 38 } | 43 } |
| 39 | 44 |
| 40 /** | 45 /** |
| 41 * @param {!HTMLSelectElement} selectElement | 46 * @param {!HTMLSelectElement} selectElement |
| 47 * @return {!MobileThrottling.ThrottlingSelector} | |
| 42 */ | 48 */ |
| 43 static decorateSelect(selectElement) { | 49 static decorateSelect(selectElement) { |
| 44 var options = []; | 50 var options = []; |
| 45 var selector = new MobileThrottling.NetworkConditionsSelector(populate, sele ct); | 51 var selector = new MobileThrottling.ThrottlingSelector(populate, select); |
| 46 selectElement.addEventListener('change', optionSelected, false); | 52 selectElement.addEventListener('change', optionSelected, false); |
| 53 return selector; | |
| 47 | 54 |
| 48 /** | 55 /** |
| 49 * @param {!Array.<!MobileThrottling.NetworkConditionsGroup>} groups | 56 * @param {!Array.<!MobileThrottling.ThrottlingConditionsGroup>} groups |
| 50 * @return {!Array<?SDK.NetworkManager.Conditions>} | 57 * @return {!Array<?SDK.MobileThrottling.Conditions>} |
| 51 */ | 58 */ |
| 52 function populate(groups) { | 59 function populate(groups) { |
| 53 selectElement.removeChildren(); | 60 selectElement.removeChildren(); |
| 54 options = []; | 61 options = []; |
| 55 for (var i = 0; i < groups.length; ++i) { | 62 for (var i = 0; i < groups.length; ++i) { |
| 56 var group = groups[i]; | 63 var group = groups[i]; |
| 57 var groupElement = selectElement.createChild('optgroup'); | 64 var groupElement = selectElement.createChild('optgroup'); |
| 58 groupElement.label = group.title; | 65 groupElement.label = group.title; |
| 59 for (var conditions of group.items) { | 66 for (var conditions of group.items) { |
| 60 var title = Common.UIString(conditions.title); | 67 var title = Common.UIString(conditions.title); |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 87 } | 94 } |
| 88 | 95 |
| 89 /** | 96 /** |
| 90 * @return {!UI.ToolbarMenuButton} | 97 * @return {!UI.ToolbarMenuButton} |
| 91 */ | 98 */ |
| 92 static createToolbarMenuButton() { | 99 static createToolbarMenuButton() { |
| 93 var button = new UI.ToolbarMenuButton(appendItems); | 100 var button = new UI.ToolbarMenuButton(appendItems); |
| 94 button.setGlyph(''); | 101 button.setGlyph(''); |
| 95 button.turnIntoSelect(); | 102 button.turnIntoSelect(); |
| 96 | 103 |
| 97 /** @type {!Array<?SDK.NetworkManager.Conditions>} */ | 104 /** @type {!Array<?SDK.MobileThrottling.Conditions>} */ |
| 98 var options = []; | 105 var options = []; |
| 99 var selectedIndex = -1; | 106 var selectedIndex = -1; |
| 100 var selector = new MobileThrottling.NetworkConditionsSelector(populate, sele ct); | 107 var selector = new MobileThrottling.ThrottlingSelector(populate, select); |
| 101 return button; | 108 return button; |
| 102 | 109 |
| 103 /** | 110 /** |
| 104 * @param {!UI.ContextMenu} contextMenu | 111 * @param {!UI.ContextMenu} contextMenu |
| 105 */ | 112 */ |
| 106 function appendItems(contextMenu) { | 113 function appendItems(contextMenu) { |
| 107 for (var index = 0; index < options.length; ++index) { | 114 for (var index = 0; index < options.length; ++index) { |
| 108 var conditions = options[index]; | 115 var conditions = options[index]; |
| 109 if (!conditions) { | 116 if (!conditions) { |
| 110 contextMenu.appendSeparator(); | 117 contextMenu.appendSeparator(); |
| 111 } else { | 118 } else { |
| 112 contextMenu.appendCheckboxItem( | 119 contextMenu.appendCheckboxItem( |
| 113 Common.UIString(conditions.title), selector.optionSelected.bind(se lector, conditions), | 120 Common.UIString(conditions.title), selector.optionSelected.bind(se lector, conditions), |
| 114 selectedIndex === index); | 121 selectedIndex === index); |
| 115 } | 122 } |
| 116 } | 123 } |
| 117 contextMenu.appendItem(Common.UIString('Edit\u2026'), selector.revealAndUp date.bind(selector)); | 124 contextMenu.appendItem(Common.UIString('Edit\u2026'), selector.revealAndUp date.bind(selector)); |
| 118 } | 125 } |
| 119 | 126 |
| 120 /** | 127 /** |
| 121 * @param {!Array.<!MobileThrottling.NetworkConditionsGroup>} groups | 128 * @param {!Array.<!MobileThrottling.ThrottlingConditionsGroup>} groups |
| 122 * @return {!Array<?SDK.NetworkManager.Conditions>} | 129 * @return {!Array<?SDK.MobileThrottling.Conditions>} |
| 123 */ | 130 */ |
| 124 function populate(groups) { | 131 function populate(groups) { |
| 125 options = []; | 132 options = []; |
| 126 for (var group of groups) { | 133 for (var group of groups) { |
| 127 for (var conditions of group.items) | 134 for (var conditions of group.items) |
| 128 options.push(conditions); | 135 options.push(conditions); |
| 129 options.push(null); | 136 options.push(null); |
| 130 } | 137 } |
| 131 return options; | 138 return options; |
| 132 } | 139 } |
| 133 | 140 |
| 134 /** | 141 /** |
| 135 * @param {number} index | 142 * @param {number} index |
| 136 */ | 143 */ |
| 137 function select(index) { | 144 function select(index) { |
| 138 selectedIndex = index; | 145 selectedIndex = index; |
| 139 button.setText(options[index].title); | 146 button.setText(options[index].title); |
| 140 } | 147 } |
| 141 } | 148 } |
| 142 | 149 |
| 143 /** | 150 /** |
| 144 * @return {!UI.ToolbarCheckbox} | 151 * @return {!UI.ToolbarCheckbox} |
| 145 */ | 152 */ |
| 146 static createOfflineToolbarCheckbox() { | 153 static createOfflineToolbarCheckbox() { |
| 147 var checkbox = new UI.ToolbarCheckbox( | 154 var checkbox = new UI.ToolbarCheckbox( |
| 148 Common.UIString('Offline'), Common.UIString('Force disconnected from net work'), forceOffline); | 155 Common.UIString('Offline'), Common.UIString('Force disconnected from net work'), forceOffline); |
| 149 SDK.multitargetNetworkManager.addEventListener( | 156 SDK.multitargetNetworkManager.addEventListener( |
| 150 SDK.MultitargetNetworkManager.Events.ConditionsChanged, networkCondition sChanged); | 157 SDK.MultitargetNetworkManager.Events.ConditionsChanged, networkCondition sChanged); |
| 151 checkbox.setChecked(SDK.multitargetNetworkManager.networkConditions() === SD K.NetworkManager.OfflineConditions); | 158 checkbox.setChecked(SDK.multitargetNetworkManager.networkConditions() === SD K.MobileThrottling.OfflineConditions); |
| 152 | 159 |
| 153 function forceOffline() { | 160 function forceOffline() { |
| 154 if (checkbox.checked()) { | 161 if (checkbox.checked()) { |
| 155 MobileThrottling.NetworkConditionsSelector._lastNetworkConditions = | 162 MobileThrottling.ThrottlingSelector._lastThrottlingConditions = |
| 156 SDK.multitargetNetworkManager.networkConditions(); | 163 SDK.multitargetNetworkManager.networkConditions(); |
| 157 SDK.multitargetNetworkManager.setNetworkConditions(SDK.NetworkManager.Of flineConditions); | 164 SDK.multitargetNetworkManager.setNetworkConditions(SDK.MobileThrottling. OfflineConditions); |
| 158 } else { | 165 } else { |
| 159 SDK.multitargetNetworkManager.setNetworkConditions( | 166 SDK.multitargetNetworkManager.setNetworkConditions( |
| 160 MobileThrottling.NetworkConditionsSelector._lastNetworkConditions); | 167 MobileThrottling.ThrottlingSelector._lastThrottlingConditions); |
| 161 } | 168 } |
| 162 } | 169 } |
| 163 | 170 |
| 164 function networkConditionsChanged() { | 171 function networkConditionsChanged() { |
| 165 var conditions = SDK.multitargetNetworkManager.networkConditions(); | 172 var conditions = SDK.multitargetNetworkManager.networkConditions(); |
| 166 checkbox.setChecked(conditions === SDK.NetworkManager.OfflineConditions); | 173 checkbox.setChecked(conditions === SDK.MobileThrottling.OfflineConditions) ; |
| 167 } | 174 } |
| 168 return checkbox; | 175 return checkbox; |
| 169 } | 176 } |
| 170 | 177 |
| 178 | |
| 179 /** | |
| 180 * @override | |
| 181 * @param {!SDK.EmulationModel} emulationModel | |
| 182 */ | |
| 183 modelAdded(emulationModel) { | |
| 184 if (this._cpuThrottlingRate !== 1) | |
| 185 emulationModel.setCPUThrottlingRate(this._cpuThrottlingRate); | |
| 186 } | |
| 187 | |
| 188 /** | |
| 189 * @override | |
| 190 * @param {!SDK.EmulationModel} emulationModel | |
| 191 */ | |
| 192 modelRemoved(emulationModel) { | |
| 193 } | |
| 194 | |
| 195 | |
| 171 _populateOptions() { | 196 _populateOptions() { |
| 172 var customGroup = {title: Common.UIString('Custom'), items: this._customSett ing.get()}; | 197 var customGroup = {title: Common.UIString('Custom'), items: this._customSett ing.get()}; |
| 173 var presetsGroup = {title: Common.UIString('Presets'), items: MobileThrottli ng.NetworkConditionsSelector.presets}; | 198 var presetsGroup = {title: Common.UIString('Presets'), items: MobileThrottli ng.ThrottlingSelector.presets}; |
| 174 var disabledGroup = {title: Common.UIString('Disabled'), items: [SDK.Network Manager.NoThrottlingConditions]}; | 199 var disabledGroup = {title: Common.UIString('Disabled'), items: [SDK.MobileT hrottling.NoThrottlingConditions]}; |
| 175 this._options = this._populateCallback([disabledGroup, presetsGroup, customG roup]); | 200 this._options = this._populateCallback([disabledGroup, presetsGroup, customG roup]); |
| 176 if (!this._conditionsChanged()) { | 201 if (!this._conditionsChanged()) { |
| 177 for (var i = this._options.length - 1; i >= 0; i--) { | 202 for (var i = this._options.length - 1; i >= 0; i--) { |
| 178 if (this._options[i]) { | 203 if (this._options[i]) { |
| 179 this.optionSelected(/** @type {!SDK.NetworkManager.Conditions} */ (thi s._options[i])); | 204 this.optionSelected(/** @type {!SDK.MobileThrottling.Conditions} */ (t his._options[i])); |
| 180 break; | 205 break; |
| 181 } | 206 } |
| 182 } | 207 } |
| 183 } | 208 } |
| 184 } | 209 } |
| 185 | 210 |
| 186 revealAndUpdate() { | 211 revealAndUpdate() { |
| 187 Common.Revealer.reveal(this._customSetting); | 212 Common.Revealer.reveal(this._customSetting); |
| 188 this._conditionsChanged(); | 213 this._conditionsChanged(); |
| 189 } | 214 } |
| 190 | 215 |
| 191 /** | 216 /** |
| 192 * @param {!SDK.NetworkManager.Conditions} conditions | 217 * @param {!SDK.MobileThrottling.Conditions} conditions |
| 193 */ | 218 */ |
| 194 optionSelected(conditions) { | 219 optionSelected(conditions) { |
| 195 this._manager.setNetworkConditions(conditions); | 220 this._manager.setNetworkConditions(conditions); |
| 221 this._setCPUThrottling(conditions); | |
| 196 } | 222 } |
| 197 | 223 |
| 198 /** | 224 /** |
| 225 * @return {number} | |
| 226 */ | |
| 227 cpuThrottlingRate() { | |
| 228 return this._cpuThrottlingRate; | |
| 229 } | |
| 230 | |
| 231 /** | |
| 232 * @param {!SDK.MobileThrottling.Conditions} conditions | |
| 233 */ | |
| 234 _setCPUThrottling(conditions) { | |
| 235 this._cpuThrottlingRate = conditions.cpuThrottlingRate; | |
| 236 for (var emulationModel of SDK.targetManager.models(SDK.EmulationModel)) | |
| 237 emulationModel.setCPUThrottlingRate(this._cpuThrottlingRate); | |
| 238 var icon = null; | |
| 239 if (this._cpuThrottlingRate !== 1) { | |
| 240 Host.userMetrics.actionTaken(Host.UserMetrics.Action.CpuThrottlingEnabled) ; | |
| 241 icon = UI.Icon.create('smallicon-warning'); | |
| 242 icon.title = Common.UIString('CPU throttling is enabled'); | |
| 243 } | |
| 244 UI.inspectorView.setPanelIcon('timeline', icon); | |
|
dgozman
2017/06/13 01:47:08
Where did this come from? Why only timeline, if I
chenwilliam
2017/06/13 21:54:51
This is basically:
https://cs.chromium.org/chromiu
dgozman
2017/06/13 23:18:39
Let's work on good UI. This feature is all about g
| |
| 245 this.dispatchEventToListeners(MobileThrottling.Events.CPURateChanged); | |
| 246 } | |
| 247 | |
| 248 /** | |
| 199 * @return {boolean} | 249 * @return {boolean} |
| 200 */ | 250 */ |
| 201 _conditionsChanged() { | 251 _conditionsChanged() { |
| 202 var value = this._manager.networkConditions(); | 252 var value = this._manager.networkConditions(); |
| 203 for (var index = 0; index < this._options.length; ++index) { | 253 for (var index = 0; index < this._options.length; ++index) { |
| 204 var option = this._options[index]; | 254 var option = this._options[index]; |
| 205 if (option && option.download === value.download && option.upload === valu e.upload && | 255 if (option && option.download === value.download && option.upload === valu e.upload && |
| 206 option.latency === value.latency && option.title === value.title) { | 256 option.latency === value.latency && option.title === value.title && |
| 257 option.cpuThrottlingRate === value.cpuThrottlingRate) { | |
| 207 this._selectCallback(index); | 258 this._selectCallback(index); |
| 208 return true; | 259 return true; |
| 209 } | 260 } |
| 210 } | 261 } |
| 211 return false; | 262 return false; |
| 212 } | 263 } |
| 213 }; | 264 }; |
| 214 | 265 |
| 215 /** @typedef {!{title: string, items: !Array<!SDK.NetworkManager.Conditions>}} * / | 266 /** @typedef {!{title: string, items: !Array<!SDK.MobileThrottling.Conditions>}} */ |
| 216 MobileThrottling.NetworkConditionsGroup; | 267 MobileThrottling.ThrottlingConditionsGroup; |
| 217 | 268 |
| 218 | 269 |
| 219 /** @type {!Array.<!SDK.NetworkManager.Conditions>} */ | 270 /** @enum {number} */ |
| 220 MobileThrottling.NetworkConditionsSelector.presets = [ | 271 MobileThrottling.CPUSlowdownMultiplier = { |
| 221 SDK.NetworkManager.OfflineConditions, | 272 MidTier: 4, |
| 222 {title: 'Slow 3G', download: 500 * 1024 / 8 * .8, upload: 500 * 1024 / 8 * .8, latency: 400 * 5}, | 273 LowTier: 6, |
| 223 {title: 'Fast 3G', download: 1.6 * 1024 * 1024 / 8 * .9, upload: 750 * 1024 / 8 * .9, latency: 150 * 3.75} | 274 }; |
| 275 | |
| 276 /** @type {!Array.<!SDK.MobileThrottling.Conditions>} */ | |
| 277 MobileThrottling.ThrottlingSelector.presets = [ | |
| 278 SDK.MobileThrottling.OfflineConditions, | |
| 279 { | |
| 280 title: 'Low-tier phone (Slow 3G)', | |
| 281 download: 500 * 1024 / 8 * .8, | |
| 282 upload: 500 * 1024 / 8 * .8, | |
| 283 latency: 400 * 5, | |
| 284 cpuThrottlingRate: MobileThrottling.CPUSlowdownMultiplier.LowTier | |
| 285 }, | |
| 286 { | |
| 287 title: 'Mid-tier phone (Fast 3G)', | |
| 288 download: 1.6 * 1024 * 1024 / 8 * .9, | |
| 289 upload: 750 * 1024 / 8 * .9, | |
| 290 latency: 150 * 3.75, | |
| 291 cpuThrottlingRate: MobileThrottling.CPUSlowdownMultiplier.MidTier | |
| 292 }, | |
| 224 ]; | 293 ]; |
| 225 | 294 |
| 295 /** @enum {symbol} */ | |
| 296 MobileThrottling.Events = { | |
|
dgozman
2017/06/13 01:47:08
MobileThrottling.ThrottlingSelector.Events
chenwilliam
2017/06/13 21:54:51
Done.
| |
| 297 CPURateChanged: Symbol('CPURateChanged') | |
| 298 }; | |
| 299 | |
| 300 | |
| 226 /** | 301 /** |
| 227 * @implements {UI.ActionDelegate} | 302 * @implements {UI.ActionDelegate} |
| 228 * @unrestricted | 303 * @unrestricted |
| 229 */ | 304 */ |
| 230 MobileThrottling.NetworkConditionsActionDelegate = class { | 305 MobileThrottling.NetworkConditionsActionDelegate = class { |
| 231 /** | 306 /** |
| 232 * @override | 307 * @override |
| 233 * @param {!UI.Context} context | 308 * @param {!UI.Context} context |
| 234 * @param {string} actionId | 309 * @param {string} actionId |
| 235 * @return {boolean} | 310 * @return {boolean} |
| 236 */ | 311 */ |
| 237 handleAction(context, actionId) { | 312 handleAction(context, actionId) { |
| 238 if (actionId === 'network-conditions.network-online') { | 313 if (actionId === 'network-conditions.network-online') { |
| 239 SDK.multitargetNetworkManager.setNetworkConditions(SDK.NetworkManager.NoTh rottlingConditions); | 314 SDK.multitargetNetworkManager.setNetworkConditions(SDK.MobileThrottling.No ThrottlingConditions); |
| 240 return true; | 315 return true; |
| 241 } | 316 } |
| 242 if (actionId === 'network-conditions.network-offline') { | 317 if (actionId === 'network-conditions.network-offline') { |
| 243 SDK.multitargetNetworkManager.setNetworkConditions(SDK.NetworkManager.Offl ineConditions); | 318 SDK.multitargetNetworkManager.setNetworkConditions(SDK.MobileThrottling.Of flineConditions); |
| 244 return true; | 319 return true; |
| 245 } | 320 } |
| 246 return false; | 321 return false; |
| 247 } | 322 } |
| 248 }; | 323 }; |
| OLD | NEW |