1// Copyright 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5cr.define('help', function() { 6 var Page = cr.ui.pageManager.Page; 7 var PageManager = cr.ui.pageManager.PageManager; 8 9 /** 10 * Encapsulated handling of the channel change overlay. 11 */ 12 function ChannelChangePage() { 13 Page.call(this, 'channel-change-page', '', 'channel-change-page'); 14 } 15 16 cr.addSingletonGetter(ChannelChangePage); 17 18 ChannelChangePage.prototype = { 19 __proto__: Page.prototype, 20 21 /** 22 * Name of the channel the device is currently on. 23 * @private 24 */ 25 currentChannel_: null, 26 27 /** 28 * Name of the channel the device is supposed to be on. 29 * @private 30 */ 31 targetChannel_: null, 32 33 /** 34 * True iff the device is enterprise-managed. 35 * @private 36 */ 37 isEnterpriseManaged_: undefined, 38 39 /** 40 * List of the channels names, from the least stable to the most stable. 41 * @private 42 */ 43 channelList_: ['dev-channel', 'beta-channel', 'stable-channel'], 44 45 /** 46 * List of the possible ui states. 47 * @private 48 */ 49 uiClassTable_: ['selected-channel-requires-powerwash', 50 'selected-channel-requires-delayed-update', 51 'selected-channel-good', 52 'selected-channel-unstable'], 53 54 /** override */ 55 initializePage: function() { 56 Page.prototype.initializePage.call(this); 57 58 $('channel-change-page-cancel-button').onclick = 59 PageManager.closeOverlay.bind(PageManager); 60 61 var self = this; 62 var options = this.getAllChannelOptions_(); 63 for (var i = 0; i < options.length; i++) { 64 var option = options[i]; 65 option.onclick = function() { 66 self.updateUI_(this.value); 67 }; 68 } 69 70 $('channel-change-page-powerwash-button').onclick = function() { 71 self.setChannel_(self.getSelectedOption_(), true); 72 PageManager.closeOverlay(); 73 }; 74 75 $('channel-change-page-change-button').onclick = function() { 76 self.setChannel_(self.getSelectedOption_(), false); 77 PageManager.closeOverlay(); 78 }; 79 }, 80 81 /** @override */ 82 didShowPage: function() { 83 if (this.targetChannel_ != null) 84 this.selectOption_(this.targetChannel_); 85 else if (this.currentChannel_ != null) 86 this.selectOption_(this.currentChannel_); 87 var options = this.getAllChannelOptions_(); 88 for (var i = 0; i < options.length; i++) { 89 var option = options[i]; 90 if (option.checked) 91 option.focus(); 92 } 93 }, 94 95 /** 96 * Returns the list of all radio buttons responsible for channel selection. 97 * @return {NodeList} Array of radio buttons 98 * @private 99 */ 100 getAllChannelOptions_: function() { 101 return this.pageDiv.querySelectorAll('input[type="radio"]'); 102 }, 103 104 /** 105 * Returns value of the selected option. 106 * @return {?string} Selected channel name or null, if neither 107 * option is selected. 108 * @private 109 */ 110 getSelectedOption_: function() { 111 var options = this.getAllChannelOptions_(); 112 for (var i = 0; i < options.length; i++) { 113 var option = options[i]; 114 if (option.checked) 115 return option.value; 116 } 117 return null; 118 }, 119 120 /** 121 * Selects option for a given channel. 122 * @param {string} channel Name of channel option that should be selected. 123 * @private 124 */ 125 selectOption_: function(channel) { 126 var options = this.getAllChannelOptions_(); 127 for (var i = 0; i < options.length; i++) { 128 var option = options[i]; 129 if (option.value == channel) { 130 option.checked = true; 131 } 132 } 133 this.updateUI_(channel); 134 }, 135 136 /** 137 * Updates UI according to selected channel. 138 * @param {string} selectedChannel Selected channel 139 * @private 140 */ 141 updateUI_: function(selectedChannel) { 142 var currentStability = this.channelList_.indexOf(this.currentChannel_); 143 var newStability = this.channelList_.indexOf(selectedChannel); 144 145 var newOverlayClass = null; 146 147 if (selectedChannel == this.currentChannel_) { 148 if (this.currentChannel_ != this.targetChannel_) { 149 // Allow user to switch back to the current channel. 150 newOverlayClass = 'selected-channel-good'; 151 } 152 } else if (selectedChannel != this.targetChannel_) { 153 // Selected channel isn't equal to the current and target channel. 154 if (newStability > currentStability) { 155 // More stable channel is selected. For customer devices 156 // notify user about powerwash. 157 if (this.isEnterpriseManaged_) 158 newOverlayClass = 'selected-channel-requires-delayed-update'; 159 else 160 newOverlayClass = 'selected-channel-requires-powerwash'; 161 } else if (selectedChannel == 'dev-channel') { 162 // Warn user about unstable channel. 163 newOverlayClass = 'selected-channel-unstable'; 164 } else { 165 // Switching to the less stable channel. 166 newOverlayClass = 'selected-channel-good'; 167 } 168 } 169 170 // Switch to the new UI state. 171 for (var i = 0; i < this.uiClassTable_.length; i++) 172 this.pageDiv.classList.remove(this.uiClassTable_[i]); 173 174 if (newOverlayClass) 175 this.pageDiv.classList.add(newOverlayClass); 176 }, 177 178 /** 179 * Sets the device target channel. 180 * @param {string} channel The name of the target channel 181 * @param {boolean} isPowerwashAllowed True iff powerwash is allowed 182 * @private 183 */ 184 setChannel_: function(channel, isPowerwashAllowed) { 185 this.targetChannel_ = channel; 186 this.updateUI_(channel); 187 help.HelpPage.setChannel(channel, isPowerwashAllowed); 188 }, 189 190 /** 191 * Updates page UI according to device owhership policy. 192 * @param {boolean} isEnterpriseManaged True if the device is 193 * enterprise managed 194 * @private 195 */ 196 updateIsEnterpriseManaged_: function(isEnterpriseManaged) { 197 this.isEnterpriseManaged_ = isEnterpriseManaged; 198 }, 199 200 /** 201 * Updates name of the current channel, i.e. the name of the 202 * channel the device is currently on. 203 * @param {string} channel The name of the current channel 204 * @private 205 */ 206 updateCurrentChannel_: function(channel) { 207 if (this.channelList_.indexOf(channel) < 0) 208 return; 209 this.currentChannel_ = channel; 210 this.selectOption_(channel); 211 }, 212 213 /** 214 * Updates name of the target channel, i.e. the name of the 215 * channel the device is supposed to be in case of a pending 216 * channel change. 217 * @param {string} channel The name of the target channel 218 * @private 219 */ 220 updateTargetChannel_: function(channel) { 221 if (this.channelList_.indexOf(channel) < 0) 222 return; 223 this.targetChannel_ = channel; 224 }, 225 226 /** 227 * @return {boolean} True if the page is ready and can be 228 * displayed, false otherwise 229 * @private 230 */ 231 isPageReady_: function() { 232 if (typeof this.isEnterpriseManaged_ == 'undefined') 233 return false; 234 if (!this.currentChannel_ || !this.targetChannel_) 235 return false; 236 return true; 237 }, 238 }; 239 240 ChannelChangePage.updateIsEnterpriseManaged = function(isEnterpriseManaged) { 241 ChannelChangePage.getInstance().updateIsEnterpriseManaged_( 242 isEnterpriseManaged); 243 }; 244 245 ChannelChangePage.updateCurrentChannel = function(channel) { 246 ChannelChangePage.getInstance().updateCurrentChannel_(channel); 247 }; 248 249 ChannelChangePage.updateTargetChannel = function(channel) { 250 ChannelChangePage.getInstance().updateTargetChannel_(channel); 251 }; 252 253 ChannelChangePage.isPageReady = function() { 254 return ChannelChangePage.getInstance().isPageReady_(); 255 }; 256 257 // Export 258 return { 259 ChannelChangePage: ChannelChangePage 260 }; 261}); 262