| OLD | NEW | 
|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "chrome/browser/instant/instant_service.h" | 5 #include "chrome/browser/instant/instant_service.h" | 
| 6 | 6 | 
|  | 7 #include "base/strings/string_number_conversions.h" | 
|  | 8 #include "chrome/browser/history/history_notifications.h" | 
| 7 #include "chrome/browser/instant/instant_io_context.h" | 9 #include "chrome/browser/instant/instant_io_context.h" | 
|  | 10 #include "chrome/browser/instant/instant_service_factory.h" | 
| 8 #include "chrome/browser/profiles/profile.h" | 11 #include "chrome/browser/profiles/profile.h" | 
| 9 #include "chrome/browser/ui/webui/ntp/thumbnail_source.h" | 12 #include "chrome/browser/ui/webui/ntp/thumbnail_source.h" | 
| 10 #include "chrome/common/chrome_notification_types.h" | 13 #include "chrome/common/chrome_notification_types.h" | 
| 11 #include "content/public/browser/browser_thread.h" | 14 #include "content/public/browser/browser_thread.h" | 
| 12 #include "content/public/browser/notification_service.h" | 15 #include "content/public/browser/notification_service.h" | 
| 13 #include "content/public/browser/notification_types.h" | 16 #include "content/public/browser/notification_types.h" | 
| 14 #include "content/public/browser/render_process_host.h" | 17 #include "content/public/browser/render_process_host.h" | 
| 15 #include "content/public/browser/url_data_source.h" | 18 #include "content/public/browser/url_data_source.h" | 
|  | 19 #include "googleurl/src/gurl.h" | 
|  | 20 #include "net/url_request/url_request.h" | 
| 16 | 21 | 
| 17 using content::BrowserThread; | 22 using content::BrowserThread; | 
| 18 | 23 | 
|  | 24 namespace { | 
|  | 25 | 
|  | 26 // Copies deleted urls out of the history data structure |details| into a | 
|  | 27 // straight vector of GURLs. | 
|  | 28 void HistoryDetailsToDeletedURLs(const history::URLsDeletedDetails& details, | 
|  | 29                                  std::vector<GURL>* deleted_urls) { | 
|  | 30   for (history::URLRows::const_iterator it = details.rows.begin(); | 
|  | 31        it != details.rows.end(); | 
|  | 32        ++it) { | 
|  | 33     deleted_urls->push_back(it->url()); | 
|  | 34   } | 
|  | 35 } | 
|  | 36 | 
|  | 37 }  // namespace | 
|  | 38 | 
| 19 InstantService::InstantService(Profile* profile) | 39 InstantService::InstantService(Profile* profile) | 
| 20     : profile_(profile) { | 40     : profile_(profile), | 
|  | 41       last_most_visited_item_id_(0) { | 
| 21   // Stub for unit tests. | 42   // Stub for unit tests. | 
| 22   if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) | 43   if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) | 
| 23     return; | 44     return; | 
| 24 | 45 | 
| 25   registrar_.Add(this, | 46   registrar_.Add(this, | 
| 26                  content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, | 47                  content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, | 
| 27                  content::NotificationService::AllSources()); | 48                  content::NotificationService::AllSources()); | 
|  | 49   registrar_.Add(this, | 
|  | 50                  chrome::NOTIFICATION_HISTORY_URLS_DELETED, | 
|  | 51                  content::NotificationService::AllSources()); | 
| 28 | 52 | 
| 29   instant_io_context_ = new InstantIOContext(); | 53   instant_io_context_ = new InstantIOContext(); | 
| 30 | 54 | 
| 31   if (profile_ && profile_->GetResourceContext()) { | 55   if (profile_ && profile_->GetResourceContext()) { | 
| 32     BrowserThread::PostTask( | 56     BrowserThread::PostTask( | 
| 33         BrowserThread::IO, FROM_HERE, | 57         BrowserThread::IO, FROM_HERE, | 
| 34         base::Bind(&InstantIOContext::SetUserDataOnIO, | 58         base::Bind(&InstantIOContext::SetUserDataOnIO, | 
| 35                    profile->GetResourceContext(), instant_io_context_)); | 59                    profile->GetResourceContext(), instant_io_context_)); | 
| 36   } | 60   } | 
| 37 | 61 | 
| 38   content::URLDataSource::Add(profile, new ThumbnailSource(profile)); | 62   content::URLDataSource::Add(profile, new ThumbnailSource(profile)); | 
| 39 } | 63 } | 
| 40 | 64 | 
| 41 InstantService::~InstantService() { | 65 InstantService::~InstantService() { | 
| 42 } | 66 } | 
| 43 | 67 | 
|  | 68 // static | 
|  | 69 const std::string InstantService::MaybeTranslateInstantPathOnUI( | 
|  | 70     Profile* profile, const std::string& path) { | 
|  | 71   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 
|  | 72   InstantService* instant_service = | 
|  | 73       InstantServiceFactory::GetForProfile(profile); | 
|  | 74   if (!instant_service) | 
|  | 75     return path; | 
|  | 76 | 
|  | 77   uint64 most_visited_item_id = 0; | 
|  | 78   if (base::StringToUint64(path, &most_visited_item_id)) { | 
|  | 79     GURL url; | 
|  | 80     if (instant_service->GetURLForMostVisitedItemId(most_visited_item_id, &url)) | 
|  | 81       return url.spec(); | 
|  | 82   } | 
|  | 83   return path; | 
|  | 84 } | 
|  | 85 | 
|  | 86 const std::string InstantService::MaybeTranslateInstantPathOnIO( | 
|  | 87     const net::URLRequest* request, const std::string& path) { | 
|  | 88   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 
|  | 89   uint64 most_visited_item_id = 0; | 
|  | 90   if (base::StringToUint64(path, &most_visited_item_id)) { | 
|  | 91     GURL url; | 
|  | 92     if (InstantIOContext::GetURLForMostVisitedItemId(request, | 
|  | 93                                                      most_visited_item_id, | 
|  | 94                                                      &url)) | 
|  | 95       return url.spec(); | 
|  | 96   } | 
|  | 97   return path; | 
|  | 98 } | 
|  | 99 | 
|  | 100 // static | 
|  | 101 bool InstantService::IsInstantPath(const GURL& url) { | 
|  | 102   // Strip leading slash. | 
|  | 103   std::string path = url.path().substr(1); | 
|  | 104 | 
|  | 105   // Check that path is of Most Visited item ID form. | 
|  | 106   uint64 dummy = 0; | 
|  | 107   return base::StringToUint64(path, &dummy); | 
|  | 108 } | 
|  | 109 | 
| 44 void InstantService::AddInstantProcess(int process_id) { | 110 void InstantService::AddInstantProcess(int process_id) { | 
| 45   process_ids_.insert(process_id); | 111   process_ids_.insert(process_id); | 
| 46 | 112 | 
| 47   if (instant_io_context_) { | 113   if (instant_io_context_) { | 
| 48     BrowserThread::PostTask( | 114     BrowserThread::PostTask( | 
| 49         BrowserThread::IO, FROM_HERE, | 115         BrowserThread::IO, FROM_HERE, | 
| 50         base::Bind(&InstantIOContext::AddInstantProcessOnIO, | 116         base::Bind(&InstantIOContext::AddInstantProcessOnIO, | 
| 51                    instant_io_context_, process_id)); | 117                    instant_io_context_, process_id)); | 
| 52   } | 118   } | 
| 53 } | 119 } | 
| 54 | 120 | 
| 55 bool InstantService::IsInstantProcess(int process_id) const { | 121 bool InstantService::IsInstantProcess(int process_id) const { | 
| 56   return process_ids_.find(process_id) != process_ids_.end(); | 122   return process_ids_.find(process_id) != process_ids_.end(); | 
| 57 } | 123 } | 
| 58 | 124 | 
|  | 125 uint64 InstantService::AddURL(const GURL& url) { | 
|  | 126   uint64 id = 0; | 
|  | 127   if (GetMostVisitedItemIDForURL(url, &id)) | 
|  | 128     return id; | 
|  | 129 | 
|  | 130   last_most_visited_item_id_++; | 
|  | 131   most_visited_item_id_to_url_map_[last_most_visited_item_id_] = url; | 
|  | 132   url_to_most_visited_item_id_map_[url] = last_most_visited_item_id_; | 
|  | 133 | 
|  | 134   if (instant_io_context_) { | 
|  | 135     BrowserThread::PostTask( | 
|  | 136         BrowserThread::IO, FROM_HERE, | 
|  | 137         base::Bind(&InstantIOContext::AddMostVisitedItemIDOnIO, | 
|  | 138                    instant_io_context_, last_most_visited_item_id_, url)); | 
|  | 139   } | 
|  | 140 | 
|  | 141   return last_most_visited_item_id_; | 
|  | 142 } | 
|  | 143 | 
|  | 144 bool InstantService::GetMostVisitedItemIDForURL( | 
|  | 145     const GURL& url, | 
|  | 146     uint64 *most_visited_item_id) { | 
|  | 147   std::map<GURL, uint64>::iterator it = | 
|  | 148       url_to_most_visited_item_id_map_.find(url); | 
|  | 149   if (it != url_to_most_visited_item_id_map_.end()) { | 
|  | 150     *most_visited_item_id = it->second; | 
|  | 151     return true; | 
|  | 152   } | 
|  | 153   *most_visited_item_id = 0; | 
|  | 154   return false; | 
|  | 155 } | 
|  | 156 | 
|  | 157 bool InstantService::GetURLForMostVisitedItemId(uint64 most_visited_item_id, | 
|  | 158                                                 GURL* url) { | 
|  | 159   std::map<uint64, GURL>::iterator it = | 
|  | 160       most_visited_item_id_to_url_map_.find(most_visited_item_id); | 
|  | 161   if (it != most_visited_item_id_to_url_map_.end()) { | 
|  | 162     *url = it->second; | 
|  | 163     return true; | 
|  | 164   } | 
|  | 165   *url = GURL(); | 
|  | 166   return false; | 
|  | 167 } | 
|  | 168 | 
| 59 void InstantService::Shutdown() { | 169 void InstantService::Shutdown() { | 
| 60   process_ids_.clear(); | 170   process_ids_.clear(); | 
| 61 | 171 | 
| 62   if (instant_io_context_) { | 172   if (instant_io_context_) { | 
| 63     BrowserThread::PostTask( | 173     BrowserThread::PostTask( | 
| 64         BrowserThread::IO, FROM_HERE, | 174         BrowserThread::IO, FROM_HERE, | 
| 65         base::Bind(&InstantIOContext::ClearInstantProcessesOnIO, | 175         base::Bind(&InstantIOContext::ClearInstantProcessesOnIO, | 
| 66                    instant_io_context_)); | 176                    instant_io_context_)); | 
| 67   } | 177   } | 
| 68   instant_io_context_ = NULL; | 178   instant_io_context_ = NULL; | 
| 69 } | 179 } | 
| 70 | 180 | 
| 71 void InstantService::Observe(int type, | 181 void InstantService::Observe(int type, | 
| 72                              const content::NotificationSource& source, | 182                              const content::NotificationSource& source, | 
| 73                              const content::NotificationDetails& details) { | 183                              const content::NotificationDetails& details) { | 
| 74   DCHECK_EQ(type, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED); | 184   switch (type) { | 
| 75   int process_id = content::Source<content::RenderProcessHost>(source)->GetID(); | 185     case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: { | 
| 76   process_ids_.erase(process_id); | 186       int process_id = | 
|  | 187           content::Source<content::RenderProcessHost>(source)->GetID(); | 
|  | 188       process_ids_.erase(process_id); | 
| 77 | 189 | 
| 78   if (instant_io_context_) { | 190       if (instant_io_context_) { | 
| 79     BrowserThread::PostTask( | 191         BrowserThread::PostTask( | 
| 80         BrowserThread::IO, FROM_HERE, | 192             BrowserThread::IO, FROM_HERE, | 
| 81         base::Bind(&InstantIOContext::RemoveInstantProcessOnIO, | 193             base::Bind(&InstantIOContext::RemoveInstantProcessOnIO, | 
| 82                    instant_io_context_, process_id)); | 194                        instant_io_context_, process_id)); | 
|  | 195       } | 
|  | 196       break; | 
|  | 197     } | 
|  | 198     case chrome::NOTIFICATION_HISTORY_URLS_DELETED: { | 
|  | 199       content::Details<history::URLsDeletedDetails> det(details); | 
|  | 200       std::vector<GURL> deleted_urls; | 
|  | 201       HistoryDetailsToDeletedURLs(*det.ptr(), &deleted_urls); | 
|  | 202 | 
|  | 203       std::vector<uint64> deleted_ids; | 
|  | 204       DeleteHistoryURLs(deleted_urls, det->all_history, &deleted_ids); | 
|  | 205 | 
|  | 206       if (instant_io_context_) { | 
|  | 207         BrowserThread::PostTask( | 
|  | 208             BrowserThread::IO, FROM_HERE, | 
|  | 209             base::Bind(&InstantIOContext::DeleteMostVisitedURLsOnIO, | 
|  | 210                        instant_io_context_, deleted_ids, det->all_history)); | 
|  | 211       } | 
|  | 212       break; | 
|  | 213     } | 
|  | 214     default: | 
|  | 215       NOTREACHED() << "Unexpected notification type in InstantService."; | 
| 83   } | 216   } | 
| 84 } | 217 } | 
|  | 218 | 
|  | 219 void InstantService::DeleteHistoryURLs(const std::vector<GURL>& deleted_urls, | 
|  | 220                                        bool all_history, | 
|  | 221                                        std::vector<uint64>* deleted_ids) { | 
|  | 222   if (all_history) { | 
|  | 223     url_to_most_visited_item_id_map_.clear(); | 
|  | 224     most_visited_item_id_to_url_map_.clear(); | 
|  | 225     return; | 
|  | 226   } | 
|  | 227 | 
|  | 228   for (std::vector<GURL>::const_iterator it = deleted_urls.begin(); | 
|  | 229        it != deleted_urls.end(); | 
|  | 230        ++it) { | 
|  | 231     std::map<GURL, uint64>::iterator item = | 
|  | 232         url_to_most_visited_item_id_map_.find(*it); | 
|  | 233     if (item != url_to_most_visited_item_id_map_.end()) { | 
|  | 234       uint64 most_visited_item_id = item->second; | 
|  | 235       url_to_most_visited_item_id_map_.erase(item); | 
|  | 236       most_visited_item_id_to_url_map_.erase( | 
|  | 237           most_visited_item_id_to_url_map_.find(most_visited_item_id)); | 
|  | 238       deleted_ids->push_back(most_visited_item_id); | 
|  | 239     } | 
|  | 240   } | 
|  | 241 } | 
| OLD | NEW | 
|---|