| 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 (getContent()) { |
| 264 // after a conservative GC prevents resetAnimation() from upsetting ongoing | 249 // If possible, delay the resetting until back at the event loop. Doing so |
| 265 // animation updates (crbug.com/613709) | 250 // after a conservative GC prevents resetAnimation() from upsetting ongoing |
| 266 if (!ThreadHeap::willObjectBeLazilySwept(this)) { | 251 // animation updates (crbug.com/613709) |
| 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 { |
| 266 if (!getContent()) { |
| 267 DCHECK(!data()); |
| 268 return nullptr; |
| 269 } |
| 270 |
| 279 if (data()) | 271 if (data()) |
| 280 return data(); | 272 return data(); |
| 281 return getContent()->resourceBuffer(); | 273 return getContent()->resourceBuffer(); |
| 282 } | 274 } |
| 283 | 275 |
| 284 void ImageResource::appendData(const char* data, size_t length) { | 276 void ImageResource::appendData(const char* data, size_t length) { |
| 285 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(length); | 277 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(length); |
| 286 if (m_multipartParser) { | 278 if (m_multipartParser) { |
| 287 m_multipartParser->appendData(data, length); | 279 m_multipartParser->appendData(data, length); |
| 288 } else { | 280 } else { |
| 289 Resource::appendData(data, length); | 281 Resource::appendData(data, length); |
| 290 | 282 |
| 283 if (!getContent()) |
| 284 return; |
| 285 |
| 291 // Update the image immediately if needed. | 286 // Update the image immediately if needed. |
| 292 if (getContent()->shouldUpdateImageImmediately()) { | 287 if (getContent()->shouldUpdateImageImmediately()) { |
| 293 updateImage(this->data(), ImageResourceContent::UpdateImage, false); | 288 updateImage(this->data(), ImageResourceContent::UpdateImage, false); |
| 294 return; | 289 return; |
| 295 } | 290 } |
| 296 | 291 |
| 297 // For other cases, only update at |kFlushDelaySeconds| intervals. This | 292 // For other cases, only update at |kFlushDelaySeconds| intervals. This |
| 298 // throttles how frequently we update |m_image| and how frequently we | 293 // throttles how frequently we update |m_image| and how frequently we |
| 299 // inform the clients which causes an invalidation of this image. In other | 294 // inform the clients which causes an invalidation of this image. In other |
| 300 // words, we only invalidate this image every |kFlushDelaySeconds| seconds | 295 // words, we only invalidate this image every |kFlushDelaySeconds| seconds |
| (...skipping 22 matching lines...) Expand all Loading... |
| 323 } | 318 } |
| 324 | 319 |
| 325 void ImageResource::decodeError(bool allDataReceived) { | 320 void ImageResource::decodeError(bool allDataReceived) { |
| 326 size_t size = encodedSize(); | 321 size_t size = encodedSize(); |
| 327 | 322 |
| 328 clearData(); | 323 clearData(); |
| 329 setEncodedSize(0); | 324 setEncodedSize(0); |
| 330 if (!errorOccurred()) | 325 if (!errorOccurred()) |
| 331 setStatus(ResourceStatus::DecodeError); | 326 setStatus(ResourceStatus::DecodeError); |
| 332 | 327 |
| 328 // Tries to reload here to avoid imageNotifyFinished() |
| 329 // notification in the case of decode error. |
| 330 if (loader()) |
| 331 loader()->reloadIfLoFiOrPlaceholderImage(this); |
| 332 |
| 333 // Finishes loading if needed, and notifies observers. | 333 // Finishes loading if needed, and notifies observers. |
| 334 if (!allDataReceived && loader()) { | 334 if (!allDataReceived && loader()) { |
| 335 // Observers are notified via ImageResource::finish(). | 335 // Observers are notified via ImageResource::finish(). |
| 336 // TODO(hiroshige): Do not call didFinishLoading() directly. | 336 // TODO(hiroshige): Do not call didFinishLoading() directly. |
| 337 loader()->didFinishLoading(monotonicallyIncreasingTime(), size, size); | 337 loader()->didFinishLoading(monotonicallyIncreasingTime(), size, size); |
| 338 } else { | 338 } else if (getContent()) { |
| 339 auto result = getContent()->updateImage( | 339 auto result = getContent()->updateImage( |
| 340 nullptr, ImageResourceContent::ClearImageAndNotifyObservers, | 340 nullptr, ImageResourceContent::ClearImageAndNotifyObservers, |
| 341 allDataReceived); | 341 allDataReceived); |
| 342 DCHECK_EQ(result, ImageResourceContent::UpdateImageResult::NoDecodeError); | 342 DCHECK_EQ(result, ImageResourceContent::UpdateImageResult::NoDecodeError); |
| 343 } | 343 } |
| 344 | 344 |
| 345 memoryCache()->remove(this); | 345 memoryCache()->remove(this); |
| 346 } | 346 } |
| 347 | 347 |
| 348 void ImageResource::updateImageAndClearBuffer() { | 348 void ImageResource::updateImageAndClearBuffer() { |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 451 return errorOccurred(); | 451 return errorOccurred(); |
| 452 case PlaceholderOption::ReloadPlaceholderOnDecodeError: | 452 case PlaceholderOption::ReloadPlaceholderOnDecodeError: |
| 453 return getStatus() == ResourceStatus::DecodeError; | 453 return getStatus() == ResourceStatus::DecodeError; |
| 454 case PlaceholderOption::DoNotReloadPlaceholder: | 454 case PlaceholderOption::DoNotReloadPlaceholder: |
| 455 return false; | 455 return false; |
| 456 } | 456 } |
| 457 NOTREACHED(); | 457 NOTREACHED(); |
| 458 return false; | 458 return false; |
| 459 } | 459 } |
| 460 | 460 |
| 461 void ImageResource::detachContent() { |
| 462 bool contentHadObservers = getContent() && getContent()->hasObservers(); |
| 463 |
| 464 m_content = nullptr; |
| 465 clearData(); |
| 466 memoryCache()->remove(this); |
| 467 |
| 468 if (contentHadObservers) |
| 469 didRemoveClientOrObserver(); |
| 470 } |
| 471 |
| 461 static bool isLoFiImage(const ImageResource& resource) { | 472 static bool isLoFiImage(const ImageResource& resource) { |
| 462 if (!(resource.resourceRequest().previewsState() & | 473 if (!(resource.resourceRequest().previewsState() & |
| 463 WebURLRequest::ServerLoFiOn)) { | 474 WebURLRequest::ServerLoFiOn)) { |
| 464 return false; | 475 return false; |
| 465 } | 476 } |
| 466 return !resource.isLoaded() || | 477 return !resource.isLoaded() || |
| 467 resource.response() | 478 resource.response() |
| 468 .httpHeaderField("chrome-proxy-content-transform") | 479 .httpHeaderField("chrome-proxy-content-transform") |
| 469 .contains("empty-image"); | 480 .contains("empty-image"); |
| 470 } | 481 } |
| 471 | 482 |
| 472 void ImageResource::reloadIfLoFiOrPlaceholderImage( | 483 ImageResource* ImageResource::reloadIfLoFiOrPlaceholderImage( |
| 473 ResourceFetcher* fetcher, | 484 ResourceFetcher* fetcher, |
| 474 ReloadLoFiOrPlaceholderPolicy policy) { | 485 ReloadLoFiOrPlaceholderPolicy policy) { |
| 486 DCHECK(fetcher); |
| 487 |
| 475 if (policy == kReloadIfNeeded && !shouldReloadBrokenPlaceholder()) | 488 if (policy == kReloadIfNeeded && !shouldReloadBrokenPlaceholder()) |
| 476 return; | 489 return nullptr; |
| 477 | 490 |
| 478 if (m_placeholderOption == PlaceholderOption::DoNotReloadPlaceholder && | 491 if (m_placeholderOption == PlaceholderOption::DoNotReloadPlaceholder && |
| 479 !isLoFiImage(*this)) | 492 !isLoFiImage(*this)) |
| 480 return; | 493 return nullptr; |
| 481 | 494 |
| 482 // Prevent clients and observers from being notified of completion while the | 495 ImageResourceContent* content = getContent(); |
| 483 // reload is being scheduled, so that e.g. canceling an existing load in | 496 if (!content) |
| 484 // progress doesn't cause clients and observers to be notified of completion | 497 return nullptr; |
| 485 // prematurely. | |
| 486 DCHECK(!m_isSchedulingReload); | |
| 487 m_isSchedulingReload = true; | |
| 488 | 498 |
| 489 setCachePolicyBypassingCache(); | 499 // Creates request/options for new ImageResource for reloading. |
| 500 ResourceLoaderOptions reloadingOptions = options(); |
| 501 ResourceRequest reloadingRequest = resourceRequest(); |
| 502 reloadingRequest.setCachePolicy(WebCachePolicy::BypassingCache); |
| 503 reloadingRequest.setPreviewsState(WebURLRequest::PreviewsNoTransform); |
| 504 if (m_placeholderOption != PlaceholderOption::DoNotReloadPlaceholder) |
| 505 reloadingRequest.clearHTTPHeaderField("range"); |
| 490 | 506 |
| 491 setPreviewsStateNoTransform(); | 507 // Clear the image before reloading starts to avoid mixing the image from |
| 508 // previous response with the response from the new reloading response. |
| 509 updateImage(nullptr, ImageResourceContent::ClearImageAndNotifyObservers, |
| 510 false); |
| 492 | 511 |
| 493 if (m_placeholderOption != PlaceholderOption::DoNotReloadPlaceholder) | 512 detachContent(); |
| 494 clearRangeRequestHeader(); | 513 // |this->getContent()| is nullptr after this point. |
| 495 m_placeholderOption = PlaceholderOption::DoNotReloadPlaceholder; | |
| 496 | 514 |
| 497 if (isLoading()) { | 515 // TODO(hiroshige): Use ResourceFetcher::requestResource() to unify the |
| 498 loader()->cancel(); | 516 // starting points of resource loading into requestResource(). |
| 499 // Canceling the loader causes error() to be called, which in turn calls | 517 // Currently we call ResourceFetcher::startLoad() instead, in order to avoid |
| 500 // clear() and notifyObservers(), so there's no need to call these again | 518 // re-applying modifications to ResourceRequest in requestResource(). |
| 501 // here. | 519 ImageResource* reloadingResource = |
| 502 } else { | 520 new ImageResource(reloadingRequest, reloadingOptions, content, false); |
| 503 clearData(); | 521 DCHECK(!reloadingResource || content == reloadingResource->getContent()); |
| 504 setEncodedSize(0); | 522 memoryCache()->add(reloadingResource); |
| 505 updateImage(nullptr, ImageResourceContent::ClearImageAndNotifyObservers, | 523 fetcher->addToDocumentResources(reloadingResource); |
| 506 false); | 524 fetcher->startLoad(reloadingResource); |
| 507 } | |
| 508 | 525 |
| 509 setStatus(ResourceStatus::NotStarted); | 526 return reloadingResource; |
| 510 | |
| 511 DCHECK(m_isSchedulingReload); | |
| 512 m_isSchedulingReload = false; | |
| 513 | |
| 514 fetcher->startLoad(this); | |
| 515 } | 527 } |
| 516 | 528 |
| 517 void ImageResource::onePartInMultipartReceived( | 529 void ImageResource::onePartInMultipartReceived( |
| 518 const ResourceResponse& response) { | 530 const ResourceResponse& response) { |
| 519 DCHECK(m_multipartParser); | 531 DCHECK(m_multipartParser); |
| 520 | 532 |
| 521 setResponse(response); | 533 setResponse(response); |
| 522 if (m_multipartParsingState == MultipartParsingState::WaitingForFirstPart) { | 534 if (m_multipartParsingState == MultipartParsingState::WaitingForFirstPart) { |
| 523 // We have nothing to do because we don't have any data. | 535 // We have nothing to do because we don't have any data. |
| 524 m_multipartParsingState = MultipartParsingState::ParsingFirstPart; | 536 m_multipartParsingState = MultipartParsingState::ParsingFirstPart; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 563 | 575 |
| 564 ImageResourceContent* ImageResource::getContent() { | 576 ImageResourceContent* ImageResource::getContent() { |
| 565 return m_content; | 577 return m_content; |
| 566 } | 578 } |
| 567 | 579 |
| 568 const ImageResourceContent* ImageResource::getContent() const { | 580 const ImageResourceContent* ImageResource::getContent() const { |
| 569 return m_content; | 581 return m_content; |
| 570 } | 582 } |
| 571 | 583 |
| 572 ResourcePriority ImageResource::priorityFromObservers() { | 584 ResourcePriority ImageResource::priorityFromObservers() { |
| 585 if (!getContent()) |
| 586 return ResourcePriority(); |
| 573 return getContent()->priorityFromObservers(); | 587 return getContent()->priorityFromObservers(); |
| 574 } | 588 } |
| 575 | 589 |
| 576 void ImageResource::updateImage( | 590 void ImageResource::updateImage( |
| 577 PassRefPtr<SharedBuffer> sharedBuffer, | 591 PassRefPtr<SharedBuffer> sharedBuffer, |
| 578 ImageResourceContent::UpdateImageOption updateImageOption, | 592 ImageResourceContent::UpdateImageOption updateImageOption, |
| 579 bool allDataReceived) { | 593 bool allDataReceived) { |
| 594 if (!getContent()) |
| 595 return; |
| 580 auto result = getContent()->updateImage(std::move(sharedBuffer), | 596 auto result = getContent()->updateImage(std::move(sharedBuffer), |
| 581 updateImageOption, allDataReceived); | 597 updateImageOption, allDataReceived); |
| 582 if (result == ImageResourceContent::UpdateImageResult::ShouldDecodeError) { | 598 if (result == ImageResourceContent::UpdateImageResult::ShouldDecodeError) { |
| 599 // TODO before commit (hiroshige): Update the comment. |
| 583 // In case of decode error, we call imageNotifyFinished() iff we don't | 600 // In case of decode error, we call imageNotifyFinished() iff we don't |
| 584 // initiate reloading: | 601 // initiate reloading: |
| 585 // [(a): when this is in the middle of loading, or (b): otherwise] | 602 // [(a): when this is in the middle of loading, or (b): otherwise] |
| 586 // 1. The updateImage() call above doesn't call notifyObservers(). | 603 // 1. The updateImage() call above doesn't call notifyObservers(). |
| 587 // 2. notifyObservers(ShouldNotifyFinish) is called | 604 // 2. notifyObservers(ShouldNotifyFinish) is called |
| 588 // (a) via updateImage() called in ImageResource::finish() | 605 // (a) via updateImage() called in ImageResource::finish() |
| 589 // called via didFinishLoading() called in decodeError(), or | 606 // called via didFinishLoading() called in decodeError(), or |
| 590 // (b) via updateImage() called in decodeError(). | 607 // (b) via updateImage() called in decodeError(). |
| 591 // imageNotifyFinished() is called here iff we will not initiate | 608 // imageNotifyFinished() is called here iff we will not initiate |
| 592 // reloading in Step 3 due to notifyObservers()'s | 609 // reloading in Step 3 due to notifyObservers()'s |
| 593 // schedulingReloadOrShouldReloadBrokenPlaceholder() check. | 610 // schedulingReloadOrShouldReloadBrokenPlaceholder() check. |
| 594 // 3. reloadIfLoFiOrPlaceholderImage() is called via ResourceFetcher | 611 // 3. reloadIfLoFiOrPlaceholderImage() is called via ResourceFetcher |
| 595 // (a) via didFinishLoading() called in decodeError(), or | 612 // (a) via didFinishLoading() called in decodeError(), or |
| 596 // (b) after returning ImageResource::updateImage(). | 613 // (b) after returning ImageResource::updateImage(). |
| 597 decodeError(allDataReceived); | 614 decodeError(allDataReceived); |
| 598 } | 615 } |
| 599 } | 616 } |
| 600 | 617 |
| 601 } // namespace blink | 618 } // namespace blink |
| OLD | NEW |