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

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

Powered by Google App Engine
This is Rietveld 408576698