dom/html/TextTrackManager.h
author Nicholas Nethercote <nnethercote@mozilla.com>
Fri, 03 Mar 2017 15:32:11 +1100
changeset 374836 4e196d802c7be7f3a3c147cc6c5b6406656584b1
parent 373042 c0f61862e942b67173955dc2543da7456b62118a
permissions -rw-r--r--
Bug 1344118 - Fix the profiler's sleeping threads optimization. r=jseward. When ProfilerBuffer::reset() is called, DuplicateLastSample() will start failing for all sleeping threads because there will be no prior thread data in the buffer to duplicate. But the sampling loop doesn't detect such failure. This causes two problems: - Missing samples. - CPU usage goes through the roof, because each time around the sampling loop the length of the failing search increases. The fix is simple: detect failure in the sampling loop and do a normal sample in that case. The patch also removes ThreadInfo::DuplicateLastSample(), because it just calls onto ProfileBuffer::DuplicateLastSample().

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef mozilla_dom_TextTrackManager_h
#define mozilla_dom_TextTrackManager_h

#include "mozilla/dom/TextTrack.h"
#include "mozilla/dom/TextTrackList.h"
#include "mozilla/dom/TextTrackCueList.h"
#include "mozilla/StaticPtr.h"
#include "nsContentUtils.h"

class nsIWebVTTParserWrapper;

namespace mozilla {
namespace dom {

class HTMLMediaElement;

class CompareTextTracks {
private:
  HTMLMediaElement* mMediaElement;
  int32_t TrackChildPosition(TextTrack* aTrack) const;
public:
  explicit CompareTextTracks(HTMLMediaElement* aMediaElement);
  bool Equals(TextTrack* aOne, TextTrack* aTwo) const;
  bool LessThan(TextTrack* aOne, TextTrack* aTwo) const;
};

class TextTrack;
class TextTrackCue;

class TextTrackManager final : public nsIDOMEventListener
{
  ~TextTrackManager();

public:
  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
  NS_DECL_CYCLE_COLLECTION_CLASS(TextTrackManager)

  NS_DECL_NSIDOMEVENTLISTENER

  explicit TextTrackManager(HTMLMediaElement* aMediaElement);

  TextTrackList* GetTextTracks() const;
  already_AddRefed<TextTrack> AddTextTrack(TextTrackKind aKind,
                                           const nsAString& aLabel,
                                           const nsAString& aLanguage,
                                           TextTrackMode aMode,
                                           TextTrackReadyState aReadyState,
                                           TextTrackSource aTextTrackSource);
  void AddTextTrack(TextTrack* aTextTrack);
  void RemoveTextTrack(TextTrack* aTextTrack, bool aPendingListOnly);
  void DidSeek();

  void NotifyCueAdded(TextTrackCue& aCue);
  void AddCues(TextTrack* aTextTrack);
  void NotifyCueRemoved(TextTrackCue& aCue);
  /**
   * Overview of WebVTT cuetext and anonymous content setup.
   *
   * WebVTT nodes are the parsed version of WebVTT cuetext. WebVTT cuetext is
   * the portion of a WebVTT cue that specifies what the caption will actually
   * show up as on screen.
   *
   * WebVTT cuetext can contain markup that loosely relates to HTML markup. It
   * can contain tags like <b>, <u>, <i>, <c>, <v>, <ruby>, <rt>, <lang>,
   * including timestamp tags.
   *
   * When the caption is ready to be displayed the WebVTT nodes are converted
   * over to anonymous DOM content. <i>, <u>, <b>, <ruby>, and <rt> all become
   * HTMLElements of their corresponding HTML markup tags. <c> and <v> are
   * converted to <span> tags. Timestamp tags are converted to XML processing
   * instructions. Additionally, all cuetext tags support specifying of classes.
   * This takes the form of <foo.class.subclass>. These classes are then parsed
   * and set as the anonymous content's class attribute.
   *
   * Rules on constructing DOM objects from WebVTT nodes can be found here
   * http://dev.w3.org/html5/webvtt/#webvtt-cue-text-dom-construction-rules.
   * Current rules are taken from revision on April 15, 2013.
   */

  void PopulatePendingList();

  void AddListeners();

  // The HTMLMediaElement that this TextTrackManager manages the TextTracks of.
  RefPtr<HTMLMediaElement> mMediaElement;

  void DispatchTimeMarchesOn();
  void TimeMarchesOn();
  void DispatchUpdateCueDisplay();

  void NotifyShutdown()
  {
    mShutdown = true;
  }

  void NotifyCueUpdated(TextTrackCue *aCue);

  void NotifyReset();

  bool IsLoaded();

private:
  /**
   * Converts the TextTrackCue's cuetext into a tree of DOM objects
   * and attaches it to a div on its owning TrackElement's
   * MediaElement's caption overlay.
   */
  void UpdateCueDisplay();

  // List of the TextTrackManager's owning HTMLMediaElement's TextTracks.
  RefPtr<TextTrackList> mTextTracks;
  // List of text track objects awaiting loading.
  RefPtr<TextTrackList> mPendingTextTracks;
  // List of newly introduced Text Track cues.

  // Contain all cues for a MediaElement. Not sorted.
  RefPtr<TextTrackCueList> mNewCues;
  // The active cues for the last TimeMarchesOn iteration.
  RefPtr<TextTrackCueList> mLastActiveCues;

  // True if the media player playback changed due to seeking prior to and
  // during running the "Time Marches On" algorithm.
  bool mHasSeeked;
  // Playback position at the time of last "Time Marches On" call
  double mLastTimeMarchesOnCalled;

  bool mTimeMarchesOnDispatched;
  bool mUpdateCueDisplayDispatched;

  static StaticRefPtr<nsIWebVTTParserWrapper> sParserWrapper;

  bool performedTrackSelection;

  // Runs the algorithm for performing automatic track selection.
  void HonorUserPreferencesForTrackSelection();
  // Performs track selection for a single TextTrackKind.
  void PerformTrackSelection(TextTrackKind aTextTrackKind);
  //Performs track selection for a set of TextTrackKinds, for example,
  // 'subtitles' and 'captions' should be selected together.
  void PerformTrackSelection(TextTrackKind aTextTrackKinds[], uint32_t size);
  void GetTextTracksOfKinds(TextTrackKind aTextTrackKinds[], uint32_t size,
                            nsTArray<TextTrack*>& aTextTracks);
  void GetTextTracksOfKind(TextTrackKind aTextTrackKind,
                           nsTArray<TextTrack*>& aTextTracks);
  bool TrackIsDefault(TextTrack* aTextTrack);

  void ReportTelemetryForTrack(TextTrack* aTextTrack) const;
  void ReportTelemetryForCue();

  // If there is at least one cue has been added to the cue list once, we would
  // report the usage of cue to Telemetry.
  bool mCueTelemetryReported;

  class ShutdownObserverProxy final : public nsIObserver
  {
    NS_DECL_ISUPPORTS

  public:
    explicit ShutdownObserverProxy(TextTrackManager* aManager)
      : mManager(aManager)
    {
      nsContentUtils::RegisterShutdownObserver(this);
    }

    NS_IMETHODIMP Observe(nsISupports *aSubject, const char *aTopic, const char16_t *aData) override
    {
      MOZ_ASSERT(NS_IsMainThread());
      if (strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) {
        nsContentUtils::UnregisterShutdownObserver(this);
        mManager->NotifyShutdown();
      }
      return NS_OK;
    }

  private:
    ~ShutdownObserverProxy() {};
    TextTrackManager* mManager;
  };

  RefPtr<ShutdownObserverProxy> mShutdownProxy;
  bool mShutdown;
};

} // namespace dom
} // namespace mozilla

#endif // mozilla_dom_TextTrackManager_h