| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 #include "media/blink/watch_time_reporter.h" | 5 #include "media/blink/watch_time_reporter.h" |
| 6 | 6 |
| 7 #include "base/power_monitor/power_monitor.h" | 7 #include "base/power_monitor/power_monitor.h" |
| 8 | 8 |
| 9 namespace media { | 9 namespace media { |
| 10 | 10 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 81 volume_ = volume; | 81 volume_ = volume; |
| 82 | 82 |
| 83 // We're only interesting in transitions in and out of the muted state. | 83 // We're only interesting in transitions in and out of the muted state. |
| 84 if (!old_volume && volume) | 84 if (!old_volume && volume) |
| 85 MaybeStartReportingTimer(get_media_time_cb_.Run()); | 85 MaybeStartReportingTimer(get_media_time_cb_.Run()); |
| 86 else if (old_volume && !volume_) | 86 else if (old_volume && !volume_) |
| 87 MaybeFinalizeWatchTime(FinalizeTime::ON_NEXT_UPDATE); | 87 MaybeFinalizeWatchTime(FinalizeTime::ON_NEXT_UPDATE); |
| 88 } | 88 } |
| 89 | 89 |
| 90 void WatchTimeReporter::OnShown() { | 90 void WatchTimeReporter::OnShown() { |
| 91 if (!has_video_) |
| 92 return; |
| 93 |
| 91 is_visible_ = true; | 94 is_visible_ = true; |
| 92 MaybeStartReportingTimer(get_media_time_cb_.Run()); | 95 MaybeStartReportingTimer(get_media_time_cb_.Run()); |
| 93 } | 96 } |
| 94 | 97 |
| 95 void WatchTimeReporter::OnHidden() { | 98 void WatchTimeReporter::OnHidden() { |
| 99 if (!has_video_) |
| 100 return; |
| 101 |
| 96 is_visible_ = false; | 102 is_visible_ = false; |
| 97 MaybeFinalizeWatchTime(FinalizeTime::ON_NEXT_UPDATE); | 103 MaybeFinalizeWatchTime(FinalizeTime::ON_NEXT_UPDATE); |
| 98 } | 104 } |
| 99 | 105 |
| 100 void WatchTimeReporter::OnPowerStateChange(bool on_battery_power) { | 106 void WatchTimeReporter::OnPowerStateChange(bool on_battery_power) { |
| 101 if (!reporting_timer_.IsRunning()) | 107 if (!reporting_timer_.IsRunning()) |
| 102 return; | 108 return; |
| 103 | 109 |
| 104 // Defer changing |is_on_battery_power_| until the next watch time report to | 110 // Defer changing |is_on_battery_power_| until the next watch time report to |
| 105 // avoid momentary power changes from affecting the results. | 111 // avoid momentary power changes from affecting the results. |
| 106 if (is_on_battery_power_ != on_battery_power) { | 112 if (is_on_battery_power_ != on_battery_power) { |
| 107 end_timestamp_for_power_ = get_media_time_cb_.Run(); | 113 end_timestamp_for_power_ = get_media_time_cb_.Run(); |
| 108 | 114 |
| 109 // Restart the reporting timer so the full hysteresis is afforded. | 115 // Restart the reporting timer so the full hysteresis is afforded. |
| 110 reporting_timer_.Start(FROM_HERE, reporting_interval_, this, | 116 reporting_timer_.Start(FROM_HERE, reporting_interval_, this, |
| 111 &WatchTimeReporter::UpdateWatchTime); | 117 &WatchTimeReporter::UpdateWatchTime); |
| 112 return; | 118 return; |
| 113 } | 119 } |
| 114 | 120 |
| 115 end_timestamp_for_power_ = kNoTimestamp; | 121 end_timestamp_for_power_ = kNoTimestamp; |
| 116 } | 122 } |
| 117 | 123 |
| 118 bool WatchTimeReporter::ShouldReportWatchTime() { | 124 bool WatchTimeReporter::ShouldReportWatchTime() { |
| 119 // Only report watch time for media of sufficient size with both audio and | 125 // Report listen time or watch time only for tracks that are audio-only or |
| 120 // video tracks present. | 126 // have both an audio and video track of sufficient size. |
| 121 return has_audio_ && has_video_ && | 127 return (!has_video_ && has_audio_) || |
| 122 initial_video_size_.height() >= kMinimumVideoSize.height() && | 128 (has_video_ && has_audio_ && |
| 123 initial_video_size_.width() >= kMinimumVideoSize.width(); | 129 initial_video_size_.height() >= kMinimumVideoSize.height() && |
| 130 initial_video_size_.width() >= kMinimumVideoSize.width()); |
| 124 } | 131 } |
| 125 | 132 |
| 126 void WatchTimeReporter::MaybeStartReportingTimer( | 133 void WatchTimeReporter::MaybeStartReportingTimer( |
| 127 base::TimeDelta start_timestamp) { | 134 base::TimeDelta start_timestamp) { |
| 128 // Don't start the timer if any of our state indicates we shouldn't; this | 135 // Don't start the timer if any of our state indicates we shouldn't; this |
| 129 // check is important since the various event handlers do not have to care | 136 // check is important since the various event handlers do not have to care |
| 130 // about the state of other events. | 137 // about the state of other events. |
| 131 if (!ShouldReportWatchTime() || !is_playing_ || !volume_ || !is_visible_) { | 138 if (!ShouldReportWatchTime() || !is_playing_ || !volume_ || !is_visible_) { |
| 132 // If we reach this point the timer should already have been stopped or | 139 // If we reach this point the timer should already have been stopped or |
| 133 // there is a pending finalize in flight. | 140 // there is a pending finalize in flight. |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 192 // if a seek is taking some time to complete or the playback is stalled for | 199 // if a seek is taking some time to complete or the playback is stalled for |
| 193 // some reason. | 200 // some reason. |
| 194 if (elapsed >= kMinimumElapsedWatchTime && | 201 if (elapsed >= kMinimumElapsedWatchTime && |
| 195 last_media_timestamp_ != current_timestamp) { | 202 last_media_timestamp_ != current_timestamp) { |
| 196 last_media_timestamp_ = current_timestamp; | 203 last_media_timestamp_ = current_timestamp; |
| 197 | 204 |
| 198 std::unique_ptr<MediaLogEvent> log_event = | 205 std::unique_ptr<MediaLogEvent> log_event = |
| 199 media_log_->CreateEvent(MediaLogEvent::Type::WATCH_TIME_UPDATE); | 206 media_log_->CreateEvent(MediaLogEvent::Type::WATCH_TIME_UPDATE); |
| 200 | 207 |
| 201 log_event->params.SetDoubleWithoutPathExpansion( | 208 log_event->params.SetDoubleWithoutPathExpansion( |
| 202 MediaLog::kWatchTimeAudioVideoAll, elapsed.InSecondsF()); | 209 has_video_ ? MediaLog::kWatchTimeAudioVideoAll |
| 210 : MediaLog::kWatchTimeAudioAll, |
| 211 elapsed.InSecondsF()); |
| 203 if (is_mse_) { | 212 if (is_mse_) { |
| 204 log_event->params.SetDoubleWithoutPathExpansion( | 213 log_event->params.SetDoubleWithoutPathExpansion( |
| 205 MediaLog::kWatchTimeAudioVideoMse, elapsed.InSecondsF()); | 214 has_video_ ? MediaLog::kWatchTimeAudioVideoMse |
| 215 : MediaLog::kWatchTimeAudioMse, |
| 216 elapsed.InSecondsF()); |
| 206 } else { | 217 } else { |
| 207 log_event->params.SetDoubleWithoutPathExpansion( | 218 log_event->params.SetDoubleWithoutPathExpansion( |
| 208 MediaLog::kWatchTimeAudioVideoSrc, elapsed.InSecondsF()); | 219 has_video_ ? MediaLog::kWatchTimeAudioVideoSrc |
| 220 : MediaLog::kWatchTimeAudioSrc, |
| 221 elapsed.InSecondsF()); |
| 209 } | 222 } |
| 210 if (is_encrypted_) { | 223 if (is_encrypted_) { |
| 211 log_event->params.SetDoubleWithoutPathExpansion( | 224 log_event->params.SetDoubleWithoutPathExpansion( |
| 212 MediaLog::kWatchTimeAudioVideoEme, elapsed.InSecondsF()); | 225 has_video_ ? MediaLog::kWatchTimeAudioVideoEme |
| 226 : MediaLog::kWatchTimeAudioEme, |
| 227 elapsed.InSecondsF()); |
| 213 } | 228 } |
| 214 | 229 |
| 215 // Record watch time using the last known value for |is_on_battery_power_|; | 230 // Record watch time using the last known value for |is_on_battery_power_|; |
| 216 // if there's a |pending_power_change_| use that to accurately finalize the | 231 // if there's a |pending_power_change_| use that to accurately finalize the |
| 217 // last bits of time in the previous bucket. | 232 // last bits of time in the previous bucket. |
| 218 const base::TimeDelta elapsed_power = | 233 const base::TimeDelta elapsed_power = |
| 219 (is_power_change_pending ? end_timestamp_for_power_ | 234 (is_power_change_pending ? end_timestamp_for_power_ |
| 220 : current_timestamp) - | 235 : current_timestamp) - |
| 221 start_timestamp_for_power_; | 236 start_timestamp_for_power_; |
| 222 | 237 |
| 223 // Again, only update watch time if enough time has elapsed; we need to | 238 // Again, only update watch time if enough time has elapsed; we need to |
| 224 // recheck the elapsed time here since the power source can change anytime. | 239 // recheck the elapsed time here since the power source can change anytime. |
| 225 if (elapsed_power >= kMinimumElapsedWatchTime) { | 240 if (elapsed_power >= kMinimumElapsedWatchTime) { |
| 226 if (is_on_battery_power_) { | 241 if (is_on_battery_power_) { |
| 227 log_event->params.SetDoubleWithoutPathExpansion( | 242 log_event->params.SetDoubleWithoutPathExpansion( |
| 228 MediaLog::kWatchTimeAudioVideoBattery, elapsed_power.InSecondsF()); | 243 has_video_ ? MediaLog::kWatchTimeAudioVideoBattery |
| 244 : MediaLog::kWatchTimeAudioBattery, |
| 245 elapsed_power.InSecondsF()); |
| 229 } else { | 246 } else { |
| 230 log_event->params.SetDoubleWithoutPathExpansion( | 247 log_event->params.SetDoubleWithoutPathExpansion( |
| 231 MediaLog::kWatchTimeAudioVideoAc, elapsed_power.InSecondsF()); | 248 has_video_ ? MediaLog::kWatchTimeAudioVideoAc |
| 249 : MediaLog::kWatchTimeAudioAc, |
| 250 elapsed_power.InSecondsF()); |
| 232 } | 251 } |
| 233 } | 252 } |
| 234 | 253 |
| 235 if (is_finalizing) | 254 if (is_finalizing) |
| 236 log_event->params.SetBoolean(MediaLog::kWatchTimeFinalize, true); | 255 log_event->params.SetBoolean(MediaLog::kWatchTimeFinalize, true); |
| 237 else if (is_power_change_pending) | 256 else if (is_power_change_pending) |
| 238 log_event->params.SetBoolean(MediaLog::kWatchTimeFinalizePower, true); | 257 log_event->params.SetBoolean(MediaLog::kWatchTimeFinalizePower, true); |
| 239 | 258 |
| 240 DVLOG(2) << "Sending watch time update."; | 259 DVLOG(2) << "Sending watch time update."; |
| 241 media_log_->AddEvent(std::move(log_event)); | 260 media_log_->AddEvent(std::move(log_event)); |
| 242 } | 261 } |
| 243 | 262 |
| 244 if (is_power_change_pending) { | 263 if (is_power_change_pending) { |
| 245 // Invert battery power status here instead of using the value returned by | 264 // Invert battery power status here instead of using the value returned by |
| 246 // the PowerObserver since there may be a pending OnPowerStateChange(). | 265 // the PowerObserver since there may be a pending OnPowerStateChange(). |
| 247 is_on_battery_power_ = !is_on_battery_power_; | 266 is_on_battery_power_ = !is_on_battery_power_; |
| 248 | 267 |
| 249 start_timestamp_for_power_ = end_timestamp_for_power_; | 268 start_timestamp_for_power_ = end_timestamp_for_power_; |
| 250 end_timestamp_for_power_ = kNoTimestamp; | 269 end_timestamp_for_power_ = kNoTimestamp; |
| 251 } | 270 } |
| 252 | 271 |
| 253 // Stop the timer if this is supposed to be our last tick. | 272 // Stop the timer if this is supposed to be our last tick. |
| 254 if (is_finalizing) { | 273 if (is_finalizing) { |
| 255 end_timestamp_ = kNoTimestamp; | 274 end_timestamp_ = kNoTimestamp; |
| 256 reporting_timer_.Stop(); | 275 reporting_timer_.Stop(); |
| 257 } | 276 } |
| 258 } | 277 } |
| 259 | 278 |
| 260 } // namespace media | 279 } // namespace media |
| OLD | NEW |