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

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

Issue 2930323003: Show client placeholders for Server LoFi images. (Closed)
Patch Set: Addressed megjablon's comments Created 3 years, 5 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 30 matching lines...) Expand all
41 #include "platform/loader/fetch/ResourceLoadingLog.h" 41 #include "platform/loader/fetch/ResourceLoadingLog.h"
42 #include "platform/network/HTTPParsers.h" 42 #include "platform/network/HTTPParsers.h"
43 #include "platform/weborigin/KURL.h" 43 #include "platform/weborigin/KURL.h"
44 #include "platform/weborigin/SecurityViolationReportingPolicy.h" 44 #include "platform/weborigin/SecurityViolationReportingPolicy.h"
45 #include "platform/wtf/CurrentTime.h" 45 #include "platform/wtf/CurrentTime.h"
46 #include "platform/wtf/StdLibExtras.h" 46 #include "platform/wtf/StdLibExtras.h"
47 #include "public/platform/Platform.h" 47 #include "public/platform/Platform.h"
48 #include "v8/include/v8.h" 48 #include "v8/include/v8.h"
49 49
50 namespace blink { 50 namespace blink {
51
51 namespace { 52 namespace {
53
52 // The amount of time to wait before informing the clients that the image has 54 // The amount of time to wait before informing the clients that the image has
53 // been updated (in seconds). This effectively throttles invalidations that 55 // been updated (in seconds). This effectively throttles invalidations that
54 // result from new data arriving for this image. 56 // result from new data arriving for this image.
55 constexpr double kFlushDelaySeconds = 1.; 57 constexpr double kFlushDelaySeconds = 1.;
58
59 bool HasServerLoFiResponseHeaders(const ResourceResponse& response) {
60 return response.HttpHeaderField("chrome-proxy-content-transform")
61 .Contains("empty-image") ||
62 // Check for the legacy Server Lo-Fi response headers, since it's
63 // possible that an old Lo-Fi image could be served from the cache.
64 response.HttpHeaderField("chrome-proxy").Contains("q=low");
65 }
66
56 } // namespace 67 } // namespace
57 68
58 class ImageResource::ImageResourceInfoImpl final 69 class ImageResource::ImageResourceInfoImpl final
59 : public GarbageCollectedFinalized<ImageResourceInfoImpl>, 70 : public GarbageCollectedFinalized<ImageResourceInfoImpl>,
60 public ImageResourceInfo { 71 public ImageResourceInfo {
61 USING_GARBAGE_COLLECTED_MIXIN(ImageResourceInfoImpl); 72 USING_GARBAGE_COLLECTED_MIXIN(ImageResourceInfoImpl);
62 73
63 public: 74 public:
64 ImageResourceInfoImpl(ImageResource* resource) : resource_(resource) { 75 ImageResourceInfoImpl(ImageResource* resource) : resource_(resource) {
65 DCHECK(resource_); 76 DCHECK(resource_);
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after
436 .ToFloat(&has_device_pixel_ratio_header_value_); 447 .ToFloat(&has_device_pixel_ratio_header_value_);
437 if (!has_device_pixel_ratio_header_value_ || 448 if (!has_device_pixel_ratio_header_value_ ||
438 device_pixel_ratio_header_value_ <= 0.0) { 449 device_pixel_ratio_header_value_ <= 0.0) {
439 device_pixel_ratio_header_value_ = 1.0; 450 device_pixel_ratio_header_value_ = 1.0;
440 has_device_pixel_ratio_header_value_ = false; 451 has_device_pixel_ratio_header_value_ = false;
441 } 452 }
442 } 453 }
443 454
444 if (placeholder_option_ == 455 if (placeholder_option_ ==
445 PlaceholderOption::kShowAndReloadPlaceholderAlways && 456 PlaceholderOption::kShowAndReloadPlaceholderAlways &&
446 IsEntireResource(this->GetResponse())) { 457 IsEntireResource(this->GetResponse())) {
kouhei (in TOK) 2017/07/07 01:38:03 Sorry I forgot why we are using this->GetResponse(
sclittle 2017/07/07 02:46:41 Looking at the code, it looks like you're correct
447 if (this->GetResponse().HttpStatusCode() < 400 || 458 if (this->GetResponse().HttpStatusCode() < 400 ||
448 this->GetResponse().HttpStatusCode() >= 600) { 459 this->GetResponse().HttpStatusCode() >= 600) {
449 // Don't treat a complete and broken image as a placeholder if the 460 // Don't treat a complete and broken image as a placeholder if the
450 // response code is something other than a 4xx or 5xx error. 461 // response code is something other than a 4xx or 5xx error.
451 // This is done to prevent reissuing the request in cases like 462 // This is done to prevent reissuing the request in cases like
452 // "204 No Content" responses to tracking requests triggered by <img> 463 // "204 No Content" responses to tracking requests triggered by <img>
453 // tags, and <img> tags used to preload non-image resources. 464 // tags, and <img> tags used to preload non-image resources.
454 placeholder_option_ = PlaceholderOption::kDoNotReloadPlaceholder; 465 placeholder_option_ = PlaceholderOption::kDoNotReloadPlaceholder;
455 } else { 466 } else {
456 placeholder_option_ = PlaceholderOption::kReloadPlaceholderOnDecodeError; 467 placeholder_option_ = PlaceholderOption::kReloadPlaceholderOnDecodeError;
457 } 468 }
458 } 469 }
470
471 if (HasServerLoFiResponseHeaders(this->GetResponse())) {
kouhei (in TOK) 2017/07/07 01:38:03 Can we omit "this->"?
sclittle 2017/07/07 02:46:41 Done.
472 // Ensure that the PreviewsState bit for Server Lo-Fi is set iff Chrome
473 // received the appropriate Server Lo-Fi response headers for this image.
474 //
475 // Normally, the |kServerLoFiOn| bit should already be set if Server Lo-Fi
476 // response headers are coming back, but it's possible for legacy Lo-Fi
477 // images to be served from the cache even if Chrome isn't in Lo-Fi mode.
478 // This also serves as a nice last line of defence to ensure that Server
479 // Lo-Fi images can be reloaded to show the original even if e.g. a server
480 // bug causes Lo-Fi images to be sent when they aren't expected.
481 SetPreviewsState(GetResourceRequest().GetPreviewsState() |
hiroshige 2017/07/07 02:52:49 Just for clarification: SetPreviewsState() calls h
sclittle 2017/07/07 21:25:28 I think that alternative would work, and it might
482 WebURLRequest::kServerLoFiOn);
483 } else if (GetResourceRequest().GetPreviewsState() &
484 WebURLRequest::kServerLoFiOn) {
485 // If Chrome expects a Lo-Fi response, but the server decided to send the
486 // full image, then clear the Server Lo-Fi Previews state bit.
487 WebURLRequest::PreviewsState new_previews_state =
488 GetResourceRequest().GetPreviewsState();
489
490 new_previews_state &= ~WebURLRequest::kServerLoFiOn;
491 if (new_previews_state == WebURLRequest::kPreviewsUnspecified)
492 new_previews_state = WebURLRequest::kPreviewsOff;
493
494 SetPreviewsState(new_previews_state);
495 }
459 } 496 }
460 497
461 bool ImageResource::ShouldShowPlaceholder() const { 498 bool ImageResource::ShouldShowPlaceholder() const {
499 if (RuntimeEnabledFeatures::ClientPlaceholdersForServerLoFiEnabled() &&
500 (GetResourceRequest().GetPreviewsState() &
501 WebURLRequest::kServerLoFiOn)) {
502 // If the runtime feature is enabled, show Client Lo-Fi placeholder images
503 // in place of Server Lo-Fi responses. This is done so that all Lo-Fi images
504 // have a consistent appearance.
505 return true;
506 }
507
462 switch (placeholder_option_) { 508 switch (placeholder_option_) {
463 case PlaceholderOption::kShowAndReloadPlaceholderAlways: 509 case PlaceholderOption::kShowAndReloadPlaceholderAlways:
464 case PlaceholderOption::kShowAndDoNotReloadPlaceholder: 510 case PlaceholderOption::kShowAndDoNotReloadPlaceholder:
465 return true; 511 return true;
466 case PlaceholderOption::kReloadPlaceholderOnDecodeError: 512 case PlaceholderOption::kReloadPlaceholderOnDecodeError:
467 case PlaceholderOption::kDoNotReloadPlaceholder: 513 case PlaceholderOption::kDoNotReloadPlaceholder:
468 return false; 514 return false;
469 } 515 }
470 NOTREACHED(); 516 NOTREACHED();
471 return false; 517 return false;
472 } 518 }
473 519
474 bool ImageResource::ShouldReloadBrokenPlaceholder() const { 520 bool ImageResource::ShouldReloadBrokenPlaceholder() const {
475 switch (placeholder_option_) { 521 switch (placeholder_option_) {
476 case PlaceholderOption::kShowAndReloadPlaceholderAlways: 522 case PlaceholderOption::kShowAndReloadPlaceholderAlways:
477 return ErrorOccurred(); 523 return ErrorOccurred();
478 case PlaceholderOption::kReloadPlaceholderOnDecodeError: 524 case PlaceholderOption::kReloadPlaceholderOnDecodeError:
479 return GetStatus() == ResourceStatus::kDecodeError; 525 return GetStatus() == ResourceStatus::kDecodeError;
480 case PlaceholderOption::kShowAndDoNotReloadPlaceholder: 526 case PlaceholderOption::kShowAndDoNotReloadPlaceholder:
481 case PlaceholderOption::kDoNotReloadPlaceholder: 527 case PlaceholderOption::kDoNotReloadPlaceholder:
482 return false; 528 return false;
483 } 529 }
484 NOTREACHED(); 530 NOTREACHED();
485 return false; 531 return false;
486 } 532 }
487 533
488 static bool IsLoFiImage(const ImageResource& resource) {
489 if (resource.IsLoaded()) {
490 return resource.GetResponse()
491 .HttpHeaderField("chrome-proxy-content-transform")
492 .Contains("empty-image") ||
493 resource.GetResponse()
494 .HttpHeaderField("chrome-proxy")
495 .Contains("q=low");
496 }
497 return resource.GetResourceRequest().GetPreviewsState() &
498 WebURLRequest::kServerLoFiOn;
499 }
500
501 void ImageResource::ReloadIfLoFiOrPlaceholderImage( 534 void ImageResource::ReloadIfLoFiOrPlaceholderImage(
502 ResourceFetcher* fetcher, 535 ResourceFetcher* fetcher,
503 ReloadLoFiOrPlaceholderPolicy policy) { 536 ReloadLoFiOrPlaceholderPolicy policy) {
504 if (policy == kReloadIfNeeded && !ShouldReloadBrokenPlaceholder()) 537 if (policy == kReloadIfNeeded && !ShouldReloadBrokenPlaceholder())
505 return; 538 return;
506 539
540 // If the image is loaded, then the |PreviewsState::kServerLoFiOn| bit should
541 // be set iff the image has Server Lo-Fi response headers.
542 DCHECK(!IsLoaded() ||
543 HasServerLoFiResponseHeaders(GetResponse()) ==
544 static_cast<bool>(GetResourceRequest().GetPreviewsState() &
545 WebURLRequest::kServerLoFiOn));
546
507 if (placeholder_option_ == PlaceholderOption::kDoNotReloadPlaceholder && 547 if (placeholder_option_ == PlaceholderOption::kDoNotReloadPlaceholder &&
508 !IsLoFiImage(*this)) 548 !(GetResourceRequest().GetPreviewsState() & WebURLRequest::kServerLoFiOn))
509 return; 549 return;
510 550
511 // Prevent clients and observers from being notified of completion while the 551 // Prevent clients and observers from being notified of completion while the
512 // reload is being scheduled, so that e.g. canceling an existing load in 552 // reload is being scheduled, so that e.g. canceling an existing load in
513 // progress doesn't cause clients and observers to be notified of completion 553 // progress doesn't cause clients and observers to be notified of completion
514 // prematurely. 554 // prematurely.
515 DCHECK(!is_scheduling_reload_); 555 DCHECK(!is_scheduling_reload_);
516 is_scheduling_reload_ = true; 556 is_scheduling_reload_ = true;
517 557
518 SetCachePolicyBypassingCache(); 558 SetCachePolicyBypassingCache();
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
645 // reloading in Step 3 due to notifyObservers()'s 685 // reloading in Step 3 due to notifyObservers()'s
646 // schedulingReloadOrShouldReloadBrokenPlaceholder() check. 686 // schedulingReloadOrShouldReloadBrokenPlaceholder() check.
647 // 3. reloadIfLoFiOrPlaceholderImage() is called via ResourceFetcher 687 // 3. reloadIfLoFiOrPlaceholderImage() is called via ResourceFetcher
648 // (a) via didFinishLoading() called in decodeError(), or 688 // (a) via didFinishLoading() called in decodeError(), or
649 // (b) after returning ImageResource::updateImage(). 689 // (b) after returning ImageResource::updateImage().
650 DecodeError(all_data_received); 690 DecodeError(all_data_received);
651 } 691 }
652 } 692 }
653 693
654 } // namespace blink 694 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698