| OLD | NEW |
| 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/importer/firefox3_importer.h" | 5 #include "chrome/browser/importer/firefox3_importer.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 | 8 |
| 9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
| 10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| 11 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
| 12 #include "base/stl_util.h" | 12 #include "base/stl_util.h" |
| 13 #include "base/string_util.h" | 13 #include "base/string_util.h" |
| 14 #include "base/utf_string_conversions.h" | 14 #include "base/utf_string_conversions.h" |
| 15 #include "chrome/browser/bookmarks/bookmark_html_reader.h" |
| 16 #include "chrome/browser/bookmarks/imported_bookmark_entry.h" |
| 15 #include "chrome/browser/browser_process.h" | 17 #include "chrome/browser/browser_process.h" |
| 16 #include "chrome/browser/history/history_types.h" | 18 #include "chrome/browser/favicon/favicon_util.h" |
| 17 #include "chrome/browser/importer/firefox2_importer.h" | 19 #include "chrome/browser/favicon/imported_favicon_usage.h" |
| 18 #include "chrome/browser/importer/firefox_importer_utils.h" | 20 #include "chrome/browser/importer/firefox_importer_utils.h" |
| 19 #include "chrome/browser/importer/importer_bridge.h" | 21 #include "chrome/browser/importer/importer_bridge.h" |
| 20 #include "chrome/browser/importer/importer_util.h" | |
| 21 #include "chrome/browser/importer/nss_decryptor.h" | 22 #include "chrome/browser/importer/nss_decryptor.h" |
| 22 #include "chrome/browser/search_engines/template_url.h" | 23 #include "chrome/browser/search_engines/template_url.h" |
| 23 #include "chrome/common/time_format.h" | 24 #include "chrome/common/time_format.h" |
| 24 #include "content/public/browser/browser_thread.h" | 25 #include "content/public/browser/browser_thread.h" |
| 25 #include "content/public/common/password_form.h" | 26 #include "content/public/common/password_form.h" |
| 26 #include "googleurl/src/gurl.h" | 27 #include "googleurl/src/gurl.h" |
| 27 #include "grit/generated_resources.h" | 28 #include "grit/generated_resources.h" |
| 28 #include "sql/connection.h" | 29 #include "sql/connection.h" |
| 29 #include "sql/statement.h" | 30 #include "sql/statement.h" |
| 30 | 31 |
| 31 using content::BrowserThread; | 32 using content::BrowserThread; |
| 32 | 33 |
| 33 namespace { | 34 namespace { |
| 34 | 35 |
| 35 // Original definition is in http://mxr.mozilla.org/firefox/source/toolkit/ | 36 // Original definition is in http://mxr.mozilla.org/firefox/source/toolkit/ |
| 36 // components/places/public/nsINavBookmarksService.idl | 37 // components/places/public/nsINavBookmarksService.idl |
| 37 enum BookmarkItemType { | 38 enum BookmarkItemType { |
| 38 TYPE_BOOKMARK = 1, | 39 TYPE_BOOKMARK = 1, |
| 39 TYPE_FOLDER = 2, | 40 TYPE_FOLDER = 2, |
| 40 TYPE_SEPARATOR = 3, | 41 TYPE_SEPARATOR = 3, |
| 41 TYPE_DYNAMIC_CONTAINER = 4 | 42 TYPE_DYNAMIC_CONTAINER = 4 |
| 42 }; | 43 }; |
| 43 | 44 |
| 45 // Creates a TemplateURL with the |keyword| and |url|. |title| may be empty. |
| 46 // This function transfers ownership of the created TemplateURL to the caller. |
| 47 TemplateURL* CreateTemplateURL(const string16& title, |
| 48 const string16& keyword, |
| 49 const GURL& url) { |
| 50 // Skip if the keyword or url is invalid. |
| 51 if (keyword.empty() || !url.is_valid()) |
| 52 return NULL; |
| 53 |
| 54 TemplateURLData data; |
| 55 // We set short name by using the title if it exists. |
| 56 // Otherwise, we use the shortcut. |
| 57 data.short_name = title.empty() ? keyword : title; |
| 58 data.SetKeyword(keyword); |
| 59 data.SetURL(TemplateURLRef::DisplayURLToURLRef(UTF8ToUTF16(url.spec()))); |
| 60 return new TemplateURL(NULL, data); |
| 61 } |
| 62 |
| 63 // Loads the default bookmarks in the Firefox installed at |app_path|, |
| 64 // and stores their locations in |urls|. |
| 65 void LoadDefaultBookmarks(const base::FilePath& app_path, |
| 66 std::set<GURL>* urls) { |
| 67 base::FilePath file = app_path.AppendASCII("defaults") |
| 68 .AppendASCII("profile") |
| 69 .AppendASCII("bookmarks.html"); |
| 70 urls->clear(); |
| 71 |
| 72 std::vector<ImportedBookmarkEntry> bookmarks; |
| 73 bookmark_html_reader::ImportBookmarksFile(base::Callback<bool(void)>(), |
| 74 base::Callback<bool(const GURL&)>(), |
| 75 file, |
| 76 &bookmarks, |
| 77 NULL); |
| 78 for (size_t i = 0; i < bookmarks.size(); ++i) |
| 79 urls->insert(bookmarks[i].url); |
| 80 } |
| 81 |
| 44 } // namespace | 82 } // namespace |
| 45 | 83 |
| 46 struct Firefox3Importer::BookmarkItem { | 84 struct Firefox3Importer::BookmarkItem { |
| 47 int parent; | 85 int parent; |
| 48 int id; | 86 int id; |
| 49 GURL url; | 87 GURL url; |
| 50 string16 title; | 88 string16 title; |
| 51 BookmarkItemType type; | 89 BookmarkItemType type; |
| 52 std::string keyword; | 90 std::string keyword; |
| 53 base::Time date_added; | 91 base::Time date_added; |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 // Get the bookmark folders that we are interested in. | 202 // Get the bookmark folders that we are interested in. |
| 165 int toolbar_folder_id = -1; | 203 int toolbar_folder_id = -1; |
| 166 int menu_folder_id = -1; | 204 int menu_folder_id = -1; |
| 167 int unsorted_folder_id = -1; | 205 int unsorted_folder_id = -1; |
| 168 LoadRootNodeID(&db, &toolbar_folder_id, &menu_folder_id, &unsorted_folder_id); | 206 LoadRootNodeID(&db, &toolbar_folder_id, &menu_folder_id, &unsorted_folder_id); |
| 169 | 207 |
| 170 // Load livemark IDs. | 208 // Load livemark IDs. |
| 171 std::set<int> livemark_id; | 209 std::set<int> livemark_id; |
| 172 LoadLivemarkIDs(&db, &livemark_id); | 210 LoadLivemarkIDs(&db, &livemark_id); |
| 173 | 211 |
| 174 // Load the default bookmarks. Its storage is the same as Firefox 2. | 212 // Load the default bookmarks. |
| 175 std::set<GURL> default_urls; | 213 std::set<GURL> default_urls; |
| 176 Firefox2Importer::LoadDefaultBookmarks(app_path_, &default_urls); | 214 LoadDefaultBookmarks(app_path_, &default_urls); |
| 177 | 215 |
| 178 BookmarkList list; | 216 BookmarkList list; |
| 179 GetTopBookmarkFolder(&db, toolbar_folder_id, &list); | 217 GetTopBookmarkFolder(&db, toolbar_folder_id, &list); |
| 180 GetTopBookmarkFolder(&db, menu_folder_id, &list); | 218 GetTopBookmarkFolder(&db, menu_folder_id, &list); |
| 181 GetTopBookmarkFolder(&db, unsorted_folder_id, &list); | 219 GetTopBookmarkFolder(&db, unsorted_folder_id, &list); |
| 182 size_t count = list.size(); | 220 size_t count = list.size(); |
| 183 for (size_t i = 0; i < count; ++i) | 221 for (size_t i = 0; i < count; ++i) |
| 184 GetWholeBookmarkFolder(&db, &list, i, NULL); | 222 GetWholeBookmarkFolder(&db, &list, i, NULL); |
| 185 | 223 |
| 186 std::vector<ProfileWriter::BookmarkEntry> bookmarks; | 224 std::vector<ImportedBookmarkEntry> bookmarks; |
| 187 std::vector<TemplateURL*> template_urls; | 225 std::vector<TemplateURL*> template_urls; |
| 188 FaviconMap favicon_map; | 226 FaviconMap favicon_map; |
| 189 | 227 |
| 190 // TODO(jcampan): http://b/issue?id=1196285 we do not support POST based | 228 // TODO(jcampan): http://b/issue?id=1196285 we do not support POST based |
| 191 // keywords yet. We won't include them in the list. | 229 // keywords yet. We won't include them in the list. |
| 192 std::set<int> post_keyword_ids; | 230 std::set<int> post_keyword_ids; |
| 193 const char* query = "SELECT b.id FROM moz_bookmarks b " | 231 const char* query = "SELECT b.id FROM moz_bookmarks b " |
| 194 "INNER JOIN moz_items_annos ia ON ia.item_id = b.id " | 232 "INNER JOIN moz_items_annos ia ON ia.item_id = b.id " |
| 195 "INNER JOIN moz_anno_attributes aa ON ia.anno_attribute_id = aa.id " | 233 "INNER JOIN moz_anno_attributes aa ON ia.anno_attribute_id = aa.id " |
| 196 "WHERE aa.name = 'bookmarkProperties/POSTData'"; | 234 "WHERE aa.name = 'bookmarkProperties/POSTData'"; |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 251 found_path = true; | 289 found_path = true; |
| 252 break; | 290 break; |
| 253 } | 291 } |
| 254 | 292 |
| 255 child = parent; | 293 child = parent; |
| 256 } | 294 } |
| 257 | 295 |
| 258 if (!found_path) | 296 if (!found_path) |
| 259 continue; | 297 continue; |
| 260 | 298 |
| 261 ProfileWriter::BookmarkEntry entry; | 299 ImportedBookmarkEntry entry; |
| 262 entry.creation_time = item->date_added; | 300 entry.creation_time = item->date_added; |
| 263 entry.title = item->title; | 301 entry.title = item->title; |
| 264 entry.url = item->url; | 302 entry.url = item->url; |
| 265 entry.path = path; | 303 entry.path = path; |
| 266 entry.in_toolbar = is_in_toolbar; | 304 entry.in_toolbar = is_in_toolbar; |
| 267 entry.is_folder = item->type == TYPE_FOLDER; | 305 entry.is_folder = item->type == TYPE_FOLDER; |
| 268 | 306 |
| 269 bookmarks.push_back(entry); | 307 bookmarks.push_back(entry); |
| 270 | 308 |
| 271 if (item->type == TYPE_BOOKMARK) { | 309 if (item->type == TYPE_BOOKMARK) { |
| 272 if (item->favicon) | 310 if (item->favicon) |
| 273 favicon_map[item->favicon].insert(item->url); | 311 favicon_map[item->favicon].insert(item->url); |
| 274 | 312 |
| 275 // This bookmark has a keyword, we import it to our TemplateURL model. | 313 // This bookmark has a keyword, we import it to our TemplateURL model. |
| 276 TemplateURL* t_url = Firefox2Importer::CreateTemplateURL( | 314 TemplateURL* t_url = CreateTemplateURL( |
| 277 item->title, UTF8ToUTF16(item->keyword), item->url); | 315 item->title, UTF8ToUTF16(item->keyword), item->url); |
| 278 if (t_url) | 316 if (t_url) |
| 279 template_urls.push_back(t_url); | 317 template_urls.push_back(t_url); |
| 280 } | 318 } |
| 281 } | 319 } |
| 282 | 320 |
| 283 STLDeleteElements(&list); | 321 STLDeleteElements(&list); |
| 284 | 322 |
| 285 // Write into profile. | 323 // Write into profile. |
| 286 if (!bookmarks.empty() && !cancelled()) { | 324 if (!bookmarks.empty() && !cancelled()) { |
| 287 const string16& first_folder_name = | 325 const string16& first_folder_name = |
| 288 bridge_->GetLocalizedString(IDS_BOOKMARK_GROUP_FROM_FIREFOX); | 326 bridge_->GetLocalizedString(IDS_BOOKMARK_GROUP_FROM_FIREFOX); |
| 289 bridge_->AddBookmarks(bookmarks, first_folder_name); | 327 bridge_->AddBookmarks(bookmarks, first_folder_name); |
| 290 } | 328 } |
| 291 if (!template_urls.empty() && !cancelled()) | 329 if (!template_urls.empty() && !cancelled()) |
| 292 bridge_->SetKeywords(template_urls, false); | 330 bridge_->SetKeywords(template_urls, false); |
| 293 else | 331 else |
| 294 STLDeleteElements(&template_urls); | 332 STLDeleteElements(&template_urls); |
| 295 if (!favicon_map.empty() && !cancelled()) { | 333 if (!favicon_map.empty() && !cancelled()) { |
| 296 std::vector<history::ImportedFaviconUsage> favicons; | 334 std::vector<ImportedFaviconUsage> favicons; |
| 297 LoadFavicons(&db, favicon_map, &favicons); | 335 LoadFavicons(&db, favicon_map, &favicons); |
| 298 bridge_->SetFavicons(favicons); | 336 bridge_->SetFavicons(favicons); |
| 299 } | 337 } |
| 300 } | 338 } |
| 301 | 339 |
| 302 void Firefox3Importer::ImportPasswords() { | 340 void Firefox3Importer::ImportPasswords() { |
| 303 // Initializes NSS3. | 341 // Initializes NSS3. |
| 304 NSSDecryptor decryptor; | 342 NSSDecryptor decryptor; |
| 305 if (!decryptor.Init(source_path_, source_path_) && | 343 if (!decryptor.Init(source_path_, source_path_) && |
| 306 !decryptor.Init(app_path_, source_path_)) { | 344 !decryptor.Init(app_path_, source_path_)) { |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 531 list->push_back(*i); | 569 list->push_back(*i); |
| 532 // Recursive add bookmarks in sub-folders. | 570 // Recursive add bookmarks in sub-folders. |
| 533 if ((*i)->type == TYPE_FOLDER) | 571 if ((*i)->type == TYPE_FOLDER) |
| 534 GetWholeBookmarkFolder(db, list, list->size() - 1, &(*i)->empty_folder); | 572 GetWholeBookmarkFolder(db, list, list->size() - 1, &(*i)->empty_folder); |
| 535 } | 573 } |
| 536 } | 574 } |
| 537 | 575 |
| 538 void Firefox3Importer::LoadFavicons( | 576 void Firefox3Importer::LoadFavicons( |
| 539 sql::Connection* db, | 577 sql::Connection* db, |
| 540 const FaviconMap& favicon_map, | 578 const FaviconMap& favicon_map, |
| 541 std::vector<history::ImportedFaviconUsage>* favicons) { | 579 std::vector<ImportedFaviconUsage>* favicons) { |
| 542 const char* query = "SELECT url, data FROM moz_favicons WHERE id=?"; | 580 const char* query = "SELECT url, data FROM moz_favicons WHERE id=?"; |
| 543 sql::Statement s(db->GetUniqueStatement(query)); | 581 sql::Statement s(db->GetUniqueStatement(query)); |
| 544 | 582 |
| 545 if (!s.is_valid()) | 583 if (!s.is_valid()) |
| 546 return; | 584 return; |
| 547 | 585 |
| 548 for (FaviconMap::const_iterator i = favicon_map.begin(); | 586 for (FaviconMap::const_iterator i = favicon_map.begin(); |
| 549 i != favicon_map.end(); ++i) { | 587 i != favicon_map.end(); ++i) { |
| 550 s.BindInt64(0, i->first); | 588 s.BindInt64(0, i->first); |
| 551 if (s.Step()) { | 589 if (s.Step()) { |
| 552 history::ImportedFaviconUsage usage; | 590 ImportedFaviconUsage usage; |
| 553 | 591 |
| 554 usage.favicon_url = GURL(s.ColumnString(0)); | 592 usage.favicon_url = GURL(s.ColumnString(0)); |
| 555 if (!usage.favicon_url.is_valid()) | 593 if (!usage.favicon_url.is_valid()) |
| 556 continue; // Don't bother importing favicons with invalid URLs. | 594 continue; // Don't bother importing favicons with invalid URLs. |
| 557 | 595 |
| 558 std::vector<unsigned char> data; | 596 std::vector<unsigned char> data; |
| 559 s.ColumnBlobAsVector(1, &data); | 597 s.ColumnBlobAsVector(1, &data); |
| 560 if (data.empty()) | 598 if (data.empty()) |
| 561 continue; // Data definitely invalid. | 599 continue; // Data definitely invalid. |
| 562 | 600 |
| 563 if (!importer::ReencodeFavicon(&data[0], data.size(), &usage.png_data)) | 601 if (!FaviconUtil::ReencodeFavicon(&data[0], data.size(), &usage.png_data)) |
| 564 continue; // Unable to decode. | 602 continue; // Unable to decode. |
| 565 | 603 |
| 566 usage.urls = i->second; | 604 usage.urls = i->second; |
| 567 favicons->push_back(usage); | 605 favicons->push_back(usage); |
| 568 } | 606 } |
| 569 s.Reset(true); | 607 s.Reset(true); |
| 570 } | 608 } |
| 571 } | 609 } |
| OLD | NEW |