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" | 7 #include "base/strings/string_number_conversions.h" |
8 #include "chrome/browser/history/history_notifications.h" | |
9 #include "chrome/browser/instant/instant_io_context.h" | 8 #include "chrome/browser/instant/instant_io_context.h" |
10 #include "chrome/browser/instant/instant_service_factory.h" | 9 #include "chrome/browser/instant/instant_service_factory.h" |
11 #include "chrome/browser/profiles/profile.h" | 10 #include "chrome/browser/profiles/profile.h" |
12 #include "chrome/browser/ui/webui/ntp/thumbnail_source.h" | 11 #include "chrome/browser/ui/webui/ntp/thumbnail_source.h" |
13 #include "chrome/common/chrome_notification_types.h" | 12 #include "chrome/common/chrome_notification_types.h" |
14 #include "content/public/browser/browser_thread.h" | 13 #include "content/public/browser/browser_thread.h" |
15 #include "content/public/browser/notification_service.h" | 14 #include "content/public/browser/notification_service.h" |
16 #include "content/public/browser/notification_types.h" | 15 #include "content/public/browser/notification_types.h" |
17 #include "content/public/browser/render_process_host.h" | 16 #include "content/public/browser/render_process_host.h" |
18 #include "content/public/browser/url_data_source.h" | 17 #include "content/public/browser/url_data_source.h" |
19 #include "googleurl/src/gurl.h" | 18 #include "googleurl/src/gurl.h" |
20 #include "net/url_request/url_request.h" | 19 #include "net/url_request/url_request.h" |
21 | 20 |
22 using content::BrowserThread; | 21 using content::BrowserThread; |
23 | 22 |
24 namespace { | 23 namespace { |
25 | 24 |
26 // Copies deleted urls out of the history data structure |details| into a | 25 // Size of the most visited item cache. |
27 // straight vector of GURLs. | 26 const int kMostVisitedItemCacheSize = 1000; |
dhollowa
2013/03/14 00:02:43
This needs to be the same number as in instant_io_
Shishir
2013/03/14 19:53:03
Done.
| |
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 | 27 |
37 } // namespace | 28 } // namespace |
38 | 29 |
39 InstantService::InstantService(Profile* profile) | 30 InstantService::InstantService(Profile* profile) |
40 : profile_(profile), | 31 : profile_(profile), |
41 last_most_visited_item_id_(0) { | 32 most_visited_item_cache_(kMostVisitedItemCacheSize) { |
42 // Stub for unit tests. | 33 // Stub for unit tests. |
43 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) | 34 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) |
44 return; | 35 return; |
45 | 36 |
46 registrar_.Add(this, | 37 registrar_.Add(this, |
47 content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, | 38 content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, |
48 content::NotificationService::AllSources()); | 39 content::NotificationService::AllSources()); |
49 registrar_.Add(this, | |
50 chrome::NOTIFICATION_HISTORY_URLS_DELETED, | |
51 content::NotificationService::AllSources()); | |
52 | 40 |
53 instant_io_context_ = new InstantIOContext(); | 41 instant_io_context_ = new InstantIOContext(); |
54 | 42 |
55 if (profile_ && profile_->GetResourceContext()) { | 43 if (profile_ && profile_->GetResourceContext()) { |
56 BrowserThread::PostTask( | 44 BrowserThread::PostTask( |
57 BrowserThread::IO, FROM_HERE, | 45 BrowserThread::IO, FROM_HERE, |
58 base::Bind(&InstantIOContext::SetUserDataOnIO, | 46 base::Bind(&InstantIOContext::SetUserDataOnIO, |
59 profile->GetResourceContext(), instant_io_context_)); | 47 profile->GetResourceContext(), instant_io_context_)); |
60 } | 48 } |
61 | 49 |
62 content::URLDataSource::Add(profile, new ThumbnailSource(profile)); | 50 content::URLDataSource::Add(profile, new ThumbnailSource(profile)); |
63 } | 51 } |
64 | 52 |
65 InstantService::~InstantService() { | 53 InstantService::~InstantService() { |
66 } | 54 } |
67 | 55 |
68 // static | 56 // static |
69 const std::string InstantService::MaybeTranslateInstantPathOnUI( | 57 const std::string InstantService::MaybeTranslateInstantPathOnUI( |
70 Profile* profile, const std::string& path) { | 58 Profile* profile, const std::string& path) { |
71 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 59 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
72 InstantService* instant_service = | 60 InstantService* instant_service = |
73 InstantServiceFactory::GetForProfile(profile); | 61 InstantServiceFactory::GetForProfile(profile); |
74 if (!instant_service) | 62 if (!instant_service) |
75 return path; | 63 return path; |
76 | 64 |
77 uint64 most_visited_item_id = 0; | 65 InstantRestrictedID restricted_id = 0; |
78 if (base::StringToUint64(path, &most_visited_item_id)) { | 66 if (base::StringToInt(path, &restricted_id)) { |
79 GURL url; | 67 InstantMostVisitedItem item; |
80 if (instant_service->GetURLForMostVisitedItemId(most_visited_item_id, &url)) | 68 if (instant_service->GetMostVisitedItemForID(restricted_id, &item)) |
81 return url.spec(); | 69 return item.url.spec(); |
82 } | 70 } |
83 return path; | 71 return path; |
84 } | 72 } |
85 | 73 |
86 const std::string InstantService::MaybeTranslateInstantPathOnIO( | 74 const std::string InstantService::MaybeTranslateInstantPathOnIO( |
87 const net::URLRequest* request, const std::string& path) { | 75 const net::URLRequest* request, const std::string& path) { |
88 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 76 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
89 uint64 most_visited_item_id = 0; | 77 int restricted_id = 0; |
palmer
2013/03/13 23:50:37
Should be InstantRestrictedID, not int.
dhollowa
2013/03/14 00:02:43
s/int/InstantRestrictedID/
Shishir
2013/03/14 19:53:03
Done.
Shishir
2013/03/14 19:53:03
Done.
| |
90 if (base::StringToUint64(path, &most_visited_item_id)) { | 78 if (base::StringToInt(path, &restricted_id)) { |
dhollowa
2013/03/14 00:02:43
DCHECK_EQ(sizeof(InstantRestrictedID), sizeof(unsi
dhollowa
2013/03/14 00:02:43
StringToUint
Shishir
2013/03/14 19:53:03
Please comment about unsigned.
Shishir
2013/03/14 19:53:03
Done.
dhollowa
2013/03/14 23:40:00
I like int.
| |
91 GURL url; | 79 GURL url; |
92 if (InstantIOContext::GetURLForMostVisitedItemId(request, | 80 if (InstantIOContext::GetURLForMostVisitedItemID(request, |
93 most_visited_item_id, | 81 restricted_id, |
94 &url)) | 82 &url)) { |
95 return url.spec(); | 83 return url.spec(); |
84 } | |
96 } | 85 } |
97 return path; | 86 return path; |
98 } | 87 } |
99 | 88 |
100 // static | 89 // static |
101 bool InstantService::IsInstantPath(const GURL& url) { | 90 bool InstantService::IsInstantPath(const GURL& url) { |
102 // Strip leading slash. | 91 // Strip leading slash. |
103 std::string path = url.path().substr(1); | 92 std::string path = url.path().substr(1); |
104 | 93 |
105 // Check that path is of Most Visited item ID form. | 94 // Check that path is of Most Visited item ID form. |
106 uint64 dummy = 0; | 95 uint64 dummy = 0; |
107 return base::StringToUint64(path, &dummy); | 96 return base::StringToUint64(path, &dummy); |
108 } | 97 } |
109 | 98 |
110 void InstantService::AddInstantProcess(int process_id) { | 99 void InstantService::AddInstantProcess(int process_id) { |
111 process_ids_.insert(process_id); | 100 process_ids_.insert(process_id); |
112 | 101 |
113 if (instant_io_context_) { | 102 if (instant_io_context_) { |
114 BrowserThread::PostTask( | 103 BrowserThread::PostTask( |
115 BrowserThread::IO, FROM_HERE, | 104 BrowserThread::IO, FROM_HERE, |
116 base::Bind(&InstantIOContext::AddInstantProcessOnIO, | 105 base::Bind(&InstantIOContext::AddInstantProcessOnIO, |
117 instant_io_context_, process_id)); | 106 instant_io_context_, process_id)); |
118 } | 107 } |
119 } | 108 } |
120 | 109 |
121 bool InstantService::IsInstantProcess(int process_id) const { | 110 bool InstantService::IsInstantProcess(int process_id) const { |
122 return process_ids_.find(process_id) != process_ids_.end(); | 111 return process_ids_.find(process_id) != process_ids_.end(); |
123 } | 112 } |
124 | 113 |
125 uint64 InstantService::AddURL(const GURL& url) { | 114 void InstantService::AddMostVisitedItems( |
126 uint64 id = 0; | 115 const std::vector<InstantMostVisitedItem>& items) { |
127 if (GetMostVisitedItemIDForURL(url, &id)) | 116 most_visited_item_cache_.AddItems(items); |
128 return id; | |
129 | 117 |
130 last_most_visited_item_id_++; | 118 // Post task to the IO thread to copy the data. |
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_) { | 119 if (instant_io_context_) { |
120 std::vector<InstantMostVisitedItemIDPair> items; | |
121 most_visited_item_cache_.GetCurrentItems(&items); | |
135 BrowserThread::PostTask( | 122 BrowserThread::PostTask( |
136 BrowserThread::IO, FROM_HERE, | 123 BrowserThread::IO, FROM_HERE, |
137 base::Bind(&InstantIOContext::AddMostVisitedItemIDOnIO, | 124 base::Bind(&InstantIOContext::AddMostVisitedItemsOnIO, |
138 instant_io_context_, last_most_visited_item_id_, url)); | 125 instant_io_context_, |
126 items)); | |
139 } | 127 } |
140 | |
141 return last_most_visited_item_id_; | |
142 } | 128 } |
143 | 129 |
144 bool InstantService::GetMostVisitedItemIDForURL( | 130 void InstantService::GetCurrentMostVisitedItems( |
145 const GURL& url, | 131 std::vector<InstantMostVisitedItemIDPair>* items) { |
146 uint64 *most_visited_item_id) { | 132 most_visited_item_cache_.GetCurrentItems(items); |
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 } | 133 } |
156 | 134 |
157 bool InstantService::GetURLForMostVisitedItemId(uint64 most_visited_item_id, | 135 bool InstantService::GetMostVisitedItemForID( |
158 GURL* url) { | 136 InstantRestrictedID restricted_id, |
159 std::map<uint64, GURL>::iterator it = | 137 InstantMostVisitedItem* item) const { |
160 most_visited_item_id_to_url_map_.find(most_visited_item_id); | 138 return most_visited_item_cache_.GetItemWithRestrictedID(restricted_id, item); |
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 } | 139 } |
168 | 140 |
169 void InstantService::Shutdown() { | 141 void InstantService::Shutdown() { |
170 process_ids_.clear(); | 142 process_ids_.clear(); |
171 | 143 |
172 if (instant_io_context_) { | 144 if (instant_io_context_) { |
173 BrowserThread::PostTask( | 145 BrowserThread::PostTask( |
174 BrowserThread::IO, FROM_HERE, | 146 BrowserThread::IO, FROM_HERE, |
175 base::Bind(&InstantIOContext::ClearInstantProcessesOnIO, | 147 base::Bind(&InstantIOContext::ClearInstantProcessesOnIO, |
176 instant_io_context_)); | 148 instant_io_context_)); |
(...skipping 11 matching lines...) Expand all Loading... | |
188 process_ids_.erase(process_id); | 160 process_ids_.erase(process_id); |
189 | 161 |
190 if (instant_io_context_) { | 162 if (instant_io_context_) { |
191 BrowserThread::PostTask( | 163 BrowserThread::PostTask( |
192 BrowserThread::IO, FROM_HERE, | 164 BrowserThread::IO, FROM_HERE, |
193 base::Bind(&InstantIOContext::RemoveInstantProcessOnIO, | 165 base::Bind(&InstantIOContext::RemoveInstantProcessOnIO, |
194 instant_io_context_, process_id)); | 166 instant_io_context_, process_id)); |
195 } | 167 } |
196 break; | 168 break; |
197 } | 169 } |
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 if (det->all_history) { | |
205 url_to_most_visited_item_id_map_.clear(); | |
206 most_visited_item_id_to_url_map_.clear(); | |
207 } else { | |
208 DeleteHistoryURLs(deleted_urls, &deleted_ids); | |
209 } | |
210 | |
211 if (instant_io_context_) { | |
212 BrowserThread::PostTask( | |
213 BrowserThread::IO, FROM_HERE, | |
214 base::Bind(&InstantIOContext::DeleteMostVisitedURLsOnIO, | |
215 instant_io_context_, deleted_ids, det->all_history)); | |
216 } | |
217 break; | |
218 } | |
219 default: | 170 default: |
220 NOTREACHED() << "Unexpected notification type in InstantService."; | 171 NOTREACHED() << "Unexpected notification type in InstantService."; |
221 } | 172 } |
222 } | 173 } |
223 | |
224 void InstantService::DeleteHistoryURLs(const std::vector<GURL>& deleted_urls, | |
225 std::vector<uint64>* deleted_ids) { | |
226 for (std::vector<GURL>::const_iterator it = deleted_urls.begin(); | |
227 it != deleted_urls.end(); | |
228 ++it) { | |
229 std::map<GURL, uint64>::iterator item = | |
230 url_to_most_visited_item_id_map_.find(*it); | |
231 if (item != url_to_most_visited_item_id_map_.end()) { | |
232 uint64 most_visited_item_id = item->second; | |
233 url_to_most_visited_item_id_map_.erase(item); | |
234 most_visited_item_id_to_url_map_.erase( | |
235 most_visited_item_id_to_url_map_.find(most_visited_item_id)); | |
236 deleted_ids->push_back(most_visited_item_id); | |
237 } | |
238 } | |
239 } | |
OLD | NEW |