VirtualBox

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

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

Audio/Main: Renaming (HRESULT hr -> hrc). bugref:10050

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