| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. | 2 * Copyright (C) 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2012 Google Inc. All rights reserved. | 3 * Copyright (C) 2012 Google Inc. All rights reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
| 7 * are met: | 7 * are met: |
| 8 * | 8 * |
| 9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 #include "core/dom/ClientRect.h" | 34 #include "core/dom/ClientRect.h" |
| 35 #include "core/dom/TaskRunnerHelper.h" | 35 #include "core/dom/TaskRunnerHelper.h" |
| 36 #include "core/dom/Text.h" | 36 #include "core/dom/Text.h" |
| 37 #include "core/dom/shadow/ShadowRoot.h" | 37 #include "core/dom/shadow/ShadowRoot.h" |
| 38 #include "core/events/KeyboardEvent.h" | 38 #include "core/events/KeyboardEvent.h" |
| 39 #include "core/events/MouseEvent.h" | 39 #include "core/events/MouseEvent.h" |
| 40 #include "core/frame/LocalFrame.h" | 40 #include "core/frame/LocalFrame.h" |
| 41 #include "core/frame/Settings.h" | 41 #include "core/frame/Settings.h" |
| 42 #include "core/frame/UseCounter.h" | 42 #include "core/frame/UseCounter.h" |
| 43 #include "core/html/HTMLAnchorElement.h" | 43 #include "core/html/HTMLAnchorElement.h" |
| 44 #include "core/html/HTMLLabelElement.h" | |
| 45 #include "core/html/HTMLSpanElement.h" | |
| 46 #include "core/html/HTMLVideoElement.h" | 44 #include "core/html/HTMLVideoElement.h" |
| 47 #include "core/html/TimeRanges.h" | 45 #include "core/html/TimeRanges.h" |
| 48 #include "core/html/media/HTMLMediaElementControlsList.h" | 46 #include "core/html/media/HTMLMediaElementControlsList.h" |
| 49 #include "core/html/media/HTMLMediaSource.h" | 47 #include "core/html/media/HTMLMediaSource.h" |
| 50 #include "core/html/media/MediaControls.h" | 48 #include "core/html/media/MediaControls.h" |
| 51 #include "core/html/shadow/ShadowElementNames.h" | 49 #include "core/html/shadow/ShadowElementNames.h" |
| 52 #include "core/html/track/TextTrackList.h" | 50 #include "core/html/track/TextTrackList.h" |
| 53 #include "core/input/EventHandler.h" | 51 #include "core/input/EventHandler.h" |
| 54 #include "core/layout/LayoutBoxModelObject.h" | 52 #include "core/layout/LayoutBoxModelObject.h" |
| 55 #include "core/layout/api/LayoutSliderItem.h" | 53 #include "core/layout/api/LayoutSliderItem.h" |
| 56 #include "core/page/ChromeClient.h" | 54 #include "core/page/ChromeClient.h" |
| 57 #include "core/page/Page.h" | 55 #include "core/page/Page.h" |
| 58 #include "platform/EventDispatchForbiddenScope.h" | |
| 59 #include "platform/Histogram.h" | 56 #include "platform/Histogram.h" |
| 60 #include "platform/RuntimeEnabledFeatures.h" | 57 #include "platform/RuntimeEnabledFeatures.h" |
| 61 #include "platform/text/PlatformLocale.h" | |
| 62 #include "public/platform/Platform.h" | 58 #include "public/platform/Platform.h" |
| 63 #include "public/platform/UserMetricsAction.h" | 59 #include "public/platform/UserMetricsAction.h" |
| 64 #include "public/platform/WebScreenInfo.h" | 60 #include "public/platform/WebScreenInfo.h" |
| 65 | 61 |
| 66 namespace blink { | 62 namespace blink { |
| 67 | 63 |
| 68 using namespace HTMLNames; | 64 using namespace HTMLNames; |
| 69 | 65 |
| 70 namespace { | 66 namespace { |
| 71 | 67 |
| 72 // This is the duration from mediaControls.css | |
| 73 const double kFadeOutDuration = 0.3; | |
| 74 | |
| 75 const QualifiedName& TrackIndexAttrName() { | |
| 76 // Save the track index in an attribute to avoid holding a pointer to the text | |
| 77 // track. | |
| 78 DEFINE_STATIC_LOCAL(QualifiedName, track_index_attr, | |
| 79 (g_null_atom, "data-track-index", g_null_atom)); | |
| 80 return track_index_attr; | |
| 81 } | |
| 82 | |
| 83 // When specified as trackIndex, disable text tracks. | |
| 84 const int kTrackIndexOffValue = -1; | |
| 85 | |
| 86 bool IsUserInteractionEvent(Event* event) { | 68 bool IsUserInteractionEvent(Event* event) { |
| 87 const AtomicString& type = event->type(); | 69 const AtomicString& type = event->type(); |
| 88 return type == EventTypeNames::mousedown || type == EventTypeNames::mouseup || | 70 return type == EventTypeNames::mousedown || type == EventTypeNames::mouseup || |
| 89 type == EventTypeNames::click || type == EventTypeNames::dblclick || | 71 type == EventTypeNames::click || type == EventTypeNames::dblclick || |
| 90 event->IsKeyboardEvent() || event->IsTouchEvent(); | 72 event->IsKeyboardEvent() || event->IsTouchEvent(); |
| 91 } | 73 } |
| 92 | 74 |
| 93 // Sliders (the volume control and timeline) need to capture some additional | 75 // Sliders (the volume control and timeline) need to capture some additional |
| 94 // events used when dragging the thumb. | 76 // events used when dragging the thumb. |
| 95 bool IsUserInteractionEventForSlider(Event* event, | 77 bool IsUserInteractionEventForSlider(Event* event, |
| (...skipping 24 matching lines...) Expand all Loading... |
| 120 Element* ElementFromCenter(Element& element) { | 102 Element* ElementFromCenter(Element& element) { |
| 121 ClientRect* client_rect = element.getBoundingClientRect(); | 103 ClientRect* client_rect = element.getBoundingClientRect(); |
| 122 int center_x = | 104 int center_x = |
| 123 static_cast<int>((client_rect->left() + client_rect->right()) / 2); | 105 static_cast<int>((client_rect->left() + client_rect->right()) / 2); |
| 124 int center_y = | 106 int center_y = |
| 125 static_cast<int>((client_rect->top() + client_rect->bottom()) / 2); | 107 static_cast<int>((client_rect->top() + client_rect->bottom()) / 2); |
| 126 | 108 |
| 127 return element.GetDocument().ElementFromPoint(center_x, center_y); | 109 return element.GetDocument().ElementFromPoint(center_x, center_y); |
| 128 } | 110 } |
| 129 | 111 |
| 130 bool HasDuplicateLabel(TextTrack* current_track) { | |
| 131 DCHECK(current_track); | |
| 132 TextTrackList* track_list = current_track->TrackList(); | |
| 133 // The runtime of this method is quadratic but since there are usually very | |
| 134 // few text tracks it won't affect the performance much. | |
| 135 String current_track_label = current_track->label(); | |
| 136 for (unsigned i = 0; i < track_list->length(); i++) { | |
| 137 TextTrack* track = track_list->AnonymousIndexedGetter(i); | |
| 138 if (current_track != track && current_track_label == track->label()) | |
| 139 return true; | |
| 140 } | |
| 141 return false; | |
| 142 } | |
| 143 | |
| 144 } // anonymous namespace | 112 } // anonymous namespace |
| 145 | 113 |
| 146 MediaControlPanelElement::MediaControlPanelElement( | |
| 147 MediaControls& media_controls) | |
| 148 : MediaControlDivElement(media_controls, kMediaControlsPanel), | |
| 149 is_displayed_(false), | |
| 150 opaque_(true), | |
| 151 transition_timer_(TaskRunnerHelper::Get(TaskType::kUnspecedTimer, | |
| 152 &media_controls.OwnerDocument()), | |
| 153 this, | |
| 154 &MediaControlPanelElement::TransitionTimerFired) {} | |
| 155 | |
| 156 MediaControlPanelElement* MediaControlPanelElement::Create( | |
| 157 MediaControls& media_controls) { | |
| 158 MediaControlPanelElement* panel = | |
| 159 new MediaControlPanelElement(media_controls); | |
| 160 panel->SetShadowPseudoId(AtomicString("-webkit-media-controls-panel")); | |
| 161 return panel; | |
| 162 } | |
| 163 | |
| 164 void MediaControlPanelElement::DefaultEventHandler(Event* event) { | |
| 165 // Suppress the media element activation behavior (toggle play/pause) when | |
| 166 // any part of the control panel is clicked. | |
| 167 if (event->type() == EventTypeNames::click) { | |
| 168 event->SetDefaultHandled(); | |
| 169 return; | |
| 170 } | |
| 171 HTMLDivElement::DefaultEventHandler(event); | |
| 172 } | |
| 173 | |
| 174 void MediaControlPanelElement::StartTimer() { | |
| 175 StopTimer(); | |
| 176 | |
| 177 // The timer is required to set the property display:'none' on the panel, | |
| 178 // such that captions are correctly displayed at the bottom of the video | |
| 179 // at the end of the fadeout transition. | |
| 180 // FIXME: Racing a transition with a setTimeout like this is wrong. | |
| 181 transition_timer_.StartOneShot(kFadeOutDuration, BLINK_FROM_HERE); | |
| 182 } | |
| 183 | |
| 184 void MediaControlPanelElement::StopTimer() { | |
| 185 transition_timer_.Stop(); | |
| 186 } | |
| 187 | |
| 188 void MediaControlPanelElement::TransitionTimerFired(TimerBase*) { | |
| 189 if (!opaque_) | |
| 190 SetIsWanted(false); | |
| 191 | |
| 192 StopTimer(); | |
| 193 } | |
| 194 | |
| 195 void MediaControlPanelElement::DidBecomeVisible() { | |
| 196 DCHECK(is_displayed_ && opaque_); | |
| 197 MediaElement().MediaControlsDidBecomeVisible(); | |
| 198 } | |
| 199 | |
| 200 bool MediaControlPanelElement::IsOpaque() const { | |
| 201 return opaque_; | |
| 202 } | |
| 203 | |
| 204 void MediaControlPanelElement::MakeOpaque() { | |
| 205 if (opaque_) | |
| 206 return; | |
| 207 | |
| 208 SetInlineStyleProperty(CSSPropertyOpacity, 1.0, | |
| 209 CSSPrimitiveValue::UnitType::kNumber); | |
| 210 opaque_ = true; | |
| 211 | |
| 212 if (is_displayed_) { | |
| 213 SetIsWanted(true); | |
| 214 DidBecomeVisible(); | |
| 215 } | |
| 216 } | |
| 217 | |
| 218 void MediaControlPanelElement::MakeTransparent() { | |
| 219 if (!opaque_) | |
| 220 return; | |
| 221 | |
| 222 SetInlineStyleProperty(CSSPropertyOpacity, 0.0, | |
| 223 CSSPrimitiveValue::UnitType::kNumber); | |
| 224 | |
| 225 opaque_ = false; | |
| 226 StartTimer(); | |
| 227 } | |
| 228 | |
| 229 void MediaControlPanelElement::SetIsDisplayed(bool is_displayed) { | |
| 230 if (is_displayed_ == is_displayed) | |
| 231 return; | |
| 232 | |
| 233 is_displayed_ = is_displayed; | |
| 234 if (is_displayed_ && opaque_) | |
| 235 DidBecomeVisible(); | |
| 236 } | |
| 237 | |
| 238 bool MediaControlPanelElement::KeepEventInNode(Event* event) { | |
| 239 return IsUserInteractionEvent(event); | |
| 240 } | |
| 241 | |
| 242 // ---------------------------- | |
| 243 | |
| 244 MediaControlPlayButtonElement::MediaControlPlayButtonElement( | 114 MediaControlPlayButtonElement::MediaControlPlayButtonElement( |
| 245 MediaControls& media_controls) | 115 MediaControls& media_controls) |
| 246 : MediaControlInputElement(media_controls, kMediaPlayButton) {} | 116 : MediaControlInputElement(media_controls, kMediaPlayButton) {} |
| 247 | 117 |
| 248 MediaControlPlayButtonElement* MediaControlPlayButtonElement::Create( | 118 MediaControlPlayButtonElement* MediaControlPlayButtonElement::Create( |
| 249 MediaControls& media_controls) { | 119 MediaControls& media_controls) { |
| 250 MediaControlPlayButtonElement* button = | 120 MediaControlPlayButtonElement* button = |
| 251 new MediaControlPlayButtonElement(media_controls); | 121 new MediaControlPlayButtonElement(media_controls); |
| 252 button->EnsureUserAgentShadowRoot(); | 122 button->EnsureUserAgentShadowRoot(); |
| 253 button->setType(InputTypeNames::button); | 123 button->setType(InputTypeNames::button); |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 374 MediaControlInputElement::DefaultEventHandler(event); | 244 MediaControlInputElement::DefaultEventHandler(event); |
| 375 } | 245 } |
| 376 | 246 |
| 377 WebLocalizedString::Name | 247 WebLocalizedString::Name |
| 378 MediaControlToggleClosedCaptionsButtonElement::GetOverflowStringName() { | 248 MediaControlToggleClosedCaptionsButtonElement::GetOverflowStringName() { |
| 379 return WebLocalizedString::kOverflowMenuCaptions; | 249 return WebLocalizedString::kOverflowMenuCaptions; |
| 380 } | 250 } |
| 381 | 251 |
| 382 // ---------------------------- | 252 // ---------------------------- |
| 383 | 253 |
| 384 MediaControlTextTrackListElement::MediaControlTextTrackListElement( | |
| 385 MediaControls& media_controls) | |
| 386 : MediaControlDivElement(media_controls, kMediaTextTrackList) {} | |
| 387 | |
| 388 MediaControlTextTrackListElement* MediaControlTextTrackListElement::Create( | |
| 389 MediaControls& media_controls) { | |
| 390 MediaControlTextTrackListElement* element = | |
| 391 new MediaControlTextTrackListElement(media_controls); | |
| 392 element->SetShadowPseudoId( | |
| 393 AtomicString("-internal-media-controls-text-track-list")); | |
| 394 element->SetIsWanted(false); | |
| 395 return element; | |
| 396 } | |
| 397 | |
| 398 void MediaControlTextTrackListElement::DefaultEventHandler(Event* event) { | |
| 399 if (event->type() == EventTypeNames::change) { | |
| 400 // Identify which input element was selected and set track to showing | |
| 401 Node* target = event->target()->ToNode(); | |
| 402 if (!target || !target->IsElementNode()) | |
| 403 return; | |
| 404 | |
| 405 GetMediaControls().DisableShowingTextTracks(); | |
| 406 int track_index = | |
| 407 ToElement(target)->GetIntegralAttribute(TrackIndexAttrName()); | |
| 408 if (track_index != kTrackIndexOffValue) { | |
| 409 DCHECK_GE(track_index, 0); | |
| 410 GetMediaControls().ShowTextTrackAtIndex(track_index); | |
| 411 MediaElement().DisableAutomaticTextTrackSelection(); | |
| 412 } | |
| 413 | |
| 414 event->SetDefaultHandled(); | |
| 415 } | |
| 416 MediaControlDivElement::DefaultEventHandler(event); | |
| 417 } | |
| 418 | |
| 419 void MediaControlTextTrackListElement::SetVisible(bool visible) { | |
| 420 if (visible) { | |
| 421 SetIsWanted(true); | |
| 422 RefreshTextTrackListMenu(); | |
| 423 } else { | |
| 424 SetIsWanted(false); | |
| 425 } | |
| 426 } | |
| 427 | |
| 428 String MediaControlTextTrackListElement::GetTextTrackLabel(TextTrack* track) { | |
| 429 if (!track) { | |
| 430 return MediaElement().GetLocale().QueryString( | |
| 431 WebLocalizedString::kTextTracksOff); | |
| 432 } | |
| 433 | |
| 434 String track_label = track->label(); | |
| 435 | |
| 436 if (track_label.IsEmpty()) | |
| 437 track_label = track->language(); | |
| 438 | |
| 439 if (track_label.IsEmpty()) { | |
| 440 track_label = String(MediaElement().GetLocale().QueryString( | |
| 441 WebLocalizedString::kTextTracksNoLabel, | |
| 442 String::Number(track->TrackIndex() + 1))); | |
| 443 } | |
| 444 | |
| 445 return track_label; | |
| 446 } | |
| 447 | |
| 448 // TextTrack parameter when passed in as a nullptr, creates the "Off" list item | |
| 449 // in the track list. | |
| 450 Element* MediaControlTextTrackListElement::CreateTextTrackListItem( | |
| 451 TextTrack* track) { | |
| 452 int track_index = track ? track->TrackIndex() : kTrackIndexOffValue; | |
| 453 HTMLLabelElement* track_item = HTMLLabelElement::Create(GetDocument()); | |
| 454 track_item->SetShadowPseudoId( | |
| 455 AtomicString("-internal-media-controls-text-track-list-item")); | |
| 456 HTMLInputElement* track_item_input = | |
| 457 HTMLInputElement::Create(GetDocument(), false); | |
| 458 track_item_input->SetShadowPseudoId( | |
| 459 AtomicString("-internal-media-controls-text-track-list-item-input")); | |
| 460 track_item_input->setType(InputTypeNames::checkbox); | |
| 461 track_item_input->SetIntegralAttribute(TrackIndexAttrName(), track_index); | |
| 462 if (!MediaElement().TextTracksVisible()) { | |
| 463 if (!track) | |
| 464 track_item_input->setChecked(true); | |
| 465 } else { | |
| 466 // If there are multiple text tracks set to showing, they must all have | |
| 467 // checkmarks displayed. | |
| 468 if (track && track->mode() == TextTrack::ShowingKeyword()) | |
| 469 track_item_input->setChecked(true); | |
| 470 } | |
| 471 | |
| 472 track_item->AppendChild(track_item_input); | |
| 473 String track_label = GetTextTrackLabel(track); | |
| 474 track_item->AppendChild(Text::Create(GetDocument(), track_label)); | |
| 475 // Add a track kind marker icon if there are multiple tracks with the same | |
| 476 // label or if the track has no label. | |
| 477 if (track && (track->label().IsEmpty() || HasDuplicateLabel(track))) { | |
| 478 HTMLSpanElement* track_kind_marker = HTMLSpanElement::Create(GetDocument()); | |
| 479 if (track->kind() == track->CaptionsKeyword()) { | |
| 480 track_kind_marker->SetShadowPseudoId(AtomicString( | |
| 481 "-internal-media-controls-text-track-list-kind-captions")); | |
| 482 } else { | |
| 483 DCHECK_EQ(track->kind(), track->SubtitlesKeyword()); | |
| 484 track_kind_marker->SetShadowPseudoId(AtomicString( | |
| 485 "-internal-media-controls-text-track-list-kind-subtitles")); | |
| 486 } | |
| 487 track_item->AppendChild(track_kind_marker); | |
| 488 } | |
| 489 return track_item; | |
| 490 } | |
| 491 | |
| 492 void MediaControlTextTrackListElement::RefreshTextTrackListMenu() { | |
| 493 if (!MediaElement().HasClosedCaptions() || | |
| 494 !MediaElement().TextTracksAreReady()) | |
| 495 return; | |
| 496 | |
| 497 EventDispatchForbiddenScope::AllowUserAgentEvents allow_events; | |
| 498 RemoveChildren(kOmitSubtreeModifiedEvent); | |
| 499 | |
| 500 // Construct a menu for subtitles and captions. Pass in a nullptr to | |
| 501 // createTextTrackListItem to create the "Off" track item. | |
| 502 AppendChild(CreateTextTrackListItem(nullptr)); | |
| 503 | |
| 504 TextTrackList* track_list = MediaElement().textTracks(); | |
| 505 for (unsigned i = 0; i < track_list->length(); i++) { | |
| 506 TextTrack* track = track_list->AnonymousIndexedGetter(i); | |
| 507 if (!track->CanBeRendered()) | |
| 508 continue; | |
| 509 AppendChild(CreateTextTrackListItem(track)); | |
| 510 } | |
| 511 } | |
| 512 | |
| 513 // ---------------------------- | |
| 514 MediaControlOverflowMenuButtonElement::MediaControlOverflowMenuButtonElement( | 254 MediaControlOverflowMenuButtonElement::MediaControlOverflowMenuButtonElement( |
| 515 MediaControls& media_controls) | 255 MediaControls& media_controls) |
| 516 : MediaControlInputElement(media_controls, kMediaOverflowButton) {} | 256 : MediaControlInputElement(media_controls, kMediaOverflowButton) {} |
| 517 | 257 |
| 518 MediaControlOverflowMenuButtonElement* | 258 MediaControlOverflowMenuButtonElement* |
| 519 MediaControlOverflowMenuButtonElement::Create(MediaControls& media_controls) { | 259 MediaControlOverflowMenuButtonElement::Create(MediaControls& media_controls) { |
| 520 MediaControlOverflowMenuButtonElement* button = | 260 MediaControlOverflowMenuButtonElement* button = |
| 521 new MediaControlOverflowMenuButtonElement(media_controls); | 261 new MediaControlOverflowMenuButtonElement(media_controls); |
| 522 button->EnsureUserAgentShadowRoot(); | 262 button->EnsureUserAgentShadowRoot(); |
| 523 button->setType(InputTypeNames::button); | 263 button->setType(InputTypeNames::button); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 537 UserMetricsAction("Media.Controls.OverflowOpen")); | 277 UserMetricsAction("Media.Controls.OverflowOpen")); |
| 538 | 278 |
| 539 GetMediaControls().ToggleOverflowMenu(); | 279 GetMediaControls().ToggleOverflowMenu(); |
| 540 event->SetDefaultHandled(); | 280 event->SetDefaultHandled(); |
| 541 } | 281 } |
| 542 | 282 |
| 543 MediaControlInputElement::DefaultEventHandler(event); | 283 MediaControlInputElement::DefaultEventHandler(event); |
| 544 } | 284 } |
| 545 | 285 |
| 546 // ---------------------------- | 286 // ---------------------------- |
| 547 MediaControlOverflowMenuListElement::MediaControlOverflowMenuListElement( | |
| 548 MediaControls& media_controls) | |
| 549 : MediaControlDivElement(media_controls, kMediaOverflowList) {} | |
| 550 | |
| 551 MediaControlOverflowMenuListElement* | |
| 552 MediaControlOverflowMenuListElement::Create(MediaControls& media_controls) { | |
| 553 MediaControlOverflowMenuListElement* element = | |
| 554 new MediaControlOverflowMenuListElement(media_controls); | |
| 555 element->SetIsWanted(false); | |
| 556 element->SetShadowPseudoId( | |
| 557 AtomicString("-internal-media-controls-overflow-menu-list")); | |
| 558 return element; | |
| 559 } | |
| 560 | |
| 561 void MediaControlOverflowMenuListElement::DefaultEventHandler(Event* event) { | |
| 562 if (event->type() == EventTypeNames::click) | |
| 563 event->SetDefaultHandled(); | |
| 564 | |
| 565 MediaControlDivElement::DefaultEventHandler(event); | |
| 566 } | |
| 567 | |
| 568 // ---------------------------- | |
| 569 MediaControlDownloadButtonElement::MediaControlDownloadButtonElement( | 287 MediaControlDownloadButtonElement::MediaControlDownloadButtonElement( |
| 570 MediaControls& media_controls) | 288 MediaControls& media_controls) |
| 571 : MediaControlInputElement(media_controls, kMediaDownloadButton) {} | 289 : MediaControlInputElement(media_controls, kMediaDownloadButton) {} |
| 572 | 290 |
| 573 MediaControlDownloadButtonElement* MediaControlDownloadButtonElement::Create( | 291 MediaControlDownloadButtonElement* MediaControlDownloadButtonElement::Create( |
| 574 MediaControls& media_controls) { | 292 MediaControls& media_controls) { |
| 575 MediaControlDownloadButtonElement* button = | 293 MediaControlDownloadButtonElement* button = |
| 576 new MediaControlDownloadButtonElement(media_controls); | 294 new MediaControlDownloadButtonElement(media_controls); |
| 577 button->EnsureUserAgentShadowRoot(); | 295 button->EnsureUserAgentShadowRoot(); |
| 578 button->setType(InputTypeNames::button); | 296 button->setType(InputTypeNames::button); |
| (...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1027 | 745 |
| 1028 void MediaControlCastButtonElement::RecordMetrics(CastOverlayMetrics metric) { | 746 void MediaControlCastButtonElement::RecordMetrics(CastOverlayMetrics metric) { |
| 1029 DCHECK(is_overlay_button_); | 747 DCHECK(is_overlay_button_); |
| 1030 DEFINE_STATIC_LOCAL( | 748 DEFINE_STATIC_LOCAL( |
| 1031 EnumerationHistogram, overlay_histogram, | 749 EnumerationHistogram, overlay_histogram, |
| 1032 ("Cast.Sender.Overlay", static_cast<int>(CastOverlayMetrics::kCount))); | 750 ("Cast.Sender.Overlay", static_cast<int>(CastOverlayMetrics::kCount))); |
| 1033 overlay_histogram.Count(static_cast<int>(metric)); | 751 overlay_histogram.Count(static_cast<int>(metric)); |
| 1034 } | 752 } |
| 1035 | 753 |
| 1036 } // namespace blink | 754 } // namespace blink |
| OLD | NEW |