OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "base/json/json_parser.h" |
| 6 #include "base/strings/utf_string_conversions.h" |
| 7 #include "base/values.h" |
| 8 #include "chrome/browser/bitmap_fetcher/bitmap_fetcher.h" |
| 9 #include "chrome/browser/enhanced_bookmarks/android/bookmark_image_service_andro
id.h" |
| 10 #include "chrome/browser/enhanced_bookmarks/enhanced_bookmark_model_factory.h" |
| 11 #include "chrome/grit/browser_resources.h" |
| 12 #include "components/bookmarks/browser/bookmark_model.h" |
| 13 #include "components/enhanced_bookmarks/enhanced_bookmark_model.h" |
| 14 #include "content/public/browser/browser_context.h" |
| 15 #include "content/public/browser/browser_thread.h" |
| 16 #include "content/public/browser/navigation_entry.h" |
| 17 #include "content/public/browser/render_frame_host.h" |
| 18 #include "content/public/browser/web_contents.h" |
| 19 #include "content/public/common/referrer.h" |
| 20 #include "net/base/load_flags.h" |
| 21 #include "ui/base/resource/resource_bundle.h" |
| 22 #include "ui/gfx/image/image_skia.h" |
| 23 |
| 24 using content::Referrer; |
| 25 using bookmarks::BookmarkNode; |
| 26 |
| 27 namespace enhanced_bookmarks { |
| 28 |
| 29 BookmarkImageServiceAndroid::BookmarkImageServiceAndroid( |
| 30 content::BrowserContext* browserContext) |
| 31 : BookmarkImageService( |
| 32 browserContext->GetPath(), |
| 33 EnhancedBookmarkModelFactory::GetForBrowserContext(browserContext), |
| 34 make_scoped_refptr(content::BrowserThread::GetBlockingPool())), |
| 35 browser_context_(browserContext) { |
| 36 } |
| 37 |
| 38 void BookmarkImageServiceAndroid::RetrieveSalientImage( |
| 39 const GURL& page_url, |
| 40 const GURL& image_url, |
| 41 const std::string& referrer, |
| 42 net::URLRequest::ReferrerPolicy referrer_policy, |
| 43 bool update_bookmark) { |
| 44 const BookmarkNode* bookmark = |
| 45 enhanced_bookmark_model_->bookmark_model() |
| 46 ->GetMostRecentlyAddedUserNodeForURL(page_url); |
| 47 if (!bookmark || !image_url.is_valid()) { |
| 48 ProcessNewImage(page_url, update_bookmark, gfx::Image(), image_url); |
| 49 return; |
| 50 } |
| 51 |
| 52 BitmapFetcherHandler* bitmap_fetcher_handler = |
| 53 new BitmapFetcherHandler(this, image_url); |
| 54 bitmap_fetcher_handler->Start( |
| 55 browser_context_, referrer, referrer_policy, |
| 56 net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES, |
| 57 update_bookmark, page_url); |
| 58 } |
| 59 |
| 60 void BookmarkImageServiceAndroid::RetrieveSalientImageFromContext( |
| 61 content::RenderFrameHost* render_frame_host, |
| 62 const GURL& page_url, |
| 63 bool update_bookmark) { |
| 64 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 65 if (IsPageUrlInProgress(page_url)) |
| 66 return; // A request for this URL is already in progress. |
| 67 |
| 68 const BookmarkNode* bookmark = enhanced_bookmark_model_->bookmark_model() |
| 69 ->GetMostRecentlyAddedUserNodeForURL(page_url); |
| 70 if (!bookmark) |
| 71 return; |
| 72 |
| 73 // Stop the image extraction if there is already an image present. |
| 74 GURL url; |
| 75 int height, width; |
| 76 if (enhanced_bookmark_model_->GetOriginalImage(bookmark, &url, &width, |
| 77 &height) || |
| 78 enhanced_bookmark_model_->GetThumbnailImage(bookmark, &url, &width, |
| 79 &height)) { |
| 80 return; |
| 81 } |
| 82 |
| 83 if (script_.empty()) { |
| 84 script_ = |
| 85 base::UTF8ToUTF16(ResourceBundle::GetSharedInstance() |
| 86 .GetRawDataResource(IDR_GET_SALIENT_IMAGE_URL_JS) |
| 87 .as_string()); |
| 88 } |
| 89 |
| 90 render_frame_host->ExecuteJavaScript( |
| 91 script_, |
| 92 base::Bind( |
| 93 &BookmarkImageServiceAndroid::RetrieveSalientImageFromContextCallback, |
| 94 base::Unretained(this), page_url, update_bookmark)); |
| 95 } |
| 96 |
| 97 void BookmarkImageServiceAndroid::FinishSuccessfulPageLoadForTab( |
| 98 content::WebContents* web_contents, bool update_bookmark) { |
| 99 content::NavigationEntry* entry = |
| 100 web_contents->GetController().GetVisibleEntry(); |
| 101 |
| 102 // If the navigation is a simple back or forward, do not extract images, those |
| 103 // were extracted already. |
| 104 if (!entry || (entry->GetTransitionType() & ui::PAGE_TRANSITION_FORWARD_BACK)) |
| 105 return; |
| 106 const GURL& entry_url = entry->GetURL(); |
| 107 const GURL& entry_original_url = entry->GetOriginalRequestURL(); |
| 108 std::vector<GURL> urls; |
| 109 urls.push_back(entry_url); |
| 110 if (entry_url != entry_original_url) |
| 111 urls.push_back(entry_original_url); |
| 112 for (GURL url : urls) { |
| 113 if (enhanced_bookmark_model_->bookmark_model()->IsBookmarked(url)) { |
| 114 RetrieveSalientImageFromContext(web_contents->GetMainFrame(), url, |
| 115 update_bookmark); |
| 116 } |
| 117 } |
| 118 } |
| 119 |
| 120 void BookmarkImageServiceAndroid::RetrieveSalientImageFromContextCallback( |
| 121 const GURL& page_url, |
| 122 bool update_bookmark, |
| 123 const base::Value* result) { |
| 124 if (!result) |
| 125 return; |
| 126 |
| 127 std::string json; |
| 128 if (!result->GetAsString(&json)) { |
| 129 LOG(WARNING) |
| 130 << "Salient image extracting script returned non-string result."; |
| 131 return; |
| 132 } |
| 133 |
| 134 scoped_ptr<base::Value> json_data; |
| 135 int error_code = 0; |
| 136 std::string errorMessage; |
| 137 json_data.reset(base::JSONReader::ReadAndReturnError( |
| 138 json, base::JSON_PARSE_RFC, &error_code, &errorMessage)); |
| 139 if (error_code || !json_data) { |
| 140 LOG(WARNING) << "JSON parse error: " << errorMessage.c_str() << json; |
| 141 return; |
| 142 } |
| 143 |
| 144 base::DictionaryValue* dict; |
| 145 if (!json_data->GetAsDictionary(&dict)) { |
| 146 LOG(WARNING) << "JSON parse error, not a dict: " << json; |
| 147 return; |
| 148 } |
| 149 |
| 150 std::string referrerPolicy; |
| 151 std::string image_url; |
| 152 dict->GetString("referrerPolicy", &referrerPolicy); |
| 153 dict->GetString("imageUrl", &image_url); |
| 154 |
| 155 // The policy strings are guaranteed to be in lower-case. |
| 156 blink::WebReferrerPolicy policy = blink::WebReferrerPolicyDefault; |
| 157 if (referrerPolicy == "never") |
| 158 policy = blink::WebReferrerPolicyNever; |
| 159 if (referrerPolicy == "always") |
| 160 policy = blink::WebReferrerPolicyAlways; |
| 161 if (referrerPolicy == "origin") |
| 162 policy = blink::WebReferrerPolicyOrigin; |
| 163 |
| 164 in_progress_page_urls_.insert(page_url); |
| 165 |
| 166 Referrer referrer = |
| 167 Referrer::SanitizeForRequest(GURL(image_url), Referrer(page_url, policy)); |
| 168 net::URLRequest::ReferrerPolicy referrer_policy = |
| 169 net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE; |
| 170 if (!referrer.url.is_empty()) { |
| 171 switch (policy) { |
| 172 case blink::WebReferrerPolicyDefault: |
| 173 break; |
| 174 case blink::WebReferrerPolicyAlways: |
| 175 case blink::WebReferrerPolicyNever: |
| 176 case blink::WebReferrerPolicyOrigin: |
| 177 referrer_policy = net::URLRequest::NEVER_CLEAR_REFERRER; |
| 178 break; |
| 179 default: |
| 180 NOTREACHED(); |
| 181 } |
| 182 } |
| 183 RetrieveSalientImage(page_url, GURL(image_url), referrer.url.spec(), |
| 184 referrer_policy, update_bookmark); |
| 185 } |
| 186 |
| 187 void BookmarkImageServiceAndroid::BitmapFetcherHandler::Start( |
| 188 content::BrowserContext* browser_context, |
| 189 const std::string& referrer, |
| 190 net::URLRequest::ReferrerPolicy referrer_policy, |
| 191 int load_flags, |
| 192 bool update_bookmark, |
| 193 const GURL& page_url) { |
| 194 update_bookmark_ = update_bookmark; |
| 195 page_url_ = page_url; |
| 196 |
| 197 bitmap_fetcher_.Start(browser_context->GetRequestContext(), referrer, |
| 198 referrer_policy, load_flags); |
| 199 } |
| 200 |
| 201 void BookmarkImageServiceAndroid::BitmapFetcherHandler::OnFetchComplete( |
| 202 const GURL url, |
| 203 const SkBitmap* bitmap) { |
| 204 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 205 |
| 206 gfx::Image image; |
| 207 if (bitmap) { |
| 208 gfx::ImageSkia imageSkia = gfx::ImageSkia::CreateFrom1xBitmap(*bitmap); |
| 209 imageSkia.MakeThreadSafe(); |
| 210 image = gfx::Image(imageSkia); |
| 211 } |
| 212 service_->ProcessNewImage(page_url_, update_bookmark_, image, url); |
| 213 |
| 214 delete this; |
| 215 } |
| 216 |
| 217 } // namespace enhanced_bookmarks |
OLD | NEW |