Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Side by Side Diff: third_party/WebKit/Source/core/loader/resource/ImageResource.cpp

Issue 2527353002: Phase II Step 3: Reload LoFi/placeholder images via new ImageResource
Patch Set: Use startLoad() again to avoid re-applying modifications to ResourceRequest on reload Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 23 matching lines...) Expand all
34 #include "platform/SharedBuffer.h" 34 #include "platform/SharedBuffer.h"
35 #include "platform/instrumentation/tracing/TraceEvent.h" 35 #include "platform/instrumentation/tracing/TraceEvent.h"
36 #include "platform/loader/fetch/MemoryCache.h" 36 #include "platform/loader/fetch/MemoryCache.h"
37 #include "platform/loader/fetch/ResourceClient.h" 37 #include "platform/loader/fetch/ResourceClient.h"
38 #include "platform/loader/fetch/ResourceFetcher.h" 38 #include "platform/loader/fetch/ResourceFetcher.h"
39 #include "platform/loader/fetch/ResourceLoader.h" 39 #include "platform/loader/fetch/ResourceLoader.h"
40 #include "platform/loader/fetch/ResourceLoadingLog.h" 40 #include "platform/loader/fetch/ResourceLoadingLog.h"
41 #include "platform/network/HTTPParsers.h" 41 #include "platform/network/HTTPParsers.h"
42 #include "platform/weborigin/SecurityViolationReportingPolicy.h" 42 #include "platform/weborigin/SecurityViolationReportingPolicy.h"
43 #include "public/platform/Platform.h" 43 #include "public/platform/Platform.h"
44 #include "public/platform/WebCachePolicy.h"
44 #include "v8/include/v8.h" 45 #include "v8/include/v8.h"
45 #include "wtf/CurrentTime.h" 46 #include "wtf/CurrentTime.h"
46 #include "wtf/StdLibExtras.h" 47 #include "wtf/StdLibExtras.h"
47 48
48 namespace blink { 49 namespace blink {
49 namespace { 50 namespace {
50 // The amount of time to wait before informing the clients that the image has 51 // The amount of time to wait before informing the clients that the image has
51 // been updated (in seconds). This effectively throttles invalidations that 52 // been updated (in seconds). This effectively throttles invalidations that
52 // result from new data arriving for this image. 53 // result from new data arriving for this image.
53 constexpr double kFlushDelaySeconds = 1.; 54 constexpr double kFlushDelaySeconds = 1.;
54 } // namespace 55 } // namespace
55 56
56 class ImageResource::ImageResourceInfoImpl final 57 class ImageResource::ImageResourceInfoImpl final
57 : public GarbageCollectedFinalized<ImageResourceInfoImpl>, 58 : public GarbageCollectedFinalized<ImageResourceInfoImpl>,
58 public ImageResourceInfo { 59 public ImageResourceInfo {
59 USING_GARBAGE_COLLECTED_MIXIN(ImageResourceInfoImpl); 60 USING_GARBAGE_COLLECTED_MIXIN(ImageResourceInfoImpl);
60 61
61 public: 62 public:
62 ImageResourceInfoImpl(ImageResource* resource) : m_resource(resource) { 63 ImageResourceInfoImpl(ImageResource* resource) : m_resource(resource) {
63 DCHECK(m_resource); 64 DCHECK(m_resource);
64 } 65 }
65 DEFINE_INLINE_VIRTUAL_TRACE() { 66 DEFINE_INLINE_VIRTUAL_TRACE() {
66 visitor->trace(m_resource); 67 visitor->trace(m_resource);
67 ImageResourceInfo::trace(visitor); 68 ImageResourceInfo::trace(visitor);
68 } 69 }
69 70
70 private: 71 private:
71 const KURL& url() const override { return m_resource->url(); } 72 const KURL& url() const override { return m_resource->url(); }
72 bool isSchedulingReload() const override {
73 return m_resource->m_isSchedulingReload;
74 }
75 bool hasDevicePixelRatioHeaderValue() const override { 73 bool hasDevicePixelRatioHeaderValue() const override {
76 return m_resource->m_hasDevicePixelRatioHeaderValue; 74 return m_resource->m_hasDevicePixelRatioHeaderValue;
77 } 75 }
78 float devicePixelRatioHeaderValue() const override { 76 float devicePixelRatioHeaderValue() const override {
79 return m_resource->m_devicePixelRatioHeaderValue; 77 return m_resource->m_devicePixelRatioHeaderValue;
80 } 78 }
81 const ResourceResponse& response() const override { 79 const ResourceResponse& response() const override {
82 return m_resource->response(); 80 return m_resource->response();
83 } 81 }
84 ResourceStatus getStatus() const override { return m_resource->getStatus(); } 82 ResourceStatus getStatus() const override { return m_resource->getStatus(); }
85 bool shouldShowPlaceholder() const override { 83 bool shouldShowPlaceholder() const override {
86 return m_resource->shouldShowPlaceholder(); 84 return m_resource->shouldShowPlaceholder();
87 } 85 }
88 bool isCacheValidator() const override { 86 bool isCacheValidator() const override {
89 return m_resource->isCacheValidator(); 87 return m_resource->isCacheValidator();
90 } 88 }
91 bool schedulingReloadOrShouldReloadBrokenPlaceholder() const override {
92 return m_resource->m_isSchedulingReload ||
93 m_resource->shouldReloadBrokenPlaceholder();
94 }
95 bool isAccessAllowed( 89 bool isAccessAllowed(
96 SecurityOrigin* securityOrigin, 90 SecurityOrigin* securityOrigin,
97 DoesCurrentFrameHaveSingleSecurityOrigin 91 DoesCurrentFrameHaveSingleSecurityOrigin
98 doesCurrentFrameHasSingleSecurityOrigin) const override { 92 doesCurrentFrameHasSingleSecurityOrigin) const override {
99 return m_resource->isAccessAllowed(securityOrigin, 93 return m_resource->isAccessAllowed(securityOrigin,
100 doesCurrentFrameHasSingleSecurityOrigin); 94 doesCurrentFrameHasSingleSecurityOrigin);
101 } 95 }
102 bool hasCacheControlNoStoreHeader() const override { 96 bool hasCacheControlNoStoreHeader() const override {
103 return m_resource->hasCacheControlNoStoreHeader(); 97 return m_resource->hasCacheControlNoStoreHeader();
104 } 98 }
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 fetcher->context().sendImagePing(requestURL); 162 fetcher->context().sendImagePing(requestURL);
169 } 163 }
170 return nullptr; 164 return nullptr;
171 } 165 }
172 166
173 return toImageResource( 167 return toImageResource(
174 fetcher->requestResource(request, ImageResourceFactory(request))); 168 fetcher->requestResource(request, ImageResourceFactory(request)));
175 } 169 }
176 170
177 bool ImageResource::canReuse(const FetchRequest& request) const { 171 bool ImageResource::canReuse(const FetchRequest& request) const {
172 if (!getContent())
173 return false;
174
178 // If the image is a placeholder, but this fetch doesn't allow a 175 // If the image is a placeholder, but this fetch doesn't allow a
179 // placeholder, then do not reuse this resource. 176 // placeholder, then do not reuse this resource.
180 if (request.placeholderImageRequestType() != FetchRequest::AllowPlaceholder && 177 if (request.placeholderImageRequestType() != FetchRequest::AllowPlaceholder &&
181 m_placeholderOption != PlaceholderOption::DoNotReloadPlaceholder) 178 m_placeholderOption != PlaceholderOption::DoNotReloadPlaceholder)
182 return false; 179 return false;
180
183 return true; 181 return true;
184 } 182 }
185 183
186 ImageResource* ImageResource::create(const ResourceRequest& request) { 184 ImageResource* ImageResource::create(const ResourceRequest& request) {
187 return new ImageResource(request, ResourceLoaderOptions(), 185 return new ImageResource(request, ResourceLoaderOptions(),
188 ImageResourceContent::create(), false); 186 ImageResourceContent::create(), false);
189 } 187 }
190 188
191 ImageResource::ImageResource(const ResourceRequest& resourceRequest, 189 ImageResource::ImageResource(const ResourceRequest& resourceRequest,
192 const ResourceLoaderOptions& options, 190 const ResourceLoaderOptions& options,
193 ImageResourceContent* content, 191 ImageResourceContent* content,
194 bool isPlaceholder) 192 bool isPlaceholder)
195 : Resource(resourceRequest, Image, options), 193 : Resource(resourceRequest, Image, options),
196 m_content(content), 194 m_content(content),
197 m_devicePixelRatioHeaderValue(1.0), 195 m_devicePixelRatioHeaderValue(1.0),
198 m_hasDevicePixelRatioHeaderValue(false), 196 m_hasDevicePixelRatioHeaderValue(false),
199 m_isSchedulingReload(false),
200 m_placeholderOption( 197 m_placeholderOption(
201 isPlaceholder ? PlaceholderOption::ShowAndReloadPlaceholderAlways 198 isPlaceholder ? PlaceholderOption::ShowAndReloadPlaceholderAlways
202 : PlaceholderOption::DoNotReloadPlaceholder), 199 : PlaceholderOption::DoNotReloadPlaceholder),
203 m_flushTimer(this, &ImageResource::flushImageIfNeeded) { 200 m_flushTimer(this, &ImageResource::flushImageIfNeeded) {
204 DCHECK(getContent()); 201 DCHECK(getContent());
205 RESOURCE_LOADING_DVLOG(1) << "new ImageResource(ResourceRequest) " << this; 202 RESOURCE_LOADING_DVLOG(1) << "new ImageResource(ResourceRequest) " << this;
206 getContent()->setImageResourceInfo(new ImageResourceInfoImpl(this)); 203 getContent()->setImageResourceInfo(new ImageResourceInfoImpl(this));
207 } 204 }
208 205
209 ImageResource::~ImageResource() { 206 ImageResource::~ImageResource() {
210 RESOURCE_LOADING_DVLOG(1) << "~ImageResource " << this; 207 RESOURCE_LOADING_DVLOG(1) << "~ImageResource " << this;
211 } 208 }
212 209
213 DEFINE_TRACE(ImageResource) { 210 DEFINE_TRACE(ImageResource) {
214 visitor->trace(m_multipartParser); 211 visitor->trace(m_multipartParser);
215 visitor->trace(m_content); 212 visitor->trace(m_content);
216 Resource::trace(visitor); 213 Resource::trace(visitor);
217 MultipartImageResourceParser::Client::trace(visitor); 214 MultipartImageResourceParser::Client::trace(visitor);
218 } 215 }
219 216
220 void ImageResource::checkNotify() {
221 // Don't notify clients of completion if this ImageResource is
222 // about to be reloaded.
223 if (m_isSchedulingReload || shouldReloadBrokenPlaceholder())
224 return;
225
226 Resource::checkNotify();
227 }
228
229 bool ImageResource::hasClientsOrObservers() const { 217 bool ImageResource::hasClientsOrObservers() const {
230 return Resource::hasClientsOrObservers() || getContent()->hasObservers(); 218 return Resource::hasClientsOrObservers() ||
219 (getContent() && getContent()->hasObservers());
231 } 220 }
232 221
233 void ImageResource::didAddClient(ResourceClient* client) { 222 void ImageResource::didAddClient(ResourceClient* client) {
234 DCHECK((m_multipartParser && isLoading()) || !data() || 223 DCHECK((m_multipartParser && isLoading()) || !data() ||
235 getContent()->hasImage()); 224 (getContent() && getContent()->hasImage()));
236
237 // Don't notify observers and clients of completion if this ImageResource is
238 // about to be reloaded.
239 if (m_isSchedulingReload || shouldReloadBrokenPlaceholder())
240 return;
241
242 Resource::didAddClient(client); 225 Resource::didAddClient(client);
243 } 226 }
244 227
245 void ImageResource::destroyDecodedDataForFailedRevalidation() { 228 void ImageResource::destroyDecodedDataForFailedRevalidation() {
246 // Clears the image, as we must create a new image for the failed 229 // Clears the image, as we must create a new image for the failed
247 // revalidation response. 230 // revalidation response.
248 updateImage(nullptr, ImageResourceContent::ClearAndUpdateImage, false); 231 updateImage(nullptr, ImageResourceContent::ClearAndUpdateImage, false);
249 setDecodedSize(0); 232 setDecodedSize(0);
250 } 233 }
251 234
252 void ImageResource::destroyDecodedDataIfPossible() { 235 void ImageResource::destroyDecodedDataIfPossible() {
236 if (!getContent())
237 return;
253 getContent()->destroyDecodedData(); 238 getContent()->destroyDecodedData();
254 if (getContent()->hasImage() && !isPreloaded() && 239 if (getContent()->hasImage() && !isPreloaded() &&
255 getContent()->isRefetchableDataFromDiskCache()) { 240 getContent()->isRefetchableDataFromDiskCache()) {
256 UMA_HISTOGRAM_MEMORY_KB("Memory.Renderer.EstimatedDroppableEncodedSize", 241 UMA_HISTOGRAM_MEMORY_KB("Memory.Renderer.EstimatedDroppableEncodedSize",
257 encodedSize() / 1024); 242 encodedSize() / 1024);
258 } 243 }
259 } 244 }
260 245
261 void ImageResource::allClientsAndObserversRemoved() { 246 void ImageResource::allClientsAndObserversRemoved() {
262 CHECK(!getContent()->hasImage() || !errorOccurred()); 247 CHECK(!getContent() || !getContent()->hasImage() || !errorOccurred());
263 // If possible, delay the resetting until back at the event loop. Doing so 248 // If possible, delay the resetting until back at the event loop. Doing so
yhirano 2017/03/17 13:09:35 This comment should be inside of the outer if stat
264 // after a conservative GC prevents resetAnimation() from upsetting ongoing 249 // after a conservative GC prevents resetAnimation() from upsetting ongoing
265 // animation updates (crbug.com/613709) 250 // animation updates (crbug.com/613709)
266 if (!ThreadHeap::willObjectBeLazilySwept(this)) { 251 if (getContent()) {
267 Platform::current()->currentThread()->getWebTaskRunner()->postTask( 252 if (!ThreadHeap::willObjectBeLazilySwept(this)) {
268 BLINK_FROM_HERE, WTF::bind(&ImageResourceContent::doResetAnimation, 253 Platform::current()->currentThread()->getWebTaskRunner()->postTask(
269 wrapWeakPersistent(getContent()))); 254 BLINK_FROM_HERE, WTF::bind(&ImageResourceContent::doResetAnimation,
270 } else { 255 wrapWeakPersistent(getContent())));
271 getContent()->doResetAnimation(); 256 } else {
257 getContent()->doResetAnimation();
258 }
272 } 259 }
273 if (m_multipartParser) 260 if (m_multipartParser)
274 m_multipartParser->cancel(); 261 m_multipartParser->cancel();
275 Resource::allClientsAndObserversRemoved(); 262 Resource::allClientsAndObserversRemoved();
276 } 263 }
277 264
278 PassRefPtr<const SharedBuffer> ImageResource::resourceBuffer() const { 265 PassRefPtr<const SharedBuffer> ImageResource::resourceBuffer() const {
279 if (data()) 266 if (data())
kouhei (in TOK) 2017/03/15 10:25:28 Is this when we tried to access ::resourceBuffer w
hiroshige 2017/03/15 19:03:31 Yes. (Probably we check getContent() first for co
280 return data(); 267 return data();
268 if (!getContent())
269 return nullptr;
281 return getContent()->resourceBuffer(); 270 return getContent()->resourceBuffer();
282 } 271 }
283 272
284 void ImageResource::appendData(const char* data, size_t length) { 273 void ImageResource::appendData(const char* data, size_t length) {
285 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(length); 274 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(length);
286 if (m_multipartParser) { 275 if (m_multipartParser) {
287 m_multipartParser->appendData(data, length); 276 m_multipartParser->appendData(data, length);
288 } else { 277 } else {
289 Resource::appendData(data, length); 278 Resource::appendData(data, length);
290 279
280 if (!getContent())
281 return;
282
291 // Update the image immediately if needed. 283 // Update the image immediately if needed.
292 if (getContent()->shouldUpdateImageImmediately()) { 284 if (getContent()->shouldUpdateImageImmediately()) {
293 updateImage(this->data(), ImageResourceContent::UpdateImage, false); 285 updateImage(this->data(), ImageResourceContent::UpdateImage, false);
294 return; 286 return;
295 } 287 }
296 288
297 // For other cases, only update at |kFlushDelaySeconds| intervals. This 289 // For other cases, only update at |kFlushDelaySeconds| intervals. This
298 // throttles how frequently we update |m_image| and how frequently we 290 // throttles how frequently we update |m_image| and how frequently we
299 // inform the clients which causes an invalidation of this image. In other 291 // inform the clients which causes an invalidation of this image. In other
300 // words, we only invalidate this image every |kFlushDelaySeconds| seconds 292 // words, we only invalidate this image every |kFlushDelaySeconds| seconds
(...skipping 22 matching lines...) Expand all
323 } 315 }
324 316
325 void ImageResource::decodeError(bool allDataReceived) { 317 void ImageResource::decodeError(bool allDataReceived) {
326 size_t size = encodedSize(); 318 size_t size = encodedSize();
327 319
328 clearData(); 320 clearData();
329 setEncodedSize(0); 321 setEncodedSize(0);
330 if (!errorOccurred()) 322 if (!errorOccurred())
331 setStatus(ResourceStatus::DecodeError); 323 setStatus(ResourceStatus::DecodeError);
332 324
325 // Tries to reload here to avoid imageNotifyFinished()
326 // notification in the case of decode error.
327 if (loader())
328 loader()->reloadIfLoFiOrPlaceholderImage(this);
329
333 // Finishes loading if needed, and notifies observers. 330 // Finishes loading if needed, and notifies observers.
334 if (!allDataReceived && loader()) { 331 if (!allDataReceived && loader()) {
335 // Observers are notified via ImageResource::finish(). 332 // Observers are notified via ImageResource::finish().
336 // TODO(hiroshige): Do not call didFinishLoading() directly. 333 // TODO(hiroshige): Do not call didFinishLoading() directly.
337 loader()->didFinishLoading(monotonicallyIncreasingTime(), size, size); 334 loader()->didFinishLoading(monotonicallyIncreasingTime(), size, size);
338 } else { 335 } else if (getContent()) {
339 auto result = getContent()->updateImage( 336 auto result = getContent()->updateImage(
340 nullptr, ImageResourceContent::ClearImageAndNotifyObservers, 337 nullptr, ImageResourceContent::ClearImageAndNotifyObservers,
341 allDataReceived); 338 allDataReceived);
342 DCHECK_EQ(result, ImageResourceContent::UpdateImageResult::NoDecodeError); 339 DCHECK_EQ(result, ImageResourceContent::UpdateImageResult::NoDecodeError);
343 } 340 }
344 341
345 memoryCache()->remove(this); 342 memoryCache()->remove(this);
346 } 343 }
347 344
348 void ImageResource::updateImageAndClearBuffer() { 345 void ImageResource::updateImageAndClearBuffer() {
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 return errorOccurred(); 448 return errorOccurred();
452 case PlaceholderOption::ReloadPlaceholderOnDecodeError: 449 case PlaceholderOption::ReloadPlaceholderOnDecodeError:
453 return getStatus() == ResourceStatus::DecodeError; 450 return getStatus() == ResourceStatus::DecodeError;
454 case PlaceholderOption::DoNotReloadPlaceholder: 451 case PlaceholderOption::DoNotReloadPlaceholder:
455 return false; 452 return false;
456 } 453 }
457 NOTREACHED(); 454 NOTREACHED();
458 return false; 455 return false;
459 } 456 }
460 457
458 void ImageResource::detachContent() {
459 bool hasObservers = getContent() && getContent()->hasObservers();
kouhei (in TOK) 2017/03/15 10:25:28 Optional: contentHadObservers?
460
461 m_content = nullptr;
462 clearData();
463 memoryCache()->remove(this);
464
465 if (hasObservers)
466 didRemoveClientOrObserver();
467 }
468
461 static bool isLoFiImage(const ImageResource& resource) { 469 static bool isLoFiImage(const ImageResource& resource) {
462 if (!(resource.resourceRequest().previewsState() & 470 if (!(resource.resourceRequest().previewsState() &
463 WebURLRequest::ServerLoFiOn)) { 471 WebURLRequest::ServerLoFiOn)) {
464 return false; 472 return false;
465 } 473 }
466 return !resource.isLoaded() || 474 return !resource.isLoaded() ||
467 resource.response() 475 resource.response()
468 .httpHeaderField("chrome-proxy-content-transform") 476 .httpHeaderField("chrome-proxy-content-transform")
469 .contains("empty-image"); 477 .contains("empty-image");
470 } 478 }
471 479
472 void ImageResource::reloadIfLoFiOrPlaceholderImage( 480 ImageResource* ImageResource::reloadIfLoFiOrPlaceholderImage(
473 ResourceFetcher* fetcher, 481 ResourceFetcher* fetcher,
474 ReloadLoFiOrPlaceholderPolicy policy) { 482 ReloadLoFiOrPlaceholderPolicy policy) {
483 if (!fetcher)
yhirano 2017/03/17 13:09:35 Is passing nullptr valid?
484 return nullptr;
485
475 if (policy == kReloadIfNeeded && !shouldReloadBrokenPlaceholder()) 486 if (policy == kReloadIfNeeded && !shouldReloadBrokenPlaceholder())
476 return; 487 return nullptr;
477 488
478 if (m_placeholderOption == PlaceholderOption::DoNotReloadPlaceholder && 489 if (m_placeholderOption == PlaceholderOption::DoNotReloadPlaceholder &&
479 !isLoFiImage(*this)) 490 !isLoFiImage(*this))
480 return; 491 return nullptr;
481 492
482 // Prevent clients and observers from being notified of completion while the 493 ImageResourceContent* content = getContent();
483 // reload is being scheduled, so that e.g. canceling an existing load in 494 if (!content)
484 // progress doesn't cause clients and observers to be notified of completion 495 return nullptr;
485 // prematurely.
486 DCHECK(!m_isSchedulingReload);
487 m_isSchedulingReload = true;
488 496
489 setCachePolicyBypassingCache(); 497 // Creates request/options for new ImageResource for reloading.
498 ResourceLoaderOptions reloadingOptions = options();
499 ResourceRequest reloadingRequest = resourceRequest();
500 reloadingRequest.setCachePolicy(WebCachePolicy::BypassingCache);
501 reloadingRequest.setPreviewsState(WebURLRequest::PreviewsNoTransform);
502 if (m_placeholderOption != PlaceholderOption::DoNotReloadPlaceholder)
503 reloadingRequest.clearHTTPHeaderField("range");
490 504
491 setPreviewsStateNoTransform(); 505 // Clear the image before reloading starts to avoid mixing the image from
506 // previous response with the response from the new reloading response.
507 updateImage(nullptr, ImageResourceContent::ClearImageAndNotifyObservers,
508 false);
492 509
493 if (m_placeholderOption != PlaceholderOption::DoNotReloadPlaceholder) 510 detachContent();
494 clearRangeRequestHeader(); 511 // |this->getContent()| is nullptr after this point.
495 m_placeholderOption = PlaceholderOption::DoNotReloadPlaceholder;
496 512
497 if (isLoading()) { 513 // TODO(hiroshige): Use ResourceFetcher::requestResource() to unify the
498 loader()->cancel(); 514 // starting points of resource loading into requestResource().
499 // Canceling the loader causes error() to be called, which in turn calls 515 // Currently we call ResourceFetcher::startLoad() instead, in order to avoid
500 // clear() and notifyObservers(), so there's no need to call these again 516 // re-applying modifications to ResourceRequest in requestResource().
501 // here. 517 ImageResource* reloadingResource =
502 } else { 518 new ImageResource(reloadingRequest, reloadingOptions, content, false);
503 clearData(); 519 DCHECK(!reloadingResource || content == reloadingResource->getContent());
504 setEncodedSize(0); 520 memoryCache()->add(reloadingResource);
505 updateImage(nullptr, ImageResourceContent::ClearImageAndNotifyObservers, 521 fetcher->addToDocumentResources(reloadingResource);
506 false); 522 fetcher->startLoad(reloadingResource);
507 }
508 523
509 setStatus(ResourceStatus::NotStarted); 524 return reloadingResource;
510
511 DCHECK(m_isSchedulingReload);
512 m_isSchedulingReload = false;
513
514 fetcher->startLoad(this);
515 } 525 }
516 526
517 void ImageResource::onePartInMultipartReceived( 527 void ImageResource::onePartInMultipartReceived(
518 const ResourceResponse& response) { 528 const ResourceResponse& response) {
519 DCHECK(m_multipartParser); 529 DCHECK(m_multipartParser);
520 530
521 setResponse(response); 531 setResponse(response);
522 if (m_multipartParsingState == MultipartParsingState::WaitingForFirstPart) { 532 if (m_multipartParsingState == MultipartParsingState::WaitingForFirstPart) {
523 // We have nothing to do because we don't have any data. 533 // We have nothing to do because we don't have any data.
524 m_multipartParsingState = MultipartParsingState::ParsingFirstPart; 534 m_multipartParsingState = MultipartParsingState::ParsingFirstPart;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
563 573
564 ImageResourceContent* ImageResource::getContent() { 574 ImageResourceContent* ImageResource::getContent() {
565 return m_content; 575 return m_content;
566 } 576 }
567 577
568 const ImageResourceContent* ImageResource::getContent() const { 578 const ImageResourceContent* ImageResource::getContent() const {
569 return m_content; 579 return m_content;
570 } 580 }
571 581
572 ResourcePriority ImageResource::priorityFromObservers() { 582 ResourcePriority ImageResource::priorityFromObservers() {
583 if (!getContent())
584 return ResourcePriority();
573 return getContent()->priorityFromObservers(); 585 return getContent()->priorityFromObservers();
574 } 586 }
575 587
576 void ImageResource::updateImage( 588 void ImageResource::updateImage(
577 PassRefPtr<SharedBuffer> sharedBuffer, 589 PassRefPtr<SharedBuffer> sharedBuffer,
578 ImageResourceContent::UpdateImageOption updateImageOption, 590 ImageResourceContent::UpdateImageOption updateImageOption,
579 bool allDataReceived) { 591 bool allDataReceived) {
592 if (!getContent())
593 return;
580 auto result = getContent()->updateImage(std::move(sharedBuffer), 594 auto result = getContent()->updateImage(std::move(sharedBuffer),
581 updateImageOption, allDataReceived); 595 updateImageOption, allDataReceived);
582 if (result == ImageResourceContent::UpdateImageResult::ShouldDecodeError) { 596 if (result == ImageResourceContent::UpdateImageResult::ShouldDecodeError) {
597 // TODO before commit (hiroshige): Update the comment.
583 // In case of decode error, we call imageNotifyFinished() iff we don't 598 // In case of decode error, we call imageNotifyFinished() iff we don't
584 // initiate reloading: 599 // initiate reloading:
585 // [(a): when this is in the middle of loading, or (b): otherwise] 600 // [(a): when this is in the middle of loading, or (b): otherwise]
586 // 1. The updateImage() call above doesn't call notifyObservers(). 601 // 1. The updateImage() call above doesn't call notifyObservers().
587 // 2. notifyObservers(ShouldNotifyFinish) is called 602 // 2. notifyObservers(ShouldNotifyFinish) is called
588 // (a) via updateImage() called in ImageResource::finish() 603 // (a) via updateImage() called in ImageResource::finish()
589 // called via didFinishLoading() called in decodeError(), or 604 // called via didFinishLoading() called in decodeError(), or
590 // (b) via updateImage() called in decodeError(). 605 // (b) via updateImage() called in decodeError().
591 // imageNotifyFinished() is called here iff we will not initiate 606 // imageNotifyFinished() is called here iff we will not initiate
592 // reloading in Step 3 due to notifyObservers()'s 607 // reloading in Step 3 due to notifyObservers()'s
593 // schedulingReloadOrShouldReloadBrokenPlaceholder() check. 608 // schedulingReloadOrShouldReloadBrokenPlaceholder() check.
594 // 3. reloadIfLoFiOrPlaceholderImage() is called via ResourceFetcher 609 // 3. reloadIfLoFiOrPlaceholderImage() is called via ResourceFetcher
595 // (a) via didFinishLoading() called in decodeError(), or 610 // (a) via didFinishLoading() called in decodeError(), or
596 // (b) after returning ImageResource::updateImage(). 611 // (b) after returning ImageResource::updateImage().
597 decodeError(allDataReceived); 612 decodeError(allDataReceived);
598 } 613 }
599 } 614 }
600 615
601 } // namespace blink 616 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698