15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/thumbnails/thumbnail_service_impl.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/command_line.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted_memory.h"
9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/time/time.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/history/history_service.h"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/thumbnails/content_based_thumbnailing_algorithm.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/thumbnails/simple_thumbnail_crop.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/thumbnails/thumbnailing_context.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "components/search/search.h"
164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "url/gurl.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using content::BrowserThread;
19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The thumbnail size in DIP.
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kThumbnailWidth = 212;
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst int kThumbnailHeight = 142;
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// True if thumbnail retargeting feature is enabled (Finch/flags).
27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool IsThumbnailRetargetingEnabled() {
28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!chrome::IsInstantExtendedAPIEnabled())
29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return false;
30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return CommandLine::ForCurrentProcess()->HasSwitch(
32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      switches::kEnableThumbnailRetargeting);
33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AddForcedURLOnUIThread(scoped_refptr<history::TopSites> top_sites,
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                            const GURL& url) {
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (top_sites.get() != NULL)
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    top_sites->AddForcedURL(url, base::Time::Now());
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
43d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}  // namespace
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace thumbnails {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ThumbnailServiceImpl::ThumbnailServiceImpl(Profile* profile)
48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    : top_sites_(profile->GetTopSites()),
49d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      use_thumbnail_retargeting_(IsThumbnailRetargetingEnabled()) {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ThumbnailServiceImpl::~ThumbnailServiceImpl() {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ThumbnailServiceImpl::SetPageThumbnail(const ThumbnailingContext& context,
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            const gfx::Image& thumbnail) {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<history::TopSites> local_ptr(top_sites_);
58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (local_ptr.get() == NULL)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return local_ptr->SetPageThumbnail(context.url, thumbnail, context.score);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ThumbnailServiceImpl::GetPageThumbnail(
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& url,
66d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    bool prefix_match,
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<base::RefCountedMemory>* bytes) {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<history::TopSites> local_ptr(top_sites_);
69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (local_ptr.get() == NULL)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  return local_ptr->GetPageThumbnail(url, prefix_match, bytes);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ThumbnailServiceImpl::AddForcedURL(const GURL& url) {
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_refptr<history::TopSites> local_ptr(top_sites_);
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (local_ptr.get() == NULL)
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Adding
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                          base::Bind(AddForcedURLOnUIThread, local_ptr, url));
83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ThumbnailingAlgorithm* ThumbnailServiceImpl::GetThumbnailingAlgorithm()
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const {
87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const gfx::Size thumbnail_size(kThumbnailWidth, kThumbnailHeight);
88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (use_thumbnail_retargeting_)
89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return new ContentBasedThumbnailingAlgorithm(thumbnail_size);
90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return new SimpleThumbnailCrop(thumbnail_size);
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ThumbnailServiceImpl::ShouldAcquirePageThumbnail(const GURL& url) {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<history::TopSites> local_ptr(top_sites_);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (local_ptr.get() == NULL)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Skip if the given URL is not appropriate for history.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!HistoryService::CanAddURL(url))
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Skip if the top sites list is full, and the URL is not known.
103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (local_ptr->IsNonForcedFull() && !local_ptr->IsKnownURL(url))
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Skip if we don't have to udpate the existing thumbnail.
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ThumbnailScore current_score;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (local_ptr->GetPageThumbnailScore(url, &current_score) &&
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !current_score.ShouldConsiderUpdating())
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Skip if we don't have to udpate the temporary thumbnail (i.e. the one
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // not yet saved).
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ThumbnailScore temporary_score;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (local_ptr->GetTemporaryPageThumbnailScore(url, &temporary_score) &&
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !temporary_score.ShouldConsiderUpdating())
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ThumbnailServiceImpl::ShutdownOnUIThread() {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since each call uses its own scoped_refptr, we can just clear the reference
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // here by assigning null. If another call is completed, it added its own
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // reference.
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  top_sites_ = NULL;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}  // namespace thumbnails
128