1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
4  * You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 #include "AudioStreamTrack.h"
7 
8 #include "MediaTrackGraph.h"
9 #include "nsContentUtils.h"
10 
11 namespace mozilla::dom {
12 
AddAudioOutput(void * aKey)13 void AudioStreamTrack::AddAudioOutput(void* aKey) {
14   if (Ended()) {
15     return;
16   }
17   if (UniquePtr<CrossGraphPort>* cgm = mCrossGraphs.Get(aKey)) {
18     (*cgm)->AddAudioOutput(aKey);
19     return;
20   }
21   mTrack->AddAudioOutput(aKey);
22 }
23 
RemoveAudioOutput(void * aKey)24 void AudioStreamTrack::RemoveAudioOutput(void* aKey) {
25   if (Ended()) {
26     return;
27   }
28   if (UniquePtr<CrossGraphPort>* cgm = mCrossGraphs.Get(aKey)) {
29     (*cgm)->RemoveAudioOutput(aKey);
30     return;
31   }
32   mTrack->RemoveAudioOutput(aKey);
33 }
34 
SetAudioOutputVolume(void * aKey,float aVolume)35 void AudioStreamTrack::SetAudioOutputVolume(void* aKey, float aVolume) {
36   if (Ended()) {
37     return;
38   }
39   if (UniquePtr<CrossGraphPort>* cgm = mCrossGraphs.Get(aKey)) {
40     (*cgm)->SetAudioOutputVolume(aKey, aVolume);
41     return;
42   }
43   mTrack->SetAudioOutputVolume(aKey, aVolume);
44 }
45 
GetLabel(nsAString & aLabel,CallerType aCallerType)46 void AudioStreamTrack::GetLabel(nsAString& aLabel, CallerType aCallerType) {
47   if (nsContentUtils::ResistFingerprinting(aCallerType)) {
48     aLabel.AssignLiteral("Internal Microphone");
49     return;
50   }
51   MediaStreamTrack::GetLabel(aLabel, aCallerType);
52 }
53 
CloneInternal()54 already_AddRefed<MediaStreamTrack> AudioStreamTrack::CloneInternal() {
55   return do_AddRef(new AudioStreamTrack(mWindow, mInputTrack, mSource,
56                                         ReadyState(), Muted(), mConstraints));
57 }
58 
SetReadyState(MediaStreamTrackState aState)59 void AudioStreamTrack::SetReadyState(MediaStreamTrackState aState) {
60   if (!mCrossGraphs.IsEmpty() && !Ended() &&
61       mReadyState == MediaStreamTrackState::Live &&
62       aState == MediaStreamTrackState::Ended) {
63     for (const auto& data : mCrossGraphs.Values()) {
64       (*data)->Destroy();
65       data->reset();
66     }
67     mCrossGraphs.Clear();
68   }
69   MediaStreamTrack::SetReadyState(aState);
70 }
71 
SetAudioOutputDevice(void * key,AudioDeviceInfo * aSink)72 RefPtr<GenericPromise> AudioStreamTrack::SetAudioOutputDevice(
73     void* key, AudioDeviceInfo* aSink) {
74   MOZ_ASSERT(aSink);
75 
76   if (Ended()) {
77     return GenericPromise::CreateAndResolve(true, __func__);
78   }
79 
80   UniquePtr<CrossGraphPort> manager =
81       CrossGraphPort::Connect(this, aSink, mWindow);
82   if (!manager) {
83     // We are setting the default output device.
84     auto entry = mCrossGraphs.Lookup(key);
85     if (entry) {
86       // There is an existing non-default output device for this track. Remove
87       // it.
88       (*entry.Data())->Destroy();
89       entry.Remove();
90     }
91     return GenericPromise::CreateAndResolve(true, __func__);
92   }
93 
94   // We are setting a non-default output device.
95   UniquePtr<CrossGraphPort>& crossGraphPtr = *mCrossGraphs.GetOrInsertNew(key);
96   if (crossGraphPtr) {
97     // This key already has a non-default output device set. Destroy it.
98     crossGraphPtr->Destroy();
99   }
100 
101   crossGraphPtr = std::move(manager);
102   return crossGraphPtr->EnsureConnected();
103 }
104 
105 }  // namespace mozilla::dom
106