Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(59)

Side by Side Diff: chrome/browser/sync/test/integration/bookmarks_helper.cc

Issue 11428004: Sync the bookmark's icon URL (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 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/sync/test/integration/bookmarks_helper.h" 5 #include "chrome/browser/sync/test/integration/bookmarks_helper.h"
6 6
7 #include "base/compiler_specific.h" 7 #include "base/compiler_specific.h"
8 #include "base/rand_util.h" 8 #include "base/rand_util.h"
9 #include "base/string_number_conversions.h" 9 #include "base/string_number_conversions.h"
10 #include "base/stringprintf.h" 10 #include "base/stringprintf.h"
11 #include "base/synchronization/waitable_event.h" 11 #include "base/synchronization/waitable_event.h"
12 #include "base/utf_string_conversions.h" 12 #include "base/utf_string_conversions.h"
13 #include "chrome/browser/bookmarks/bookmark_model.h" 13 #include "chrome/browser/bookmarks/bookmark_model.h"
14 #include "chrome/browser/bookmarks/bookmark_model_factory.h" 14 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
15 #include "chrome/browser/bookmarks/bookmark_model_observer.h" 15 #include "chrome/browser/bookmarks/bookmark_model_observer.h"
16 #include "chrome/browser/bookmarks/bookmark_utils.h" 16 #include "chrome/browser/bookmarks/bookmark_utils.h"
17 #include "chrome/browser/favicon/favicon_service_factory.h" 17 #include "chrome/browser/favicon/favicon_service_factory.h"
18 #include "chrome/browser/favicon/favicon_util.h"
18 #include "chrome/browser/history/history_service_factory.h" 19 #include "chrome/browser/history/history_service_factory.h"
19 #include "chrome/browser/history/history_types.h" 20 #include "chrome/browser/history/history_types.h"
20 #include "chrome/browser/profiles/profile.h" 21 #include "chrome/browser/profiles/profile.h"
21 #include "chrome/browser/sync/profile_sync_service_harness.h" 22 #include "chrome/browser/sync/profile_sync_service_harness.h"
22 #include "chrome/browser/sync/test/integration/sync_test.h" 23 #include "chrome/browser/sync/test/integration/sync_test.h"
23 #include "chrome/browser/sync/test/integration/sync_datatype_helper.h" 24 #include "chrome/browser/sync/test/integration/sync_datatype_helper.h"
24 #include "chrome/test/base/ui_test_utils.h" 25 #include "chrome/test/base/ui_test_utils.h"
25 #include "testing/gtest/include/gtest/gtest.h" 26 #include "testing/gtest/include/gtest/gtest.h"
26 #include "third_party/skia/include/core/SkBitmap.h" 27 #include "third_party/skia/include/core/SkBitmap.h"
27 #include "ui/base/models/tree_node_iterator.h" 28 #include "ui/base/models/tree_node_iterator.h"
28 #include "ui/gfx/codec/png_codec.h" 29 #include "ui/gfx/image/image_skia.h"
29 30
30 using sync_datatype_helper::test; 31 using sync_datatype_helper::test;
31 32
32 namespace { 33 namespace {
33 34
34 // History task which runs all pending tasks on the history thread and 35 // History task which runs all pending tasks on the history thread and
35 // signals when the tasks have completed. 36 // signals when the tasks have completed.
36 class HistoryEmptyTask : public HistoryDBTask { 37 class HistoryEmptyTask : public HistoryDBTask {
37 public: 38 public:
38 explicit HistoryEmptyTask(base::WaitableEvent* done) : done_(done) {} 39 explicit HistoryEmptyTask(base::WaitableEvent* done) : done_(done) {}
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 void* node_pixel_addr_b = bitmap_b.getPixels(); 157 void* node_pixel_addr_b = bitmap_b.getPixels();
157 EXPECT_TRUE(node_pixel_addr_b); 158 EXPECT_TRUE(node_pixel_addr_b);
158 if (memcmp(node_pixel_addr_a, node_pixel_addr_b, bitmap_a.getSize()) != 0) { 159 if (memcmp(node_pixel_addr_a, node_pixel_addr_b, bitmap_a.getSize()) != 0) {
159 LOG(ERROR) << "Favicon bitmap mismatch"; 160 LOG(ERROR) << "Favicon bitmap mismatch";
160 return false; 161 return false;
161 } else { 162 } else {
162 return true; 163 return true;
163 } 164 }
164 } 165 }
165 166
166 // Gets the favicon associated with |node| in |model|. 167 // Represents a favicon image and the icon URL associated with it.
167 gfx::Image GetFavicon(BookmarkModel* model, const BookmarkNode* node) { 168 struct FaviconData {
169 FaviconData() {
170 }
171
172 FaviconData(const gfx::Image& favicon_image,
173 const GURL& favicon_url)
174 : image(favicon_image),
175 icon_url(favicon_url) {
176 }
177
178 ~FaviconData() {
179 }
180
181 gfx::Image image;
182 GURL icon_url;
183 };
184
185 // Gets the favicon and icon URL associated with |node| in |model|.
186 FaviconData GetFaviconData(BookmarkModel* model,
187 const BookmarkNode* node) {
168 // If a favicon wasn't explicitly set for a particular URL, simply return its 188 // If a favicon wasn't explicitly set for a particular URL, simply return its
169 // blank favicon. 189 // blank favicon.
170 if (!urls_with_favicons_ || 190 if (!urls_with_favicons_ ||
171 urls_with_favicons_->find(node->url()) == urls_with_favicons_->end()) { 191 urls_with_favicons_->find(node->url()) == urls_with_favicons_->end()) {
172 return gfx::Image(); 192 return FaviconData();
173 } 193 }
174 // If a favicon was explicitly set, we may need to wait for it to be loaded 194 // If a favicon was explicitly set, we may need to wait for it to be loaded
175 // via BookmarkModel::GetFavicon(), which is an asynchronous operation. 195 // via BookmarkModel::GetFavicon(), which is an asynchronous operation.
176 if (!node->is_favicon_loaded()) { 196 if (!node->is_favicon_loaded()) {
177 FaviconChangeObserver observer(model, node); 197 FaviconChangeObserver observer(model, node);
178 model->GetFavicon(node); 198 model->GetFavicon(node);
179 observer.WaitForGetFavicon(); 199 observer.WaitForGetFavicon();
180 } 200 }
181 EXPECT_TRUE(node->is_favicon_loaded()); 201 EXPECT_TRUE(node->is_favicon_loaded());
182 EXPECT_FALSE(model->GetFavicon(node).IsEmpty()); 202 EXPECT_FALSE(model->GetFavicon(node).IsEmpty());
183 return model->GetFavicon(node); 203 return FaviconData(model->GetFavicon(node), node->icon_url());
184 } 204 }
185 205
186 // Sets the favicon for |profile| and |node|. |profile| may be 206 // Sets the favicon for |profile| and |node|. |profile| may be
187 // |test()->verifier()|. 207 // |test()->verifier()|.
188 void SetFaviconImpl(Profile* profile, 208 void SetFaviconImpl(Profile* profile,
189 const BookmarkNode* node, 209 const BookmarkNode* node,
210 const GURL& icon_url,
190 const gfx::Image& image) { 211 const gfx::Image& image) {
191 BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile); 212 BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile);
192 213
193 FaviconChangeObserver observer(model, node); 214 FaviconChangeObserver observer(model, node);
194 FaviconService* favicon_service = 215 FaviconService* favicon_service =
195 FaviconServiceFactory::GetForProfile(profile, 216 FaviconServiceFactory::GetForProfile(profile,
196 Profile::EXPLICIT_ACCESS); 217 Profile::EXPLICIT_ACCESS);
197 favicon_service->SetFavicons(node->url(), 218 favicon_service->SetFavicons(node->url(),
198 node->url(), 219 icon_url,
199 history::FAVICON, 220 history::FAVICON,
200 image); 221 image);
201 222
202 // Wait for the favicon for |node| to be invalidated. 223 // Wait for the favicon for |node| to be invalidated.
203 observer.WaitForSetFavicon(); 224 observer.WaitForSetFavicon();
204 // Wait for the BookmarkModel to fetch the updated favicon and for the new 225 // Wait for the BookmarkModel to fetch the updated favicon and for the new
205 // favicon to be sent to BookmarkChangeProcessor. 226 // favicon to be sent to BookmarkChangeProcessor.
206 GetFavicon(model, node); 227 GetFaviconData(model, node);
207 } 228 }
208 229
209 // Wait for all currently scheduled tasks on the history thread for all 230 // Wait for all currently scheduled tasks on the history thread for all
210 // profiles to complete and any notifications sent to the UI thread to have 231 // profiles to complete and any notifications sent to the UI thread to have
211 // finished processing. 232 // finished processing.
212 void WaitForHistoryToProcessPendingTasks() { 233 void WaitForHistoryToProcessPendingTasks() {
213 // Skip waiting for history to complete for tests without favicons. 234 // Skip waiting for history to complete for tests without favicons.
214 if (!urls_with_favicons_) 235 if (!urls_with_favicons_)
215 return; 236 return;
216 237
(...skipping 17 matching lines...) Expand all
234 // to the UI thread are processed. 255 // to the UI thread are processed.
235 content::RunAllPendingInMessageLoop(); 256 content::RunAllPendingInMessageLoop();
236 } 257 }
237 258
238 // Checks if the favicon in |node_a| from |model_a| matches that of |node_b| 259 // Checks if the favicon in |node_a| from |model_a| matches that of |node_b|
239 // from |model_b|. Returns true if they match. 260 // from |model_b|. Returns true if they match.
240 bool FaviconsMatch(BookmarkModel* model_a, 261 bool FaviconsMatch(BookmarkModel* model_a,
241 BookmarkModel* model_b, 262 BookmarkModel* model_b,
242 const BookmarkNode* node_a, 263 const BookmarkNode* node_a,
243 const BookmarkNode* node_b) { 264 const BookmarkNode* node_b) {
244 const gfx::Image& bitmap_a = GetFavicon(model_a, node_a); 265 FaviconData favicon_data_a = GetFaviconData(model_a, node_a);
245 const gfx::Image& bitmap_b = GetFavicon(model_b, node_b); 266 FaviconData favicon_data_b = GetFaviconData(model_b, node_b);
246 267
247 if (bitmap_a.IsEmpty() && bitmap_b.IsEmpty()) 268 if (favicon_data_a.icon_url != favicon_data_b.icon_url)
269 return false;
270
271 gfx::Image image_a = favicon_data_a.image;
272 gfx::Image image_b = favicon_data_b.image;
273
274 if (image_a.IsEmpty() && image_b.IsEmpty())
248 return true; // Two empty images are equivalent. 275 return true; // Two empty images are equivalent.
249 return !bitmap_a.IsEmpty() && !bitmap_b.IsEmpty() && 276
250 FaviconBitmapsMatch(*bitmap_a.ToSkBitmap(), *bitmap_b.ToSkBitmap()); 277 if (image_a.IsEmpty() != image_b.IsEmpty())
278 return false;
279
280 // Compare only the 1x bitmaps as only those are synced.
281 SkBitmap bitmap_a = image_a.AsImageSkia().GetRepresentation(
282 ui::SCALE_FACTOR_100P).sk_bitmap();
283 SkBitmap bitmap_b = image_b.AsImageSkia().GetRepresentation(
284 ui::SCALE_FACTOR_100P).sk_bitmap();
285 return FaviconBitmapsMatch(bitmap_a, bitmap_b);
251 } 286 }
252 287
253 // Does a deep comparison of BookmarkNode fields in |model_a| and |model_b|. 288 // Does a deep comparison of BookmarkNode fields in |model_a| and |model_b|.
254 // Returns true if they are all equal. 289 // Returns true if they are all equal.
255 bool NodesMatch(const BookmarkNode* node_a, const BookmarkNode* node_b) { 290 bool NodesMatch(const BookmarkNode* node_a, const BookmarkNode* node_b) {
256 if (node_a == NULL || node_b == NULL) 291 if (node_a == NULL || node_b == NULL)
257 return node_a == node_b; 292 return node_a == node_b;
258 if (node_a->is_folder() != node_b->is_folder()) { 293 if (node_a->is_folder() != node_b->is_folder()) {
259 LOG(ERROR) << "Cannot compare folder with bookmark"; 294 LOG(ERROR) << "Cannot compare folder with bookmark";
260 return false; 295 return false;
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
450 if (test()->use_verifier()) { 485 if (test()->use_verifier()) {
451 const BookmarkNode* v_node = NULL; 486 const BookmarkNode* v_node = NULL;
452 FindNodeInVerifier(GetBookmarkModel(profile), node, &v_node); 487 FindNodeInVerifier(GetBookmarkModel(profile), node, &v_node);
453 GetVerifierBookmarkModel()->SetTitle(v_node, WideToUTF16(new_title)); 488 GetVerifierBookmarkModel()->SetTitle(v_node, WideToUTF16(new_title));
454 } 489 }
455 GetBookmarkModel(profile)->SetTitle(node, WideToUTF16(new_title)); 490 GetBookmarkModel(profile)->SetTitle(node, WideToUTF16(new_title));
456 } 491 }
457 492
458 void SetFavicon(int profile, 493 void SetFavicon(int profile,
459 const BookmarkNode* node, 494 const BookmarkNode* node,
460 const std::vector<unsigned char>& icon_bytes_vector) { 495 const GURL& icon_url,
461 scoped_refptr<base::RefCountedBytes> bitmap_data( 496 const gfx::Image& image) {
462 new base::RefCountedBytes(icon_bytes_vector));
463 gfx::Image image(bitmap_data->front(), bitmap_data->size());
464 ASSERT_EQ(GetBookmarkModel(profile)->GetNodeByID(node->id()), node) 497 ASSERT_EQ(GetBookmarkModel(profile)->GetNodeByID(node->id()), node)
465 << "Node " << node->GetTitle() << " does not belong to " 498 << "Node " << node->GetTitle() << " does not belong to "
466 << "Profile " << profile; 499 << "Profile " << profile;
467 ASSERT_EQ(BookmarkNode::URL, node->type()) 500 ASSERT_EQ(BookmarkNode::URL, node->type())
468 << "Node " << node->GetTitle() << " must be a url."; 501 << "Node " << node->GetTitle() << " must be a url.";
469 if (urls_with_favicons_ == NULL) 502 if (urls_with_favicons_ == NULL)
470 urls_with_favicons_ = new std::set<GURL>(); 503 urls_with_favicons_ = new std::set<GURL>();
471 urls_with_favicons_->insert(node->url()); 504 urls_with_favicons_->insert(node->url());
472 if (test()->use_verifier()) { 505 if (test()->use_verifier()) {
473 const BookmarkNode* v_node = NULL; 506 const BookmarkNode* v_node = NULL;
474 FindNodeInVerifier(GetBookmarkModel(profile), node, &v_node); 507 FindNodeInVerifier(GetBookmarkModel(profile), node, &v_node);
475 SetFaviconImpl(test()->verifier(), v_node, image); 508 SetFaviconImpl(test()->verifier(), v_node, icon_url, image);
476 } 509 }
477 SetFaviconImpl(test()->GetProfile(profile), node, image); 510 SetFaviconImpl(test()->GetProfile(profile), node, icon_url, image);
478 } 511 }
479 512
480 const BookmarkNode* SetURL(int profile, 513 const BookmarkNode* SetURL(int profile,
481 const BookmarkNode* node, 514 const BookmarkNode* node,
482 const GURL& new_url) { 515 const GURL& new_url) {
483 if (GetBookmarkModel(profile)->GetNodeByID(node->id()) != node) { 516 if (GetBookmarkModel(profile)->GetNodeByID(node->id()) != node) {
484 LOG(ERROR) << "Node " << node->GetTitle() << " does not belong to " 517 LOG(ERROR) << "Node " << node->GetTitle() << " does not belong to "
485 << "Profile " << profile; 518 << "Profile " << profile;
486 return NULL; 519 return NULL;
487 } 520 }
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
646 BookmarkNode::URL, 679 BookmarkNode::URL,
647 WideToUTF16(title)); 680 WideToUTF16(title));
648 } 681 }
649 682
650 int CountFoldersWithTitlesMatching(int profile, const std::wstring& title) { 683 int CountFoldersWithTitlesMatching(int profile, const std::wstring& title) {
651 return CountNodesWithTitlesMatching(GetBookmarkModel(profile), 684 return CountNodesWithTitlesMatching(GetBookmarkModel(profile),
652 BookmarkNode::FOLDER, 685 BookmarkNode::FOLDER,
653 WideToUTF16(title)); 686 WideToUTF16(title));
654 } 687 }
655 688
656 std::vector<unsigned char> CreateFavicon(int seed) { 689 gfx::Image CreateFavicon(SkColor color) {
657 const int w = 16; 690 const int dip_width = 16;
658 const int h = 16; 691 const int dip_height = 16;
659 SkBitmap bmp; 692 std::vector<ui::ScaleFactor> favicon_scale_factors =
660 bmp.setConfig(SkBitmap::kARGB_8888_Config, w, h); 693 FaviconUtil::GetFaviconScaleFactors();
661 bmp.allocPixels(); 694 gfx::ImageSkia favicon;
662 uint32_t* src_data = bmp.getAddr32(0, 0); 695 for (size_t i = 0; i < favicon_scale_factors.size(); ++i) {
663 for (int i = 0; i < w * h; ++i) { 696 float scale = ui::GetScaleFactorScale(favicon_scale_factors[i]);
664 src_data[i] = SkPreMultiplyARGB((seed + i) % 255, 697 int pixel_width = dip_width * scale;
665 (seed + i) % 250, 698 int pixel_height = dip_height * scale;
666 (seed + i) % 245, 699 SkBitmap bmp;
667 (seed + i) % 240); 700 bmp.setConfig(SkBitmap::kARGB_8888_Config, pixel_width, pixel_height);
701 bmp.allocPixels();
702 bmp.eraseColor(color);
703 favicon.AddRepresentation(gfx::ImageSkiaRep(bmp, favicon_scale_factors[i]));
668 } 704 }
669 std::vector<unsigned char> favicon; 705 return gfx::Image(favicon);
670 gfx::PNGCodec::EncodeBGRASkBitmap(bmp, false, &favicon);
671 return favicon;
672 } 706 }
673 707
674 std::string IndexedURL(int i) { 708 std::string IndexedURL(int i) {
675 return StringPrintf("http://www.host.ext:1234/path/filename/%d", i); 709 return StringPrintf("http://www.host.ext:1234/path/filename/%d", i);
676 } 710 }
677 711
678 std::wstring IndexedURLTitle(int i) { 712 std::wstring IndexedURLTitle(int i) {
679 return StringPrintf(L"URL Title %d", i); 713 return StringPrintf(L"URL Title %d", i);
680 } 714 }
681 715
682 std::wstring IndexedFolderName(int i) { 716 std::wstring IndexedFolderName(int i) {
683 return StringPrintf(L"Folder Name %d", i); 717 return StringPrintf(L"Folder Name %d", i);
684 } 718 }
685 719
686 std::wstring IndexedSubfolderName(int i) { 720 std::wstring IndexedSubfolderName(int i) {
687 return StringPrintf(L"Subfolder Name %d", i); 721 return StringPrintf(L"Subfolder Name %d", i);
688 } 722 }
689 723
690 std::wstring IndexedSubsubfolderName(int i) { 724 std::wstring IndexedSubsubfolderName(int i) {
691 return StringPrintf(L"Subsubfolder Name %d", i); 725 return StringPrintf(L"Subsubfolder Name %d", i);
692 } 726 }
693 727
694 } // namespace bookmarks_helper 728 } // namespace bookmarks_helper
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698