2 * Copyright 2010-2013 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
6 * John Scipione, jscipione@gmail.com
7 * Clemens Zeidler, haiku@clemens-zeidler.de
11 #include "IndexServer.h"
17 VolumeObserverHandler::VolumeObserverHandler(IndexServer
* indexServer
)
19 fIndexServer(indexServer
)
26 VolumeObserverHandler::MessageReceived(BMessage
* message
)
28 if (message
->what
!= B_NODE_MONITOR
)
33 message
->FindInt32("opcode", &opcode
) ;
35 case B_DEVICE_MOUNTED
:
36 message
->FindInt32("new device", &device
);
37 fIndexServer
->AddVolume(BVolume(device
));
40 case B_DEVICE_UNMOUNTED
:
41 message
->FindInt32("device", &device
);
42 fIndexServer
->RemoveVolume(BVolume(device
));
48 AnalyserMonitorHandler::AnalyserMonitorHandler(IndexServer
* indexServer
)
50 fIndexServer(indexServer
)
57 AnalyserMonitorHandler::AddOnEnabled(const add_on_entry_info
* entryInfo
)
60 make_entry_ref(entryInfo
->dir_nref
.device
, entryInfo
->dir_nref
.node
,
61 entryInfo
->name
, &ref
);
62 fIndexServer
->RegisterAddOn(ref
);
67 AnalyserMonitorHandler::AddOnDisabled(const add_on_entry_info
* entryInfo
)
70 make_entry_ref(entryInfo
->dir_nref
.device
, entryInfo
->dir_nref
.node
,
71 entryInfo
->name
, &ref
);
72 fIndexServer
->UnregisterAddOn(ref
);
76 IndexServer::IndexServer()
78 BApplication("application/x-vnd.Haiku-index_server"),
79 fVolumeObserverHandler(this),
80 fAddOnMonitorHandler(this),
83 AddHandler(&fVolumeObserverHandler
);
84 AddHandler(&fAddOnMonitorHandler
);
88 IndexServer::~IndexServer()
90 for (int i
= 0; i
< fAddOnList
.CountItems(); i
++) {
91 IndexServerAddOn
* addon
= fAddOnList
.ItemAt(i
);
92 for (int i
= 0; i
< fVolumeWatcherList
.CountItems(); i
++)
93 fVolumeWatcherList
.ItemAt(i
)->RemoveAnalyser(addon
->Name());
94 image_id image
= addon
->ImageId();
99 _StopWatchingVolumes();
103 RemoveHandler(&fVolumeObserverHandler
);
104 RemoveHandler(&fAddOnMonitorHandler
);
109 IndexServer::ReadyToRun()
111 _StartWatchingAddOns();
112 _StartWatchingVolumes();
117 IndexServer::MessageReceived(BMessage
*message
)
119 BApplication::MessageReceived(message
);
124 IndexServer::QuitRequested()
126 _StopWatchingVolumes();
127 return BApplication::QuitRequested();
132 IndexServer::AddVolume(const BVolume
& volume
)
134 // ignore volumes like / or /dev
135 if (volume
.Capacity() == 0)
138 // check if volume is already in our list
139 for (int i
= 0; i
< fVolumeWatcherList
.CountItems(); i
++) {
140 VolumeWatcher
* current
= fVolumeWatcherList
.ItemAt(i
);
141 if (current
->Volume() == volume
)
146 volume
.GetName(name
);
147 STRACE("IndexServer::AddVolume %s\n", name
);
149 VolumeWatcher
* watcher
= new VolumeWatcher(volume
);
150 /* if (!watcher->Enabled()) {
154 fVolumeWatcherList
.AddItem(watcher
);
155 _SetupVolumeWatcher(watcher
);
156 watcher
->StartWatching();
161 IndexServer::RemoveVolume(const BVolume
& volume
)
163 VolumeWatcher
* watcher
= NULL
;
164 for (int i
= 0; i
< fVolumeWatcherList
.CountItems(); i
++) {
165 VolumeWatcher
* current
= fVolumeWatcherList
.ItemAt(i
);
166 if (current
->Volume() == volume
) {
176 fVolumeWatcherList
.RemoveItem(watcher
);
177 watcher
->PostMessage(B_QUIT_REQUESTED
);
182 IndexServer::RegisterAddOn(entry_ref ref
)
184 STRACE("RegisterAddOn %s\n", ref
.name
);
187 image_id image
= load_add_on(path
.Path());
191 create_index_server_addon
* createFunc
;
193 // Get the instantiation function
194 status_t status
= get_image_symbol(image
, "instantiate_index_server_addon",
195 B_SYMBOL_TYPE_TEXT
, (void**)&createFunc
);
196 if (status
!= B_OK
) {
197 unload_add_on(image
);
201 IndexServerAddOn
* addon
= createFunc(image
, ref
.name
);
203 unload_add_on(image
);
206 if (!fAddOnList
.AddItem(addon
)) {
207 unload_add_on(image
);
211 for (int i
= 0; i
< fVolumeWatcherList
.CountItems(); i
++) {
212 VolumeWatcher
* watcher
= fVolumeWatcherList
.ItemAt(i
);
213 FileAnalyser
* analyser
= _SetupFileAnalyser(addon
, watcher
->Volume());
216 if (!watcher
->AddAnalyser(analyser
))
224 IndexServer::UnregisterAddOn(entry_ref ref
)
226 IndexServerAddOn
* addon
= _FindAddon(ref
.name
);
230 for (int i
= 0; i
< fVolumeWatcherList
.CountItems(); i
++)
231 fVolumeWatcherList
.ItemAt(i
)->RemoveAnalyser(addon
->Name());
233 fAddOnList
.RemoveItem(addon
);
234 unload_add_on(addon
->ImageId());
240 IndexServer::CreateFileAnalyser(const BString
& name
, const BVolume
& volume
)
243 IndexServerAddOn
* addon
= _FindAddon(name
);
248 FileAnalyser
* analyser
= addon
->CreateFileAnalyser(volume
);
255 IndexServer::_StartWatchingVolumes()
258 while (fVolumeRoster
.GetNextVolume(&volume
) != B_BAD_VALUE
)
260 fVolumeRoster
.StartWatching(this);
265 IndexServer::_StopWatchingVolumes()
267 STRACE("_StopWatchingVolumes\n");
269 for (int i
= 0; i
< fVolumeWatcherList
.CountItems(); i
++) {
270 VolumeWatcher
* watcher
= fVolumeWatcherList
.ItemAt(i
);
272 watcher
->PostMessage(B_QUIT_REQUESTED
);
274 fVolumeWatcherList
.MakeEmpty();
279 IndexServer::_SetupVolumeWatcher(VolumeWatcher
* watcher
)
281 for (int i
= 0; i
< fAddOnList
.CountItems(); i
++) {
282 IndexServerAddOn
* addon
= fAddOnList
.ItemAt(i
);
283 FileAnalyser
* analyser
= _SetupFileAnalyser(addon
, watcher
->Volume());
286 if (!watcher
->AddAnalyser(analyser
))
293 IndexServer::_SetupFileAnalyser(IndexServerAddOn
* addon
, const BVolume
& volume
)
295 FileAnalyser
* analyser
= addon
->CreateFileAnalyser(volume
);
298 AnalyserSettings
* settings
= new AnalyserSettings(analyser
->Name(),
300 BReference
<AnalyserSettings
> settingsRef(settings
, true);
305 analyser
->SetSettings(settings
);
311 IndexServer::_StartWatchingAddOns()
313 AddHandler(&fAddOnMonitorHandler
);
315 BMessage
pulse(B_PULSE
);
316 fPulseRunner
= new BMessageRunner(&fAddOnMonitorHandler
, &pulse
, 1000000LL);
317 // the monitor handler needs a pulse to check if add-ons are ready
319 fAddOnMonitorHandler
.AddAddOnDirectories("index_server");
324 IndexServer::_FindAddon(const BString
& name
)
326 for (int i
= 0; i
< fAddOnList
.CountItems(); i
++) {
327 IndexServerAddOn
* current
= fAddOnList
.ItemAt(i
);
328 if (current
->Name() == name
)