xref: /haiku/src/servers/registrar/Registrar.cpp (revision 5d9e40fe9252c8f9c5e5e41594545bfa4419fcc7)
1 // Registrar.cpp
2 
3 #include "Debug.h"
4 
5 #include <Application.h>
6 #include <Message.h>
7 #include <OS.h>
8 #include <RegistrarDefs.h>
9 #include <RosterPrivate.h>
10 
11 #include "ClipboardHandler.h"
12 #include "EventQueue.h"
13 #include "MessageEvent.h"
14 #include "MessageRunnerManager.h"
15 #include "MIMEManager.h"
16 #include "Registrar.h"
17 #include "TRoster.h"
18 
19 /*!
20 	\class Registrar
21 	\brief The application class of the registrar.
22 
23 	Glues the registrar services together and dispatches the roster messages.
24 */
25 
26 //! Name of the event queue.
27 static const char *kEventQueueName = "timer_thread";
28 
29 //! Time interval between two roster sanity checks (1 s).
30 static const bigtime_t kRosterSanityEventInterval = 1000000LL;
31 
32 // constructor
33 /*!	\brief Creates the registrar application class.
34 */
35 Registrar::Registrar()
36 		 : BApplication(kRegistrarSignature),
37 		   fRoster(NULL),
38 		   fClipboardHandler(NULL),
39 		   fMIMEManager(NULL),
40 		   fEventQueue(NULL),
41 		   fMessageRunnerManager(NULL),
42 		   fSanityEvent(NULL)
43 {
44 	FUNCTION_START();
45 }
46 
47 // destructor
48 /*!	\brief Frees all resources associated with the registrar.
49 
50 	All registrar services, that haven't been shut down earlier, are
51 	terminated.
52 */
53 Registrar::~Registrar()
54 {
55 	FUNCTION_START();
56 	Lock();
57 	fEventQueue->Die();
58 	delete fMessageRunnerManager;
59 	delete fEventQueue;
60 	delete fSanityEvent;
61 	fMIMEManager->Lock();
62 	fMIMEManager->Quit();
63 	RemoveHandler(fClipboardHandler);
64 	delete fClipboardHandler;
65 	delete fRoster;
66 	// Invalidate the global be_roster, so that the BApplication destructor
67 	// won't dead-lock when sending a message to itself.
68 	BRoster::Private().SetTo(BMessenger(), BMessenger());
69 	FUNCTION_END();
70 }
71 
72 // MessageReceived
73 /*!	\brief Overrides the super class version to dispatch roster specific
74 		   messages.
75 	\param message The message to be handled
76 */
77 void
78 Registrar::MessageReceived(BMessage *message)
79 {
80 //	FUNCTION_START();
81 	switch (message->what) {
82 		// general requests
83 		case B_REG_GET_MIME_MESSENGER:
84 		{
85 			PRINT(("B_REG_GET_MIME_MESSENGER\n"));
86 			BMessenger messenger(NULL, fMIMEManager);
87 			BMessage reply(B_REG_SUCCESS);
88 			reply.AddMessenger("messenger", messenger);
89 			message->SendReply(&reply);
90 			break;
91 		}
92 		case B_REG_GET_CLIPBOARD_MESSENGER:
93 		{
94 			PRINT(("B_REG_GET_CLIPBOARD_MESSENGER\n"));
95 			BMessenger messenger(fClipboardHandler);
96 			BMessage reply(B_REG_SUCCESS);
97 			reply.AddMessenger("messenger", messenger);
98 			message->SendReply(&reply);
99 			break;
100 		}
101 		// roster requests
102 		case B_REG_ADD_APP:
103 			fRoster->HandleAddApplication(message);
104 			break;
105 		case B_REG_COMPLETE_REGISTRATION:
106 			fRoster->HandleCompleteRegistration(message);
107 			break;
108 		case B_REG_IS_APP_PRE_REGISTERED:
109 			fRoster->HandleIsAppPreRegistered(message);
110 			break;
111 		case B_REG_REMOVE_PRE_REGISTERED_APP:
112 			fRoster->HandleRemovePreRegApp(message);
113 			break;
114 		case B_REG_REMOVE_APP:
115 			fRoster->HandleRemoveApp(message);
116 			break;
117 		case B_REG_SET_THREAD_AND_TEAM:
118 			fRoster->HandleSetThreadAndTeam(message);
119 			break;
120 		case B_REG_SET_SIGNATURE:
121 			fRoster->HandleSetSignature(message);
122 			break;
123 		case B_REG_GET_APP_INFO:
124 			fRoster->HandleGetAppInfo(message);
125 			break;
126 		case B_REG_GET_APP_LIST:
127 			fRoster->HandleGetAppList(message);
128 			break;
129 		case B_REG_ACTIVATE_APP:
130 			fRoster->HandleActivateApp(message);
131 			break;
132 		case B_REG_BROADCAST:
133 			fRoster->HandleBroadcast(message);
134 			break;
135 		case B_REG_START_WATCHING:
136 			fRoster->HandleStartWatching(message);
137 			break;
138 		case B_REG_STOP_WATCHING:
139 			fRoster->HandleStopWatching(message);
140 			break;
141 		case B_REG_GET_RECENT_DOCUMENTS:
142 			fRoster->HandleGetRecentDocuments(message);
143 			break;
144 		case B_REG_GET_RECENT_FOLDERS:
145 			fRoster->HandleGetRecentFolders(message);
146 			break;
147 		case B_REG_GET_RECENT_APPS:
148 			fRoster->HandleGetRecentApps(message);
149 			break;
150 		case B_REG_ADD_TO_RECENT_DOCUMENTS:
151 			fRoster->HandleAddToRecentDocuments(message);
152 			break;
153 		case B_REG_ADD_TO_RECENT_FOLDERS:
154 			fRoster->HandleAddToRecentFolders(message);
155 			break;
156 		case B_REG_ADD_TO_RECENT_APPS:
157 			fRoster->HandleAddToRecentApps(message);
158 			break;
159 		case B_REG_CLEAR_RECENT_DOCUMENTS:
160 			fRoster->ClearRecentDocuments();
161 			break;
162 		case B_REG_CLEAR_RECENT_FOLDERS:
163 			fRoster->ClearRecentFolders();
164 			break;
165 		case B_REG_CLEAR_RECENT_APPS:
166 			fRoster->ClearRecentApps();
167 			break;
168 		case B_REG_LOAD_RECENT_LISTS:
169 			fRoster->HandleLoadRecentLists(message);
170 			break;
171 		case B_REG_SAVE_RECENT_LISTS:
172 			fRoster->HandleSaveRecentLists(message);
173 			break;
174 		// message runner requests
175 		case B_REG_REGISTER_MESSAGE_RUNNER:
176 			fMessageRunnerManager->HandleRegisterRunner(message);
177 			break;
178 		case B_REG_UNREGISTER_MESSAGE_RUNNER:
179 			fMessageRunnerManager->HandleUnregisterRunner(message);
180 			break;
181 		case B_REG_SET_MESSAGE_RUNNER_PARAMS:
182 			fMessageRunnerManager->HandleSetRunnerParams(message);
183 			break;
184 		case B_REG_GET_MESSAGE_RUNNER_INFO:
185 			fMessageRunnerManager->HandleGetRunnerInfo(message);
186 			break;
187 		// internal messages
188 		case B_REG_ROSTER_SANITY_EVENT:
189 			fRoster->CheckSanity();
190 			fSanityEvent->SetTime(system_time() + kRosterSanityEventInterval);
191 			fEventQueue->AddEvent(fSanityEvent);
192 			break;
193 		default:
194 			BApplication::MessageReceived(message);
195 			break;
196 	}
197 //	FUNCTION_END();
198 }
199 
200 // ReadyToRun
201 /*!	\brief Overrides the super class version to initialize the registrar
202 		   services.
203 */
204 void
205 Registrar::ReadyToRun()
206 {
207 	FUNCTION_START();
208 	// create event queue
209 	fEventQueue = new EventQueue(kEventQueueName);
210 	// create roster
211 	fRoster = new TRoster;
212 	fRoster->Init();
213 	// create clipboard handler
214 	fClipboardHandler = new ClipboardHandler;
215 	AddHandler(fClipboardHandler);
216 	// create MIME manager
217 	fMIMEManager = new MIMEManager;
218 	fMIMEManager->Run();
219 	// create message runner manager
220 	fMessageRunnerManager = new MessageRunnerManager(fEventQueue);
221 	// init the global be_roster
222 	BRoster::Private().SetTo(be_app_messenger, BMessenger(NULL, fMIMEManager));
223 	// create and schedule the sanity message event
224 	fSanityEvent = new MessageEvent(system_time() + kRosterSanityEventInterval,
225 									this, B_REG_ROSTER_SANITY_EVENT);
226 	fSanityEvent->SetAutoDelete(false);
227 	fEventQueue->AddEvent(fSanityEvent);
228 	FUNCTION_END();
229 }
230 
231 // QuitRequested
232 /*!	\brief Overrides the super class version to avoid termination of the
233 		   registrar until the system shutdown.
234 */
235 bool
236 Registrar::QuitRequested()
237 {
238 	FUNCTION_START();
239 	// The final registrar must not quit. At least not that easily. ;-)
240 	return BApplication::QuitRequested();
241 }
242 
243 // GetEventQueue
244 /*!	\brief Returns the registrar's event queue.
245 	\return The registrar's event queue.
246 */
247 EventQueue*
248 Registrar::GetEventQueue() const
249 {
250 	return fEventQueue;
251 }
252 
253 // App
254 /*!	\brief Returns the Registrar application object.
255 	\return The Registrar application object.
256 */
257 Registrar*
258 Registrar::App()
259 {
260 	return dynamic_cast<Registrar*>(be_app);
261 }
262 
263 
264 // main
265 /*!	\brief Creates and runs the registrar application.
266 
267 	The main thread is renamed.
268 
269 	\return 0.
270 */
271 int
272 main()
273 {
274 	FUNCTION_START();
275 	// rename the main thread
276 	rename_thread(find_thread(NULL), kRosterThreadName);
277 	// create and run the registrar application
278 	Registrar *app = new Registrar();
279 PRINT(("app->Run()...\n"));
280 	app->Run();
281 PRINT(("delete app...\n"));
282 	delete app;
283 	FUNCTION_END();
284 	return 0;
285 }
286 
287