Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de) | 2 Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de) |
| 3 Copyright (C) 2001 Dirk Mueller (mueller@kde.org) | 3 Copyright (C) 2001 Dirk Mueller (mueller@kde.org) |
| 4 Copyright (C) 2002 Waldo Bastian (bastian@kde.org) | 4 Copyright (C) 2002 Waldo Bastian (bastian@kde.org) |
| 5 Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) | 5 Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) |
| 6 Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. | 6 Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. |
| 7 | 7 |
| 8 This library is free software; you can redistribute it and/or | 8 This library is free software; you can redistribute it and/or |
| 9 modify it under the terms of the GNU Library General Public | 9 modify it under the terms of the GNU Library General Public |
| 10 License as published by the Free Software Foundation; either | 10 License as published by the Free Software Foundation; either |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 64 | 64 |
| 65 return toImageResource( | 65 return toImageResource( |
| 66 fetcher->requestResource(request, ImageResourceFactory())); | 66 fetcher->requestResource(request, ImageResourceFactory())); |
| 67 } | 67 } |
| 68 | 68 |
| 69 ImageResource::ImageResource(const ResourceRequest& resourceRequest, | 69 ImageResource::ImageResource(const ResourceRequest& resourceRequest, |
| 70 const ResourceLoaderOptions& options) | 70 const ResourceLoaderOptions& options) |
| 71 : Resource(resourceRequest, Image, options), | 71 : Resource(resourceRequest, Image, options), |
| 72 m_devicePixelRatioHeaderValue(1.0), | 72 m_devicePixelRatioHeaderValue(1.0), |
| 73 m_image(nullptr), | 73 m_image(nullptr), |
| 74 m_hasDevicePixelRatioHeaderValue(false) { | 74 m_hasDevicePixelRatioHeaderValue(false), |
| 75 m_isSchedulingReload(false) { | |
| 75 RESOURCE_LOADING_DVLOG(1) << "new ImageResource(ResourceRequest) " << this; | 76 RESOURCE_LOADING_DVLOG(1) << "new ImageResource(ResourceRequest) " << this; |
| 76 } | 77 } |
| 77 | 78 |
| 78 ImageResource::ImageResource(blink::Image* image, | 79 ImageResource::ImageResource(blink::Image* image, |
| 79 const ResourceLoaderOptions& options) | 80 const ResourceLoaderOptions& options) |
| 80 : Resource(ResourceRequest(""), Image, options), | 81 : Resource(ResourceRequest(""), Image, options), |
| 81 m_devicePixelRatioHeaderValue(1.0), | 82 m_devicePixelRatioHeaderValue(1.0), |
| 82 m_image(image), | 83 m_image(image), |
| 83 m_hasDevicePixelRatioHeaderValue(false) { | 84 m_hasDevicePixelRatioHeaderValue(false), |
| 85 m_isSchedulingReload(false) { | |
| 84 RESOURCE_LOADING_DVLOG(1) << "new ImageResource(Image) " << this; | 86 RESOURCE_LOADING_DVLOG(1) << "new ImageResource(Image) " << this; |
| 85 setStatus(Cached); | 87 setStatus(Cached); |
| 86 } | 88 } |
| 87 | 89 |
| 88 ImageResource::~ImageResource() { | 90 ImageResource::~ImageResource() { |
| 89 RESOURCE_LOADING_DVLOG(1) << "~ImageResource " << this; | 91 RESOURCE_LOADING_DVLOG(1) << "~ImageResource " << this; |
| 90 clearImage(); | 92 clearImage(); |
| 91 } | 93 } |
| 92 | 94 |
| 93 DEFINE_TRACE(ImageResource) { | 95 DEFINE_TRACE(ImageResource) { |
| 94 visitor->trace(m_multipartParser); | 96 visitor->trace(m_multipartParser); |
| 95 Resource::trace(visitor); | 97 Resource::trace(visitor); |
| 96 ImageObserver::trace(visitor); | 98 ImageObserver::trace(visitor); |
| 97 MultipartImageResourceParser::Client::trace(visitor); | 99 MultipartImageResourceParser::Client::trace(visitor); |
| 98 } | 100 } |
| 99 | 101 |
| 100 void ImageResource::checkNotify() { | 102 void ImageResource::checkNotify() { |
| 103 // Don't notify observers and clients of completion if this ImageResource is | |
| 104 // about to be reloaded. | |
| 105 if (m_isSchedulingReload) | |
| 106 return; | |
| 107 | |
| 101 notifyObserversInternal(MarkFinishedOption::ShouldMarkFinished); | 108 notifyObserversInternal(MarkFinishedOption::ShouldMarkFinished); |
| 102 Resource::checkNotify(); | 109 Resource::checkNotify(); |
| 103 } | 110 } |
| 104 | 111 |
| 105 void ImageResource::notifyObserversInternal( | 112 void ImageResource::notifyObserversInternal( |
| 106 MarkFinishedOption markFinishedOption) { | 113 MarkFinishedOption markFinishedOption) { |
| 107 if (isLoading()) | 114 if (isLoading() || m_isSchedulingReload) |
|
Nate Chapin
2016/10/12 23:45:23
This should be redundant. checkNotify() is already
sclittle
2016/10/12 23:49:05
Done.
| |
| 108 return; | 115 return; |
| 109 | 116 |
| 110 for (auto* observer : m_observers.asVector()) { | 117 for (auto* observer : m_observers.asVector()) { |
| 111 if (m_observers.contains(observer)) { | 118 if (m_observers.contains(observer)) { |
| 112 if (markFinishedOption == MarkFinishedOption::ShouldMarkFinished) | 119 if (markFinishedOption == MarkFinishedOption::ShouldMarkFinished) |
| 113 markObserverFinished(observer); | 120 markObserverFinished(observer); |
| 114 observer->imageNotifyFinished(this); | 121 observer->imageNotifyFinished(this); |
| 115 } | 122 } |
| 116 } | 123 } |
| 117 } | 124 } |
| 118 | 125 |
| 119 void ImageResource::markObserverFinished(ImageResourceObserver* observer) { | 126 void ImageResource::markObserverFinished(ImageResourceObserver* observer) { |
| 120 if (m_observers.contains(observer)) { | 127 if (m_observers.contains(observer)) { |
| 121 m_finishedObservers.add(observer); | 128 m_finishedObservers.add(observer); |
| 122 m_observers.remove(observer); | 129 m_observers.remove(observer); |
| 123 } | 130 } |
| 124 } | 131 } |
| 125 | 132 |
| 126 void ImageResource::didAddClient(ResourceClient* client) { | 133 void ImageResource::didAddClient(ResourceClient* client) { |
| 127 DCHECK((m_multipartParser && isLoading()) || !data() || m_image); | 134 DCHECK((m_multipartParser && isLoading()) || !data() || m_image); |
| 135 | |
| 136 // Don't notify observers and clients of completion if this ImageResource is | |
| 137 // about to be reloaded. | |
| 138 if (m_isSchedulingReload) | |
| 139 return; | |
| 140 | |
| 128 Resource::didAddClient(client); | 141 Resource::didAddClient(client); |
| 129 } | 142 } |
| 130 | 143 |
| 131 void ImageResource::addObserver(ImageResourceObserver* observer) { | 144 void ImageResource::addObserver(ImageResourceObserver* observer) { |
| 132 willAddClientOrObserver(MarkAsReferenced); | 145 willAddClientOrObserver(MarkAsReferenced); |
| 133 | 146 |
| 134 m_observers.add(observer); | 147 m_observers.add(observer); |
| 135 | 148 |
| 136 if (isCacheValidator()) | 149 if (isCacheValidator()) |
| 137 return; | 150 return; |
| 138 | 151 |
| 139 // When the response is not multipart, if |data()| exists, |m_image| must be | 152 // When the response is not multipart, if |data()| exists, |m_image| must be |
| 140 // created. This is assured that |updateImage()| is called when |appendData()| | 153 // created. This is assured that |updateImage()| is called when |appendData()| |
| 141 // is called. | 154 // is called. |
| 142 // | 155 // |
| 143 // On the other hand, when the response is multipart, |updateImage()| is not | 156 // On the other hand, when the response is multipart, |updateImage()| is not |
| 144 // called in |appendData()|, which means |m_image| might not be created even | 157 // called in |appendData()|, which means |m_image| might not be created even |
| 145 // when |data()| exists. This is intentional since creating a |m_image| on | 158 // when |data()| exists. This is intentional since creating a |m_image| on |
| 146 // receiving data might destroy an existing image in a previous part. | 159 // receiving data might destroy an existing image in a previous part. |
| 147 DCHECK((m_multipartParser && isLoading()) || !data() || m_image); | 160 DCHECK((m_multipartParser && isLoading()) || !data() || m_image); |
| 148 | 161 |
| 149 if (m_image && !m_image->isNull()) { | 162 if (m_image && !m_image->isNull()) { |
| 150 observer->imageChanged(this); | 163 observer->imageChanged(this); |
| 151 } | 164 } |
| 152 | 165 |
| 153 if (isLoaded()) { | 166 if (isLoaded() && !m_isSchedulingReload) { |
| 154 markObserverFinished(observer); | 167 markObserverFinished(observer); |
| 155 observer->imageNotifyFinished(this); | 168 observer->imageNotifyFinished(this); |
| 156 } | 169 } |
| 157 } | 170 } |
| 158 | 171 |
| 159 void ImageResource::removeObserver(ImageResourceObserver* observer) { | 172 void ImageResource::removeObserver(ImageResourceObserver* observer) { |
| 160 DCHECK(observer); | 173 DCHECK(observer); |
| 161 | 174 |
| 162 if (m_observers.contains(observer)) | 175 if (m_observers.contains(observer)) |
| 163 m_observers.remove(observer); | 176 m_observers.remove(observer); |
| (...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 525 m_image->setAnimationPolicy(newPolicy); | 538 m_image->setAnimationPolicy(newPolicy); |
| 526 } | 539 } |
| 527 } | 540 } |
| 528 | 541 |
| 529 void ImageResource::reloadIfLoFi(ResourceFetcher* fetcher) { | 542 void ImageResource::reloadIfLoFi(ResourceFetcher* fetcher) { |
| 530 if (resourceRequest().loFiState() != WebURLRequest::LoFiOn) | 543 if (resourceRequest().loFiState() != WebURLRequest::LoFiOn) |
| 531 return; | 544 return; |
| 532 if (isLoaded() && | 545 if (isLoaded() && |
| 533 !response().httpHeaderField("chrome-proxy").contains("q=low")) | 546 !response().httpHeaderField("chrome-proxy").contains("q=low")) |
| 534 return; | 547 return; |
| 548 | |
| 549 // Prevent clients and observers from being notified of completion while the | |
| 550 // reload is being scheduled, so that e.g. canceling an existing load in | |
| 551 // progress doesn't cause clients and observers to be notified of completion | |
| 552 // prematurely. | |
| 553 DCHECK(!m_isSchedulingReload); | |
| 554 m_isSchedulingReload = true; | |
| 555 | |
| 535 setCachePolicyBypassingCache(); | 556 setCachePolicyBypassingCache(); |
| 536 setLoFiStateOff(); | 557 setLoFiStateOff(); |
| 537 if (isLoading()) | 558 if (isLoading()) { |
| 538 loader()->cancel(); | 559 loader()->cancel(); |
| 539 clear(); | 560 // Canceling the loader causes error() to be called, which in turn calls |
| 540 notifyObservers(); | 561 // clear() and notifyObservers(), so there's no need to call these again |
| 562 // here. | |
| 563 } else { | |
| 564 clear(); | |
| 565 notifyObservers(); | |
| 566 } | |
| 541 | 567 |
| 542 setStatus(NotStarted); | 568 setStatus(NotStarted); |
| 569 | |
| 570 DCHECK(m_isSchedulingReload); | |
| 571 m_isSchedulingReload = false; | |
| 572 | |
| 543 fetcher->startLoad(this); | 573 fetcher->startLoad(this); |
| 544 } | 574 } |
| 545 | 575 |
| 546 void ImageResource::changedInRect(const blink::Image* image, | 576 void ImageResource::changedInRect(const blink::Image* image, |
| 547 const IntRect& rect) { | 577 const IntRect& rect) { |
| 548 if (!image || image != m_image) | 578 if (!image || image != m_image) |
| 549 return; | 579 return; |
| 550 notifyObservers(&rect); | 580 notifyObservers(&rect); |
| 551 } | 581 } |
| 552 | 582 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 586 return response().serviceWorkerResponseType() != | 616 return response().serviceWorkerResponseType() != |
| 587 WebServiceWorkerResponseTypeOpaque; | 617 WebServiceWorkerResponseTypeOpaque; |
| 588 if (!getImage()->currentFrameHasSingleSecurityOrigin()) | 618 if (!getImage()->currentFrameHasSingleSecurityOrigin()) |
| 589 return false; | 619 return false; |
| 590 if (passesAccessControlCheck(securityOrigin)) | 620 if (passesAccessControlCheck(securityOrigin)) |
| 591 return true; | 621 return true; |
| 592 return !securityOrigin->taintsCanvas(response().url()); | 622 return !securityOrigin->taintsCanvas(response().url()); |
| 593 } | 623 } |
| 594 | 624 |
| 595 } // namespace blink | 625 } // namespace blink |
| OLD | NEW |