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 23 matching lines...) Expand all Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |