Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(292)

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/mobile_throttling/ThrottlingManager.js

Issue 2938503002: DevTools: unify Network & CPU throttling (Closed)
Patch Set: update test Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698