VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/AudioAdapterImpl.cpp@ 55436

Last change on this file since 55436 was 55401, checked in by vboxsync, 10 years ago

added a couple of missing Id headers

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.0 KB
Line 
1/* $Id: AudioAdapterImpl.cpp 55401 2015-04-23 10:03:17Z vboxsync $ */
2/** @file
3 *
4 * VirtualBox COM class implementation
5 */
6
7/*
8 * Copyright (C) 2006-2015 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19#include "AudioAdapterImpl.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 "Logging.h"
29
30struct AudioAdapterData
31{
32 AudioAdapterData() :
33 mEnabled(false),
34 mAudioDriver(AudioDriverType_Null),
35 mAudioController(AudioControllerType_AC97)
36 {}
37
38 BOOL mEnabled;
39 AudioDriverType_T mAudioDriver;
40 AudioControllerType_T mAudioController;
41};
42
43struct AudioAdapter::Data
44{
45 Backupable<AudioAdapterData> m;
46};
47
48// constructor / destructor
49/////////////////////////////////////////////////////////////////////////////
50
51AudioAdapter::AudioAdapter()
52 : mParent(NULL),
53 mData(NULL)
54{
55}
56
57AudioAdapter::~AudioAdapter()
58{
59}
60
61HRESULT AudioAdapter::FinalConstruct()
62{
63 return BaseFinalConstruct();
64}
65
66void AudioAdapter::FinalRelease()
67{
68 uninit();
69 BaseFinalRelease();
70}
71
72// public initializer/uninitializer for internal purposes only
73/////////////////////////////////////////////////////////////////////////////
74
75/**
76 * Initializes the audio adapter object.
77 *
78 * @param aParent Handle of the parent object.
79 */
80HRESULT AudioAdapter::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 /* Get the default audio driver out of the system properties */
91 ComPtr<IVirtualBox> VBox;
92 HRESULT rc = aParent->COMGETTER(Parent)(VBox.asOutParam());
93 if (FAILED(rc)) return rc;
94 ComPtr<ISystemProperties> sysProps;
95 rc = VBox->COMGETTER(SystemProperties)(sysProps.asOutParam());
96 if (FAILED(rc)) return rc;
97 AudioDriverType_T defaultAudioDriver;
98 rc = sysProps->COMGETTER(DefaultAudioDriver)(&defaultAudioDriver);
99 if (FAILED(rc)) return rc;
100
101 unconst(mParent) = aParent;
102 /* mPeer is left null */
103
104 mData = new Data();
105 mData->m.allocate();
106 mData->m->mAudioDriver = defaultAudioDriver;
107
108 /* Confirm a successful initialization */
109 autoInitSpan.setSucceeded();
110
111 return S_OK;
112}
113
114/**
115 * Initializes the audio adapter object given another audio adapter object
116 * (a kind of copy constructor). This object shares data with
117 * the object passed as an argument.
118 *
119 * @note This object must be destroyed before the original object
120 * it shares data with is destroyed.
121 *
122 * @note Locks @a aThat object for reading.
123 */
124HRESULT AudioAdapter::init (Machine *aParent, AudioAdapter *aThat)
125{
126 LogFlowThisFunc(("aParent=%p, aThat=%p\n", aParent, aThat));
127
128 ComAssertRet(aParent && aThat, E_INVALIDARG);
129
130 /* Enclose the state transition NotReady->InInit->Ready */
131 AutoInitSpan autoInitSpan(this);
132 AssertReturn(autoInitSpan.isOk(), E_FAIL);
133
134 unconst(mParent) = aParent;
135 unconst(mPeer) = aThat;
136
137 AutoCaller thatCaller (aThat);
138 AssertComRCReturnRC(thatCaller.rc());
139
140 AutoReadLock thatLock(aThat COMMA_LOCKVAL_SRC_POS);
141 mData = new Data();
142 mData->m.share (aThat->mData->m);
143
144 /* Confirm a successful initialization */
145 autoInitSpan.setSucceeded();
146
147 return S_OK;
148}
149
150/**
151 * Initializes the guest object given another guest object
152 * (a kind of copy constructor). This object makes a private copy of data
153 * of the original object passed as an argument.
154 *
155 * @note Locks @a aThat object for reading.
156 */
157HRESULT AudioAdapter::initCopy (Machine *aParent, AudioAdapter *aThat)
158{
159 LogFlowThisFunc(("aParent=%p, aThat=%p\n", aParent, aThat));
160
161 ComAssertRet(aParent && aThat, E_INVALIDARG);
162
163 /* Enclose the state transition NotReady->InInit->Ready */
164 AutoInitSpan autoInitSpan(this);
165 AssertReturn(autoInitSpan.isOk(), E_FAIL);
166
167 unconst(mParent) = aParent;
168 /* mPeer is left null */
169
170 AutoCaller thatCaller (aThat);
171 AssertComRCReturnRC(thatCaller.rc());
172
173 AutoReadLock thatLock(aThat COMMA_LOCKVAL_SRC_POS);
174 mData = new Data();
175 mData->m.attachCopy (aThat->mData->m);
176
177 /* Confirm a successful initialization */
178 autoInitSpan.setSucceeded();
179
180 return S_OK;
181}
182
183/**
184 * Uninitializes the instance and sets the ready flag to FALSE.
185 * Called either from FinalRelease() or by the parent when it gets destroyed.
186 */
187void AudioAdapter::uninit()
188{
189 LogFlowThisFunc(("\n"));
190
191 /* Enclose the state transition Ready->InUninit->NotReady */
192 AutoUninitSpan autoUninitSpan(this);
193 if (autoUninitSpan.uninitDone())
194 return;
195
196 mData->m.free();
197 delete mData;
198 mData = NULL;
199
200 unconst(mPeer) = NULL;
201 unconst(mParent) = NULL;
202}
203
204// IAudioAdapter properties
205/////////////////////////////////////////////////////////////////////////////
206
207HRESULT AudioAdapter::getEnabled(BOOL *aEnabled)
208{
209 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
210
211 *aEnabled = mData->m->mEnabled;
212
213 return S_OK;
214}
215
216HRESULT AudioAdapter::setEnabled(BOOL aEnabled)
217{
218 /* the machine needs to be mutable */
219 AutoMutableStateDependency adep(mParent);
220 if (FAILED(adep.rc())) return adep.rc();
221
222 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
223
224 if (mData->m->mEnabled != aEnabled)
225 {
226 mData->m.backup();
227 mData->m->mEnabled = aEnabled;
228
229 alock.release();
230 AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS); // mParent is const, needs no locking
231 mParent->i_setModified(Machine::IsModified_AudioAdapter);
232 }
233
234 return S_OK;
235}
236
237HRESULT AudioAdapter::getAudioDriver(AudioDriverType_T *aAudioDriver)
238{
239 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
240
241 *aAudioDriver = mData->m->mAudioDriver;
242
243 return S_OK;
244}
245
246HRESULT AudioAdapter::setAudioDriver(AudioDriverType_T aAudioDriver)
247{
248
249 /* the machine needs to be mutable */
250 AutoMutableOrSavedStateDependency adep(mParent);
251 if (FAILED(adep.rc())) return adep.rc();
252
253 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
254
255 HRESULT rc = S_OK;
256
257 if (mData->m->mAudioDriver != aAudioDriver)
258 {
259 if (settings::MachineConfigFile::isAudioDriverAllowedOnThisHost(aAudioDriver))
260 {
261 mData->m.backup();
262 mData->m->mAudioDriver = aAudioDriver;
263 alock.release();
264 AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS); // mParent is const, needs no locking
265 mParent->i_setModified(Machine::IsModified_AudioAdapter);
266 }
267 else
268 {
269 AssertMsgFailed(("Wrong audio driver type %d\n", aAudioDriver));
270 rc = E_FAIL;
271 }
272 }
273
274 return rc;
275}
276
277HRESULT AudioAdapter::getAudioController(AudioControllerType_T *aAudioController)
278{
279 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
280
281 *aAudioController = mData->m->mAudioController;
282
283 return S_OK;
284}
285
286HRESULT AudioAdapter::setAudioController(AudioControllerType_T aAudioController)
287{
288 /* the machine needs to be mutable */
289 AutoMutableStateDependency adep(mParent);
290 if (FAILED(adep.rc())) return adep.rc();
291
292 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
293
294 HRESULT rc = S_OK;
295
296 if (mData->m->mAudioController != aAudioController)
297 {
298 /*
299 * which audio hardware type are we supposed to use?
300 */
301 switch (aAudioController)
302 {
303 case AudioControllerType_AC97:
304 case AudioControllerType_SB16:
305 case AudioControllerType_HDA:
306 {
307 mData->m.backup();
308 mData->m->mAudioController = aAudioController;
309 alock.release();
310 AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS); // mParent is const, needs no locking
311 mParent->i_setModified(Machine::IsModified_AudioAdapter);
312 break;
313 }
314
315 default:
316 AssertMsgFailed (("Wrong audio controller type %d\n",
317 aAudioController));
318 rc = E_FAIL;
319 }
320 }
321
322 return rc;
323}
324
325// IAudioAdapter methods
326/////////////////////////////////////////////////////////////////////////////
327
328// public methods only for internal purposes
329/////////////////////////////////////////////////////////////////////////////
330
331/**
332 * Loads settings from the given machine node.
333 * May be called once right after this object creation.
334 *
335 * @param aMachineNode <Machine> node.
336 *
337 * @note Locks this object for writing.
338 */
339HRESULT AudioAdapter::i_loadSettings(const settings::AudioAdapter &data)
340{
341 AutoCaller autoCaller(this);
342 AssertComRCReturnRC(autoCaller.rc());
343
344 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
345
346 /* Note: we assume that the default values for attributes of optional
347 * nodes are assigned in the Data::Data() constructor and don't do it
348 * here. It implies that this method may only be called after constructing
349 * a new AudioAdapter object while all its data fields are in the default
350 * values. Exceptions are fields whose creation time defaults don't match
351 * values that should be applied when these fields are not explicitly set
352 * in the settings file (for backwards compatibility reasons). This takes
353 * place when a setting of a newly created object must default to A while
354 * the same setting of an object loaded from the old settings file must
355 * default to B. */
356
357 mData->m->mEnabled = data.fEnabled;
358 mData->m->mAudioController = data.controllerType;
359 mData->m->mAudioDriver = data.driverType;
360
361 return S_OK;
362}
363
364/**
365 * Saves settings to the given machine node.
366 *
367 * @param aMachineNode <Machine> node.
368 *
369 * @note Locks this object for reading.
370 */
371HRESULT AudioAdapter::i_saveSettings(settings::AudioAdapter &data)
372{
373 AutoCaller autoCaller(this);
374 AssertComRCReturnRC(autoCaller.rc());
375
376 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
377
378 data.fEnabled = !!mData->m->mEnabled;
379 data.controllerType = mData->m->mAudioController;
380 data.driverType = mData->m->mAudioDriver;
381 return S_OK;
382}
383
384/**
385 * @note Locks this object for writing.
386 */
387void AudioAdapter::i_rollback()
388{
389 /* sanity */
390 AutoCaller autoCaller(this);
391 AssertComRCReturnVoid(autoCaller.rc());
392
393 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
394
395 mData->m.rollback();
396}
397
398/**
399 * @note Locks this object for writing, together with the peer object (also
400 * for writing) if there is one.
401 */
402void AudioAdapter::i_commit()
403{
404 /* sanity */
405 AutoCaller autoCaller(this);
406 AssertComRCReturnVoid (autoCaller.rc());
407
408 /* sanity too */
409 AutoCaller peerCaller (mPeer);
410 AssertComRCReturnVoid (peerCaller.rc());
411
412 /* lock both for writing since we modify both (mPeer is "master" so locked
413 * first) */
414 AutoMultiWriteLock2 alock(mPeer, this COMMA_LOCKVAL_SRC_POS);
415
416 if (mData->m.isBackedUp())
417 {
418 mData->m.commit();
419 if (mPeer)
420 {
421 /* attach new data to the peer and reshare it */
422 mPeer->mData->m.attach (mData->m);
423 }
424 }
425}
426
427/**
428 * @note Locks this object for writing, together with the peer object
429 * represented by @a aThat (locked for reading).
430 */
431void AudioAdapter::i_copyFrom(AudioAdapter *aThat)
432{
433 AssertReturnVoid (aThat != NULL);
434
435 /* sanity */
436 AutoCaller autoCaller(this);
437 AssertComRCReturnVoid (autoCaller.rc());
438
439 /* sanity too */
440 AutoCaller thatCaller (aThat);
441 AssertComRCReturnVoid (thatCaller.rc());
442
443 /* peer is not modified, lock it for reading (aThat is "master" so locked
444 * first) */
445 AutoReadLock rl(aThat COMMA_LOCKVAL_SRC_POS);
446 AutoWriteLock wl(this COMMA_LOCKVAL_SRC_POS);
447
448 /* this will back up current data */
449 mData->m.assignCopy(aThat->mData->m);
450}
451/* vi: set tabstop=4 shiftwidth=4 expandtab: */
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