# 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