Author: axeld Date: 2009-12-05 16:09:48 +0100 (Sat, 05 Dec 2009) New Revision: 34512 Changeset: http://dev.haiku-os.org/changeset/34512/haiku Modified: haiku/trunk/src/servers/media_addon/Jamfile haiku/trunk/src/servers/media_addon/MediaAddonServer.cpp Log: * The media_addon_server is now using the more or less shared AddOnMonitorHandler solution, instead of doing its own thing. Modified: haiku/trunk/src/servers/media_addon/Jamfile =================================================================== --- haiku/trunk/src/servers/media_addon/Jamfile 2009-12-05 15:07:49 UTC (rev 34511) +++ haiku/trunk/src/servers/media_addon/Jamfile 2009-12-05 15:09:48 UTC (rev 34512) @@ -2,7 +2,8 @@ SetSubDirSupportedPlatformsBeOSCompatible ; -UsePrivateHeaders media shared ; +UsePrivateHeaders media shared storage ; +UsePrivateSystemHeaders ; AddResources media_addon_server : media_addon_server.rdef ; @@ -10,6 +11,13 @@ MediaAddonServer.cpp MediaFilePlayer.cpp SystemTimeSource.cpp + + # storage + AddOnMonitorHandler.cpp + NodeMonitorHandler.cpp : be libmedia.so game $(TARGET_LIBSUPC++) ; + +SEARCH on [ FGristFiles AddOnMonitorHandler.cpp NodeMonitorHandler.cpp ] + += [ FDirName $(SUBDIR) $(DOTDOT) $(DOTDOT) kits storage ] ; Modified: haiku/trunk/src/servers/media_addon/MediaAddonServer.cpp =================================================================== --- haiku/trunk/src/servers/media_addon/MediaAddonServer.cpp 2009-12-05 15:07:49 UTC (rev 34511) +++ haiku/trunk/src/servers/media_addon/MediaAddonServer.cpp 2009-12-05 15:09:48 UTC (rev 34512) @@ -37,15 +37,20 @@ #include <Application.h> #include <Beep.h> #include <Directory.h> +#include <driver_settings.h> #include <Entry.h> #include <FindDirectory.h> #include <MediaAddOn.h> #include <MediaRoster.h> -#include <NodeMonitor.h> +#include <MessageRunner.h> #include <Path.h> #include <Roster.h> #include <String.h> +#include <safemode_defs.h> +#include <syscalls.h> + +#include <AddOnMonitorHandler.h> #include <debug.h> #include <DataExchange.h> #include <DormantNodeManager.h> @@ -86,7 +91,9 @@ virtual void MessageReceived(BMessage* message); private: - void _WatchDir(BEntry* dir); + class MonitorHandler; + friend class MonitorHandler; + void _AddOnAdded(const char* path, ino_t fileNode); void _AddOnRemoved(ino_t fileNode); void _HandleMessage(int32 code, const void* data, @@ -112,8 +119,8 @@ InfoMap fInfoMap; BMediaRoster* fMediaRoster; - ino_t fSystemAddOnsNode; - ino_t fUserAddOnsNode; + MonitorHandler* fMonitorHandler; + BMessageRunner* fPulseRunner; port_id fControlPort; thread_id fControlThread; bool fStartup; @@ -121,6 +128,18 @@ }; +class MediaAddonServer::MonitorHandler : public AddOnMonitorHandler { +public: + MonitorHandler(MediaAddonServer* server); + + virtual void AddOnEnabled(const add_on_entry_info* info); + virtual void AddOnDisabled(const add_on_entry_info* info); + +private: + MediaAddonServer* fServer; +}; + + #if DEBUG >= 2 static void DumpFlavorInfo(const flavor_info* info) @@ -153,6 +172,35 @@ // #pragma mark - +MediaAddonServer::MonitorHandler::MonitorHandler(MediaAddonServer* server) +{ + fServer = server; +} + + +void +MediaAddonServer::MonitorHandler::AddOnEnabled(const add_on_entry_info* info) +{ + entry_ref ref; + make_entry_ref(info->dir_nref.device, info->dir_nref.node, + info->name, &ref); + + BPath path(&ref); + if (path.InitCheck() == B_OK) + fServer->_AddOnAdded(path.Path(), info->nref.node); +} + + +void +MediaAddonServer::MonitorHandler::AddOnDisabled(const add_on_entry_info* info) +{ + fServer->_AddOnRemoved(info->nref.node); +} + + +// #pragma mark - + + MediaAddonServer::MediaAddonServer(const char* signature) : BApplication(signature), @@ -223,27 +271,50 @@ // will be autostarted. Finally, add-ons that don't have // any active nodes (flavors) will be unloaded. + char parameter[32]; + size_t parameterLength = sizeof(parameter); + bool safeMode = false; + if (_kern_get_safemode_option(B_SAFEMODE_SAFE_MODE, parameter, + ¶meterLength) == B_OK) { + if (!strcasecmp(parameter, "enabled") || !strcasecmp(parameter, "on") + || !strcasecmp(parameter, "true") || !strcasecmp(parameter, "yes") + || !strcasecmp(parameter, "enable") || !strcmp(parameter, "1")) + safeMode = true; + } + + fMonitorHandler = new MonitorHandler(this); + AddHandler(fMonitorHandler); + + BMessage pulse(B_PULSE); + fPulseRunner = new BMessageRunner(fMonitorHandler, &pulse, 1000000LL); + // the monitor handler needs a pulse to check if add-ons are ready + // load dormant media nodes - BPath path; - find_directory(B_BEOS_ADDONS_DIRECTORY, &path); - path.Append("media"); + const directory_which directories[] = { + B_USER_ADDONS_DIRECTORY, + B_COMMON_ADDONS_DIRECTORY, + B_BEOS_ADDONS_DIRECTORY + }; - node_ref nref; - BEntry entry(path.Path()); - entry.GetNodeRef(&nref); - fSystemAddOnsNode = nref.node; - _WatchDir(&entry); + // when safemode, only B_BEOS_ADDONS_DIRECTORY is used + for (uint32 i = safeMode ? 2 : 0; + i < sizeof(directories) / sizeof(directory_which); i++) { + BDirectory directory; + node_ref nodeRef; + BPath path; + if (find_directory(directories[i], &path) == B_OK + && path.Append("media") == B_OK + && directory.SetTo(path.Path()) == B_OK + && directory.GetNodeRef(&nodeRef) == B_OK) + fMonitorHandler->AddDirectory(&nodeRef); + } #ifdef USER_ADDON_PATH - entry.SetTo(USER_ADDON_PATH); -#else - find_directory(B_USER_ADDONS_DIRECTORY, &path); - path.Append("media"); - entry.SetTo(path.Path()); + node_ref nodeRef; + if (entry.SetTo(USER_ADDON_PATH) == B_OK + && entry.GetNodeRef(&nodeRef) == B_OK) + fMonitorHandler->AddDirectory(&nodeRef); #endif - entry.GetNodeRef(&nref); - fUserAddOnsNode = nref.node; - _WatchDir(&entry); fStartup = false; @@ -299,66 +370,6 @@ return; } - case B_NODE_MONITOR: - { - switch (message->FindInt32("opcode")) { - case B_ENTRY_CREATED: - { - const char *name; - entry_ref ref; - ino_t node; - BEntry e; - BPath p; - message->FindString("name", &name); - message->FindInt64("node", &node); - message->FindInt32("device", &ref.device); - message->FindInt64("directory", &ref.directory); - ref.set_name(name); - e.SetTo(&ref,false);// build a BEntry for the created file/link/dir - e.GetPath(&p); // get the path to the file/link/dir - e.SetTo(&ref,true); // travese links to see - if (e.IsFile()) { // if it's a link to a file, or a file - if (!message->FindBool("nowait")) { - // TODO: wait 5 seconds if this is a regular notification - // because the file creation may not be finshed when the - // notification arrives (very ugly, how can we fix this?) - // this will also fail if copying takes longer than 5 seconds - snooze(5000000); - } - _AddOnAdded(p.Path(), node); - } - return; - } - case B_ENTRY_REMOVED: - { - ino_t node; - message->FindInt64("node", &node); - _AddOnRemoved(node); - return; - } - case B_ENTRY_MOVED: - { - ino_t from; - ino_t to; - message->FindInt64("from directory", &from); - message->FindInt64("to directory", &to); - if (fSystemAddOnsNode == from || fUserAddOnsNode == from) { - message->ReplaceInt32("opcode", B_ENTRY_REMOVED); - message->AddInt64("directory", from); - MessageReceived(message); - } - if (fSystemAddOnsNode == to || fUserAddOnsNode == to) { - message->ReplaceInt32("opcode", B_ENTRY_CREATED); - message->AddInt64("directory", to); - message->AddBool("nowait", true); - MessageReceived(message); - } - return; - } - } - break; - } - default: BApplication::MessageReceived(message); break; @@ -804,34 +815,6 @@ } -void -MediaAddonServer::_WatchDir(BEntry* dir) -{ - // send fake notices to trigger add-on loading - BDirectory directory(dir); - BEntry entry; - while (directory.GetNextEntry(&entry, false) == B_OK) { - node_ref nodeRef; - entry_ref ref; - if (entry.GetRef(&ref) != B_OK || entry.GetNodeRef(&nodeRef) != B_OK) - continue; - - BMessage msg(B_NODE_MONITOR); - msg.AddInt32("opcode", B_ENTRY_CREATED); - msg.AddInt32("device", ref.device); - msg.AddInt64("directory", ref.directory); - msg.AddInt64("node", nodeRef.node); - msg.AddString("name", ref.name); - msg.AddBool("nowait", true); - MessageReceived(&msg); - } - - node_ref nodeRef; - if (dir->GetNodeRef(&nodeRef) == B_OK) - watch_node(&nodeRef, B_WATCH_DIRECTORY, be_app_messenger); -} - - // #pragma mark -