Bug 1524358 - use ownTaskId, instead of as_slugid('decision'), in .taskcluster.yml...
[gecko.git] / chrome / nsChromeRegistryChrome.cpp
blob8123fe30958629bfcbd5d9e3b90b363bcf619311
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 LanguagesMatch(const nsACString& a, const nsACString& b) {
60 if (a.Length() < 2 || b.Length() < 2) return false;
62 nsACString::const_iterator as, ae, bs, be;
63 a.BeginReading(as);
64 a.EndReading(ae);
65 b.BeginReading(bs);
66 b.EndReading(be);
68 while (*as == *bs) {
69 if (*as == '-') return true;
71 ++as;
72 ++bs;
74 // reached the end
75 if (as == ae && bs == be) return true;
77 // "a" is short
78 if (as == ae) return (*bs == '-');
80 // "b" is short
81 if (bs == be) return (*as == '-');
84 return false;
87 nsChromeRegistryChrome::nsChromeRegistryChrome()
88 : mProfileLoaded(false), mDynamicRegistration(true) {}
90 nsChromeRegistryChrome::~nsChromeRegistryChrome() {}
92 nsresult nsChromeRegistryChrome::Init() {
93 nsresult rv = nsChromeRegistry::Init();
94 if (NS_FAILED(rv)) return rv;
96 mSelectedSkin = NS_LITERAL_CSTRING("classic/1.0");
98 bool safeMode = false;
99 nsCOMPtr<nsIXULRuntime> xulrun(do_GetService(XULAPPINFO_SERVICE_CONTRACTID));
100 if (xulrun) xulrun->GetInSafeMode(&safeMode);
102 nsCOMPtr<nsIPrefService> prefserv(do_GetService(NS_PREFSERVICE_CONTRACTID));
103 nsCOMPtr<nsIPrefBranch> prefs;
105 if (prefserv) {
106 if (safeMode) {
107 prefserv->GetDefaultBranch(nullptr, getter_AddRefs(prefs));
108 } else {
109 prefs = do_QueryInterface(prefserv);
113 if (!prefs) {
114 NS_WARNING("Could not get pref service!");
115 } else {
116 nsAutoCString provider;
117 rv = prefs->GetCharPref(SELECTED_SKIN_PREF, provider);
118 if (NS_SUCCEEDED(rv)) mSelectedSkin = provider;
120 rv = prefs->AddObserver(SELECTED_SKIN_PREF, this, true);
123 nsCOMPtr<nsIObserverService> obsService =
124 mozilla::services::GetObserverService();
125 if (obsService) {
126 obsService->AddObserver(this, "profile-initial-state", true);
127 obsService->AddObserver(this, "intl:app-locales-changed", true);
130 return NS_OK;
133 NS_IMETHODIMP
134 nsChromeRegistryChrome::CheckForOSAccessibility() {
135 int32_t useAccessibilityTheme =
136 LookAndFeel::GetInt(LookAndFeel::eIntID_UseAccessibilityTheme, 0);
138 if (useAccessibilityTheme) {
139 /* Set the skin to classic and remove pref observers */
140 if (!mSelectedSkin.EqualsLiteral("classic/1.0")) {
141 mSelectedSkin.AssignLiteral("classic/1.0");
142 RefreshSkins();
145 nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID));
146 if (prefs) {
147 prefs->RemoveObserver(SELECTED_SKIN_PREF, this);
151 return NS_OK;
154 NS_IMETHODIMP
155 nsChromeRegistryChrome::GetLocalesForPackage(
156 const nsACString& aPackage, nsIUTF8StringEnumerator** aResult) {
157 nsCString realpackage;
158 nsresult rv = OverrideLocalePackage(aPackage, realpackage);
159 if (NS_FAILED(rv)) return rv;
161 nsTArray<nsCString>* a = new nsTArray<nsCString>;
162 if (!a) return NS_ERROR_OUT_OF_MEMORY;
164 PackageEntry* entry;
165 if (mPackagesHash.Get(realpackage, &entry)) {
166 entry->locales.EnumerateToArray(a);
169 rv = NS_NewAdoptingUTF8StringEnumerator(aResult, a);
170 if (NS_FAILED(rv)) delete a;
172 return rv;
175 NS_IMETHODIMP
176 nsChromeRegistryChrome::IsLocaleRTL(const nsACString& package, bool* aResult) {
177 *aResult = false;
179 nsAutoCString locale;
180 GetSelectedLocale(package, false, locale);
181 if (locale.Length() < 2) return NS_OK;
183 *aResult = GetDirectionForLocale(locale);
184 return NS_OK;
188 * This method negotiates only between the app locale and the available
189 * chrome packages.
191 * If you want to get the current application's UI locale, please use
192 * LocaleService::GetAppLocaleAsLangTag.
194 nsresult nsChromeRegistryChrome::GetSelectedLocale(const nsACString& aPackage,
195 bool aAsBCP47,
196 nsACString& aLocale) {
197 nsAutoCString reqLocale;
198 if (aPackage.EqualsLiteral("global")) {
199 LocaleService::GetInstance()->GetAppLocaleAsLangTag(reqLocale);
200 } else {
201 AutoTArray<nsCString, 10> requestedLocales;
202 LocaleService::GetInstance()->GetRequestedLocales(requestedLocales);
203 reqLocale.Assign(requestedLocales[0]);
206 nsCString realpackage;
207 nsresult rv = OverrideLocalePackage(aPackage, realpackage);
208 if (NS_FAILED(rv)) return rv;
209 PackageEntry* entry;
210 if (!mPackagesHash.Get(realpackage, &entry)) return NS_ERROR_FILE_NOT_FOUND;
212 aLocale = entry->locales.GetSelected(reqLocale, nsProviderArray::LOCALE);
213 if (aLocale.IsEmpty()) return NS_ERROR_FAILURE;
215 if (aAsBCP47) {
216 SanitizeForBCP47(aLocale);
219 return NS_OK;
222 nsresult nsChromeRegistryChrome::OverrideLocalePackage(
223 const nsACString& aPackage, nsACString& aOverride) {
224 const nsACString& pref =
225 NS_LITERAL_CSTRING(PACKAGE_OVERRIDE_BRANCH) + aPackage;
226 nsAutoCString override;
227 nsresult rv = mozilla::Preferences::GetCString(PromiseFlatCString(pref).get(),
228 override);
229 if (NS_SUCCEEDED(rv)) {
230 aOverride = override;
231 } else {
232 aOverride = aPackage;
234 return NS_OK;
237 NS_IMETHODIMP
238 nsChromeRegistryChrome::Observe(nsISupports* aSubject, const char* aTopic,
239 const char16_t* someData) {
240 nsresult rv = NS_OK;
242 if (!strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, aTopic)) {
243 nsCOMPtr<nsIPrefBranch> prefs(do_QueryInterface(aSubject));
244 NS_ASSERTION(prefs, "Bad observer call!");
246 NS_ConvertUTF16toUTF8 pref(someData);
248 if (pref.EqualsLiteral(SELECTED_SKIN_PREF)) {
249 nsAutoCString provider;
250 rv = prefs->GetCharPref(pref.get(), provider);
251 if (NS_FAILED(rv)) {
252 NS_ERROR("Couldn't get new skin pref!");
253 return rv;
256 mSelectedSkin = provider;
257 RefreshSkins();
258 } else {
259 NS_ERROR("Unexpected pref!");
261 } else if (!strcmp("profile-initial-state", aTopic)) {
262 mProfileLoaded = true;
263 } else if (!strcmp("intl:app-locales-changed", aTopic)) {
264 if (mProfileLoaded) {
265 FlushAllCaches();
267 } else {
268 NS_ERROR("Unexpected observer topic!");
271 return rv;
274 NS_IMETHODIMP
275 nsChromeRegistryChrome::CheckForNewChrome() {
276 mPackagesHash.Clear();
277 mOverrideTable.Clear();
279 mDynamicRegistration = false;
281 nsComponentManagerImpl::gComponentManager->RereadChromeManifests();
283 mDynamicRegistration = true;
285 SendRegisteredChrome(nullptr);
286 return NS_OK;
289 static void SerializeURI(nsIURI* aURI, SerializedURI& aSerializedURI) {
290 if (!aURI) return;
292 aURI->GetSpec(aSerializedURI.spec);
295 void nsChromeRegistryChrome::SendRegisteredChrome(
296 mozilla::dom::PContentParent* aParent) {
297 InfallibleTArray<ChromePackage> packages;
298 InfallibleTArray<SubstitutionMapping> resources;
299 InfallibleTArray<OverrideMapping> overrides;
301 for (auto iter = mPackagesHash.Iter(); !iter.Done(); iter.Next()) {
302 ChromePackage chromePackage;
303 ChromePackageFromPackageEntry(iter.Key(), iter.UserData(), &chromePackage,
304 mSelectedSkin);
305 packages.AppendElement(chromePackage);
308 // If we were passed a parent then a new child process has been created and
309 // has requested all of the chrome so send it the resources too. Otherwise
310 // resource mappings are sent by the resource protocol handler dynamically.
311 if (aParent) {
312 nsCOMPtr<nsIIOService> io(do_GetIOService());
313 NS_ENSURE_TRUE_VOID(io);
315 nsCOMPtr<nsIProtocolHandler> ph;
316 nsresult rv = io->GetProtocolHandler("resource", getter_AddRefs(ph));
317 NS_ENSURE_SUCCESS_VOID(rv);
319 nsCOMPtr<nsIResProtocolHandler> irph(do_QueryInterface(ph));
320 nsResProtocolHandler* rph = static_cast<nsResProtocolHandler*>(irph.get());
321 rv = rph->CollectSubstitutions(resources);
322 NS_ENSURE_SUCCESS_VOID(rv);
325 for (auto iter = mOverrideTable.Iter(); !iter.Done(); iter.Next()) {
326 SerializedURI chromeURI, overrideURI;
328 SerializeURI(iter.Key(), chromeURI);
329 SerializeURI(iter.UserData(), overrideURI);
331 OverrideMapping override = {chromeURI, overrideURI};
332 overrides.AppendElement(override);
335 nsAutoCString appLocale;
336 LocaleService::GetInstance()->GetAppLocaleAsLangTag(appLocale);
338 if (aParent) {
339 bool success = aParent->SendRegisterChrome(packages, resources, overrides,
340 appLocale, false);
341 NS_ENSURE_TRUE_VOID(success);
342 } else {
343 nsTArray<ContentParent*> parents;
344 ContentParent::GetAll(parents);
345 if (!parents.Length()) return;
347 for (uint32_t i = 0; i < parents.Length(); i++) {
348 DebugOnly<bool> success = parents[i]->SendRegisterChrome(
349 packages, resources, overrides, appLocale, true);
350 NS_WARNING_ASSERTION(success,
351 "couldn't reset a child's registered chrome");
356 /* static */ void nsChromeRegistryChrome::ChromePackageFromPackageEntry(
357 const nsACString& aPackageName, PackageEntry* aPackage,
358 ChromePackage* aChromePackage, const nsCString& aSelectedSkin) {
359 nsAutoCString appLocale;
360 LocaleService::GetInstance()->GetAppLocaleAsLangTag(appLocale);
362 SerializeURI(aPackage->baseURI, aChromePackage->contentBaseURI);
363 SerializeURI(aPackage->locales.GetBase(appLocale, nsProviderArray::LOCALE),
364 aChromePackage->localeBaseURI);
365 SerializeURI(aPackage->skins.GetBase(aSelectedSkin, nsProviderArray::ANY),
366 aChromePackage->skinBaseURI);
367 aChromePackage->package = aPackageName;
368 aChromePackage->flags = aPackage->flags;
371 static bool CanLoadResource(nsIURI* aResourceURI) {
372 bool isLocalResource = false;
373 (void)NS_URIChainHasFlags(aResourceURI,
374 nsIProtocolHandler::URI_IS_LOCAL_RESOURCE,
375 &isLocalResource);
376 return isLocalResource;
379 nsIURI* nsChromeRegistryChrome::GetBaseURIFromPackage(
380 const nsCString& aPackage, const nsCString& aProvider,
381 const nsCString& aPath) {
382 PackageEntry* entry;
383 if (!mPackagesHash.Get(aPackage, &entry)) {
384 if (!mInitialized) return nullptr;
386 LogMessage("No chrome package registered for chrome://%s/%s/%s",
387 aPackage.get(), aProvider.get(), aPath.get());
389 return nullptr;
392 if (aProvider.EqualsLiteral("locale")) {
393 nsAutoCString appLocale;
394 LocaleService::GetInstance()->GetAppLocaleAsLangTag(appLocale);
395 return entry->locales.GetBase(appLocale, nsProviderArray::LOCALE);
396 } else if (aProvider.EqualsLiteral("skin")) {
397 return entry->skins.GetBase(mSelectedSkin, nsProviderArray::ANY);
398 } else if (aProvider.EqualsLiteral("content")) {
399 return entry->baseURI;
401 return nullptr;
404 nsresult nsChromeRegistryChrome::GetFlagsFromPackage(const nsCString& aPackage,
405 uint32_t* aFlags) {
406 PackageEntry* entry;
407 if (!mPackagesHash.Get(aPackage, &entry)) return NS_ERROR_FILE_NOT_FOUND;
409 *aFlags = entry->flags;
410 return NS_OK;
413 nsChromeRegistryChrome::ProviderEntry*
414 nsChromeRegistryChrome::nsProviderArray::GetProvider(
415 const nsACString& aPreferred, MatchType aType) {
416 size_t i = mArray.Length();
417 if (!i) return nullptr;
419 ProviderEntry* found = nullptr; // Only set if we find a partial-match locale
420 ProviderEntry* entry = nullptr;
422 while (i--) {
423 entry = &mArray[i];
424 if (aPreferred.Equals(entry->provider)) return entry;
426 if (aType != LOCALE) continue;
428 if (LanguagesMatch(aPreferred, entry->provider)) {
429 found = entry;
430 continue;
433 if (!found && entry->provider.EqualsLiteral("en-US")) found = entry;
436 if (!found && aType != EXACT) return entry;
438 return found;
441 nsIURI* nsChromeRegistryChrome::nsProviderArray::GetBase(
442 const nsACString& aPreferred, MatchType aType) {
443 ProviderEntry* provider = GetProvider(aPreferred, aType);
445 if (!provider) return nullptr;
447 return provider->baseURI;
450 const nsACString& nsChromeRegistryChrome::nsProviderArray::GetSelected(
451 const nsACString& aPreferred, MatchType aType) {
452 ProviderEntry* entry = GetProvider(aPreferred, aType);
454 if (entry) return entry->provider;
456 return EmptyCString();
459 void nsChromeRegistryChrome::nsProviderArray::SetBase(
460 const nsACString& aProvider, nsIURI* aBaseURL) {
461 ProviderEntry* provider = GetProvider(aProvider, EXACT);
463 if (provider) {
464 provider->baseURI = aBaseURL;
465 return;
468 // no existing entries, add a new one
469 mArray.AppendElement(ProviderEntry(aProvider, aBaseURL));
472 void nsChromeRegistryChrome::nsProviderArray::EnumerateToArray(
473 nsTArray<nsCString>* a) {
474 int32_t i = mArray.Length();
475 while (i--) {
476 a->AppendElement(mArray[i].provider);
480 nsIURI* nsChromeRegistry::ManifestProcessingContext::GetManifestURI() {
481 if (!mManifestURI) {
482 nsCString uri;
483 mFile.GetURIString(uri);
484 NS_NewURI(getter_AddRefs(mManifestURI), uri);
486 return mManifestURI;
489 already_AddRefed<nsIURI>
490 nsChromeRegistry::ManifestProcessingContext::ResolveURI(const char* uri) {
491 nsIURI* baseuri = GetManifestURI();
492 if (!baseuri) return nullptr;
494 nsCOMPtr<nsIURI> resolved;
495 nsresult rv = NS_NewURI(getter_AddRefs(resolved), uri, baseuri);
496 if (NS_FAILED(rv)) return nullptr;
498 return resolved.forget();
501 static void EnsureLowerCase(char* aBuf) {
502 for (; *aBuf; ++aBuf) {
503 char ch = *aBuf;
504 if (ch >= 'A' && ch <= 'Z') *aBuf = ch + 'a' - 'A';
508 static void SendManifestEntry(const ChromeRegistryItem& aItem) {
509 nsTArray<ContentParent*> parents;
510 ContentParent::GetAll(parents);
511 if (!parents.Length()) return;
513 for (uint32_t i = 0; i < parents.Length(); i++) {
514 Unused << parents[i]->SendRegisterChromeItem(aItem);
518 void nsChromeRegistryChrome::ManifestContent(ManifestProcessingContext& cx,
519 int lineno, char* const* argv,
520 int flags) {
521 char* package = argv[0];
522 char* uri = argv[1];
524 EnsureLowerCase(package);
526 nsCOMPtr<nsIURI> resolved = cx.ResolveURI(uri);
527 if (!resolved) {
528 LogMessageWithContext(
529 cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
530 "During chrome registration, unable to create URI '%s'.", uri);
531 return;
534 if (!CanLoadResource(resolved)) {
535 LogMessageWithContext(resolved, lineno, nsIScriptError::warningFlag,
536 "During chrome registration, cannot register "
537 "non-local URI '%s' as content.",
538 uri);
539 return;
542 nsDependentCString packageName(package);
543 PackageEntry* entry = mPackagesHash.LookupOrAdd(packageName);
544 entry->baseURI = resolved;
545 entry->flags = flags;
547 if (mDynamicRegistration) {
548 ChromePackage chromePackage;
549 ChromePackageFromPackageEntry(packageName, entry, &chromePackage,
550 mSelectedSkin);
551 SendManifestEntry(chromePackage);
555 void nsChromeRegistryChrome::ManifestLocale(ManifestProcessingContext& cx,
556 int lineno, char* const* argv,
557 int flags) {
558 char* package = argv[0];
559 char* provider = argv[1];
560 char* uri = argv[2];
562 EnsureLowerCase(package);
564 nsCOMPtr<nsIURI> resolved = cx.ResolveURI(uri);
565 if (!resolved) {
566 LogMessageWithContext(
567 cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
568 "During chrome registration, unable to create URI '%s'.", uri);
569 return;
572 if (!CanLoadResource(resolved)) {
573 LogMessageWithContext(resolved, lineno, nsIScriptError::warningFlag,
574 "During chrome registration, cannot register "
575 "non-local URI '%s' as content.",
576 uri);
577 return;
580 nsDependentCString packageName(package);
581 PackageEntry* entry = mPackagesHash.LookupOrAdd(packageName);
582 entry->locales.SetBase(nsDependentCString(provider), resolved);
584 if (mDynamicRegistration) {
585 ChromePackage chromePackage;
586 ChromePackageFromPackageEntry(packageName, entry, &chromePackage,
587 mSelectedSkin);
588 SendManifestEntry(chromePackage);
591 // We use mainPackage as the package we track for reporting new locales being
592 // registered. For most cases it will be "global", but for Fennec it will be
593 // "browser".
594 nsAutoCString mainPackage;
595 nsresult rv =
596 OverrideLocalePackage(NS_LITERAL_CSTRING("global"), mainPackage);
597 if (NS_FAILED(rv)) {
598 return;
602 void nsChromeRegistryChrome::ManifestSkin(ManifestProcessingContext& cx,
603 int lineno, char* const* argv,
604 int flags) {
605 char* package = argv[0];
606 char* provider = argv[1];
607 char* uri = argv[2];
609 EnsureLowerCase(package);
611 nsCOMPtr<nsIURI> resolved = cx.ResolveURI(uri);
612 if (!resolved) {
613 LogMessageWithContext(
614 cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
615 "During chrome registration, unable to create URI '%s'.", uri);
616 return;
619 if (!CanLoadResource(resolved)) {
620 LogMessageWithContext(resolved, lineno, nsIScriptError::warningFlag,
621 "During chrome registration, cannot register "
622 "non-local URI '%s' as content.",
623 uri);
624 return;
627 nsDependentCString packageName(package);
628 PackageEntry* entry = mPackagesHash.LookupOrAdd(packageName);
629 entry->skins.SetBase(nsDependentCString(provider), resolved);
631 if (mDynamicRegistration) {
632 ChromePackage chromePackage;
633 ChromePackageFromPackageEntry(packageName, entry, &chromePackage,
634 mSelectedSkin);
635 SendManifestEntry(chromePackage);
639 void nsChromeRegistryChrome::ManifestOverride(ManifestProcessingContext& cx,
640 int lineno, char* const* argv,
641 int flags) {
642 char* chrome = argv[0];
643 char* resolved = argv[1];
645 nsCOMPtr<nsIURI> chromeuri = cx.ResolveURI(chrome);
646 nsCOMPtr<nsIURI> resolveduri = cx.ResolveURI(resolved);
647 if (!chromeuri || !resolveduri) {
648 LogMessageWithContext(cx.GetManifestURI(), lineno,
649 nsIScriptError::warningFlag,
650 "During chrome registration, unable to create URI.");
651 return;
654 if (cx.mType == NS_SKIN_LOCATION) {
655 bool chromeSkinOnly = false;
656 nsresult rv = chromeuri->SchemeIs("chrome", &chromeSkinOnly);
657 chromeSkinOnly = chromeSkinOnly && NS_SUCCEEDED(rv);
658 if (chromeSkinOnly) {
659 rv = resolveduri->SchemeIs("chrome", &chromeSkinOnly);
660 chromeSkinOnly = chromeSkinOnly && NS_SUCCEEDED(rv);
662 if (chromeSkinOnly) {
663 nsAutoCString chromePath, resolvedPath;
664 chromeuri->GetPathQueryRef(chromePath);
665 resolveduri->GetPathQueryRef(resolvedPath);
666 chromeSkinOnly =
667 StringBeginsWith(chromePath, NS_LITERAL_CSTRING("/skin/")) &&
668 StringBeginsWith(resolvedPath, NS_LITERAL_CSTRING("/skin/"));
670 if (!chromeSkinOnly) {
671 LogMessageWithContext(
672 cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
673 "Cannot register non-chrome://.../skin/ URIs '%s' and '%s' as "
674 "overrides and/or to be overridden from a skin manifest.",
675 chrome, resolved);
676 return;
680 if (!CanLoadResource(resolveduri)) {
681 LogMessageWithContext(
682 cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
683 "Cannot register non-local URI '%s' for an override.", resolved);
684 return;
686 mOverrideTable.Put(chromeuri, resolveduri);
688 if (mDynamicRegistration) {
689 SerializedURI serializedChrome;
690 SerializedURI serializedOverride;
692 SerializeURI(chromeuri, serializedChrome);
693 SerializeURI(resolveduri, serializedOverride);
695 OverrideMapping override = {serializedChrome, serializedOverride};
696 SendManifestEntry(override);
700 void nsChromeRegistryChrome::ManifestResource(ManifestProcessingContext& cx,
701 int lineno, char* const* argv,
702 int flags) {
703 char* package = argv[0];
704 char* uri = argv[1];
706 EnsureLowerCase(package);
707 nsDependentCString host(package);
709 nsCOMPtr<nsIIOService> io = mozilla::services::GetIOService();
710 if (!io) {
711 NS_WARNING("No IO service trying to process chrome manifests");
712 return;
715 nsCOMPtr<nsIProtocolHandler> ph;
716 nsresult rv = io->GetProtocolHandler("resource", getter_AddRefs(ph));
717 if (NS_FAILED(rv)) return;
719 nsCOMPtr<nsIResProtocolHandler> rph = do_QueryInterface(ph);
721 nsCOMPtr<nsIURI> resolved = cx.ResolveURI(uri);
722 if (!resolved) {
723 LogMessageWithContext(
724 cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
725 "During chrome registration, unable to create URI '%s'.", uri);
726 return;
729 if (!CanLoadResource(resolved)) {
730 LogMessageWithContext(
731 cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
732 "Warning: cannot register non-local URI '%s' as a resource.", uri);
733 return;
736 // By default, Firefox resources are not content-accessible unless the
737 // manifests opts in.
738 bool contentAccessible = (flags & nsChromeRegistry::CONTENT_ACCESSIBLE);
740 uint32_t substitutionFlags = 0;
741 if (contentAccessible) {
742 substitutionFlags |= nsIResProtocolHandler::ALLOW_CONTENT_ACCESS;
744 rv = rph->SetSubstitutionWithFlags(host, resolved, substitutionFlags);
745 if (NS_FAILED(rv)) {
746 LogMessageWithContext(cx.GetManifestURI(), lineno,
747 nsIScriptError::warningFlag,
748 "Warning: cannot set substitution for '%s'.", uri);