Bug 1492908 [wpt PR 13122] - Update wpt metadata, a=testonly
[gecko.git] / chrome / nsChromeRegistryChrome.cpp
blob41b4d90bd771f0b25672d4fa046da2ee39ad2cb6
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 sts=2 sw=2 et tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/dom/ContentParent.h"
8 #include "RegistryMessageUtils.h"
9 #include "nsResProtocolHandler.h"
11 #include "nsChromeRegistryChrome.h"
13 #if defined(XP_WIN)
14 #include <windows.h>
15 #elif defined(XP_MACOSX)
16 #include <CoreServices/CoreServices.h>
17 #endif
19 #include "nsArrayEnumerator.h"
20 #include "nsComponentManager.h"
21 #include "nsEnumeratorUtils.h"
22 #include "nsNetUtil.h"
23 #include "nsStringEnumerator.h"
24 #include "nsTextFormatter.h"
25 #include "nsXPCOMCIDInternal.h"
27 #include "mozilla/LookAndFeel.h"
28 #include "mozilla/Unused.h"
29 #include "mozilla/intl/LocaleService.h"
31 #include "nsIObserverService.h"
32 #include "nsIPrefBranch.h"
33 #include "nsIPrefService.h"
34 #include "mozilla/Preferences.h"
35 #include "nsIResProtocolHandler.h"
36 #include "nsIScriptError.h"
37 #include "nsIXULRuntime.h"
39 #define SELECTED_SKIN_PREF "general.skins.selectedSkin"
40 #define PACKAGE_OVERRIDE_BRANCH "chrome.override_package."
42 using namespace mozilla;
43 using mozilla::dom::ContentParent;
44 using mozilla::dom::PContentParent;
45 using mozilla::intl::LocaleService;
47 // We use a "best-fit" algorithm for matching locales and themes.
48 // 1) the exact selected locale/theme
49 // 2) (locales only) same language, different country
50 // e.g. en-GB is the selected locale, only en-US is available
51 // 3) any available locale/theme
53 /**
54 * Match the language-part of two lang-COUNTRY codes, hopefully but
55 * not guaranteed to be in the form ab-CD or abz-CD. "ab" should also
56 * work, any other garbage-in will produce undefined results as long
57 * as it does not crash.
59 static bool
60 LanguagesMatch(const nsACString& a, const nsACString& b)
62 if (a.Length() < 2 || b.Length() < 2)
63 return false;
65 nsACString::const_iterator as, ae, bs, be;
66 a.BeginReading(as);
67 a.EndReading(ae);
68 b.BeginReading(bs);
69 b.EndReading(be);
71 while (*as == *bs) {
72 if (*as == '-')
73 return true;
75 ++as; ++bs;
77 // reached the end
78 if (as == ae && bs == be)
79 return true;
81 // "a" is short
82 if (as == ae)
83 return (*bs == '-');
85 // "b" is short
86 if (bs == be)
87 return (*as == '-');
90 return false;
93 nsChromeRegistryChrome::nsChromeRegistryChrome()
94 : mProfileLoaded(false)
95 , mDynamicRegistration(true)
99 nsChromeRegistryChrome::~nsChromeRegistryChrome()
103 nsresult
104 nsChromeRegistryChrome::Init()
106 nsresult rv = nsChromeRegistry::Init();
107 if (NS_FAILED(rv))
108 return rv;
110 mSelectedSkin = NS_LITERAL_CSTRING("classic/1.0");
112 bool safeMode = false;
113 nsCOMPtr<nsIXULRuntime> xulrun (do_GetService(XULAPPINFO_SERVICE_CONTRACTID));
114 if (xulrun)
115 xulrun->GetInSafeMode(&safeMode);
117 nsCOMPtr<nsIPrefService> prefserv (do_GetService(NS_PREFSERVICE_CONTRACTID));
118 nsCOMPtr<nsIPrefBranch> prefs;
120 if (prefserv) {
121 if (safeMode) {
122 prefserv->GetDefaultBranch(nullptr, getter_AddRefs(prefs));
123 } else {
124 prefs = do_QueryInterface(prefserv);
128 if (!prefs) {
129 NS_WARNING("Could not get pref service!");
130 } else {
131 nsAutoCString provider;
132 rv = prefs->GetCharPref(SELECTED_SKIN_PREF, provider);
133 if (NS_SUCCEEDED(rv))
134 mSelectedSkin = provider;
136 rv = prefs->AddObserver(SELECTED_SKIN_PREF, this, true);
139 nsCOMPtr<nsIObserverService> obsService = mozilla::services::GetObserverService();
140 if (obsService) {
141 obsService->AddObserver(this, "profile-initial-state", true);
142 obsService->AddObserver(this, "intl:app-locales-changed", true);
145 return NS_OK;
148 NS_IMETHODIMP
149 nsChromeRegistryChrome::CheckForOSAccessibility()
151 int32_t useAccessibilityTheme =
152 LookAndFeel::GetInt(LookAndFeel::eIntID_UseAccessibilityTheme, 0);
154 if (useAccessibilityTheme) {
155 /* Set the skin to classic and remove pref observers */
156 if (!mSelectedSkin.EqualsLiteral("classic/1.0")) {
157 mSelectedSkin.AssignLiteral("classic/1.0");
158 RefreshSkins();
161 nsCOMPtr<nsIPrefBranch> prefs (do_GetService(NS_PREFSERVICE_CONTRACTID));
162 if (prefs) {
163 prefs->RemoveObserver(SELECTED_SKIN_PREF, this);
167 return NS_OK;
170 NS_IMETHODIMP
171 nsChromeRegistryChrome::GetLocalesForPackage(const nsACString& aPackage,
172 nsIUTF8StringEnumerator* *aResult)
174 nsCString realpackage;
175 nsresult rv = OverrideLocalePackage(aPackage, realpackage);
176 if (NS_FAILED(rv))
177 return rv;
179 nsTArray<nsCString> *a = new nsTArray<nsCString>;
180 if (!a)
181 return NS_ERROR_OUT_OF_MEMORY;
183 PackageEntry* entry;
184 if (mPackagesHash.Get(realpackage, &entry)) {
185 entry->locales.EnumerateToArray(a);
188 rv = NS_NewAdoptingUTF8StringEnumerator(aResult, a);
189 if (NS_FAILED(rv))
190 delete a;
192 return rv;
195 NS_IMETHODIMP
196 nsChromeRegistryChrome::IsLocaleRTL(const nsACString& package, bool *aResult)
198 *aResult = false;
200 nsAutoCString locale;
201 GetSelectedLocale(package, false, locale);
202 if (locale.Length() < 2)
203 return NS_OK;
205 *aResult = GetDirectionForLocale(locale);
206 return NS_OK;
210 * This method negotiates only between the app locale and the available
211 * chrome packages.
213 * If you want to get the current application's UI locale, please use
214 * LocaleService::GetAppLocaleAsLangTag.
216 nsresult
217 nsChromeRegistryChrome::GetSelectedLocale(const nsACString& aPackage,
218 bool aAsBCP47,
219 nsACString& aLocale)
221 nsAutoCString reqLocale;
222 if (aPackage.EqualsLiteral("global")) {
223 LocaleService::GetInstance()->GetAppLocaleAsLangTag(reqLocale);
224 } else {
225 AutoTArray<nsCString, 10> requestedLocales;
226 LocaleService::GetInstance()->GetRequestedLocales(requestedLocales);
227 reqLocale.Assign(requestedLocales[0]);
230 nsCString realpackage;
231 nsresult rv = OverrideLocalePackage(aPackage, realpackage);
232 if (NS_FAILED(rv))
233 return rv;
234 PackageEntry* entry;
235 if (!mPackagesHash.Get(realpackage, &entry))
236 return NS_ERROR_FILE_NOT_FOUND;
238 aLocale = entry->locales.GetSelected(reqLocale, nsProviderArray::LOCALE);
239 if (aLocale.IsEmpty())
240 return NS_ERROR_FAILURE;
242 if (aAsBCP47) {
243 SanitizeForBCP47(aLocale);
246 return NS_OK;
249 nsresult
250 nsChromeRegistryChrome::OverrideLocalePackage(const nsACString& aPackage,
251 nsACString& aOverride)
253 const nsACString& pref = NS_LITERAL_CSTRING(PACKAGE_OVERRIDE_BRANCH) + aPackage;
254 nsAutoCString override;
255 nsresult rv =
256 mozilla::Preferences::GetCString(PromiseFlatCString(pref).get(), override);
257 if (NS_SUCCEEDED(rv)) {
258 aOverride = override;
259 } else {
260 aOverride = aPackage;
262 return NS_OK;
265 NS_IMETHODIMP
266 nsChromeRegistryChrome::Observe(nsISupports *aSubject, const char *aTopic,
267 const char16_t *someData)
269 nsresult rv = NS_OK;
271 if (!strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, aTopic)) {
272 nsCOMPtr<nsIPrefBranch> prefs (do_QueryInterface(aSubject));
273 NS_ASSERTION(prefs, "Bad observer call!");
275 NS_ConvertUTF16toUTF8 pref(someData);
277 if (pref.EqualsLiteral(SELECTED_SKIN_PREF)) {
278 nsAutoCString provider;
279 rv = prefs->GetCharPref(pref.get(), provider);
280 if (NS_FAILED(rv)) {
281 NS_ERROR("Couldn't get new skin pref!");
282 return rv;
285 mSelectedSkin = provider;
286 RefreshSkins();
287 } else {
288 NS_ERROR("Unexpected pref!");
291 else if (!strcmp("profile-initial-state", aTopic)) {
292 mProfileLoaded = true;
294 else if (!strcmp("intl:app-locales-changed", aTopic)) {
295 if (mProfileLoaded) {
296 FlushAllCaches();
299 else {
300 NS_ERROR("Unexpected observer topic!");
303 return rv;
306 NS_IMETHODIMP
307 nsChromeRegistryChrome::CheckForNewChrome()
309 mPackagesHash.Clear();
310 mOverrideTable.Clear();
312 mDynamicRegistration = false;
314 nsComponentManagerImpl::gComponentManager->RereadChromeManifests();
316 mDynamicRegistration = true;
318 SendRegisteredChrome(nullptr);
319 return NS_OK;
322 static void
323 SerializeURI(nsIURI* aURI,
324 SerializedURI& aSerializedURI)
326 if (!aURI)
327 return;
329 aURI->GetSpec(aSerializedURI.spec);
332 void
333 nsChromeRegistryChrome::SendRegisteredChrome(
334 mozilla::dom::PContentParent* aParent)
336 InfallibleTArray<ChromePackage> packages;
337 InfallibleTArray<SubstitutionMapping> resources;
338 InfallibleTArray<OverrideMapping> overrides;
340 for (auto iter = mPackagesHash.Iter(); !iter.Done(); iter.Next()) {
341 ChromePackage chromePackage;
342 ChromePackageFromPackageEntry(iter.Key(), iter.UserData(), &chromePackage,
343 mSelectedSkin);
344 packages.AppendElement(chromePackage);
347 // If we were passed a parent then a new child process has been created and
348 // has requested all of the chrome so send it the resources too. Otherwise
349 // resource mappings are sent by the resource protocol handler dynamically.
350 if (aParent) {
351 nsCOMPtr<nsIIOService> io (do_GetIOService());
352 NS_ENSURE_TRUE_VOID(io);
354 nsCOMPtr<nsIProtocolHandler> ph;
355 nsresult rv = io->GetProtocolHandler("resource", getter_AddRefs(ph));
356 NS_ENSURE_SUCCESS_VOID(rv);
358 nsCOMPtr<nsIResProtocolHandler> irph (do_QueryInterface(ph));
359 nsResProtocolHandler* rph = static_cast<nsResProtocolHandler*>(irph.get());
360 rv = rph->CollectSubstitutions(resources);
361 NS_ENSURE_SUCCESS_VOID(rv);
364 for (auto iter = mOverrideTable.Iter(); !iter.Done(); iter.Next()) {
365 SerializedURI chromeURI, overrideURI;
367 SerializeURI(iter.Key(), chromeURI);
368 SerializeURI(iter.UserData(), overrideURI);
370 OverrideMapping override = { chromeURI, overrideURI };
371 overrides.AppendElement(override);
374 nsAutoCString appLocale;
375 LocaleService::GetInstance()->GetAppLocaleAsLangTag(appLocale);
377 if (aParent) {
378 bool success = aParent->SendRegisterChrome(packages, resources, overrides,
379 appLocale, false);
380 NS_ENSURE_TRUE_VOID(success);
381 } else {
382 nsTArray<ContentParent*> parents;
383 ContentParent::GetAll(parents);
384 if (!parents.Length())
385 return;
387 for (uint32_t i = 0; i < parents.Length(); i++) {
388 DebugOnly<bool> success =
389 parents[i]->SendRegisterChrome(packages, resources, overrides,
390 appLocale, true);
391 NS_WARNING_ASSERTION(success,
392 "couldn't reset a child's registered chrome");
397 /* static */ void
398 nsChromeRegistryChrome::ChromePackageFromPackageEntry(const nsACString& aPackageName,
399 PackageEntry* aPackage,
400 ChromePackage* aChromePackage,
401 const nsCString& aSelectedSkin)
403 nsAutoCString appLocale;
404 LocaleService::GetInstance()->GetAppLocaleAsLangTag(appLocale);
406 SerializeURI(aPackage->baseURI, aChromePackage->contentBaseURI);
407 SerializeURI(aPackage->locales.GetBase(appLocale, nsProviderArray::LOCALE),
408 aChromePackage->localeBaseURI);
409 SerializeURI(aPackage->skins.GetBase(aSelectedSkin, nsProviderArray::ANY),
410 aChromePackage->skinBaseURI);
411 aChromePackage->package = aPackageName;
412 aChromePackage->flags = aPackage->flags;
415 static bool
416 CanLoadResource(nsIURI* aResourceURI)
418 bool isLocalResource = false;
419 (void)NS_URIChainHasFlags(aResourceURI,
420 nsIProtocolHandler::URI_IS_LOCAL_RESOURCE,
421 &isLocalResource);
422 return isLocalResource;
425 nsIURI*
426 nsChromeRegistryChrome::GetBaseURIFromPackage(const nsCString& aPackage,
427 const nsCString& aProvider,
428 const nsCString& aPath)
430 PackageEntry* entry;
431 if (!mPackagesHash.Get(aPackage, &entry)) {
432 if (!mInitialized)
433 return nullptr;
435 LogMessage("No chrome package registered for chrome://%s/%s/%s",
436 aPackage.get(), aProvider.get(), aPath.get());
438 return nullptr;
441 if (aProvider.EqualsLiteral("locale")) {
442 nsAutoCString appLocale;
443 LocaleService::GetInstance()->GetAppLocaleAsLangTag(appLocale);
444 return entry->locales.GetBase(appLocale, nsProviderArray::LOCALE);
446 else if (aProvider.EqualsLiteral("skin")) {
447 return entry->skins.GetBase(mSelectedSkin, nsProviderArray::ANY);
449 else if (aProvider.EqualsLiteral("content")) {
450 return entry->baseURI;
452 return nullptr;
455 nsresult
456 nsChromeRegistryChrome::GetFlagsFromPackage(const nsCString& aPackage,
457 uint32_t* aFlags)
459 PackageEntry* entry;
460 if (!mPackagesHash.Get(aPackage, &entry))
461 return NS_ERROR_FILE_NOT_FOUND;
463 *aFlags = entry->flags;
464 return NS_OK;
467 nsChromeRegistryChrome::ProviderEntry*
468 nsChromeRegistryChrome::nsProviderArray::GetProvider(const nsACString& aPreferred, MatchType aType)
470 size_t i = mArray.Length();
471 if (!i)
472 return nullptr;
474 ProviderEntry* found = nullptr; // Only set if we find a partial-match locale
475 ProviderEntry* entry = nullptr;
477 while (i--) {
478 entry = &mArray[i];
479 if (aPreferred.Equals(entry->provider))
480 return entry;
482 if (aType != LOCALE)
483 continue;
485 if (LanguagesMatch(aPreferred, entry->provider)) {
486 found = entry;
487 continue;
490 if (!found && entry->provider.EqualsLiteral("en-US"))
491 found = entry;
494 if (!found && aType != EXACT)
495 return entry;
497 return found;
500 nsIURI*
501 nsChromeRegistryChrome::nsProviderArray::GetBase(const nsACString& aPreferred, MatchType aType)
503 ProviderEntry* provider = GetProvider(aPreferred, aType);
505 if (!provider)
506 return nullptr;
508 return provider->baseURI;
511 const nsACString&
512 nsChromeRegistryChrome::nsProviderArray::GetSelected(const nsACString& aPreferred, MatchType aType)
514 ProviderEntry* entry = GetProvider(aPreferred, aType);
516 if (entry)
517 return entry->provider;
519 return EmptyCString();
522 void
523 nsChromeRegistryChrome::nsProviderArray::SetBase(const nsACString& aProvider, nsIURI* aBaseURL)
525 ProviderEntry* provider = GetProvider(aProvider, EXACT);
527 if (provider) {
528 provider->baseURI = aBaseURL;
529 return;
532 // no existing entries, add a new one
533 mArray.AppendElement(ProviderEntry(aProvider, aBaseURL));
536 void
537 nsChromeRegistryChrome::nsProviderArray::EnumerateToArray(nsTArray<nsCString> *a)
539 int32_t i = mArray.Length();
540 while (i--) {
541 a->AppendElement(mArray[i].provider);
545 nsIURI*
546 nsChromeRegistry::ManifestProcessingContext::GetManifestURI()
548 if (!mManifestURI) {
549 nsCString uri;
550 mFile.GetURIString(uri);
551 NS_NewURI(getter_AddRefs(mManifestURI), uri);
553 return mManifestURI;
556 already_AddRefed<nsIURI>
557 nsChromeRegistry::ManifestProcessingContext::ResolveURI(const char* uri)
559 nsIURI* baseuri = GetManifestURI();
560 if (!baseuri)
561 return nullptr;
563 nsCOMPtr<nsIURI> resolved;
564 nsresult rv = NS_NewURI(getter_AddRefs(resolved), uri, baseuri);
565 if (NS_FAILED(rv))
566 return nullptr;
568 return resolved.forget();
571 static void
572 EnsureLowerCase(char *aBuf)
574 for (; *aBuf; ++aBuf) {
575 char ch = *aBuf;
576 if (ch >= 'A' && ch <= 'Z')
577 *aBuf = ch + 'a' - 'A';
581 static void
582 SendManifestEntry(const ChromeRegistryItem &aItem)
584 nsTArray<ContentParent*> parents;
585 ContentParent::GetAll(parents);
586 if (!parents.Length())
587 return;
589 for (uint32_t i = 0; i < parents.Length(); i++) {
590 Unused << parents[i]->SendRegisterChromeItem(aItem);
594 void
595 nsChromeRegistryChrome::ManifestContent(ManifestProcessingContext& cx, int lineno,
596 char *const * argv, int flags)
598 char* package = argv[0];
599 char* uri = argv[1];
601 EnsureLowerCase(package);
603 nsCOMPtr<nsIURI> resolved = cx.ResolveURI(uri);
604 if (!resolved) {
605 LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
606 "During chrome registration, unable to create URI '%s'.", uri);
607 return;
610 if (!CanLoadResource(resolved)) {
611 LogMessageWithContext(resolved, lineno, nsIScriptError::warningFlag,
612 "During chrome registration, cannot register non-local URI '%s' as content.",
613 uri);
614 return;
617 nsDependentCString packageName(package);
618 PackageEntry* entry = mPackagesHash.LookupOrAdd(packageName);
619 entry->baseURI = resolved;
620 entry->flags = flags;
622 if (mDynamicRegistration) {
623 ChromePackage chromePackage;
624 ChromePackageFromPackageEntry(packageName, entry, &chromePackage,
625 mSelectedSkin);
626 SendManifestEntry(chromePackage);
630 void
631 nsChromeRegistryChrome::ManifestLocale(ManifestProcessingContext& cx, int lineno,
632 char *const * argv, int flags)
634 char* package = argv[0];
635 char* provider = argv[1];
636 char* uri = argv[2];
638 EnsureLowerCase(package);
640 nsCOMPtr<nsIURI> resolved = cx.ResolveURI(uri);
641 if (!resolved) {
642 LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
643 "During chrome registration, unable to create URI '%s'.", uri);
644 return;
647 if (!CanLoadResource(resolved)) {
648 LogMessageWithContext(resolved, lineno, nsIScriptError::warningFlag,
649 "During chrome registration, cannot register non-local URI '%s' as content.",
650 uri);
651 return;
654 nsDependentCString packageName(package);
655 PackageEntry* entry = mPackagesHash.LookupOrAdd(packageName);
656 entry->locales.SetBase(nsDependentCString(provider), resolved);
658 if (mDynamicRegistration) {
659 ChromePackage chromePackage;
660 ChromePackageFromPackageEntry(packageName, entry, &chromePackage,
661 mSelectedSkin);
662 SendManifestEntry(chromePackage);
665 // We use mainPackage as the package we track for reporting new locales being
666 // registered. For most cases it will be "global", but for Fennec it will be
667 // "browser".
668 nsAutoCString mainPackage;
669 nsresult rv = OverrideLocalePackage(NS_LITERAL_CSTRING("global"), mainPackage);
670 if (NS_FAILED(rv)) {
671 return;
675 void
676 nsChromeRegistryChrome::ManifestSkin(ManifestProcessingContext& cx, int lineno,
677 char *const * argv, int flags)
679 char* package = argv[0];
680 char* provider = argv[1];
681 char* uri = argv[2];
683 EnsureLowerCase(package);
685 nsCOMPtr<nsIURI> resolved = cx.ResolveURI(uri);
686 if (!resolved) {
687 LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
688 "During chrome registration, unable to create URI '%s'.", uri);
689 return;
692 if (!CanLoadResource(resolved)) {
693 LogMessageWithContext(resolved, lineno, nsIScriptError::warningFlag,
694 "During chrome registration, cannot register non-local URI '%s' as content.",
695 uri);
696 return;
699 nsDependentCString packageName(package);
700 PackageEntry* entry = mPackagesHash.LookupOrAdd(packageName);
701 entry->skins.SetBase(nsDependentCString(provider), resolved);
703 if (mDynamicRegistration) {
704 ChromePackage chromePackage;
705 ChromePackageFromPackageEntry(packageName, entry, &chromePackage,
706 mSelectedSkin);
707 SendManifestEntry(chromePackage);
711 void
712 nsChromeRegistryChrome::ManifestOverride(ManifestProcessingContext& cx, int lineno,
713 char *const * argv, int flags)
715 char* chrome = argv[0];
716 char* resolved = argv[1];
718 nsCOMPtr<nsIURI> chromeuri = cx.ResolveURI(chrome);
719 nsCOMPtr<nsIURI> resolveduri = cx.ResolveURI(resolved);
720 if (!chromeuri || !resolveduri) {
721 LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
722 "During chrome registration, unable to create URI.");
723 return;
726 if (cx.mType == NS_SKIN_LOCATION) {
727 bool chromeSkinOnly = false;
728 nsresult rv = chromeuri->SchemeIs("chrome", &chromeSkinOnly);
729 chromeSkinOnly = chromeSkinOnly && NS_SUCCEEDED(rv);
730 if (chromeSkinOnly) {
731 rv = resolveduri->SchemeIs("chrome", &chromeSkinOnly);
732 chromeSkinOnly = chromeSkinOnly && NS_SUCCEEDED(rv);
734 if (chromeSkinOnly) {
735 nsAutoCString chromePath, resolvedPath;
736 chromeuri->GetPathQueryRef(chromePath);
737 resolveduri->GetPathQueryRef(resolvedPath);
738 chromeSkinOnly = StringBeginsWith(chromePath, NS_LITERAL_CSTRING("/skin/")) &&
739 StringBeginsWith(resolvedPath, NS_LITERAL_CSTRING("/skin/"));
741 if (!chromeSkinOnly) {
742 LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
743 "Cannot register non-chrome://.../skin/ URIs '%s' and '%s' as overrides and/or to be overridden from a skin manifest.",
744 chrome, resolved);
745 return;
749 if (!CanLoadResource(resolveduri)) {
750 LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
751 "Cannot register non-local URI '%s' for an override.", resolved);
752 return;
754 mOverrideTable.Put(chromeuri, resolveduri);
756 if (mDynamicRegistration) {
757 SerializedURI serializedChrome;
758 SerializedURI serializedOverride;
760 SerializeURI(chromeuri, serializedChrome);
761 SerializeURI(resolveduri, serializedOverride);
763 OverrideMapping override = { serializedChrome, serializedOverride };
764 SendManifestEntry(override);
768 void
769 nsChromeRegistryChrome::ManifestResource(ManifestProcessingContext& cx, int lineno,
770 char *const * argv, int flags)
772 char* package = argv[0];
773 char* uri = argv[1];
775 EnsureLowerCase(package);
776 nsDependentCString host(package);
778 nsCOMPtr<nsIIOService> io = mozilla::services::GetIOService();
779 if (!io) {
780 NS_WARNING("No IO service trying to process chrome manifests");
781 return;
784 nsCOMPtr<nsIProtocolHandler> ph;
785 nsresult rv = io->GetProtocolHandler("resource", getter_AddRefs(ph));
786 if (NS_FAILED(rv))
787 return;
789 nsCOMPtr<nsIResProtocolHandler> rph = do_QueryInterface(ph);
791 nsCOMPtr<nsIURI> resolved = cx.ResolveURI(uri);
792 if (!resolved) {
793 LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
794 "During chrome registration, unable to create URI '%s'.", uri);
795 return;
798 if (!CanLoadResource(resolved)) {
799 LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
800 "Warning: cannot register non-local URI '%s' as a resource.",
801 uri);
802 return;
805 // By default, Firefox resources are not content-accessible unless the
806 // manifests opts in.
807 bool contentAccessible = (flags & nsChromeRegistry::CONTENT_ACCESSIBLE);
809 uint32_t substitutionFlags = 0;
810 if (contentAccessible) {
811 substitutionFlags |= nsIResProtocolHandler::ALLOW_CONTENT_ACCESS;
813 rv = rph->SetSubstitutionWithFlags(host, resolved, substitutionFlags);
814 if (NS_FAILED(rv)) {
815 LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
816 "Warning: cannot set substitution for '%s'.",
817 uri);