Global Metrics

path: .metrics.loc.blank
old: 24.0
new: 34.0

path: .metrics.loc.cloc
old: 29.0
new: 55.0

path: .metrics.loc.lloc
old: 164.0
new: 6.0

path: .metrics.loc.sloc
old: 374.0
new: 188.0

path: .metrics.loc.ploc
old: 321.0
new: 99.0

path: .metrics.nom.functions
old: 7.0
new: 5.0

path: .metrics.nom.total
old: 7.0
new: 5.0

path: .metrics.nexits.average
old: 4.857142857142857
new: 0.0

path: .metrics.nexits.sum
old: 34.0
new: 0.0

path: .metrics.cognitive.sum
old: 164.0
new: 0.0

path: .metrics.cognitive.average
old: 23.428571428571427
new: 0.0

path: .metrics.cyclomatic.average
old: 9.4
new: 1.0

path: .metrics.cyclomatic.sum
old: 94.0
new: 10.0

path: .metrics.nargs.sum
old: 21.0
new: 1.0

path: .metrics.nargs.average
old: 3.0
new: 0.2

path: .metrics.mi.mi_visual_studio
old: 2.3157210742867056
new: 24.62601484425289

path: .metrics.mi.mi_sei
old: -39.51024511627421
new: 23.232948366357384

path: .metrics.mi.mi_original
old: 3.9598830370302665
new: 42.11048538367244

path: .metrics.halstead.N2
old: 718.0
new: 186.0

path: .metrics.halstead.time
old: 89626.83763760023
new: 2053.486668142841

path: .metrics.halstead.effort
old: 1613283.077476804
new: 36962.760026571144

path: .metrics.halstead.level
old: 0.008356545961002786
new: 0.08315412186379928

path: .metrics.halstead.length
old: 1891.0
new: 437.0

path: .metrics.halstead.estimated_program_length
old: 884.5206849480167
new: 854.129154368926

path: .metrics.halstead.purity_ratio
old: 0.46775287411317645
new: 1.9545289573659632

path: .metrics.halstead.N1
old: 1173.0
new: 251.0

path: .metrics.halstead.volume
old: 13481.474185042933
new: 3073.605851671866

path: .metrics.halstead.bugs
old: 4.585138558278588
new: 0.3698750246406713

path: .metrics.halstead.difficulty
old: 119.66666666666669
new: 12.025862068965518

path: .metrics.halstead.n1
old: 35.0
new: 15.0

path: .metrics.halstead.n2
old: 105.0
new: 116.0

path: .metrics.halstead.vocabulary
old: 140.0
new: 131.0

Spaces Data

Minimal test - lines (25, 186)

path: .spaces[0].metrics.mi.mi_sei
old: -40.47672696829757
new: 27.526773269099543

path: .spaces[0].metrics.mi.mi_original
old: 4.884104517707911
new: 45.03378977810722

path: .spaces[0].metrics.mi.mi_visual_studio
old: 2.8562014723438076
new: 26.33554957784048

path: .spaces[0].metrics.nargs.sum
old: 21.0
new: 1.0

path: .spaces[0].metrics.nargs.average
old: 3.0
new: 0.2

path: .spaces[0].metrics.nexits.average
old: 4.857142857142857
new: 0.0

path: .spaces[0].metrics.nexits.sum
old: 34.0
new: 0.0

path: .spaces[0].metrics.nom.functions
old: 7.0
new: 5.0

path: .spaces[0].metrics.nom.total
old: 7.0
new: 5.0

path: .spaces[0].metrics.halstead.N1
old: 1173.0
new: 251.0

path: .spaces[0].metrics.halstead.effort
old: 1643932.0658335912
new: 36462.63915286676

path: .spaces[0].metrics.halstead.length
old: 1888.0
new: 423.0

path: .spaces[0].metrics.halstead.n2
old: 102.0
new: 103.0

path: .spaces[0].metrics.halstead.level
old: 0.008151848151848152
new: 0.07984496124031007

path: .spaces[0].metrics.halstead.n1
old: 35.0
new: 15.0

path: .spaces[0].metrics.halstead.estimated_program_length
old: 860.1122904741662
new: 747.3129132339992

path: .spaces[0].metrics.halstead.vocabulary
old: 137.0
new: 118.0

path: .spaces[0].metrics.halstead.N2
old: 715.0
new: 172.0

path: .spaces[0].metrics.halstead.bugs
old: 4.643028217846332
new: 0.3665310843064229

path: .spaces[0].metrics.halstead.difficulty
old: 122.67156862745098
new: 12.524271844660197

path: .spaces[0].metrics.halstead.purity_ratio
old: 0.4555679504630118
new: 1.7666971944066174

path: .spaces[0].metrics.halstead.time
old: 91329.55921297728
new: 2025.7021751592645

path: .spaces[0].metrics.halstead.volume
old: 13401.084572629474
new: 2911.358009880059

path: .spaces[0].metrics.cyclomatic.sum
old: 93.0
new: 9.0

path: .spaces[0].metrics.cyclomatic.average
old: 10.333333333333334
new: 1.0

path: .spaces[0].metrics.cognitive.sum
old: 164.0
new: 0.0

path: .spaces[0].metrics.cognitive.average
old: 23.428571428571427
new: 0.0

path: .spaces[0].metrics.loc.blank
old: 21.0
new: 31.0

path: .spaces[0].metrics.loc.lloc
old: 164.0
new: 6.0

path: .spaces[0].metrics.loc.ploc
old: 316.0
new: 83.0

path: .spaces[0].metrics.loc.sloc
old: 359.0
new: 162.0

path: .spaces[0].metrics.loc.cloc
old: 22.0
new: 48.0

Code

namespace mozilla {
namespace widget {

/**
 * This class implements the "MPRIS" D-Bus Service
 * (https://specifications.freedesktop.org/mpris-spec/2.2),
 * which is used to communicate with the Desktop Environment about the
 * Multimedia playing in Gecko.
 * Note that this interface requires many methods which may not be supported by
 * Gecko, the interface
 * however provides CanXYZ properties for these methods, so the method is
 * defined but won't be executed.
 *
 * Also note that the following defines are for parts that the MPRIS Spec
 * defines optional. The code won't
 * compile with any of the defines set, yet, as those aren't implemented yet and
 * probably never will be of
 * use for gecko. For sake of completeness, they have been added until the
 * decision about their implementation
 * is finally made.
 *
 * The constexpr'ed methods are capabilities of the user agent known at compile
 * time, e.g. we decided at
 * compile time whether we ever want to support closing the user agent via MPRIS
 * (Quit() and CanQuit()).
 *
 * Other properties like CanPlay() might depend on the runtime state (is there
 * media available for playback?)
 * and thus aren't a constexpr but merely a const method.
 */
class MPRISServiceHandler final : public dom::MediaControlKeySource {
  NS_INLINE_DECL_REFCOUNTING(MPRISServiceHandler, override)
 public:
  // Note that this constructor does NOT initialize the MPRIS Service but only
  // this class. The method Open() is responsible for registering and MAY FAIL.

  // The image format used in MPRIS is based on the mMimeType here. Although
  // IMAGE_JPEG or IMAGE_BMP are valid types as well but a png image with
  // transparent background will be converted into a jpeg/bmp file with a
  // colored background IMAGE_PNG format seems to be the best choice for now.
  MPRISServiceHandler() : mMimeType(IMAGE_PNG){};
  bool Open() override;
  void Close() override;
  bool IsOpened() const override;

  // From the EventSource.
  void SetPlaybackState(dom::MediaSessionPlaybackState aState) override;

  // GetPlaybackState returns dom::PlaybackState. GetPlaybackStatus returns this
  // state converted into d-bus variants.
  GVariant* GetPlaybackStatus() const;

  const char* Identity() const;
  const char* DesktopEntry() const;
  bool PressKey(dom::MediaControlKey aKey) const;

  void SetMediaMetadata(const dom::MediaMetadataBase& aMetadata) override;
  GVariant* GetMetadataAsGVariant() const;

  void SetSupportedMediaKeys(const MediaKeysArray& aSupportedKeys) override;

  bool IsMediaKeySupported(dom::MediaControlKey aKey) const;

 private:
  ~MPRISServiceHandler();

  // Note: Registration Ids for the D-Bus start with 1, so a value of 0
  // indicates an error (or an object which wasn't initialized yet)

  // a handle to our bus registration/ownership
  guint mOwnerId = 0;
  // This is for the interface org.mpris.MediaPlayer2
  guint mRootRegistrationId = 0;
  // This is for the interface org.mpris.MediaPlayer2.Player
  guint mPlayerRegistrationId = 0;
  GDBusNodeInfo* mIntrospectionData = nullptr;
  GDBusConnection* mConnection = nullptr;
  bool mInitialized = false;
  nsAutoCString mIdentity;
  nsAutoCString mDesktopEntry;

  nsCString mMimeType;

  // A bitmask indicating what keys are enabled
  uint32_t mSupportedKeys = 0;

  class MPRISMetadata : public dom::MediaMetadataBase {
   public:
    MPRISMetadata() = default;
    ~MPRISMetadata() = default;

    void UpdateFromMetadataBase(const dom::MediaMetadataBase& aMetadata) {
      mTitle = aMetadata.mTitle;
      mArtist = aMetadata.mArtist;
      mAlbum = aMetadata.mAlbum;
      mArtwork = aMetadata.mArtwork;
    }
    void Clear() {
      UpdateFromMetadataBase(MediaMetadataBase::EmptyData());
      mArtUrl.Truncate();
    }

    nsCString mArtUrl;
  };
  MPRISMetadata mMPRISMetadata;

  // The saved image file fetched from the URL
  nsCOMPtr mLocalImageFile;
  nsCOMPtr mLocalImageFolder;

  mozilla::UniquePtr mImageFetcher;
  mozilla::MozPromiseRequestHolder
      mImageFetchRequest;

  nsString mFetchingUrl;
  nsString mCurrentImageUrl;

  size_t mNextImageIndex = 0;

  // Load the image at index aIndex of the metadta's artwork to MPRIS
  // asynchronously
  void LoadImageAtIndex(const size_t aIndex);
  bool SetImageToDisplay(const char* aImageData, uint32_t aDataSize);

  bool RenewLocalImageFile(const char* aImageData, uint32_t aDataSize);
  bool InitLocalImageFile();
  bool InitLocalImageFolder();
  void RemoveAllLocalImages();
  bool LocalImageFolderExists();

  // Queries nsAppInfo to get the branded browser name and vendor
  void InitIdentity();

  // non-public API, called from events
  void OnNameAcquired(GDBusConnection* aConnection, const gchar* aName);
  void OnNameLost(GDBusConnection* aConnection, const gchar* aName);
  void OnBusAcquired(GDBusConnection* aConnection, const gchar* aName);

  static void OnNameAcquiredStatic(GDBusConnection* aConnection,
                                   const gchar* aName, gpointer aUserData);
  static void OnNameLostStatic(GDBusConnection* aConnection, const gchar* aName,
                               gpointer aUserData);
  static void OnBusAcquiredStatic(GDBusConnection* aConnection,
                                  const gchar* aName, gpointer aUserData);

  void EmitEvent(dom::MediaControlKey aKey) const;

  bool EmitMetadataChanged() const;

  void SetMediaMetadataInternal(const dom::MediaMetadataBase& aMetadata,
                                bool aClearArtUrl = true);

  bool EmitSupportedKeyChanged(mozilla::dom::MediaControlKey aKey,
                               bool aSupported) const;

  bool EmitPropertiesChangedSignal(GVariant* aParameters) const;

  void ClearMetadata();
};

}  // namespace widget
}  // namespace mozilla

Minimal test - lines (26, 185)

path: .spaces[0].spaces[0].metrics.mi.mi_visual_studio
old: 44.64642787057539
new: 26.60758131670808

path: .spaces[0].spaces[0].metrics.mi.mi_original
old: 76.34539165868391
new: 45.49896405157081

path: .spaces[0].spaces[0].metrics.mi.mi_sei
old: 48.67979284955358
new: 27.975068795388744

path: .spaces[0].spaces[0].metrics.loc.lloc
old: 21.0
new: 6.0

path: .spaces[0].spaces[0].metrics.loc.cloc
old: 1.0
new: 47.0

path: .spaces[0].spaces[0].metrics.loc.sloc
old: 33.0
new: 160.0

path: .spaces[0].spaces[0].metrics.loc.ploc
old: 33.0
new: 81.0

path: .spaces[0].spaces[0].metrics.loc.blank
old: 0.0
new: 32.0

path: .spaces[0].spaces[0].metrics.halstead.length
old: 177.0
new: 421.0

path: .spaces[0].spaces[0].metrics.halstead.n1
old: 22.0
new: 15.0

path: .spaces[0].spaces[0].metrics.halstead.volume
old: 1004.0192855289548
new: 2892.4235469446135

path: .spaces[0].spaces[0].metrics.halstead.bugs
old: 0.2860218406266799
new: 0.36589640199112927

path: .spaces[0].spaces[0].metrics.halstead.vocabulary
old: 51.0
new: 117.0

path: .spaces[0].spaces[0].metrics.halstead.N2
old: 66.0
new: 171.0

path: .spaces[0].spaces[0].metrics.halstead.difficulty
old: 25.03448275862069
new: 12.573529411764708

path: .spaces[0].spaces[0].metrics.halstead.effort
old: 25135.10349289728
new: 36367.97253878889

path: .spaces[0].spaces[0].metrics.halstead.estimated_program_length
old: 238.9889444687201
new: 739.1907438152202

path: .spaces[0].spaces[0].metrics.halstead.purity_ratio
old: 1.3502200252470062
new: 1.755797491247554

path: .spaces[0].spaces[0].metrics.halstead.time
old: 1396.3946384942933
new: 2020.442918821605

path: .spaces[0].spaces[0].metrics.halstead.level
old: 0.03994490358126722
new: 0.07953216374269005

path: .spaces[0].spaces[0].metrics.halstead.n2
old: 29.0
new: 102.0

path: .spaces[0].spaces[0].metrics.halstead.N1
old: 111.0
new: 250.0

path: .spaces[0].spaces[0].metrics.cyclomatic.average
old: 9.0
new: 1.0

path: .spaces[0].spaces[0].metrics.cyclomatic.sum
old: 9.0
new: 8.0

path: .spaces[0].spaces[0].metrics.nom.functions
old: 1.0
new: 5.0

path: .spaces[0].spaces[0].metrics.nom.total
old: 1.0
new: 5.0

path: .spaces[0].spaces[0].metrics.cognitive.average
old: 13.0
new: 0.0

path: .spaces[0].spaces[0].metrics.cognitive.sum
old: 13.0
new: 0.0

path: .spaces[0].spaces[0].metrics.nexits.average
old: 4.0
new: 0.0

path: .spaces[0].spaces[0].metrics.nexits.sum
old: 4.0
new: 0.0

path: .spaces[0].spaces[0].metrics.nargs.sum
old: 2.0
new: 1.0

path: .spaces[0].spaces[0].metrics.nargs.average
old: 2.0
new: 0.2

Code

namespace widget {

/**
 * This class implements the "MPRIS" D-Bus Service
 * (https://specifications.freedesktop.org/mpris-spec/2.2),
 * which is used to communicate with the Desktop Environment about the
 * Multimedia playing in Gecko.
 * Note that this interface requires many methods which may not be supported by
 * Gecko, the interface
 * however provides CanXYZ properties for these methods, so the method is
 * defined but won't be executed.
 *
 * Also note that the following defines are for parts that the MPRIS Spec
 * defines optional. The code won't
 * compile with any of the defines set, yet, as those aren't implemented yet and
 * probably never will be of
 * use for gecko. For sake of completeness, they have been added until the
 * decision about their implementation
 * is finally made.
 *
 * The constexpr'ed methods are capabilities of the user agent known at compile
 * time, e.g. we decided at
 * compile time whether we ever want to support closing the user agent via MPRIS
 * (Quit() and CanQuit()).
 *
 * Other properties like CanPlay() might depend on the runtime state (is there
 * media available for playback?)
 * and thus aren't a constexpr but merely a const method.
 */
class MPRISServiceHandler final : public dom::MediaControlKeySource {
  NS_INLINE_DECL_REFCOUNTING(MPRISServiceHandler, override)
 public:
  // Note that this constructor does NOT initialize the MPRIS Service but only
  // this class. The method Open() is responsible for registering and MAY FAIL.

  // The image format used in MPRIS is based on the mMimeType here. Although
  // IMAGE_JPEG or IMAGE_BMP are valid types as well but a png image with
  // transparent background will be converted into a jpeg/bmp file with a
  // colored background IMAGE_PNG format seems to be the best choice for now.
  MPRISServiceHandler() : mMimeType(IMAGE_PNG){};
  bool Open() override;
  void Close() override;
  bool IsOpened() const override;

  // From the EventSource.
  void SetPlaybackState(dom::MediaSessionPlaybackState aState) override;

  // GetPlaybackState returns dom::PlaybackState. GetPlaybackStatus returns this
  // state converted into d-bus variants.
  GVariant* GetPlaybackStatus() const;

  const char* Identity() const;
  const char* DesktopEntry() const;
  bool PressKey(dom::MediaControlKey aKey) const;

  void SetMediaMetadata(const dom::MediaMetadataBase& aMetadata) override;
  GVariant* GetMetadataAsGVariant() const;

  void SetSupportedMediaKeys(const MediaKeysArray& aSupportedKeys) override;

  bool IsMediaKeySupported(dom::MediaControlKey aKey) const;

 private:
  ~MPRISServiceHandler();

  // Note: Registration Ids for the D-Bus start with 1, so a value of 0
  // indicates an error (or an object which wasn't initialized yet)

  // a handle to our bus registration/ownership
  guint mOwnerId = 0;
  // This is for the interface org.mpris.MediaPlayer2
  guint mRootRegistrationId = 0;
  // This is for the interface org.mpris.MediaPlayer2.Player
  guint mPlayerRegistrationId = 0;
  GDBusNodeInfo* mIntrospectionData = nullptr;
  GDBusConnection* mConnection = nullptr;
  bool mInitialized = false;
  nsAutoCString mIdentity;
  nsAutoCString mDesktopEntry;

  nsCString mMimeType;

  // A bitmask indicating what keys are enabled
  uint32_t mSupportedKeys = 0;

  class MPRISMetadata : public dom::MediaMetadataBase {
   public:
    MPRISMetadata() = default;
    ~MPRISMetadata() = default;

    void UpdateFromMetadataBase(const dom::MediaMetadataBase& aMetadata) {
      mTitle = aMetadata.mTitle;
      mArtist = aMetadata.mArtist;
      mAlbum = aMetadata.mAlbum;
      mArtwork = aMetadata.mArtwork;
    }
    void Clear() {
      UpdateFromMetadataBase(MediaMetadataBase::EmptyData());
      mArtUrl.Truncate();
    }

    nsCString mArtUrl;
  };
  MPRISMetadata mMPRISMetadata;

  // The saved image file fetched from the URL
  nsCOMPtr mLocalImageFile;
  nsCOMPtr mLocalImageFolder;

  mozilla::UniquePtr mImageFetcher;
  mozilla::MozPromiseRequestHolder
      mImageFetchRequest;

  nsString mFetchingUrl;
  nsString mCurrentImageUrl;

  size_t mNextImageIndex = 0;

  // Load the image at index aIndex of the metadta's artwork to MPRIS
  // asynchronously
  void LoadImageAtIndex(const size_t aIndex);
  bool SetImageToDisplay(const char* aImageData, uint32_t aDataSize);

  bool RenewLocalImageFile(const char* aImageData, uint32_t aDataSize);
  bool InitLocalImageFile();
  bool InitLocalImageFolder();
  void RemoveAllLocalImages();
  bool LocalImageFolderExists();

  // Queries nsAppInfo to get the branded browser name and vendor
  void InitIdentity();

  // non-public API, called from events
  void OnNameAcquired(GDBusConnection* aConnection, const gchar* aName);
  void OnNameLost(GDBusConnection* aConnection, const gchar* aName);
  void OnBusAcquired(GDBusConnection* aConnection, const gchar* aName);

  static void OnNameAcquiredStatic(GDBusConnection* aConnection,
                                   const gchar* aName, gpointer aUserData);
  static void OnNameLostStatic(GDBusConnection* aConnection, const gchar* aName,
                               gpointer aUserData);
  static void OnBusAcquiredStatic(GDBusConnection* aConnection,
                                  const gchar* aName, gpointer aUserData);

  void EmitEvent(dom::MediaControlKey aKey) const;

  bool EmitMetadataChanged() const;

  void SetMediaMetadataInternal(const dom::MediaMetadataBase& aMetadata,
                                bool aClearArtUrl = true);

  bool EmitSupportedKeyChanged(mozilla::dom::MediaControlKey aKey,
                               bool aSupported) const;

  bool EmitPropertiesChangedSignal(GVariant* aParameters) const;

  void ClearMetadata();
};

}  // namespace widget