[Author: zork]
[google-gears.git] / gears / base / firefox / module.cc
blob14b4236c47d59ac7c367c84b4190baf875a9c51a
1 // Copyright 2005, Google Inc.
2 //
3 // Redistribution and use in source and binary forms, with or without
4 // modification, are permitted provided that the following conditions are met:
5 //
6 // 1. Redistributions of source code must retain the above copyright notice,
7 // this list of conditions and the following disclaimer.
8 // 2. Redistributions in binary form must reproduce the above copyright notice,
9 // this list of conditions and the following disclaimer in the documentation
10 // and/or other materials provided with the distribution.
11 // 3. Neither the name of Google Inc. nor the names of its contributors may be
12 // used to endorse or promote products derived from this software without
13 // specific prior written permission.
15 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
16 // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
17 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
18 // EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21 // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 #include <gecko_sdk/include/nsXPCOM.h>
27 #include <gecko_sdk/include/nsMemory.h>
28 #include <gecko_sdk/include/nsILocalFile.h>
29 #include <gecko_sdk/include/nsIGenericFactory.h>
30 #include <gecko_sdk/include/nsICategoryManager.h>
31 #include <gecko_internal/nsIDOMClassInfo.h>
32 #include <gecko_internal/nsIScriptNameSpaceManager.h>
34 #include "gears/base/common/thread_locals.h"
35 #include "gears/console/firefox/console_ff.h"
36 #include "gears/database/firefox/database.h"
37 #include "gears/database/firefox/result_set.h"
38 #include "gears/desktop/desktop_ff.h"
39 #include "gears/factory/firefox/factory.h"
40 #include "gears/httprequest/firefox/httprequest_ff.h"
42 #ifdef OFFICIAL_BUILD
43 // The Image and Blob APIs have not been finalized for official builds
44 #else
45 #include "gears/blob/blob_ff.h"
46 #include "gears/image/firefox/image_ff.h"
47 #include "gears/image/firefox/image_loader_ff.h"
48 #endif
50 #include "gears/localserver/firefox/cache_intercept.h"
51 #include "gears/localserver/firefox/file_submitter_ff.h"
52 #include "gears/localserver/firefox/localserver_ff.h"
53 #include "gears/localserver/firefox/managed_resource_store_ff.h"
54 #include "gears/localserver/firefox/resource_store_ff.h"
55 #include "gears/timer/timer.h"
56 #include "gears/ui/firefox/ui_utils.h"
57 #include "gears/workerpool/firefox/workerpool.h"
59 //-----------------------------------------------------------------------------
61 // TODO(cprince): can remove this when switch to google3 logging
62 #ifdef PR_LOGGING
63 PRLogModuleInfo *gLog = PR_NewLogModule(PRODUCT_SHORT_NAME_ASCII);
64 #endif
66 //-----------------------------------------------------------------------------
68 #define SINGLETON_CONSTRUCTOR(class_) \
69 static NS_METHOD class_##Constructor(nsISupports *outer, \
70 const nsIID &iid, \
71 void **result) { \
72 if (outer) \
73 return NS_ERROR_NO_AGGREGATION; \
74 static class_ *service = nsnull; \
75 if (!service) { \
76 service = new class_(); \
77 if (!service) \
78 return NS_ERROR_OUT_OF_MEMORY; \
79 NS_ADDREF(service); /* hold reference for lifetime of app */ \
80 } \
81 return service->QueryInterface(iid, result); \
84 #define SINGLETON_CONSTRUCTOR_INIT(class_) \
85 static NS_METHOD class_##Constructor(nsISupports *outer, \
86 const nsIID &iid, \
87 void **result) { \
88 if (outer) \
89 return NS_ERROR_NO_AGGREGATION; \
90 static class_ *service = nsnull; \
91 if (!service) { \
92 service = new class_(); \
93 if (!service) \
94 return NS_ERROR_OUT_OF_MEMORY; \
95 NS_ADDREF(service); /* hold reference for lifetime of app */ \
96 nsresult rv = service->Init(); \
97 if (NS_FAILED(rv)) { \
98 NS_RELEASE(service); \
99 return rv; \
102 return service->QueryInterface(iid, result); \
105 //-----------------------------------------------------------------------------
108 const char *kDomciExtensionContractId = "@google.com/" PRODUCT_SHORT_NAME_ASCII
109 "/domciextension;1";
110 const char *kDomciExtensionClassName = "DomciExtension";
111 const nsCID kDomciExtensionClassId = {0x71f2446a, 0x81ed, 0x4345, {0x8d, 0xdb,
112 0xd6, 0x9b, 0xd5, 0xc3, 0xc7, 0x32}};
113 // {71F2446A-81ED-4345-8DDB-D69BD5C3C732}
115 NS_DOMCI_EXTENSION(Scour)
116 // "Under The Hood":
117 // The entries below form the body of this extension's RegisterDOMCI method.
118 // For each block, if the string in line 1 matches the RegisterDOMCI argument,
119 // RegisterDOMClassInfo will be called for each of the enclosed IIDs.
120 // RegisterDOMClassInfo calls into gNameSpaceManager->RegisterDOMCIData.
122 // factory
123 NS_DOMCI_EXTENSION_ENTRY_BEGIN(GearsFactory)
124 NS_DOMCI_EXTENSION_ENTRY_INTERFACE(GearsFactoryInterface)
125 NS_DOMCI_EXTENSION_ENTRY_END_NO_PRIMARY_IF(GearsFactory, PR_TRUE,
126 &kGearsFactoryClassId)
128 // database
129 NS_DOMCI_EXTENSION_ENTRY_BEGIN(GearsDatabase)
130 NS_DOMCI_EXTENSION_ENTRY_INTERFACE(GearsDatabaseInterface)
131 NS_DOMCI_EXTENSION_ENTRY_END_NO_PRIMARY_IF(GearsDatabase, PR_TRUE,
132 &kGearsDatabaseClassId)
133 NS_DOMCI_EXTENSION_ENTRY_BEGIN(GearsResultSet)
134 NS_DOMCI_EXTENSION_ENTRY_INTERFACE(GearsResultSetInterface)
135 NS_DOMCI_EXTENSION_ENTRY_END_NO_PRIMARY_IF(GearsResultSet, PR_TRUE,
136 &kGearsResultSetClassId)
138 // desktop
139 NS_DOMCI_EXTENSION_ENTRY_BEGIN(GearsDesktop)
140 NS_DOMCI_EXTENSION_ENTRY_INTERFACE(GearsDesktopInterface)
141 NS_DOMCI_EXTENSION_ENTRY_END_NO_PRIMARY_IF(GearsDesktop, PR_TRUE,
142 &kGearsDesktopClassId)
144 // httprequest
145 NS_DOMCI_EXTENSION_ENTRY_BEGIN(GearsHttpRequest)
146 NS_DOMCI_EXTENSION_ENTRY_INTERFACE(GearsHttpRequestInterface)
147 NS_DOMCI_EXTENSION_ENTRY_END_NO_PRIMARY_IF(GearsHttpRequest, PR_TRUE,
148 &kGearsHttpRequestClassId)
150 // workerpool
151 NS_DOMCI_EXTENSION_ENTRY_BEGIN(GearsWorkerPool)
152 NS_DOMCI_EXTENSION_ENTRY_INTERFACE(GearsWorkerPoolInterface)
153 NS_DOMCI_EXTENSION_ENTRY_END_NO_PRIMARY_IF(GearsWorkerPool, PR_TRUE,
154 &kGearsWorkerPoolClassId)
156 // localserver
157 NS_DOMCI_EXTENSION_ENTRY_BEGIN(GearsLocalServer)
158 NS_DOMCI_EXTENSION_ENTRY_INTERFACE(GearsLocalServerInterface)
159 NS_DOMCI_EXTENSION_ENTRY_END_NO_PRIMARY_IF(GearsLocalServer, PR_TRUE,
160 &kGearsLocalServerClassId)
161 NS_DOMCI_EXTENSION_ENTRY_BEGIN(GearsManagedResourceStore)
162 NS_DOMCI_EXTENSION_ENTRY_INTERFACE(GearsManagedResourceStoreInterface)
163 NS_DOMCI_EXTENSION_ENTRY_END_NO_PRIMARY_IF(GearsManagedResourceStore, PR_TRUE,
164 &kGearsManagedResourceStoreClassId)
165 NS_DOMCI_EXTENSION_ENTRY_BEGIN(GearsResourceStore)
166 NS_DOMCI_EXTENSION_ENTRY_INTERFACE(GearsResourceStoreInterface)
167 NS_DOMCI_EXTENSION_ENTRY_END_NO_PRIMARY_IF(GearsResourceStore, PR_TRUE,
168 &kGearsResourceStoreClassId)
169 NS_DOMCI_EXTENSION_ENTRY_BEGIN(GearsFileSubmitter)
170 NS_DOMCI_EXTENSION_ENTRY_INTERFACE(GearsFileSubmitterInterface)
171 NS_DOMCI_EXTENSION_ENTRY_END_NO_PRIMARY_IF(GearsFileSubmitter, PR_TRUE,
172 &kGearsFileSubmitterClassId)
174 // timer
175 NS_DOMCI_EXTENSION_ENTRY_BEGIN(GearsTimer)
176 NS_DOMCI_EXTENSION_ENTRY_INTERFACE(GearsTimerInterface)
177 NS_DOMCI_EXTENSION_ENTRY_END_NO_PRIMARY_IF(GearsTimer, PR_TRUE,
178 &kGearsTimerClassId)
180 // console
181 NS_DOMCI_EXTENSION_ENTRY_BEGIN(GearsConsole)
182 NS_DOMCI_EXTENSION_ENTRY_INTERFACE(GearsConsoleInterface)
183 NS_DOMCI_EXTENSION_ENTRY_END_NO_PRIMARY_IF(GearsConsole, PR_TRUE,
184 &kGearsConsoleClassId)
186 #ifdef OFFICIAL_BUILD
187 // The Image and blob APIs have not been finalized for official builds
188 #else
189 // blob
190 NS_DOMCI_EXTENSION_ENTRY_BEGIN(GearsBlob)
191 NS_DOMCI_EXTENSION_ENTRY_INTERFACE(GearsBlobInterface)
192 NS_DOMCI_EXTENSION_ENTRY_END_NO_PRIMARY_IF(GearsBlob, PR_TRUE,
193 &kGearsBlobClassId)
195 // image
196 NS_DOMCI_EXTENSION_ENTRY_BEGIN(GearsImage)
197 NS_DOMCI_EXTENSION_ENTRY_INTERFACE(GearsImageInterface)
198 NS_DOMCI_EXTENSION_ENTRY_END_NO_PRIMARY_IF(GearsImage, PR_TRUE,
199 &kGearsImageClassId)
200 NS_DOMCI_EXTENSION_ENTRY_BEGIN(GearsImageLoader)
201 NS_DOMCI_EXTENSION_ENTRY_INTERFACE(GearsImageLoaderInterface)
202 NS_DOMCI_EXTENSION_ENTRY_END_NO_PRIMARY_IF(GearsImageLoader, PR_TRUE,
203 &kGearsImageLoaderClassId)
204 #endif
206 NS_DOMCI_EXTENSION_END
208 static NS_METHOD ScourRegisterSelf(nsIComponentManager *compMgr,
209 nsIFile *path,
210 const char *loaderStr,
211 const char *type,
212 const nsModuleComponentInfo *info) {
213 LOG(("RegisterSelf()\n"));
215 // Trigger early initialization of our cache interceptor.
216 nsCOMPtr<nsICategoryManager> catMgr =
217 do_GetService(NS_CATEGORYMANAGER_CONTRACTID);
218 if (!catMgr)
219 return NS_ERROR_UNEXPECTED;
221 // The cache intercept component needs to be initialized at xpcom startup
222 // time (so that it can override the default cache implementation).
223 catMgr->AddCategoryEntry(NS_XPCOM_STARTUP_OBSERVER_ID,
224 kCacheInterceptClassName,
225 kCacheInterceptContractId,
226 PR_TRUE, PR_TRUE, NULL);
229 const struct {
230 const char *className;
231 const char *interfaceName;
232 const char *interfaceIDStr;
233 } jsDOMClasses[] = {
234 // factory
235 { kGearsFactoryClassName, "GearsFactoryInterface",
236 GEARSFACTORYINTERFACE_IID_STR },
237 // database
238 { kGearsDatabaseClassName, "GearsDatabaseInterface",
239 GEARSDATABASEINTERFACE_IID_STR },
240 { kGearsResultSetClassName, "GearsResultSetInterface",
241 GEARSRESULTSETINTERFACE_IID_STR },
242 // desktop
243 { kGearsDesktopClassName, "GearsDesktopInterface",
244 GEARSDESKTOPINTERFACE_IID_STR },
245 // httprequest
246 { kGearsHttpRequestClassName, "GearsHttpRequestInterface",
247 GEARSHTTPREQUESTINTERFACE_IID_STR },
248 // workerpool
249 { kGearsWorkerPoolClassName, "GearsWorkerPoolInterface",
250 GEARSWORKERPOOLINTERFACE_IID_STR },
251 // localserver
252 { kGearsLocalServerClassName, "GearsLocalServerInterface",
253 GEARSLOCALSERVERINTERFACE_IID_STR },
254 { kGearsManagedResourceStoreClassName, "GearsManagedResourceStoreInterface",
255 GEARSMANAGEDRESOURCESTOREINTERFACE_IID_STR },
256 { kGearsResourceStoreClassName, "GearsResourceStoreInterface",
257 GEARSRESOURCESTOREINTERFACE_IID_STR },
258 { kGearsFileSubmitterClassName, "GearsFileSubmitterInterface",
259 GEARSFILESUBMITTERINTERFACE_IID_STR },
260 // timer
261 { kGearsTimerClassName, "GearsTimerInterface",
262 GEARSTIMERINTERFACE_IID_STR },
263 #ifdef OFFICIAL_BUILD
264 // The Image and blob APIs have not been finalized for official builds
265 #else
266 // blob
267 { kGearsBlobClassName, "GearsBlobInterface",
268 GEARSBLOBINTERFACE_IID_STR },
269 // image
270 { kGearsImageClassName, "GearsImageInterface",
271 GEARSIMAGEINTERFACE_IID_STR },
272 { kGearsImageLoaderClassName, "GearsImageLoaderInterface",
273 GEARSIMAGELOADERINTERFACE_IID_STR },
274 #endif
275 // console
276 { kGearsConsoleClassName, "GearsConsoleInterface",
277 GEARSCONSOLEINTERFACE_IID_STR }
280 for (size_t i = 0; i < NS_ARRAY_LENGTH(jsDOMClasses); ++i) {
281 catMgr->AddCategoryEntry(JAVASCRIPT_DOM_CLASS,
282 jsDOMClasses[i].className,
283 kDomciExtensionContractId,
284 PR_TRUE, PR_TRUE, NULL);
285 // AddCategoryEntry(JAVASCRIPT_DOM_INTERFACE, ...) does not seem to be
286 // necessary for our Gears interfaces.
289 return NS_OK;
293 // We need a NS_DECL_DOM_CLASSINFO for each
294 // NS_INTERFACE_MAP_ENTRY_EXTERNAL_DOM_CLASSINFO in the codebase.
296 // These macros inform the DOM about every Gears class it might see
297 // (indicating, for example, what methods and properties exist).
299 // "Under The Hood":
300 // NS_DECL_DOM_CLASSINFO instances a global variable. Its argument must match
301 // the argument to NS_INTERFACE_MAP_ENTRY_EXTERNAL_DOM_CLASSINFO. The value
302 // also gets string-ified and affects the class name exposed to JavaScript.
304 // factory
305 NS_DECL_DOM_CLASSINFO(GearsFactory)
306 // database
307 NS_DECL_DOM_CLASSINFO(GearsDatabase)
308 NS_DECL_DOM_CLASSINFO(GearsResultSet)
309 // desktop
310 NS_DECL_DOM_CLASSINFO(GearsDesktop)
311 // httprequest
312 NS_DECL_DOM_CLASSINFO(GearsHttpRequest)
313 // workerpool
314 NS_DECL_DOM_CLASSINFO(GearsWorkerPool)
315 // localserver
316 NS_DECL_DOM_CLASSINFO(GearsLocalServer)
317 NS_DECL_DOM_CLASSINFO(GearsManagedResourceStore)
318 NS_DECL_DOM_CLASSINFO(GearsResourceStore)
319 NS_DECL_DOM_CLASSINFO(GearsFileSubmitter)
321 // timer
322 NS_DECL_DOM_CLASSINFO(GearsTimer)
323 // console
324 NS_DECL_DOM_CLASSINFO(GearsConsole)
326 #ifdef OFFICIAL_BUILD
327 // The Image and blob APIs have not been finalized for official builds
328 #else
329 // blob
330 NS_DECL_DOM_CLASSINFO(GearsBlob)
331 // image
332 NS_DECL_DOM_CLASSINFO(GearsImage)
333 NS_DECL_DOM_CLASSINFO(GearsImageLoader)
334 #endif
336 nsresult PR_CALLBACK ScourModuleConstructor(nsIModule *self) {
337 return ThreadLocals::HandleModuleConstructed();
341 void PR_CALLBACK ScourModuleDestructor(nsIModule *self) {
342 // We need a NS_IF_RELEASE for each
343 // NS_INTERFACE_MAP_ENTRY_EXTERNAL_DOM_CLASSINFO in the codebase.
345 // factory
346 NS_IF_RELEASE(NS_CLASSINFO_NAME(GearsFactory));
347 // database
348 NS_IF_RELEASE(NS_CLASSINFO_NAME(GearsDatabase));
349 NS_IF_RELEASE(NS_CLASSINFO_NAME(GearsResultSet));
350 // desktop
351 NS_IF_RELEASE(NS_CLASSINFO_NAME(GearsDesktop));
352 // httprequest
353 NS_IF_RELEASE(NS_CLASSINFO_NAME(GearsHttpRequest));
354 // workerpool
355 NS_IF_RELEASE(NS_CLASSINFO_NAME(GearsWorkerPool));
356 // localserver
357 NS_IF_RELEASE(NS_CLASSINFO_NAME(GearsLocalServer));
358 NS_IF_RELEASE(NS_CLASSINFO_NAME(GearsManagedResourceStore));
359 NS_IF_RELEASE(NS_CLASSINFO_NAME(GearsResourceStore));
360 // timer
361 NS_IF_RELEASE(NS_CLASSINFO_NAME(GearsTimer));
362 // console
363 NS_IF_RELEASE(NS_CLASSINFO_NAME(GearsConsole));
365 #ifdef OFFICIAL_BUILD
366 // The Image and blob APIs have not been finalized for official builds
367 #else
368 // blob
369 NS_IF_RELEASE(NS_CLASSINFO_NAME(GearsBlob));
370 // image
371 NS_IF_RELEASE(NS_CLASSINFO_NAME(GearsImage));
372 NS_IF_RELEASE(NS_CLASSINFO_NAME(GearsImageLoader));
373 #endif
375 #ifdef DEBUG
376 NS_IF_RELEASE(NS_CLASSINFO_NAME(GearsFileSubmitter));
377 #endif
381 // Define nsFactory constructors for certain classes.
382 // These constructors are referenced in components[] below.
384 // We do not need to define a factory constructor for Gears objects that
385 // should only be created via GearsFactory (rather than instanced directly).
387 // IMPORTANT: objects that derive from ModuleImplBaseClass should not use
388 // singleton init because their state (like security origin) will not get
389 // updated when the page changes!
391 SINGLETON_CONSTRUCTOR(CacheIntercept)
392 SINGLETON_CONSTRUCTOR(GearsUiUtils)
393 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(GearsFactory, InitBaseFromDOM)
394 // On Firefox this C++ Factory name affects the script-visible name.
395 // It may be possible to use modified Mozilla macros to break the dependency,
396 // but we don't have that ability today.
399 static const nsModuleComponentInfo components[] = {
400 // internal plumbing
401 { kDomciExtensionClassName, // [0] fields could be any description string
402 kDomciExtensionClassId,
403 kDomciExtensionContractId,
404 NS_DOMCI_EXTENSION_CONSTRUCTOR(Scour) },
406 { kCacheInterceptClassName,
407 kCacheInterceptClassId,
408 kCacheInterceptContractId,
409 CacheInterceptConstructor,
410 ScourRegisterSelf }, // register all components in one go
412 // ui
413 { kGearsUiUtilsClassName,
414 kGearsUiUtilsClassId,
415 kGearsUiUtilsContractId,
416 GearsUiUtilsConstructor },
418 // factory
419 { kGearsFactoryClassName,
420 kGearsFactoryClassId,
421 kGearsFactoryContractId,
422 GearsFactoryConstructor }
426 NS_IMPL_NSGETMODULE_WITH_CTOR_DTOR(gears_module, components,
427 ScourModuleConstructor,
428 ScourModuleDestructor)