| OLD | NEW |
| 1 // Copyright 2017 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 /** |
| 6 * This Polymer element shows media controls for a route that is currently cast | 6 * This Polymer element shows media controls for a route that is currently cast |
| 7 * to a device. | 7 * to a device. |
| 8 * @implements {RouteControlsInterface} | 8 * @implements {RouteControlsInterface} |
| 9 */ | 9 */ |
| 10 Polymer({ | 10 Polymer({ |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 77 value: 0, | 77 value: 0, |
| 78 }, | 78 }, |
| 79 | 79 |
| 80 /** | 80 /** |
| 81 * The status of the media route shown. | 81 * The status of the media route shown. |
| 82 * @type {!media_router.RouteStatus} | 82 * @type {!media_router.RouteStatus} |
| 83 */ | 83 */ |
| 84 routeStatus: { | 84 routeStatus: { |
| 85 type: Object, | 85 type: Object, |
| 86 observer: 'onRouteStatusChange_', | 86 observer: 'onRouteStatusChange_', |
| 87 value: new media_router.RouteStatus( | 87 value: new media_router.RouteStatus(), |
| 88 '', '', false, false, false, false, false, false, 0, 0, 0), | 88 }, |
| 89 |
| 90 /** |
| 91 * The ID of the timer currently set to increment the current time of the |
| 92 * media, or 0 if the current time is not being incremented. |
| 93 * @private {number} |
| 94 */ |
| 95 timeIncrementsTimeoutId_: { |
| 96 type: Number, |
| 97 value: 0, |
| 89 }, | 98 }, |
| 90 }, | 99 }, |
| 91 | 100 |
| 92 behaviors: [ | 101 behaviors: [ |
| 93 I18nBehavior, | 102 I18nBehavior, |
| 94 ], | 103 ], |
| 95 | 104 |
| 96 /** | 105 /** |
| 97 * Called by Polymer when the element loads. Registers the element to be | 106 * Called by Polymer when the element loads. Registers the element to be |
| 98 * notified of route status updates. | 107 * notified of route status updates. |
| 99 */ | 108 */ |
| 100 ready: function() { | 109 ready: function() { |
| 101 media_router.ui.setRouteControls( | 110 media_router.ui.setRouteControls( |
| 102 /** @type {RouteControlsInterface} */ (this)); | 111 /** @type {RouteControlsInterface} */ (this)); |
| 103 }, | 112 }, |
| 104 | 113 |
| 105 /** | 114 /** |
| 115 * Current time can be incremented if the media is playing, and either the |
| 116 * duration is 0 or current time is less than the duration. |
| 117 * @return {boolean} |
| 118 * @private |
| 119 */ |
| 120 canIncrementCurrentTime_: function() { |
| 121 return this.routeStatus.playState === media_router.PlayState.PLAYING && |
| 122 (this.routeStatus.duration === 0 || |
| 123 this.routeStatus.currentTime < this.routeStatus.duration); |
| 124 }, |
| 125 |
| 126 /** |
| 106 * Converts a number representing an interval of seconds to a string with | 127 * Converts a number representing an interval of seconds to a string with |
| 107 * HH:MM:SS format. | 128 * HH:MM:SS format. |
| 108 * @param {number} timeInSec Must be non-negative. Intervals longer than 100 | 129 * @param {number} timeInSec Must be non-negative. Intervals longer than 100 |
| 109 * hours get truncated silently. | 130 * hours get truncated silently. |
| 110 * @return {string} | 131 * @return {string} |
| 111 * | |
| 112 * @private | 132 * @private |
| 113 */ | 133 */ |
| 114 getFormattedTime_: function(timeInSec) { | 134 getFormattedTime_: function(timeInSec) { |
| 115 if (timeInSec < 0) { | 135 if (timeInSec < 0) { |
| 116 return ''; | 136 return ''; |
| 117 } | 137 } |
| 118 var hours = Math.floor(timeInSec / 3600); | 138 var hours = Math.floor(timeInSec / 3600); |
| 119 var minutes = Math.floor(timeInSec / 60) % 60; | 139 var minutes = Math.floor(timeInSec / 60) % 60; |
| 120 var seconds = Math.floor(timeInSec) % 60; | 140 var seconds = Math.floor(timeInSec) % 60; |
| 121 return ('0' + hours).substr(-2) + ':' + ('0' + minutes).substr(-2) + ':' + | 141 return ('0' + hours).substr(-2) + ':' + ('0' + minutes).substr(-2) + ':' + |
| 122 ('0' + seconds).substr(-2); | 142 ('0' + seconds).substr(-2); |
| 123 }, | 143 }, |
| 124 | 144 |
| 125 /** | 145 /** |
| 126 * @param {!media_router.RouteStatus} routeStatus | 146 * @param {!media_router.RouteStatus} routeStatus |
| 127 * @return {string} The value for the icon attribute of the mute/unmute | 147 * @return {string} The value for the icon attribute of the mute/unmute |
| 128 * button. | 148 * button. |
| 129 * | |
| 130 * @private | 149 * @private |
| 131 */ | 150 */ |
| 132 getMuteUnmuteIcon_: function(routeStatus) { | 151 getMuteUnmuteIcon_: function(routeStatus) { |
| 133 return routeStatus.isMuted ? 'av:volume-off' : 'av:volume-up'; | 152 return routeStatus.isMuted ? 'av:volume-off' : 'av:volume-up'; |
| 134 }, | 153 }, |
| 135 | 154 |
| 136 /** | 155 /** |
| 137 * @param {!media_router.RouteStatus} routeStatus | 156 * @param {!media_router.RouteStatus} routeStatus |
| 138 * @return {string} Localized title for the mute/unmute button. | 157 * @return {string} Localized title for the mute/unmute button. |
| 139 * | |
| 140 * @private | 158 * @private |
| 141 */ | 159 */ |
| 142 getMuteUnmuteTitle_: function(routeStatus) { | 160 getMuteUnmuteTitle_: function(routeStatus) { |
| 143 return routeStatus.isMuted ? this.i18n('unmuteTitle') : | 161 return routeStatus.isMuted ? this.i18n('unmuteTitle') : |
| 144 this.i18n('muteTitle'); | 162 this.i18n('muteTitle'); |
| 145 }, | 163 }, |
| 146 | 164 |
| 147 /** | 165 /** |
| 148 * @param {!media_router.RouteStatus} routeStatus | 166 * @param {!media_router.RouteStatus} routeStatus |
| 149 * @return {string}The value for the icon attribute of the play/pause button. | 167 * @return {string}The value for the icon attribute of the play/pause button. |
| 150 * | |
| 151 * @private | 168 * @private |
| 152 */ | 169 */ |
| 153 getPlayPauseIcon_: function(routeStatus) { | 170 getPlayPauseIcon_: function(routeStatus) { |
| 154 return routeStatus.isPaused ? 'av:play-arrow' : 'av:pause'; | 171 return routeStatus.playState === media_router.PlayState.PAUSED ? |
| 172 'av:play-arrow' : |
| 173 'av:pause'; |
| 155 }, | 174 }, |
| 156 | 175 |
| 157 /** | 176 /** |
| 158 * @param {!media_router.RouteStatus} routeStatus | 177 * @param {!media_router.RouteStatus} routeStatus |
| 159 * @return {string} Localized title for the play/pause button. | 178 * @return {string} Localized title for the play/pause button. |
| 160 * | |
| 161 * @private | 179 * @private |
| 162 */ | 180 */ |
| 163 getPlayPauseTitle_: function(routeStatus) { | 181 getPlayPauseTitle_: function(routeStatus) { |
| 164 return routeStatus.isPaused ? this.i18n('playTitle') : | 182 return routeStatus.playState === media_router.PlayState.PAUSED ? |
| 165 this.i18n('pauseTitle'); | 183 this.i18n('playTitle') : |
| 184 this.i18n('pauseTitle'); |
| 185 }, |
| 186 |
| 187 /** |
| 188 * Checks whether the media is still playing, and if so, sends a media status |
| 189 * update incrementing the current time and schedules another call for a |
| 190 * second later. |
| 191 * @private |
| 192 */ |
| 193 maybeIncrementCurrentTime_: function() { |
| 194 if (this.canIncrementCurrentTime_()) { |
| 195 this.routeStatus.currentTime++; |
| 196 this.displayedCurrentTime_ = this.routeStatus.currentTime; |
| 197 if (this.routeStatus.duration === 0 || |
| 198 this.routeStatus.currentTime < this.routeStatus.duration) { |
| 199 this.timeIncrementsTimeoutId_ = |
| 200 setTimeout(() => this.maybeIncrementCurrentTime_(), 1000); |
| 201 } |
| 202 } else { |
| 203 this.timeIncrementsTimeoutId_ = 0; |
| 204 } |
| 166 }, | 205 }, |
| 167 | 206 |
| 168 /** | 207 /** |
| 169 * Called when the user toggles the mute status of the media. Sends a mute or | 208 * Called when the user toggles the mute status of the media. Sends a mute or |
| 170 * unmute command to the browser. | 209 * unmute command to the browser. |
| 171 * | |
| 172 * @private | 210 * @private |
| 173 */ | 211 */ |
| 174 onMuteUnmute_: function() { | 212 onMuteUnmute_: function() { |
| 175 media_router.browserApi.setCurrentMediaMute(!this.routeStatus.isMuted); | 213 media_router.browserApi.setCurrentMediaMute(!this.routeStatus.isMuted); |
| 176 }, | 214 }, |
| 177 | 215 |
| 178 /** | 216 /** |
| 179 * Called when the user toggles between playing and pausing the media. Sends a | 217 * Called when the user toggles between playing and pausing the media. Sends a |
| 180 * play or pause command to the browser. | 218 * play or pause command to the browser. |
| 181 * | |
| 182 * @private | 219 * @private |
| 183 */ | 220 */ |
| 184 onPlayPause_: function() { | 221 onPlayPause_: function() { |
| 185 if (this.routeStatus.isPaused) { | 222 if (this.routeStatus.playState === media_router.PlayState.PAUSED) { |
| 186 media_router.browserApi.playCurrentMedia(); | 223 media_router.browserApi.playCurrentMedia(); |
| 187 } else { | 224 } else { |
| 188 media_router.browserApi.pauseCurrentMedia(); | 225 media_router.browserApi.pauseCurrentMedia(); |
| 189 } | 226 } |
| 190 }, | 227 }, |
| 191 | 228 |
| 192 /** | 229 /** |
| 193 * Updates seek and volume bars if the user is not currently dragging on | 230 * Updates seek and volume bars if the user is not currently dragging on |
| 194 * them. | 231 * them. |
| 195 * @param {!media_router.RouteStatus} newRouteStatus | 232 * @param {!media_router.RouteStatus} newRouteStatus |
| 196 * | |
| 197 * @private | 233 * @private |
| 198 */ | 234 */ |
| 199 onRouteStatusChange_: function(newRouteStatus) { | 235 onRouteStatusChange_: function(newRouteStatus) { |
| 200 if (!this.isSeeking_) { | 236 if (!this.isSeeking_) { |
| 201 this.displayedCurrentTime_ = newRouteStatus.currentTime; | 237 this.displayedCurrentTime_ = newRouteStatus.currentTime; |
| 202 } | 238 } |
| 203 if (!this.isVolumeChanging_) { | 239 if (!this.isVolumeChanging_) { |
| 204 this.displayedVolume_ = newRouteStatus.volume; | 240 this.displayedVolume_ = newRouteStatus.volume; |
| 205 } | 241 } |
| 206 if (newRouteStatus.description !== '') { | 242 if (newRouteStatus.description !== '') { |
| 207 this.displayedDescription_ = newRouteStatus.description; | 243 this.displayedDescription_ = newRouteStatus.description; |
| 208 } | 244 } |
| 209 if (!this.initialLoadTime_) { | 245 if (!this.initialLoadTime_) { |
| 210 this.initialLoadTime_ = Date.now(); | 246 this.initialLoadTime_ = Date.now(); |
| 211 media_router.browserApi.reportWebUIRouteControllerLoaded( | 247 media_router.browserApi.reportWebUIRouteControllerLoaded( |
| 212 this.initialLoadTime_ - this.routeDetailsOpenTime); | 248 this.initialLoadTime_ - this.routeDetailsOpenTime); |
| 213 } | 249 } |
| 250 if (this.canIncrementCurrentTime_()) { |
| 251 if (!this.timeIncrementsTimeoutId_) { |
| 252 this.timeIncrementsTimeoutId_ = |
| 253 setTimeout(() => this.maybeIncrementCurrentTime_(), 1000); |
| 254 } |
| 255 } else { |
| 256 this.stopIncrementingCurrentTime_(); |
| 257 } |
| 214 }, | 258 }, |
| 215 | 259 |
| 216 /** | 260 /** |
| 217 * Called when the route is updated. Updates the description shown if it has | 261 * Called when the route is updated. Updates the description shown if it has |
| 218 * not been provided by status updates. | 262 * not been provided by status updates. |
| 219 * @param {!media_router.Route} route | 263 * @param {?media_router.Route} route |
| 220 */ | 264 */ |
| 221 onRouteUpdated: function(route) { | 265 onRouteUpdated: function(route) { |
| 222 if (this.routeStatus.description === '') { | 266 if (!route) { |
| 267 this.stopIncrementingCurrentTime_(); |
| 268 } |
| 269 if (route && this.routeStatus.description === '') { |
| 223 this.displayedDescription_ = | 270 this.displayedDescription_ = |
| 224 loadTimeData.getStringF('castingActivityStatus', route.description); | 271 loadTimeData.getStringF('castingActivityStatus', route.description); |
| 225 } | 272 } |
| 226 }, | 273 }, |
| 227 | 274 |
| 228 /** | 275 /** |
| 229 * Called when the user clicks on or stops dragging the seek bar. | 276 * Called when the user clicks on or stops dragging the seek bar. |
| 230 * @param {!Event} e | 277 * @param {!Event} e |
| 231 * | |
| 232 * @private | 278 * @private |
| 233 */ | 279 */ |
| 234 onSeekComplete_: function(e) { | 280 onSeekComplete_: function(e) { |
| 281 this.stopIncrementingCurrentTime_(); |
| 235 this.isSeeking_ = false; | 282 this.isSeeking_ = false; |
| 236 this.displayedCurrentTime_ = e.target.value; | 283 this.displayedCurrentTime_ = e.target.value; |
| 237 media_router.browserApi.seekCurrentMedia(this.displayedCurrentTime_); | 284 media_router.browserApi.seekCurrentMedia(this.displayedCurrentTime_); |
| 238 }, | 285 }, |
| 239 | 286 |
| 240 /** | 287 /** |
| 241 * Called when the user starts dragging the seek bar. | 288 * Called when the user starts dragging the seek bar. |
| 242 * @param {!Event} e | 289 * @param {!Event} e |
| 243 * | |
| 244 * @private | 290 * @private |
| 245 */ | 291 */ |
| 246 onSeekStart_: function(e) { | 292 onSeekStart_: function(e) { |
| 247 this.isSeeking_ = true; | 293 this.isSeeking_ = true; |
| 248 var target = /** @type {{immediateValue: number}} */ (e.target); | 294 var target = /** @type {{immediateValue: number}} */ (e.target); |
| 249 this.displayedCurrentTime_ = target.immediateValue; | 295 this.displayedCurrentTime_ = target.immediateValue; |
| 250 }, | 296 }, |
| 251 | 297 |
| 252 /** | 298 /** |
| 253 * Called when the user clicks on or stops dragging the volume bar. | 299 * Called when the user clicks on or stops dragging the volume bar. |
| 254 * @param {!Event} e | 300 * @param {!Event} e |
| 255 * | |
| 256 * @private | 301 * @private |
| 257 */ | 302 */ |
| 258 onVolumeChangeComplete_: function(e) { | 303 onVolumeChangeComplete_: function(e) { |
| 259 this.isVolumeChanging_ = false; | 304 this.isVolumeChanging_ = false; |
| 260 this.volumeSliderValue_ = e.target.value; | 305 this.volumeSliderValue_ = e.target.value; |
| 261 media_router.browserApi.setCurrentMediaVolume(this.volumeSliderValue_); | 306 media_router.browserApi.setCurrentMediaVolume(this.volumeSliderValue_); |
| 262 }, | 307 }, |
| 263 | 308 |
| 264 /** | 309 /** |
| 265 * Called when the user starts dragging the volume bar. | 310 * Called when the user starts dragging the volume bar. |
| 266 * @param {!Event} e | 311 * @param {!Event} e |
| 267 * | |
| 268 * @private | 312 * @private |
| 269 */ | 313 */ |
| 270 onVolumeChangeStart_: function(e) { | 314 onVolumeChangeStart_: function(e) { |
| 271 this.isVolumeChanging_ = true; | 315 this.isVolumeChanging_ = true; |
| 272 var target = /** @type {{immediateValue: number}} */ (e.target); | 316 var target = /** @type {{immediateValue: number}} */ (e.target); |
| 273 this.volumeSliderValue_ = target.immediateValue; | 317 this.volumeSliderValue_ = target.immediateValue; |
| 274 }, | 318 }, |
| 275 | 319 |
| 276 /** | 320 /** |
| 277 * Resets the route controls. Called when the route details view is closed. | 321 * Resets the route controls. Called when the route details view is closed. |
| 278 */ | 322 */ |
| 279 reset: function() { | 323 reset: function() { |
| 280 this.routeStatus = new media_router.RouteStatus( | 324 this.routeStatus = new media_router.RouteStatus( |
| 281 '', '', false, false, false, false, false, false, 0, 0, 0); | 325 '', '', false, false, false, false, false, false, 0, 0, 0); |
| 282 media_router.ui.setRouteControls(null); | 326 media_router.ui.setRouteControls(null); |
| 283 }, | 327 }, |
| 328 |
| 329 /** |
| 330 * If it is currently incrementing the current time shown, then stops doing |
| 331 * so. |
| 332 * @private |
| 333 */ |
| 334 stopIncrementingCurrentTime_: function() { |
| 335 if (this.timeIncrementsTimeoutId_) { |
| 336 clearTimeout(this.timeIncrementsTimeoutId_); |
| 337 this.timeIncrementsTimeoutId_ = 0; |
| 338 } |
| 339 } |
| 284 }); | 340 }); |
| OLD | NEW |