Home | History | Annotate | Download | only in android
      1 // Copyright (c) 2012 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 "chrome/browser/history/android/favicon_sql_handler.h"
      6 
      7 #include "base/logging.h"
      8 #include "base/memory/ref_counted.h"
      9 #include "base/memory/ref_counted_memory.h"
     10 #include "chrome/browser/history/thumbnail_database.h"
     11 
     12 using base::Time;
     13 
     14 namespace history {
     15 
     16 namespace {
     17 
     18 // The interesting columns of this handler.
     19 const HistoryAndBookmarkRow::ColumnID kInterestingColumns[] = {
     20   HistoryAndBookmarkRow::FAVICON};
     21 
     22 }  // namespace
     23 
     24 FaviconSQLHandler::FaviconSQLHandler(ThumbnailDatabase* thumbnail_db)
     25     : SQLHandler(kInterestingColumns, arraysize(kInterestingColumns)),
     26       thumbnail_db_(thumbnail_db) {
     27 }
     28 
     29 FaviconSQLHandler::~FaviconSQLHandler() {
     30 }
     31 
     32 bool FaviconSQLHandler::Update(const HistoryAndBookmarkRow& row,
     33                                const TableIDRows& ids_set) {
     34   if (!row.favicon_valid())
     35     return Delete(ids_set);
     36 
     37   // If the image_data will be updated, it is not reasonable to find if the
     38   // icon is already in database, just create a new favicon.
     39   // TODO(pkotwicz): Pass in real pixel size.
     40   favicon_base::FaviconID favicon_id = thumbnail_db_->AddFavicon(
     41       GURL(), favicon_base::FAVICON, row.favicon(), Time::Now(), gfx::Size());
     42 
     43   if (!favicon_id)
     44     return false;
     45 
     46   std::vector<favicon_base::FaviconID> favicon_ids;
     47   for (TableIDRows::const_iterator i = ids_set.begin();
     48        i != ids_set.end(); ++i) {
     49     // Remove all icon mappings to favicons of type FAVICON.
     50     std::vector<IconMapping> icon_mappings;
     51     thumbnail_db_->GetIconMappingsForPageURL(
     52         i->url, favicon_base::FAVICON, &icon_mappings);
     53     for (std::vector<IconMapping>::const_iterator m = icon_mappings.begin();
     54          m != icon_mappings.end(); ++m) {
     55       if (!thumbnail_db_->DeleteIconMapping(m->mapping_id))
     56         return false;
     57 
     58       // Keep the old icon for deleting it later if possible.
     59       favicon_ids.push_back(m->icon_id);
     60     }
     61     // Add the icon mapping.
     62     if (!thumbnail_db_->AddIconMapping(i->url, favicon_id))
     63       return false;
     64   }
     65   // As we update the favicon, Let's remove unused favicons if any.
     66   if (!favicon_ids.empty() && !DeleteUnusedFavicon(favicon_ids))
     67     return false;
     68 
     69   return true;
     70 }
     71 
     72 bool FaviconSQLHandler::Delete(const TableIDRows& ids_set) {
     73   std::vector<favicon_base::FaviconID> favicon_ids;
     74   for (TableIDRows::const_iterator i = ids_set.begin();
     75        i != ids_set.end(); ++i) {
     76     // Since the URL was deleted, we delete all types of icon mappings.
     77     std::vector<IconMapping> icon_mappings;
     78     thumbnail_db_->GetIconMappingsForPageURL(i->url, &icon_mappings);
     79     for (std::vector<IconMapping>::const_iterator m = icon_mappings.begin();
     80          m != icon_mappings.end(); ++m) {
     81       favicon_ids.push_back(m->icon_id);
     82     }
     83     if (!thumbnail_db_->DeleteIconMappings(i->url))
     84       return false;
     85   }
     86 
     87   if (favicon_ids.empty())
     88     return true;
     89 
     90   if (!DeleteUnusedFavicon(favicon_ids))
     91     return false;
     92 
     93   return true;
     94 }
     95 
     96 bool FaviconSQLHandler::Insert(HistoryAndBookmarkRow* row) {
     97   if (!row->is_value_set_explicitly(HistoryAndBookmarkRow::FAVICON) ||
     98       !row->favicon_valid())
     99     return true;
    100 
    101   DCHECK(row->is_value_set_explicitly(HistoryAndBookmarkRow::URL));
    102 
    103   // Is it a problem to give a empty URL?
    104   // TODO(pkotwicz): Pass in real pixel size.
    105   favicon_base::FaviconID id = thumbnail_db_->AddFavicon(
    106       GURL(), favicon_base::FAVICON, row->favicon(), Time::Now(), gfx::Size());
    107   if (!id)
    108     return false;
    109   return thumbnail_db_->AddIconMapping(row->url(), id);
    110 }
    111 
    112 bool FaviconSQLHandler::DeleteUnusedFavicon(
    113     const std::vector<favicon_base::FaviconID>& ids) {
    114   for (std::vector<favicon_base::FaviconID>::const_iterator i = ids.begin();
    115        i != ids.end();
    116        ++i) {
    117     if (!thumbnail_db_->HasMappingFor(*i) && !thumbnail_db_->DeleteFavicon(*i))
    118       return false;
    119   }
    120   return true;
    121 }
    122 
    123 }  // namespace history.
    124