2 * Copyright 2001-2015, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
6 * Ingo Weinhold, ingo_weinhold@gmx.de
16 #include <Application.h>
17 #include <Clipboard.h>
20 #include <RegistrarDefs.h>
21 #include <RosterPrivate.h>
23 #include "AuthenticationManager.h"
24 #include "ClipboardHandler.h"
26 #include "EventQueue.h"
27 #include "MessageDeliverer.h"
28 #include "MessageEvent.h"
29 #include "MessageRunnerManager.h"
30 #include "MessagingService.h"
31 #include "MIMEManager.h"
32 #include "PackageWatchingManager.h"
33 #include "ShutdownProcess.h"
39 \brief The application class of the registrar.
41 Glues the registrar services together and dispatches the roster messages.
45 using namespace BPrivate
;
47 //! Name of the event queue.
48 static const char *kEventQueueName
= "timer_thread";
50 //! Time interval between two roster sanity checks (1 s).
51 static const bigtime_t kRosterSanityEventInterval
= 1000000LL;
54 /*! \brief Creates the registrar application class.
55 \param error Passed to the BApplication constructor for returning an
58 Registrar::Registrar(status_t
* _error
)
60 BServer(B_REGISTRAR_SIGNATURE
, B_REGISTRAR_PORT_NAME
, -1, false, _error
),
62 fClipboardHandler(NULL
),
65 fMessageRunnerManager(NULL
),
67 fShutdownProcess(NULL
),
68 fAuthenticationManager(NULL
),
69 fPackageWatchingManager(NULL
)
73 set_thread_priority(find_thread(NULL
), B_NORMAL_PRIORITY
+ 1);
77 /*! \brief Frees all resources associated with the registrar.
79 All registrar services, that haven't been shut down earlier, are
82 Registrar::~Registrar()
87 delete fAuthenticationManager
;
88 delete fPackageWatchingManager
;
89 delete fMessageRunnerManager
;
94 RemoveHandler(fClipboardHandler
);
95 delete fClipboardHandler
;
97 // Invalidate the global be_roster, so that the BApplication destructor
98 // won't dead-lock when sending a message to itself.
99 BRoster::Private().SetTo(BMessenger(), BMessenger());
104 /*! \brief Overrides the super class version to dispatch roster specific
106 \param message The message to be handled
109 Registrar::MessageReceived(BMessage
*message
)
112 _MessageReceived(message
);
113 } catch (std::exception
& exception
) {
115 snprintf(buffer
, sizeof(buffer
),
116 "Registrar::MessageReceived() caught exception: %s",
120 debugger("Registrar::MessageReceived() caught unknown exception");
125 /*! \brief Overrides the super class version to initialize the registrar
129 Registrar::ReadyToRun()
133 // create message deliverer
134 status_t error
= MessageDeliverer::CreateDefault();
136 FATAL("Registrar::ReadyToRun(): Failed to create the message "
137 "deliverer: %s\n", strerror(error
));
140 // create event queue
141 fEventQueue
= new EventQueue(kEventQueueName
);
143 // create authentication manager
144 fAuthenticationManager
= new AuthenticationManager
;
145 fAuthenticationManager
->Init();
148 fRoster
= new TRoster
;
151 // create clipboard handler
152 fClipboardHandler
= new ClipboardHandler
;
153 AddHandler(fClipboardHandler
);
155 // create MIME manager
156 fMIMEManager
= new MIMEManager
;
159 // create message runner manager
160 fMessageRunnerManager
= new MessageRunnerManager(fEventQueue
);
162 // init the global be_roster
163 BRoster::Private().SetTo(be_app_messenger
, BMessenger(NULL
, fMIMEManager
));
165 // create the messaging service
166 error
= MessagingService::CreateDefault();
168 ERROR("Registrar::ReadyToRun(): Failed to init messaging service "
169 "(that's by design when running under R5): %s\n", strerror(error
));
172 // create the package watching manager
173 fPackageWatchingManager
= new PackageWatchingManager
;
175 // create and schedule the sanity message event
176 fSanityEvent
= new MessageEvent(system_time() + kRosterSanityEventInterval
,
177 this, B_REG_ROSTER_SANITY_EVENT
);
178 fSanityEvent
->SetAutoDelete(false);
179 fEventQueue
->AddEvent(fSanityEvent
);
185 /*! \brief Overrides the super class version to avoid termination of the
186 registrar until the system shutdown.
189 Registrar::QuitRequested()
192 // The final registrar must not quit. At least not that easily. ;-)
193 return BApplication::QuitRequested();
197 /*! \brief Returns the registrar's event queue.
198 \return The registrar's event queue.
201 Registrar::GetEventQueue() const
207 /*! \brief Returns the Registrar application object.
208 \return The Registrar application object.
213 return dynamic_cast<Registrar
*>(be_app
);
218 Registrar::_MessageReceived(BMessage
*message
)
220 switch (message
->what
) {
222 case B_REG_GET_MIME_MESSENGER
:
224 PRINT("B_REG_GET_MIME_MESSENGER\n");
225 BMessenger
messenger(NULL
, fMIMEManager
);
226 BMessage
reply(B_REG_SUCCESS
);
227 reply
.AddMessenger("messenger", messenger
);
228 message
->SendReply(&reply
);
232 case B_REG_GET_CLIPBOARD_MESSENGER
:
234 PRINT("B_REG_GET_CLIPBOARD_MESSENGER\n");
235 BMessenger
messenger(fClipboardHandler
);
236 BMessage
reply(B_REG_SUCCESS
);
237 reply
.AddMessenger("messenger", messenger
);
238 message
->SendReply(&reply
);
243 case B_REG_SHUT_DOWN
:
245 PRINT("B_REG_SHUT_DOWN\n");
247 _HandleShutDown(message
);
250 case B_REG_TEAM_DEBUGGER_ALERT
:
252 if (fShutdownProcess
!= NULL
)
253 fShutdownProcess
->PostMessage(message
);
259 fRoster
->HandleAddApplication(message
);
261 case B_REG_COMPLETE_REGISTRATION
:
262 fRoster
->HandleCompleteRegistration(message
);
264 case B_REG_IS_APP_REGISTERED
:
265 fRoster
->HandleIsAppRegistered(message
);
267 case B_REG_REMOVE_PRE_REGISTERED_APP
:
268 fRoster
->HandleRemovePreRegApp(message
);
270 case B_REG_REMOVE_APP
:
271 fRoster
->HandleRemoveApp(message
);
273 case B_REG_SET_THREAD_AND_TEAM
:
274 fRoster
->HandleSetThreadAndTeam(message
);
276 case B_REG_SET_SIGNATURE
:
277 fRoster
->HandleSetSignature(message
);
279 case B_REG_GET_APP_INFO
:
280 fRoster
->HandleGetAppInfo(message
);
282 case B_REG_GET_APP_LIST
:
283 fRoster
->HandleGetAppList(message
);
285 case B_REG_UPDATE_ACTIVE_APP
:
286 fRoster
->HandleUpdateActiveApp(message
);
288 case B_REG_BROADCAST
:
289 fRoster
->HandleBroadcast(message
);
291 case B_REG_START_WATCHING
:
292 fRoster
->HandleStartWatching(message
);
294 case B_REG_STOP_WATCHING
:
295 fRoster
->HandleStopWatching(message
);
297 case B_REG_GET_RECENT_DOCUMENTS
:
298 fRoster
->HandleGetRecentDocuments(message
);
300 case B_REG_GET_RECENT_FOLDERS
:
301 fRoster
->HandleGetRecentFolders(message
);
303 case B_REG_GET_RECENT_APPS
:
304 fRoster
->HandleGetRecentApps(message
);
306 case B_REG_ADD_TO_RECENT_DOCUMENTS
:
307 fRoster
->HandleAddToRecentDocuments(message
);
309 case B_REG_ADD_TO_RECENT_FOLDERS
:
310 fRoster
->HandleAddToRecentFolders(message
);
312 case B_REG_ADD_TO_RECENT_APPS
:
313 fRoster
->HandleAddToRecentApps(message
);
315 case B_REG_CLEAR_RECENT_DOCUMENTS
:
316 fRoster
->ClearRecentDocuments();
318 case B_REG_CLEAR_RECENT_FOLDERS
:
319 fRoster
->ClearRecentFolders();
321 case B_REG_CLEAR_RECENT_APPS
:
322 fRoster
->ClearRecentApps();
324 case B_REG_LOAD_RECENT_LISTS
:
325 fRoster
->HandleLoadRecentLists(message
);
327 case B_REG_SAVE_RECENT_LISTS
:
328 fRoster
->HandleSaveRecentLists(message
);
331 // message runner requests
332 case B_REG_REGISTER_MESSAGE_RUNNER
:
333 fMessageRunnerManager
->HandleRegisterRunner(message
);
335 case B_REG_UNREGISTER_MESSAGE_RUNNER
:
336 fMessageRunnerManager
->HandleUnregisterRunner(message
);
338 case B_REG_SET_MESSAGE_RUNNER_PARAMS
:
339 fMessageRunnerManager
->HandleSetRunnerParams(message
);
341 case B_REG_GET_MESSAGE_RUNNER_INFO
:
342 fMessageRunnerManager
->HandleGetRunnerInfo(message
);
345 // package watching requests
346 case B_REG_PACKAGE_START_WATCHING
:
347 case B_REG_PACKAGE_STOP_WATCHING
:
348 fPackageWatchingManager
->HandleStartStopWatching(message
);
350 case B_PACKAGE_UPDATE
:
351 fPackageWatchingManager
->NotifyWatchers(message
);
355 case B_REG_ROSTER_SANITY_EVENT
:
356 fRoster
->CheckSanity();
357 fSanityEvent
->SetTime(system_time() + kRosterSanityEventInterval
);
358 fEventQueue
->AddEvent(fSanityEvent
);
360 case B_REG_SHUTDOWN_FINISHED
:
361 if (fShutdownProcess
) {
362 fShutdownProcess
->PostMessage(B_QUIT_REQUESTED
,
364 fShutdownProcess
= NULL
;
368 case kMsgRestartAppServer
:
370 fRoster
->HandleRestartAppServer(message
);
375 BApplication::MessageReceived(message
);
381 /*! \brief Handle a shut down request message.
382 \param request The request to be handled.
385 Registrar::_HandleShutDown(BMessage
*request
)
387 status_t error
= B_OK
;
389 // check, whether we're already shutting down
390 if (fShutdownProcess
)
391 error
= B_SHUTTING_DOWN
;
393 bool needsReply
= true;
395 // create a ShutdownProcess
396 fShutdownProcess
= new(nothrow
) ShutdownProcess(fRoster
, fEventQueue
);
397 if (fShutdownProcess
) {
398 error
= fShutdownProcess
->Init(request
);
400 DetachCurrentMessage();
401 fShutdownProcess
->Run();
404 delete fShutdownProcess
;
405 fShutdownProcess
= NULL
;
412 ShutdownProcess::SendReply(request
, error
);
419 /*! \brief Creates and runs the registrar application.
421 The main thread is renamed.
430 // Create the global be_clipboard manually -- it will not work, since it
431 // wants to talk to the registrar in its constructor, but it doesn't have
432 // to and we would otherwise deadlock when initializing our GUI in the
434 be_clipboard
= new BClipboard(NULL
);
436 // create and run the registrar application
438 Registrar
*app
= new Registrar(&error
);
440 fprintf(stderr
, "REG: Failed to create the BApplication: %s\n",
445 // rename the main thread
446 rename_thread(find_thread(NULL
), "roster");
448 PRINT("app->Run()...\n");
452 } catch (std::exception
& exception
) {
454 snprintf(buffer
, sizeof(buffer
),
455 "registrar main() caught exception: %s", exception
.what());
458 debugger("registrar main() caught unknown exception");
461 PRINT("delete app...\n");