VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/AudioSettingsImpl.cpp@ 97648

Last change on this file since 97648 was 96407, checked in by vboxsync, 2 years ago

scm copyright and license note update

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.3 KB
Line 
1/* $Id: AudioSettingsImpl.cpp 96407 2022-08-22 17:43:14Z vboxsync $ */
2/** @file
3 * VirtualBox COM class implementation - Audio settings for a VM.
4 */
5
6/*
7 * Copyright (C) 2022 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28#define LOG_GROUP LOG_GROUP_MAIN_AUDIOSETTINGS
29#include "AudioSettingsImpl.h"
30#include "MachineImpl.h"
31
32#include <iprt/cpp/utils.h>
33
34#include <VBox/settings.h>
35
36#include "AutoStateDep.h"
37#include "AutoCaller.h"
38#include "LoggingNew.h"
39
40
41////////////////////////////////////////////////////////////////////////////////
42//
43// AudioSettings private data definition
44//
45////////////////////////////////////////////////////////////////////////////////
46
47struct AudioSettings::Data
48{
49 Data()
50 : pParent(NULL)
51 { }
52
53 Machine * const pParent;
54 const ComObjPtr<AudioAdapter> pAdapter;
55 const ComObjPtr<AudioSettings> pPeer;
56};
57
58DEFINE_EMPTY_CTOR_DTOR(AudioSettings)
59
60HRESULT AudioSettings::FinalConstruct()
61{
62 return BaseFinalConstruct();
63}
64
65void AudioSettings::FinalRelease()
66{
67 uninit();
68 BaseFinalRelease();
69}
70
71
72// public initializer/uninitializer for internal purposes only
73////////////////////////////////////////////////////////////////////////////////
74
75/**
76 * Initializes the audio settings object.
77 *
78 * @param aParent Handle of the parent object.
79 */
80HRESULT AudioSettings::init(Machine *aParent)
81{
82 LogFlowThisFunc(("aParent=%p\n", aParent));
83
84 ComAssertRet(aParent, E_INVALIDARG);
85
86 /* Enclose the state transition NotReady->InInit->Ready */
87 AutoInitSpan autoInitSpan(this);
88 AssertReturn(autoInitSpan.isOk(), E_FAIL);
89
90 m = new Data();
91
92 /* share the parent weakly */
93 unconst(m->pParent) = aParent;
94
95 /* create the audio adapter object (always present, default is disabled) */
96 unconst(m->pAdapter).createObject();
97 m->pAdapter->init(this);
98
99 /* Confirm a successful initialization */
100 autoInitSpan.setSucceeded();
101
102 return S_OK;
103}
104
105/**
106 * Initializes the audio settings object given another audio settings object
107 * (a kind of copy constructor). This object shares data with
108 * the object passed as an argument.
109 *
110 * @note This object must be destroyed before the original object
111 * it shares data with is destroyed.
112 *
113 * @note Locks @a aThat object for reading.
114 */
115HRESULT AudioSettings::init(Machine *aParent, AudioSettings *aThat)
116{
117 LogFlowThisFuncEnter();
118 LogFlowThisFunc(("aParent: %p, aThat: %p\n", aParent, aThat));
119
120 ComAssertRet(aParent && aThat, E_INVALIDARG);
121
122 /* Enclose the state transition NotReady->InInit->Ready */
123 AutoInitSpan autoInitSpan(this);
124 AssertReturn(autoInitSpan.isOk(), E_FAIL);
125
126 m = new Data();
127
128 unconst(m->pParent) = aParent;
129 unconst(m->pPeer) = aThat;
130
131 AutoCaller thatCaller(aThat);
132 AssertComRCReturnRC(thatCaller.rc());
133
134 AutoReadLock thatlock(aThat COMMA_LOCKVAL_SRC_POS);
135
136 unconst(m->pAdapter) = aThat->m->pAdapter;
137
138 autoInitSpan.setSucceeded();
139
140 LogFlowThisFuncLeave();
141 return S_OK;
142}
143
144/**
145 * Initializes the guest object given another guest object
146 * (a kind of copy constructor). This object makes a private copy of data
147 * of the original object passed as an argument.
148 *
149 * @note Locks @a aThat object for reading.
150 */
151HRESULT AudioSettings::initCopy(Machine *aParent, AudioSettings *aThat)
152{
153 LogFlowThisFuncEnter();
154 LogFlowThisFunc(("aParent: %p, aThat: %p\n", aParent, aThat));
155
156 ComAssertRet(aParent && aThat, E_INVALIDARG);
157
158 /* Enclose the state transition NotReady->InInit->Ready */
159 AutoInitSpan autoInitSpan(this);
160 AssertReturn(autoInitSpan.isOk(), E_FAIL);
161
162 m = new Data();
163
164 unconst(m->pParent) = aParent;
165 // pPeer is left null
166
167 AutoReadLock thatlock(aThat COMMA_LOCKVAL_SRC_POS);
168
169 HRESULT hrc = unconst(m->pAdapter).createObject();
170 ComAssertComRCRet(hrc, hrc);
171 hrc = m->pAdapter->init(this);
172 ComAssertComRCRet(hrc, hrc);
173 m->pAdapter->i_copyFrom(aThat->m->pAdapter);
174
175 autoInitSpan.setSucceeded();
176
177 LogFlowThisFuncLeave();
178 return S_OK;
179}
180
181/**
182 * Uninitializes the instance and sets the ready flag to FALSE.
183 * Called either from FinalRelease() or by the parent when it gets destroyed.
184 */
185void AudioSettings::uninit(void)
186{
187 LogFlowThisFunc(("\n"));
188
189 /* Enclose the state transition Ready->InUninit->NotReady */
190 AutoUninitSpan autoUninitSpan(this);
191 if (autoUninitSpan.uninitDone())
192 return;
193
194 delete m;
195 m = NULL;
196}
197
198
199// IAudioSettings properties
200////////////////////////////////////////////////////////////////////////////////
201
202HRESULT AudioSettings::getAdapter(ComPtr<IAudioAdapter> &aAdapter)
203{
204 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
205
206 aAdapter = m->pAdapter;
207
208 return S_OK;
209}
210
211
212// IAudioSettings methods
213////////////////////////////////////////////////////////////////////////////////
214
215HRESULT AudioSettings::getHostAudioDevice(AudioDirection_T aUsage, ComPtr<IHostAudioDevice> &aDevice)
216{
217 RT_NOREF(aUsage, aDevice);
218 ReturnComNotImplemented();
219}
220
221HRESULT AudioSettings::setHostAudioDevice(const ComPtr<IHostAudioDevice> &aDevice, AudioDirection_T aUsage)
222{
223 RT_NOREF(aDevice, aUsage);
224 ReturnComNotImplemented();
225}
226
227
228// public methods only for internal purposes
229////////////////////////////////////////////////////////////////////////////////
230
231/**
232 * Returns the parent object as a weak pointer.
233 */
234Machine* AudioSettings::i_getParent(void)
235{
236 AutoCaller autoCaller(this);
237 AssertComRCReturn(autoCaller.rc(), NULL);
238
239 AssertPtrReturn(m, NULL);
240 return m->pParent;
241}
242
243/**
244 * Determines whether the audio settings currently can be changed or not.
245 *
246 * @returns \c true if the settings can be changed, \c false if not.
247 */
248bool AudioSettings::i_canChangeSettings(void)
249{
250 AutoAnyStateDependency adep(m->pParent);
251 if (FAILED(adep.rc()))
252 return false;
253
254 /** @todo Do some more checks here? */
255 return true;
256}
257
258/**
259 * Gets called when the machine object needs to know that audio adapter settings
260 * have been changed.
261 */
262void AudioSettings::i_onAdapterChanged(IAudioAdapter *pAdapter)
263{
264 LogFlowThisFuncEnter();
265
266 AssertPtrReturnVoid(pAdapter);
267
268 m->pParent->i_onAudioAdapterChange(pAdapter); // mParent is const, needs no locking
269
270 LogFlowThisFuncLeave();
271}
272
273/**
274 * Gets called when the machine object needs to know that a host audio device
275 * has been changed.
276 */
277void AudioSettings::i_onHostDeviceChanged(IHostAudioDevice *pDevice,
278 bool fIsNew, AudioDeviceState_T enmState, IVirtualBoxErrorInfo *pErrInfo)
279{
280 LogFlowThisFuncEnter();
281
282 AssertPtrReturnVoid(pDevice);
283
284 m->pParent->i_onHostAudioDeviceChange(pDevice, fIsNew, enmState, pErrInfo); // mParent is const, needs no locking
285
286 LogFlowThisFuncLeave();
287}
288
289/**
290 * Gets called when the machine object needs to know that the audio settings
291 * have been changed.
292 */
293void AudioSettings::i_onSettingsChanged(void)
294{
295 LogFlowThisFuncEnter();
296
297 AutoWriteLock mlock(m->pParent COMMA_LOCKVAL_SRC_POS);
298 m->pParent->i_setModified(Machine::IsModified_AudioSettings);
299 mlock.release();
300
301 LogFlowThisFuncLeave();
302}
303
304/**
305 * Loads settings from the given machine node.
306 * May be called once right after this object creation.
307 *
308 * @param data Configuration settings.
309 *
310 * @note Locks this object for writing.
311 */
312HRESULT AudioSettings::i_loadSettings(const settings::AudioAdapter &data)
313{
314 AutoCaller autoCaller(this);
315 AssertComRCReturnRC(autoCaller.rc());
316
317 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
318
319 m->pAdapter->i_loadSettings(data);
320
321 /* Note: The host audio device selection is run-time only, e.g. won't be serialized in the settings! */
322 return S_OK;
323}
324
325/**
326 * Saves settings to the given node.
327 *
328 * @param data Configuration settings.
329 *
330 * @note Locks this object for reading.
331 */
332HRESULT AudioSettings::i_saveSettings(settings::AudioAdapter &data)
333{
334 AutoCaller autoCaller(this);
335 AssertComRCReturnRC(autoCaller.rc());
336
337 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
338
339 m->pAdapter->i_saveSettings(data);
340
341 /* Note: The host audio device selection is run-time only, e.g. won't be serialized in the settings! */
342 return S_OK;
343}
344
345/**
346 * @note Locks this object for writing, together with the peer object
347 * represented by @a aThat (locked for reading).
348 */
349void AudioSettings::i_copyFrom(AudioSettings *aThat)
350{
351 AssertReturnVoid(aThat != NULL);
352
353 /* sanity */
354 AutoCaller autoCaller(this);
355 AssertComRCReturnVoid(autoCaller.rc());
356
357 /* sanity too */
358 AutoCaller thatCaller(aThat);
359 AssertComRCReturnVoid(thatCaller.rc());
360
361 /* peer is not modified, lock it for reading (aThat is "master" so locked
362 * first) */
363 AutoReadLock rl(aThat COMMA_LOCKVAL_SRC_POS);
364 AutoWriteLock wl(this COMMA_LOCKVAL_SRC_POS);
365
366 m->pAdapter->i_copyFrom(aThat->m->pAdapter);
367}
368
369/**
370 * Applies default audio settings, based on the given guest OS type.
371 *
372 * @returns HRESULT
373 * @param aGuestOsType Guest OS type to use for basing the default settings on.
374 */
375HRESULT AudioSettings::i_applyDefaults(ComObjPtr<GuestOSType> &aGuestOsType)
376{
377 AutoCaller autoCaller(this);
378 AssertComRCReturnRC(autoCaller.rc());
379
380 AudioControllerType_T audioController;
381 HRESULT rc = aGuestOsType->COMGETTER(RecommendedAudioController)(&audioController);
382 if (FAILED(rc)) return rc;
383
384 rc = m->pAdapter->COMSETTER(AudioController)(audioController);
385 if (FAILED(rc)) return rc;
386
387 AudioCodecType_T audioCodec;
388 rc = aGuestOsType->COMGETTER(RecommendedAudioCodec)(&audioCodec);
389 if (FAILED(rc)) return rc;
390
391 rc = m->pAdapter->COMSETTER(AudioCodec)(audioCodec);
392 if (FAILED(rc)) return rc;
393
394 rc = m->pAdapter->COMSETTER(Enabled)(true);
395 if (FAILED(rc)) return rc;
396
397 rc = m->pAdapter->COMSETTER(EnabledOut)(true);
398 if (FAILED(rc)) return rc;
399
400 /* Note: We do NOT enable audio input by default due to security reasons!
401 * This always has to be done by the user manually. */
402
403 /* Note: Does not touch the host audio device selection, as this is a run-time only setting. */
404 return S_OK;
405}
406
407/**
408 * @note Locks this object for writing.
409 */
410void AudioSettings::i_rollback(void)
411{
412 /* sanity */
413 AutoCaller autoCaller(this);
414 AssertComRCReturnVoid(autoCaller.rc());
415
416 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
417
418 m->pAdapter->i_rollback();
419
420 /* Note: Does not touch the host audio device selection, as this is a run-time only setting. */
421}
422
423/**
424 * @note Locks this object for writing, together with the peer object (also
425 * for writing) if there is one.
426 */
427void AudioSettings::i_commit(void)
428{
429 /* sanity */
430 AutoCaller autoCaller(this);
431 AssertComRCReturnVoid(autoCaller.rc());
432
433 m->pAdapter->i_commit();
434
435 /* Note: Does not touch the host audio device selection, as this is a run-time only setting. */
436}
437
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette