Backed out changeset 2450366cf7ca (bug 1891629) for causing win msix mochitest failures
[gecko.git] / widget / IconLoader.cpp
blob41d2a29bc741a95e8f025afcc33b886a82a0197e
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "mozilla/widget/IconLoader.h"
7 #include "gfxPlatform.h"
8 #include "imgIContainer.h"
9 #include "imgLoader.h"
10 #include "imgRequestProxy.h"
11 #include "mozilla/dom/Document.h"
12 #include "mozilla/dom/FetchPriority.h"
13 #include "nsContentUtils.h"
14 #include "nsIContent.h"
15 #include "nsIContentPolicy.h"
17 using namespace mozilla;
19 namespace mozilla::widget {
21 NS_IMPL_ISUPPORTS(IconLoader, imgINotificationObserver)
23 IconLoader::IconLoader(Listener* aListener) : mListener(aListener) {}
25 IconLoader::~IconLoader() { Destroy(); }
27 void IconLoader::Destroy() {
28 if (mIconRequest) {
29 mIconRequest->CancelAndForgetObserver(NS_BINDING_ABORTED);
30 mIconRequest = nullptr;
32 mListener = nullptr;
35 nsresult IconLoader::LoadIcon(nsIURI* aIconURI, nsINode* aNode,
36 bool aIsInternalIcon) {
37 if (mIconRequest) {
38 // Another icon request is already in flight. Kill it.
39 mIconRequest->CancelWithReason(
40 NS_BINDING_ABORTED, "Another icon request is already in flight"_ns);
41 mIconRequest = nullptr;
44 if (!aNode) {
45 return NS_ERROR_FAILURE;
48 RefPtr<mozilla::dom::Document> document = aNode->OwnerDoc();
50 nsCOMPtr<nsILoadGroup> loadGroup = document->GetDocumentLoadGroup();
51 if (!loadGroup) {
52 return NS_ERROR_FAILURE;
55 RefPtr<imgLoader> loader = nsContentUtils::GetImgLoaderForDocument(document);
56 if (!loader) {
57 return NS_ERROR_FAILURE;
60 nsresult rv;
61 if (aIsInternalIcon) {
62 rv = loader->LoadImage(
63 aIconURI, nullptr, nullptr, nullptr, 0, loadGroup, this, nullptr,
64 nullptr, nsIRequest::LOAD_NORMAL, nullptr,
65 nsIContentPolicy::TYPE_INTERNAL_IMAGE, u""_ns,
66 /* aUseUrgentStartForChannel */ false, /* aLinkPreload */ false, 0,
67 dom::FetchPriority::Auto, getter_AddRefs(mIconRequest));
68 } else {
69 // TODO: nsIContentPolicy::TYPE_INTERNAL_IMAGE may not be the correct
70 // policy. See bug 1691868 for more details.
71 rv = loader->LoadImage(
72 aIconURI, nullptr, nullptr, aNode->NodePrincipal(), 0, loadGroup, this,
73 aNode, document, nsIRequest::LOAD_NORMAL, nullptr,
74 nsIContentPolicy::TYPE_INTERNAL_IMAGE, u""_ns,
75 /* aUseUrgentStartForChannel */ false,
76 /* aLinkPreload */ false, 0, dom::FetchPriority::Auto,
77 getter_AddRefs(mIconRequest));
79 if (NS_FAILED(rv)) {
80 return rv;
83 return NS_OK;
87 // imgINotificationObserver
90 void IconLoader::Notify(imgIRequest* aRequest, int32_t aType,
91 const nsIntRect* aData) {
92 if (aType == imgINotificationObserver::LOAD_COMPLETE) {
93 // Make sure the image loaded successfully.
94 uint32_t status = imgIRequest::STATUS_ERROR;
95 if (NS_FAILED(aRequest->GetImageStatus(&status)) ||
96 (status & imgIRequest::STATUS_ERROR)) {
97 mIconRequest->CancelWithReason(NS_BINDING_ABORTED,
98 "GetImageStatus failed"_ns);
99 mIconRequest = nullptr;
100 return;
103 nsCOMPtr<imgIContainer> image;
104 aRequest->GetImage(getter_AddRefs(image));
105 MOZ_ASSERT(image);
107 // Ask the image to decode at its intrinsic size.
108 int32_t width = 0, height = 0;
109 image->GetWidth(&width);
110 image->GetHeight(&height);
111 image->RequestDecodeForSize(nsIntSize(width, height),
112 imgIContainer::FLAG_HIGH_QUALITY_SCALING);
115 if (aType == imgINotificationObserver::FRAME_COMPLETE) {
116 nsCOMPtr<imgIContainer> image;
117 aRequest->GetImage(getter_AddRefs(image));
118 MOZ_ASSERT(image);
120 if (mListener) {
121 mListener->OnComplete(image);
123 return;
126 if (aType == imgINotificationObserver::DECODE_COMPLETE) {
127 if (mIconRequest && mIconRequest == aRequest) {
128 mIconRequest->CancelWithReason(NS_BINDING_ABORTED, "DECODE_COMPLETE"_ns);
129 mIconRequest = nullptr;
134 } // namespace mozilla::widget