summaryrefslogtreecommitdiffstats
path: root/widget/windows/WindowsSMTCProvider.h
blob: 2f0d1f8344fbe0cb5a0dc8c600761fe492424c60 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 WIDGET_WINDOWS_WINDOWSSTMCPROVIDER_H_
#define WIDGET_WINDOWS_WINDOWSSTMCPROVIDER_H_

#ifndef __MINGW32__

#  include <functional>
#  include <Windows.Media.h>
#  include <wrl.h>

#  include "mozilla/dom/FetchImageHelper.h"
#  include "mozilla/dom/MediaController.h"
#  include "mozilla/dom/MediaControlKeySource.h"
#  include "mozilla/UniquePtr.h"

using ISMTC = ABI::Windows::Media::ISystemMediaTransportControls;
using SMTCProperty = ABI::Windows::Media::SystemMediaTransportControlsProperty;
using ISMTCDisplayUpdater =
    ABI::Windows::Media::ISystemMediaTransportControlsDisplayUpdater;

using ABI::Windows::Foundation::IAsyncOperation;
using ABI::Windows::Storage::Streams::IDataWriter;
using ABI::Windows::Storage::Streams::IRandomAccessStream;
using ABI::Windows::Storage::Streams::IRandomAccessStreamReference;
using Microsoft::WRL::ComPtr;

class WindowsSMTCProvider final : public mozilla::dom::MediaControlKeySource {
  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WindowsSMTCProvider, override)

 public:
  WindowsSMTCProvider();

  bool IsOpened() const override;
  bool Open() override;
  void Close() override;

  void SetPlaybackState(
      mozilla::dom::MediaSessionPlaybackState aState) override;

  void SetMediaMetadata(
      const mozilla::dom::MediaMetadataBase& aMetadata) override;

  void SetSupportedMediaKeys(const MediaKeysArray& aSupportedKeys) override;

  void SetPositionState(
      const mozilla::Maybe<mozilla::dom::PositionState>& aState) override;

 private:
  ~WindowsSMTCProvider();
  void UnregisterEvents();
  bool RegisterEvents();

  void OnButtonPressed(mozilla::dom::MediaControlKey aKey) const;
  // Enable the SMTC interface
  bool EnableControl(bool aEnabled) const;
  // Sets the play, pause, next, previous, seekto buttons on the SMTC interface
  // by mSupportedKeys
  bool UpdateButtons();
  bool IsKeySupported(mozilla::dom::MediaControlKey aKey) const;
  bool EnableKey(mozilla::dom::MediaControlKey aKey, bool aEnable) const;

  void OnPositionChangeRequested(double aPosition) const;

  bool InitDisplayAndControls();

  // Sets the Metadata for the currently playing media and sets the playback
  // type to "MUSIC"
  bool SetMusicMetadata(const nsString& aArtist, const nsString& aTitle);

  // Sets one of the artwork to the SMTC interface asynchronously
  void LoadThumbnail(const nsTArray<mozilla::dom::MediaImage>& aArtwork);
  // Stores the image at index aIndex of the mArtwork to the Thumbnail
  // asynchronously
  void LoadImageAtIndex(const size_t aIndex);
  // Stores the raw binary data of an image to mImageStream and set it to the
  // Thumbnail asynchronously
  void LoadImage(const char* aImageData, uint32_t aDataSize);
  // Sets the Thumbnail to the image stored in mImageStream
  bool SetThumbnail(const nsAString& aUrl);
  void ClearThumbnail();

  bool UpdateThumbnail(const nsAString& aUrl);
  void CancelPendingStoreAsyncOperation() const;

  void ClearMetadata();

  bool mInitialized = false;

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

  ComPtr<ISMTC> mControls;
  ComPtr<ISMTCDisplayUpdater> mDisplay;

  // Use mImageDataWriter to write the binary data of image into mImageStream
  // and refer the image by mImageStreamReference and then set it to the SMTC
  // interface
  ComPtr<IDataWriter> mImageDataWriter;
  ComPtr<IRandomAccessStream> mImageStream;
  ComPtr<IRandomAccessStreamReference> mImageStreamReference;
  ComPtr<IAsyncOperation<unsigned int>> mStoreAsyncOperation;

  // mThumbnailUrl is the url of the current Thumbnail
  // mProcessingUrl is the url that is being processed. The process starts from
  // fetching an image from the url and then storing the fetched image to the
  // mImageStream. If mProcessingUrl is not empty, it means there is an image is
  // in processing
  // mThumbnailUrl and mProcessingUrl won't be set at the same time and they can
  // only be touched on main thread
  nsString mThumbnailUrl;
  nsString mProcessingUrl;

  // mArtwork can only be used in main thread in case of data racing
  CopyableTArray<mozilla::dom::MediaImage> mArtwork;
  size_t mNextImageIndex;

  mozilla::UniquePtr<mozilla::dom::FetchImageHelper> mImageFetcher;
  mozilla::MozPromiseRequestHolder<mozilla::dom::ImagePromise>
      mImageFetchRequest;

  HWND mWindow;  // handle to the invisible window

  // EventRegistrationTokens are used to have a handle on a callback (to remove
  // it again)
  EventRegistrationToken mButtonPressedToken;
  EventRegistrationToken mSeekRegistrationToken;
};

#endif  // __MINGW32__
#endif  // WIDGET_WINDOWS_WINDOWSSTMCPROVIDER_H_