* MultiAudioAddOn::_RecursiveScan() now checks the depth of the recursion,

and bails out early.
* InitCheck() now actually returns an error if something went wrong during
  initialization.
* Cleanup, part III.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24627 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2008-03-28 16:46:05 +00:00
parent d5420ddccc
commit f89d079f4e
4 changed files with 152 additions and 164 deletions
@@ -3,29 +3,28 @@
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#include <MediaDefs.h>
#include <MediaAddOn.h>
#include <Errors.h>
#include <Node.h>
#include <Mime.h>
#include <StorageDefs.h>
#include <Path.h>
#include <Directory.h>
#include <Entry.h>
#include <FindDirectory.h>
#include "MultiAudioNode.h"
#include "MultiAudioAddOn.h" #include "MultiAudioAddOn.h"
#include "MultiAudioDevice.h"
#include <limits.h> #include <limits.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <Directory.h>
#include <Entry.h>
#include <FindDirectory.h>
#include <File.h>
#include <Path.h>
#include "debug.h" #include "debug.h"
#include "MultiAudioNode.h"
#include "MultiAudioDevice.h"
#define MULTI_SAVE #define MULTI_SAVE
const char* kSettingsName = "Media/multi_audio_settings";
//! instantiation function //! instantiation function
extern "C" BMediaAddOn* extern "C" BMediaAddOn*
@@ -39,42 +38,37 @@ make_media_addon(image_id image)
// #pragma mark - // #pragma mark -
MultiAudioAddOn::MultiAudioAddOn(image_id image)
: BMediaAddOn(image),
fDevices()
{
CALLED();
fInitStatus = _RecursiveScan("/dev/audio/hmulti/");
if (fInitStatus != B_OK)
return;
_LoadSettings();
fInitStatus = B_OK;
}
MultiAudioAddOn::~MultiAudioAddOn() MultiAudioAddOn::~MultiAudioAddOn()
{ {
CALLED(); CALLED();
void *device = NULL; void *device = NULL;
for (int32 i = 0; (device = fDevices.ItemAt(i)); i++) for (int32 i = 0; (device = fDevices.ItemAt(i)); i++)
delete (MultiAudioDevice *)device; delete (MultiAudioDevice*)device;
SaveSettings(); _SaveSettings();
} }
MultiAudioAddOn::MultiAudioAddOn(image_id image)
: BMediaAddOn(image),
fDevices()
{
CALLED();
fInitCheckStatus = B_NO_INIT;
if (RecursiveScan("/dev/audio/hmulti/") != B_OK)
return;
LoadSettings();
fInitCheckStatus = B_OK;
}
// -------------------------------------------------------- //
// BMediaAddOn impl
// -------------------------------------------------------- //
status_t status_t
MultiAudioAddOn::InitCheck(const char** _failureText) MultiAudioAddOn::InitCheck(const char** _failureText)
{ {
CALLED(); CALLED();
return B_OK; return fInitStatus;
} }
@@ -87,13 +81,13 @@ MultiAudioAddOn::CountFlavors()
status_t status_t
MultiAudioAddOn::GetFlavorAt(int32 n, const flavor_info** _info) MultiAudioAddOn::GetFlavorAt(int32 index, const flavor_info** _info)
{ {
CALLED(); CALLED();
if (_info == NULL) if (_info == NULL)
return B_BAD_VALUE; return B_BAD_VALUE;
MultiAudioDevice* device = (MultiAudioDevice*)fDevices.ItemAt(n); MultiAudioDevice* device = (MultiAudioDevice*)fDevices.ItemAt(index);
if (device == NULL) if (device == NULL)
return B_BAD_INDEX; return B_BAD_INDEX;
@@ -101,7 +95,7 @@ MultiAudioAddOn::GetFlavorAt(int32 n, const flavor_info** _info)
if (info == NULL) if (info == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
MultiAudioNode::GetFlavor(info, n); MultiAudioNode::GetFlavor(info, index);
info->name = (char*)device->Description().friendly_name; info->name = (char*)device->Description().friendly_name;
*_info = info; *_info = info;
@@ -143,34 +137,28 @@ MultiAudioAddOn::InstantiateNodeFor(const flavor_info* info, BMessage* config,
status_t status_t
MultiAudioAddOn::GetConfigurationFor(BMediaNode * your_node, BMessage * into_message) MultiAudioAddOn::GetConfigurationFor(BMediaNode* _node, BMessage* message)
{ {
CALLED(); CALLED();
#ifdef MULTI_SAVE MultiAudioNode* node = dynamic_cast<MultiAudioNode*>(_node);
if (into_message == 0) { if (node == NULL)
into_message = new BMessage();
MultiAudioNode * node = dynamic_cast<MultiAudioNode*>(your_node);
if (node == 0) {
fprintf(stderr, "<- B_BAD_TYPE\n");
return B_BAD_TYPE; return B_BAD_TYPE;
}
if (node->GetConfigurationFor(into_message) == B_OK) { #ifdef MULTI_SAVE
fSettings.AddMessage(your_node->Name(), into_message); if (message == NULL) {
BMessage settings;
if (node->GetConfigurationFor(&settings) == B_OK) {
fSettings.AddMessage(node->Name(), &settings);
} }
return B_OK; return B_OK;
} }
#endif #endif
// currently never called by the media kit. Seems it is not implemented. // currently never called by the media kit. Seems it is not implemented.
if (into_message == 0) { if (message == NULL)
fprintf(stderr, "<- B_BAD_VALUE\n"); return B_BAD_VALUE;
return B_BAD_VALUE; // we refuse to crash because you were stupid
} return node->GetConfigurationFor(message);
MultiAudioNode * node = dynamic_cast<MultiAudioNode*>(your_node);
if (node == 0) {
fprintf(stderr, "<- B_BAD_TYPE\n");
return B_BAD_TYPE;
}
return node->GetConfigurationFor(into_message);
} }
@@ -192,9 +180,11 @@ MultiAudioAddOn::AutoStart(int count, BMediaNode** _node, int32* _internalID,
status_t status_t
MultiAudioAddOn::RecursiveScan(char* rootPath, BEntry* rootEntry) MultiAudioAddOn::_RecursiveScan(char* rootPath, BEntry* rootEntry, uint32 depth)
{ {
CALLED(); CALLED();
if (depth > 16)
return B_ERROR;
BDirectory root; BDirectory root;
if (rootEntry != NULL) if (rootEntry != NULL)
@@ -207,10 +197,9 @@ MultiAudioAddOn::RecursiveScan(char* rootPath, BEntry* rootEntry)
} }
BEntry entry; BEntry entry;
while (root.GetNextEntry(&entry) == B_OK) {
while (root.GetNextEntry(&entry) > B_ERROR) {
if (entry.IsDirectory()) { if (entry.IsDirectory()) {
RecursiveScan(rootPath, &entry); _RecursiveScan(rootPath, &entry, depth + 1);
} else { } else {
BPath path; BPath path;
entry.GetPath(&path); entry.GetPath(&path);
@@ -230,34 +219,37 @@ MultiAudioAddOn::RecursiveScan(char* rootPath, BEntry* rootEntry)
void void
MultiAudioAddOn::SaveSettings() MultiAudioAddOn::_SaveSettings()
{ {
CALLED(); CALLED();
BPath path; BPath path;
if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) == B_OK) { if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK)
path.Append(SETTINGS_FILE); return;
path.Append(kSettingsName);
BFile file(path.Path(), B_READ_WRITE | B_CREATE_FILE | B_ERASE_FILE); BFile file(path.Path(), B_READ_WRITE | B_CREATE_FILE | B_ERASE_FILE);
if (file.InitCheck() == B_OK) if (file.InitCheck() == B_OK)
fSettings.Flatten(&file); fSettings.Flatten(&file);
}
} }
void void
MultiAudioAddOn::LoadSettings() MultiAudioAddOn::_LoadSettings()
{ {
CALLED(); CALLED();
fSettings.MakeEmpty(); fSettings.MakeEmpty();
BPath path; BPath path;
if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) == B_OK) { if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK)
path.Append(SETTINGS_FILE); return;
path.Append(kSettingsName);
BFile file(path.Path(), B_READ_ONLY); BFile file(path.Path(), B_READ_ONLY);
if ((file.InitCheck() == B_OK) && (fSettings.Unflatten(&file) == B_OK)) if (file.InitCheck() == B_OK && fSettings.Unflatten(&file) == B_OK) {
{
PRINT_OBJECT(fSettings); PRINT_OBJECT(fSettings);
} else { } else {
PRINT(("Error unflattening settings file %s\n", path.Path())); PRINT(("Error unflattening settings file %s\n", path.Path()));
} }
}
} }
@@ -2,59 +2,47 @@
* Copyright (c) 2002, Jerome Duval ([email protected]) * Copyright (c) 2002, Jerome Duval ([email protected])
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#ifndef MULTI_AUDIO_ADDON_H
#define MULTI_AUDIO_ADDON_H
#ifndef _MULTIAUDIOADDON_H
#define _MULTIAUDIOADDON_H
#include <MediaDefs.h> #include <MediaDefs.h>
#include <MediaAddOn.h> #include <MediaAddOn.h>
#include <Message.h>
#define SETTINGS_FILE "Media/multi_audio_settings" class BEntry;
class MultiAudioAddOn :
public BMediaAddOn
{
public:
virtual ~MultiAudioAddOn(void);
explicit MultiAudioAddOn(image_id image);
/**************************/ class MultiAudioAddOn : public BMediaAddOn {
/* begin from BMediaAddOn */ public:
public: MultiAudioAddOn(image_id image);
virtual status_t InitCheck( virtual ~MultiAudioAddOn();
const char ** out_failure_text);
virtual int32 CountFlavors(void);
virtual status_t GetFlavorAt(
int32 n,
const flavor_info ** out_info);
virtual BMediaNode * InstantiateNodeFor(
const flavor_info * info,
BMessage * config,
status_t * out_error);
virtual status_t GetConfigurationFor(
BMediaNode * your_node,
BMessage * into_message);
virtual bool WantsAutoStart(void);
virtual status_t AutoStart(
int in_count,
BMediaNode ** out_node,
int32 * out_internal_id,
bool * out_has_more);
/* end from BMediaAddOn */ virtual status_t InitCheck(const char** _failureText);
/************************/ virtual int32 CountFlavors();
virtual status_t GetFlavorAt(int32 i, const flavor_info** _info);
virtual BMediaNode* InstantiateNodeFor(const flavor_info* info,
BMessage* config, status_t* _error);
virtual status_t GetConfigurationFor(BMediaNode* node,
BMessage* message);
virtual bool WantsAutoStart();
virtual status_t AutoStart(int count, BMediaNode** _node,
int32* _internalID, bool* _hasMore);
private: private:
status_t RecursiveScan(char* path, BEntry *rootEntry = NULL); status_t _RecursiveScan(char* path, BEntry* rootEntry = NULL,
void SaveSettings(); uint32 depth = 0);
void LoadSettings(); void _SaveSettings();
void _LoadSettings();
status_t fInitCheckStatus; private:
status_t fInitStatus;
BList fDevices; BList fDevices;
BMessage fSettings; // settings loaded from settings directory BMessage fSettings;
// loaded from settings directory
}; };
extern "C" _EXPORT BMediaAddOn *make_media_addon(image_id you); extern "C" BMediaAddOn* make_media_addon(image_id you);
#endif /* _MULTIAUDIOADDON_H */ #endif // MULTI_AUDIO_ADDON_H
@@ -7,26 +7,52 @@
#include "MultiAudioNode.h" #include "MultiAudioNode.h"
#if 0 #include <stdio.h>
#include <Entry.h> #include <string.h>
#include <File.h>
#include <FileInterface.h>
#endif
#include <Buffer.h> #include <Buffer.h>
#include <BufferGroup.h> #include <BufferGroup.h>
#include <ParameterWeb.h> #include <ParameterWeb.h>
#include "MultiAudioUtility.h" #include "MultiAudioUtility.h"
#ifdef DEBUG #ifdef DEBUG
# define PRINTING # define PRINTING
#endif #endif
#include "debug.h" #include "debug.h"
#include <stdio.h> class node_input {
#include <string.h> public:
node_input(media_input& input, media_format format);
~node_input();
const char * multi_string[] = { int32 fChannelId;
media_input fInput;
media_format fPreferredFormat;
media_format fFormat;
uint32 fBufferCycle;
multi_buffer_info fOldBufferInfo;
BBuffer* fBuffer;
};
class node_output {
public:
node_output(media_output& output, media_format format);
~node_output();
int32 fChannelId;
media_output fOutput;
media_format fPreferredFormat;
media_format fFormat;
BBufferGroup* fBufferGroup;
bool fOutputEnabled;
uint64 fSamplesSent;
volatile uint32 fBufferCycle;
multi_buffer_info fOldBufferInfo;
};
const char* kMultiControlString[] = {
"NAME IS ATTACHED", "NAME IS ATTACHED",
"Output", "Input", "Setup", "Tone Control", "Extended Setup", "Enhanced Setup", "Master", "Output", "Input", "Setup", "Tone Control", "Extended Setup", "Enhanced Setup", "Master",
"Beep", "Phone", "Mic", "Line", "CD", "Video", "Aux", "Wave", "Gain", "Level", "Volume", "Beep", "Phone", "Mic", "Line", "CD", "Video", "Aux", "Wave", "Gain", "Level", "Volume",
@@ -35,7 +61,7 @@ const char * multi_string[] = {
}; };
node_input::node_input(media_input &input, media_format format) node_input::node_input(media_input& input, media_format format)
{ {
CALLED(); CALLED();
fInput = input; fInput = input;
@@ -44,13 +70,19 @@ node_input::node_input(media_input &input, media_format format)
fBuffer = NULL; fBuffer = NULL;
} }
node_input::~node_input() node_input::~node_input()
{ {
CALLED(); CALLED();
} }
node_output::node_output(media_output &output, media_format format)
: fBufferGroup(NULL), // #pragma mark -
node_output::node_output(media_output& output, media_format format)
:
fBufferGroup(NULL),
fOutputEnabled(true) fOutputEnabled(true)
{ {
CALLED(); CALLED();
@@ -59,12 +91,16 @@ node_output::node_output(media_output &output, media_format format)
fBufferCycle = 1; fBufferCycle = 1;
} }
node_output::~node_output() node_output::~node_output()
{ {
CALLED(); CALLED();
} }
// #pragma mark -
MultiAudioNode::MultiAudioNode(BMediaAddOn* addon, const char* name, MultiAudioNode::MultiAudioNode(BMediaAddOn* addon, const char* name,
MultiAudioDevice* device, int32 internalID, BMessage* config) MultiAudioDevice* device, int32 internalID, BMessage* config)
: BMediaNode(name), BBufferConsumer(B_MEDIA_RAW_AUDIO), : BMediaNode(name), BBufferConsumer(B_MEDIA_RAW_AUDIO),
@@ -1292,7 +1328,7 @@ const char*
MultiAudioNode::_GetControlName(multi_mix_control& control) MultiAudioNode::_GetControlName(multi_mix_control& control)
{ {
if (control.string != S_null) if (control.string != S_null)
return multi_string[control.string]; return kMultiControlString[control.string];
return control.name; return control.name;
} }
@@ -22,37 +22,9 @@
class BDiscreteParameter; class BDiscreteParameter;
class BParameterGroup; class BParameterGroup;
class node_input;
class node_output;
class node_input {
public:
node_input(media_input& input, media_format format);
~node_input();
int32 fChannelId;
media_input fInput;
media_format fPreferredFormat;
media_format fFormat;
uint32 fBufferCycle;
multi_buffer_info fOldBufferInfo;
BBuffer* fBuffer;
};
class node_output {
public:
node_output(media_output& output, media_format format);
~node_output();
int32 fChannelId;
media_output fOutput;
media_format fPreferredFormat;
media_format fFormat;
BBufferGroup* fBufferGroup;
bool fOutputEnabled;
uint64 fSamplesSent;
volatile uint32 fBufferCycle;
multi_buffer_info fOldBufferInfo;
};
class MultiAudioNode : public BBufferConsumer, public BBufferProducer, class MultiAudioNode : public BBufferConsumer, public BBufferProducer,
public BTimeSource, public BMediaEventLooper, public BControllable { public BTimeSource, public BMediaEventLooper, public BControllable {