bookmarks_api.cc revision 010d83a9304c5a91596085d917d248abff47903a
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/api/bookmarks/bookmarks_api.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/i18n/file_util_icu.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/i18n/time_formatting.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_writer.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/lazy_instance.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/sha1.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 185e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string16.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 205e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h" 21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/bookmarks/bookmark_html_writer.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/bookmarks/bookmark_model_factory.h" 257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h" 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/api/bookmarks/bookmark_api_constants.h" 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/api/bookmarks/bookmark_api_helpers.h" 28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/importer/external_process_importer_host.h" 297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/importer/importer_uma.h" 307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/platform_util.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/chrome_select_file_policy.h" 337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/ui/host_desktop.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_paths.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/api/bookmarks.h" 36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/common/importer/importer_data_types.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h" 385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "components/bookmarks/core/browser/bookmark_model.h" 395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "components/bookmarks/core/browser/bookmark_utils.h" 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "components/user_prefs/user_prefs.h" 41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/public/browser/browser_context.h" 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h" 437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "content/public/browser/web_contents.h" 44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/event_router.h" 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "extensions/browser/extension_function_dispatcher.h" 46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/quota_service.h" 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h" 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_WIN) 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/aura/remote_window_tree_host_win.h" 527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#endif 537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace extensions { 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace keys = bookmark_api_constants; 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace bookmarks = api::bookmarks; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeDelta; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using bookmarks::BookmarkTreeNode; 610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochusing bookmarks::CreateDetails; 62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using content::BrowserContext; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef QuotaLimitHeuristic::Bucket Bucket; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef QuotaLimitHeuristic::Config Config; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef QuotaLimitHeuristic::BucketList BucketList; 69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)typedef QuotaService::TimedLimit TimedLimit; 70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)typedef QuotaService::SustainedLimit SustainedLimit; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef QuotaLimitHeuristic::BucketMapper BucketMapper; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Generates a default path (including a default filename) that will be 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// used for pre-populating the "Export Bookmarks" file chooser dialog box. 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath GetDefaultFilepathForBookmarkExport() { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time time = base::Time::Now(); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Concatenate a date stamp to the filename. 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath::StringType filename = 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l10n_util::GetStringFUTF8(IDS_EXPORT_BOOKMARKS_DEFAULT_FILENAME, 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeFormatShortDateNumeric(time)); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_WIN) 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath::StringType filename = 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l10n_util::GetStringFUTF16(IDS_EXPORT_BOOKMARKS_DEFAULT_FILENAME, 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeFormatShortDateNumeric(time)); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_util::ReplaceIllegalCharactersInPath(&filename, '_'); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath default_path; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PathService::Get(chrome::DIR_USER_DOCUMENTS, &default_path); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return default_path.Append(filename); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 100010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool BookmarksFunction::RunAsync() { 1011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile()); 102b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!model->loaded()) { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Bookmarks are not ready yet. We'll wait. 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) model->AddObserver(this); 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AddRef(); // Balanced in Loaded(). 1065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return true; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu bool success = RunOnReady(); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (success) { 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::current()->Notify( 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::NOTIFICATION_EXTENSION_BOOKMARKS_API_INVOKED, 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::Source<const Extension>(GetExtension()), 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Details<const BookmarksFunction>(this)); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendResponse(success); 1175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return true; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool BookmarksFunction::GetBookmarkIdAsInt64(const std::string& id_string, 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64* id) { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base::StringToInt64(id_string, id)) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_ = keys::kInvalidIdError; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const BookmarkNode* BookmarksFunction::GetBookmarkNodeFromId( 130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& id_string) { 131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int64 id; 132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!GetBookmarkIdAsInt64(id_string, &id)) 133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return NULL; 134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const BookmarkNode* node = GetBookmarkNodeByID( 1360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch BookmarkModelFactory::GetForProfile(GetProfile()), id); 137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!node) 138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) error_ = keys::kNoNodeError; 139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return node; 141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochconst BookmarkNode* BookmarksFunction::CreateBookmarkNode( 1440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch BookmarkModel* model, 1450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const CreateDetails& details, 1460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const BookmarkNode::MetaInfoMap* meta_info) { 1470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch int64 parentId; 1480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!details.parent_id.get()) { 1500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Optional, default to "other bookmarks". 1510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch parentId = model->other_node()->id(); 1520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } else { 1530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!GetBookmarkIdAsInt64(*details.parent_id, &parentId)) 1540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return NULL; 1550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const BookmarkNode* parent = GetBookmarkNodeByID(model, parentId); 1570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!parent) { 1580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch error_ = keys::kNoParentError; 1590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return NULL; 1600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (parent->is_root()) { // Can't create children of the root. 1620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch error_ = keys::kModifySpecialError; 1630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return NULL; 1640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch int index; 1670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!details.index.get()) { // Optional (defaults to end). 1680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch index = parent->child_count(); 1690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } else { 1700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch index = *details.index; 1710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (index > parent->child_count() || index < 0) { 1720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch error_ = keys::kInvalidIndexError; 1730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return NULL; 1740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::string16 title; // Optional. 1780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (details.title.get()) 1790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch title = base::UTF8ToUTF16(*details.title.get()); 1800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch std::string url_string; // Optional. 1820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (details.url.get()) 1830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch url_string = *details.url.get(); 1840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch GURL url(url_string); 1860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!url_string.empty() && !url.is_valid()) { 1870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch error_ = keys::kInvalidUrlError; 1880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return NULL; 1890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const BookmarkNode* node; 1920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (url_string.length()) 1930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch node = model->AddURLWithCreationTimeAndMetaInfo( 1940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch parent, index, title, url, base::Time::Now(), meta_info); 1950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch else 1960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch node = model->AddFolderWithMetaInfo(parent, index, title, meta_info); 1970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DCHECK(node); 1980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!node) { 1990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch error_ = keys::kNoNodeError; 2000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return NULL; 2010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 2020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 2030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return node; 2040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 2050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BookmarksFunction::EditBookmarksEnabled() { 2071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) PrefService* prefs = user_prefs::UserPrefs::Get(GetProfile()); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prefs->GetBoolean(prefs::kEditBookmarksEnabled)) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_ = keys::kEditBookmarksDisabled; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BookmarksFunction::BookmarkModelChanged() { 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void BookmarksFunction::BookmarkModelLoaded(BookmarkModel* model, 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool ids_reassigned) { 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) model->RemoveObserver(this); 2205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu RunOnReady(); 2215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu Release(); // Balanced in RunOnReady(). 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 224a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)BookmarkEventRouter::BookmarkEventRouter(BrowserContext* context, 225a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BookmarkModel* model) 226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : browser_context_(context), model_(model) { 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_->AddObserver(this); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)BookmarkEventRouter::~BookmarkEventRouter() { 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (model_) { 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_->RemoveObserver(this); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BookmarkEventRouter::DispatchEvent( 2374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const std::string& event_name, 238eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<base::ListValue> event_args) { 2390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EventRouter* event_router = EventRouter::Get(browser_context_); 2400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (event_router) { 2410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch event_router->BroadcastEvent( 2420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch make_scoped_ptr(new extensions::Event(event_name, event_args.Pass()))); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void BookmarkEventRouter::BookmarkModelLoaded(BookmarkModel* model, 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool ids_reassigned) { 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(erikkay): Perhaps we should send this event down to the extension 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // so they know when it's safe to use the API? 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BookmarkEventRouter::BookmarkModelBeingDeleted(BookmarkModel* model) { 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_ = NULL; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BookmarkEventRouter::BookmarkNodeMoved(BookmarkModel* model, 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const BookmarkNode* old_parent, 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int old_index, 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const BookmarkNode* new_parent, 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int new_index) { 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node = new_parent->GetChild(new_index); 262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bookmarks::OnMoved::MoveInfo move_info; 263a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) move_info.parent_id = base::Int64ToString(new_parent->id()); 264a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) move_info.index = new_index; 265a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) move_info.old_parent_id = base::Int64ToString(old_parent->id()); 266a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) move_info.old_index = old_index; 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 268a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DispatchEvent( 269a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bookmarks::OnMoved::kEventName, 270a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bookmarks::OnMoved::Create(base::Int64ToString(node->id()), move_info)); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BookmarkEventRouter::BookmarkNodeAdded(BookmarkModel* model, 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const BookmarkNode* parent, 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int index) { 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node = parent->GetChild(index); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<BookmarkTreeNode> tree_node( 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bookmark_api_helpers::GetBookmarkTreeNode(node, false, false)); 279a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DispatchEvent(bookmarks::OnCreated::kEventName, 280a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bookmarks::OnCreated::Create(base::Int64ToString(node->id()), 281a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *tree_node)); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 284010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void BookmarkEventRouter::BookmarkNodeRemoved( 285010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) BookmarkModel* model, 286010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const BookmarkNode* parent, 287010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int index, 288010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const BookmarkNode* node, 289010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const std::set<GURL>& removed_urls) { 290a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bookmarks::OnRemoved::RemoveInfo remove_info; 291a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) remove_info.parent_id = base::Int64ToString(parent->id()); 292a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) remove_info.index = index; 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 294a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DispatchEvent(bookmarks::OnRemoved::kEventName, 295a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bookmarks::OnRemoved::Create(base::Int64ToString(node->id()), 296a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) remove_info)); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 299010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void BookmarkEventRouter::BookmarkAllNodesRemoved( 300010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) BookmarkModel* model, 301010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const std::set<GURL>& removed_urls) { 302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NOTREACHED(); 303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // TODO(shashishekhar) Currently this notification is only used on Android, 304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // which does not support extensions. If Desktop needs to support this, add 305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // a new event to the extensions api. 306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BookmarkEventRouter::BookmarkNodeChanged(BookmarkModel* model, 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const BookmarkNode* node) { 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(erikkay) The only three things that BookmarkModel sends this 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // notification for are title, url and favicon. Since we're currently 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ignoring favicon and since the notification doesn't say which one anyway, 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for now we only include title and url. The ideal thing would be to change 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // BookmarkModel to indicate what changed. 315a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bookmarks::OnChanged::ChangeInfo change_info; 316a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) change_info.title = base::UTF16ToUTF8(node->GetTitle()); 317e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (node->is_url()) 318e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch change_info.url.reset(new std::string(node->url().spec())); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 320a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DispatchEvent(bookmarks::OnChanged::kEventName, 321a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bookmarks::OnChanged::Create(base::Int64ToString(node->id()), 322a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) change_info)); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BookmarkEventRouter::BookmarkNodeFaviconChanged(BookmarkModel* model, 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const BookmarkNode* node) { 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(erikkay) anything we should do here? 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BookmarkEventRouter::BookmarkNodeChildrenReordered( 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BookmarkModel* model, 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const BookmarkNode* node) { 333a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bookmarks::OnChildrenReordered::ReorderInfo reorder_info; 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int childCount = node->child_count(); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < childCount; ++i) { 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* child = node->GetChild(i); 337a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) reorder_info.child_ids.push_back(base::Int64ToString(child->id())); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 340a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DispatchEvent(bookmarks::OnChildrenReordered::kEventName, 341a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bookmarks::OnChildrenReordered::Create( 342a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Int64ToString(node->id()), reorder_info)); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BookmarkEventRouter::ExtensiveBookmarkChangesBeginning( 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BookmarkModel* model) { 347a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DispatchEvent(bookmarks::OnImportBegan::kEventName, 348a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bookmarks::OnImportBegan::Create()); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BookmarkEventRouter::ExtensiveBookmarkChangesEnded(BookmarkModel* model) { 352a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DispatchEvent(bookmarks::OnImportEnded::kEventName, 353a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bookmarks::OnImportEnded::Create()); 354a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 355a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 356a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)BookmarksAPI::BookmarksAPI(BrowserContext* context) 357a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : browser_context_(context) { 3580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EventRouter* event_router = EventRouter::Get(browser_context_); 359a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) event_router->RegisterObserver(this, bookmarks::OnCreated::kEventName); 360a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) event_router->RegisterObserver(this, bookmarks::OnRemoved::kEventName); 361a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) event_router->RegisterObserver(this, bookmarks::OnChanged::kEventName); 362a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) event_router->RegisterObserver(this, bookmarks::OnMoved::kEventName); 363a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) event_router->RegisterObserver(this, 364a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bookmarks::OnChildrenReordered::kEventName); 365a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) event_router->RegisterObserver(this, bookmarks::OnImportBegan::kEventName); 366a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) event_router->RegisterObserver(this, bookmarks::OnImportEnded::kEventName); 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)BookmarksAPI::~BookmarksAPI() { 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BookmarksAPI::Shutdown() { 3730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EventRouter::Get(browser_context_)->UnregisterObserver(this); 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 376a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static base::LazyInstance<BrowserContextKeyedAPIFactory<BookmarksAPI> > 377a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) g_factory = LAZY_INSTANCE_INITIALIZER; 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 380a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)BrowserContextKeyedAPIFactory<BookmarksAPI>* 381a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)BookmarksAPI::GetFactoryInstance() { 3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return g_factory.Pointer(); 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BookmarksAPI::OnListenerAdded(const EventListenerInfo& details) { 386a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bookmark_event_router_.reset(new BookmarkEventRouter( 387a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) browser_context_, 388a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BookmarkModelFactory::GetForProfile( 389a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Profile::FromBrowserContext(browser_context_)))); 3900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EventRouter::Get(browser_context_)->UnregisterObserver(this); 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool BookmarksGetFunction::RunOnReady() { 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<bookmarks::Get::Params> params( 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmarks::Get::Params::Create(*args_)); 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(params.get()); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<linked_ptr<BookmarkTreeNode> > nodes; 3997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (params->id_or_id_list.as_strings) { 4007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::vector<std::string>& ids = *params->id_or_id_list.as_strings; 4017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch size_t count = ids.size(); 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(count > 0); 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < count; ++i) { 404f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const BookmarkNode* node = GetBookmarkNodeFromId(ids[i]); 405f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!node) 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 407f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bookmark_api_helpers::AddNode(node, &nodes, false); 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 410f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const BookmarkNode* node = 411f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) GetBookmarkNodeFromId(*params->id_or_id_list.as_string); 412f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!node) 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bookmark_api_helpers::AddNode(node, &nodes, false); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) results_ = bookmarks::Get::Results::Create(nodes); 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool BookmarksGetChildrenFunction::RunOnReady() { 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<bookmarks::GetChildren::Params> params( 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmarks::GetChildren::Params::Create(*args_)); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(params.get()); 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 426f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const BookmarkNode* node = GetBookmarkNodeFromId(params->id); 427f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!node) 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<linked_ptr<BookmarkTreeNode> > nodes; 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int child_count = node->child_count(); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < child_count; ++i) { 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* child = node->GetChild(i); 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bookmark_api_helpers::AddNode(child, &nodes, false); 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) results_ = bookmarks::GetChildren::Results::Create(nodes); 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool BookmarksGetRecentFunction::RunOnReady() { 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<bookmarks::GetRecent::Params> params( 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmarks::GetRecent::Params::Create(*args_)); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(params.get()); 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (params->number_of_items < 1) 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<const BookmarkNode*> nodes; 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark_utils::GetMostRecentlyAddedEntries( 4501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) BookmarkModelFactory::GetForProfile(GetProfile()), 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params->number_of_items, 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &nodes); 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<linked_ptr<BookmarkTreeNode> > tree_nodes; 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<const BookmarkNode*>::iterator i = nodes.begin(); 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (; i != nodes.end(); ++i) { 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node = *i; 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bookmark_api_helpers::AddNode(node, &tree_nodes, false); 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) results_ = bookmarks::GetRecent::Results::Create(tree_nodes); 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool BookmarksGetTreeFunction::RunOnReady() { 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<linked_ptr<BookmarkTreeNode> > nodes; 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* node = 4681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) BookmarkModelFactory::GetForProfile(GetProfile())->root_node(); 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bookmark_api_helpers::AddNode(node, &nodes, true); 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) results_ = bookmarks::GetTree::Results::Create(nodes); 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool BookmarksGetSubTreeFunction::RunOnReady() { 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<bookmarks::GetSubTree::Params> params( 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmarks::GetSubTree::Params::Create(*args_)); 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(params.get()); 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 479f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const BookmarkNode* node = GetBookmarkNodeFromId(params->id); 480f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!node) 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<linked_ptr<BookmarkTreeNode> > nodes; 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bookmark_api_helpers::AddNode(node, &nodes, true); 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) results_ = bookmarks::GetSubTree::Results::Create(nodes); 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool BookmarksSearchFunction::RunOnReady() { 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<bookmarks::Search::Params> params( 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmarks::Search::Params::Create(*args_)); 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(params.get()); 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) PrefService* prefs = user_prefs::UserPrefs::Get(GetProfile()); 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string lang = prefs->GetString(prefs::kAcceptLanguages); 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<const BookmarkNode*> nodes; 4975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (params->query.as_string) { 4985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bookmark_utils::QueryFields query; 4995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) query.word_phrase_query.reset( 5005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new base::string16(base::UTF8ToUTF16(*params->query.as_string))); 5015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bookmark_utils::GetBookmarksMatchingProperties( 5025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BookmarkModelFactory::GetForProfile(GetProfile()), 5035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) query, 5045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::numeric_limits<int>::max(), 5055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) lang, 5065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &nodes); 5075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 5085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(params->query.as_object); 5095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const bookmarks::Search::Params::Query::Object& object = 5105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *params->query.as_object; 5115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bookmark_utils::QueryFields query; 5125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (object.query) { 5135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) query.word_phrase_query.reset( 5145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new base::string16(base::UTF8ToUTF16(*object.query))); 5155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 5165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (object.url) 5175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) query.url.reset(new base::string16(base::UTF8ToUTF16(*object.url))); 5185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (object.title) 5195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) query.title.reset(new base::string16(base::UTF8ToUTF16(*object.title))); 5205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bookmark_utils::GetBookmarksMatchingProperties( 5215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BookmarkModelFactory::GetForProfile(GetProfile()), 5225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) query, 5235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::numeric_limits<int>::max(), 5245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) lang, 5255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &nodes); 5265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<linked_ptr<BookmarkTreeNode> > tree_nodes; 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<const BookmarkNode*>::iterator node_iter = nodes.begin(); 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node_iter != nodes.end(); ++node_iter) { 5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bookmark_api_helpers::AddNode(*node_iter, &tree_nodes, false); 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) results_ = bookmarks::Search::Results::Create(tree_nodes); 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 539eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool BookmarksRemoveFunction::ExtractIds(const base::ListValue* args, 5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::list<int64>* ids, 5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool* invalid_id) { 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string id_string; 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!args->GetString(0, &id_string)) 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 id; 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base::StringToInt64(id_string, &id)) 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ids->push_back(id); 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *invalid_id = true; 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool BookmarksRemoveFunction::RunOnReady() { 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!EditBookmarksEnabled()) 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<bookmarks::Remove::Params> params( 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmarks::Remove::Params::Create(*args_)); 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(params.get()); 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 id; 562f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!GetBookmarkIdAsInt64(params->id, &id)) 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool recursive = false; 5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (name() == BookmarksRemoveTreeFunction::function_name()) 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) recursive = true; 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile()); 5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!bookmark_api_helpers::RemoveNode(model, id, recursive, &error_)) 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool BookmarksCreateFunction::RunOnReady() { 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!EditBookmarksEnabled()) 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<bookmarks::Create::Params> params( 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmarks::Create::Params::Create(*args_)); 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(params.get()); 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile()); 5850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const BookmarkNode* node = CreateBookmarkNode(model, params->bookmark, NULL); 5860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!node) 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<BookmarkTreeNode> ret( 5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bookmark_api_helpers::GetBookmarkTreeNode(node, false, false)); 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) results_ = bookmarks::Create::Results::Create(*ret); 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 597eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool BookmarksMoveFunction::ExtractIds(const base::ListValue* args, 5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::list<int64>* ids, 5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool* invalid_id) { 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For now, Move accepts ID parameters in the same way as an Update. 6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return BookmarksUpdateFunction::ExtractIds(args, ids, invalid_id); 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool BookmarksMoveFunction::RunOnReady() { 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!EditBookmarksEnabled()) 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<bookmarks::Move::Params> params( 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmarks::Move::Params::Create(*args_)); 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(params.get()); 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 612f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const BookmarkNode* node = GetBookmarkNodeFromId(params->id); 613f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!node) 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile()); 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (model->is_permanent_node(node)) { 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_ = keys::kModifySpecialError; 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BookmarkNode* parent = NULL; 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!params->destination.parent_id.get()) { 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Optional, defaults to current parent. 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent = node->parent(); 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 parentId; 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!GetBookmarkIdAsInt64(*params->destination.parent_id, &parentId)) 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch parent = GetBookmarkNodeByID(model, parentId); 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!parent) { 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_ = keys::kNoParentError; 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(erikkay) return an error message. 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parent == model->root_node()) { 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_ = keys::kModifySpecialError; 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index; 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (params->destination.index.get()) { // Optional (defaults to end). 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) index = *params->destination.index; 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (index > parent->child_count() || index < 0) { 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_ = keys::kInvalidIndexError; 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) index = parent->child_count(); 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model->Move(node, parent, index); 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<BookmarkTreeNode> tree_node( 6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bookmark_api_helpers::GetBookmarkTreeNode(node, false, false)); 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) results_ = bookmarks::Move::Results::Create(*tree_node); 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 664eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool BookmarksUpdateFunction::ExtractIds(const base::ListValue* args, 6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::list<int64>* ids, 6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool* invalid_id) { 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For now, Update accepts ID parameters in the same way as an Remove. 6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return BookmarksRemoveFunction::ExtractIds(args, ids, invalid_id); 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool BookmarksUpdateFunction::RunOnReady() { 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!EditBookmarksEnabled()) 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<bookmarks::Update::Params> params( 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmarks::Update::Params::Create(*args_)); 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(params.get()); 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Optional but we need to distinguish non present from an empty title. 680a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 title; 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool has_title = false; 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (params->changes.title.get()) { 6835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) title = base::UTF8ToUTF16(*params->changes.title); 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) has_title = true; 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Optional. 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url_string; 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (params->changes.url.get()) 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_string = *params->changes.url; 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL url(url_string); 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!url_string.empty() && !url.is_valid()) { 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_ = keys::kInvalidUrlError; 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 697f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const BookmarkNode* node = GetBookmarkNodeFromId(params->id); 698f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!node) 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 700f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 701f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile()); 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (model->is_permanent_node(node)) { 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_ = keys::kModifySpecialError; 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (has_title) 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model->SetTitle(node, title); 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!url.is_empty()) 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model->SetURL(node, url); 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<BookmarkTreeNode> tree_node( 7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bookmark_api_helpers::GetBookmarkTreeNode(node, false, false)); 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) results_ = bookmarks::Update::Results::Create(*tree_node); 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Mapper superclass for BookmarkFunctions. 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename BucketIdType> 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BookmarkBucketMapper : public BucketMapper { 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~BookmarkBucketMapper() { STLDeleteValues(&buckets_); } 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bucket* GetBucket(const BucketIdType& id) { 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bucket* b = buckets_[id]; 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (b == NULL) { 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) b = new Bucket(); 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buckets_[id] = b; 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return b; 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<BucketIdType, Bucket*> buckets_; 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Mapper for 'bookmarks.create'. Maps "same input to bookmarks.create" to a 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// unique bucket. 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CreateBookmarkBucketMapper : public BookmarkBucketMapper<std::string> { 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 739a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) explicit CreateBookmarkBucketMapper(BrowserContext* context) 740a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : browser_context_(context) {} 7415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // TODO(tim): This should share code with BookmarksCreateFunction::RunOnReady, 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // but I can't figure out a good way to do that with all the macros. 743eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual void GetBucketsForArgs(const base::ListValue* args, 7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BucketList* buckets) OVERRIDE { 745eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const base::DictionaryValue* json; 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!args->GetDictionary(0, &json)) 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string parent_id; 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (json->HasKey(keys::kParentIdKey)) { 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!json->GetString(keys::kParentIdKey, &parent_id)) 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 754a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BookmarkModel* model = BookmarkModelFactory::GetForProfile( 755a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Profile::FromBrowserContext(browser_context_)); 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 parent_id_int64; 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringToInt64(parent_id, &parent_id_int64); 7590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const BookmarkNode* parent = GetBookmarkNodeByID(model, parent_id_int64); 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!parent) 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string bucket_id = base::UTF16ToUTF8(parent->GetTitle()); 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string title; 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) json->GetString(keys::kTitleKey, &title); 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url_string; 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) json->GetString(keys::kUrlKey, &url_string); 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bucket_id += title; 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bucket_id += url_string; 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 20 bytes (SHA1 hash length) is very likely less than most of the 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |bucket_id| strings we construct here, so we hash it to save space. 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buckets->push_back(GetBucket(base::SHA1HashString(bucket_id))); 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 776a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BrowserContext* browser_context_; 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Mapper for 'bookmarks.remove'. 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RemoveBookmarksBucketMapper : public BookmarkBucketMapper<std::string> { 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 782a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) explicit RemoveBookmarksBucketMapper(BrowserContext* context) 783a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : browser_context_(context) {} 784eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual void GetBucketsForArgs(const base::ListValue* args, 7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BucketList* buckets) OVERRIDE { 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::list<int64> IdList; 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IdList ids; 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool invalid_id = false; 7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!BookmarksRemoveFunction::ExtractIds(args, &ids, &invalid_id) || 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) invalid_id) { 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (IdList::iterator it = ids.begin(); it != ids.end(); ++it) { 795a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BookmarkModel* model = BookmarkModelFactory::GetForProfile( 796a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Profile::FromBrowserContext(browser_context_)); 7970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const BookmarkNode* node = GetBookmarkNodeByID(model, *it); 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!node || node->is_root()) 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string bucket_id; 8025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bucket_id += base::UTF16ToUTF8(node->parent()->GetTitle()); 8035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bucket_id += base::UTF16ToUTF8(node->GetTitle()); 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bucket_id += node->url().spec(); 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buckets->push_back(GetBucket(base::SHA1HashString(bucket_id))); 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 809a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BrowserContext* browser_context_; 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Mapper for any bookmark function accepting bookmark IDs as parameters, where 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a distinct ID corresponds to a single item in terms of quota limiting. This 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is inappropriate for bookmarks.remove, for example, since repeated removals 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of the same item will actually have a different ID each time. 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class FunctionType> 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BookmarkIdMapper : public BookmarkBucketMapper<int64> { 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::list<int64> IdList; 820eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual void GetBucketsForArgs(const base::ListValue* args, 821eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch BucketList* buckets) { 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IdList ids; 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool invalid_id = false; 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!FunctionType::ExtractIds(args, &ids, &invalid_id) || invalid_id) 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (IdList::iterator it = ids.begin(); it != ids.end(); ++it) 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buckets->push_back(GetBucket(*it)); 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Builds heuristics for all BookmarkFunctions using specialized BucketMappers. 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BookmarksQuotaLimitFactory { 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For id-based bookmark functions. 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <class FunctionType> 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void Build(QuotaLimitHeuristics* heuristics) { 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BuildWithMappers(heuristics, new BookmarkIdMapper<FunctionType>(), 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new BookmarkIdMapper<FunctionType>()); 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For bookmarks.create. 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void BuildForCreate(QuotaLimitHeuristics* heuristics, 843a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BrowserContext* context) { 844a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BuildWithMappers(heuristics, 845a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) new CreateBookmarkBucketMapper(context), 846a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) new CreateBookmarkBucketMapper(context)); 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For bookmarks.remove. 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void BuildForRemove(QuotaLimitHeuristics* heuristics, 851a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BrowserContext* context) { 852a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BuildWithMappers(heuristics, 853a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) new RemoveBookmarksBucketMapper(context), 854a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) new RemoveBookmarksBucketMapper(context)); 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void BuildWithMappers(QuotaLimitHeuristics* heuristics, 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BucketMapper* short_mapper, BucketMapper* long_mapper) { 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Config kSustainedLimitConfig = { 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See bookmarks.json for current value. 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmarks::MAX_SUSTAINED_WRITE_OPERATIONS_PER_MINUTE, 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeDelta::FromMinutes(1) 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) heuristics->push_back(new SustainedLimit( 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeDelta::FromMinutes(10), 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kSustainedLimitConfig, 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) short_mapper, 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "MAX_SUSTAINED_WRITE_OPERATIONS_PER_MINUTE")); 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Config kTimedLimitConfig = { 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See bookmarks.json for current value. 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmarks::MAX_WRITE_OPERATIONS_PER_HOUR, 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeDelta::FromHours(1) 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) heuristics->push_back(new TimedLimit( 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kTimedLimitConfig, 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long_mapper, 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "MAX_WRITE_OPERATIONS_PER_HOUR")); 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_IMPLICIT_CONSTRUCTORS(BookmarksQuotaLimitFactory); 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// And finally, building the individual heuristics for each function. 8862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BookmarksRemoveFunction::GetQuotaLimitHeuristics( 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuotaLimitHeuristics* heuristics) const { 8881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) BookmarksQuotaLimitFactory::BuildForRemove(heuristics, GetProfile()); 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BookmarksMoveFunction::GetQuotaLimitHeuristics( 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuotaLimitHeuristics* heuristics) const { 8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BookmarksQuotaLimitFactory::Build<BookmarksMoveFunction>(heuristics); 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BookmarksUpdateFunction::GetQuotaLimitHeuristics( 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuotaLimitHeuristics* heuristics) const { 8982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BookmarksQuotaLimitFactory::Build<BookmarksUpdateFunction>(heuristics); 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BookmarksCreateFunction::GetQuotaLimitHeuristics( 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuotaLimitHeuristics* heuristics) const { 9031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) BookmarksQuotaLimitFactory::BuildForCreate(heuristics, GetProfile()); 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BookmarksIOFunction::BookmarksIOFunction() {} 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BookmarksIOFunction::~BookmarksIOFunction() { 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // There may be pending file dialogs, we need to tell them that we've gone 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // away so they don't try and call back to us. 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (select_file_dialog_.get()) 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) select_file_dialog_->ListenerDestroyed(); 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarksIOFunction::SelectFile(ui::SelectFileDialog::Type type) { 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // GetDefaultFilepathForBookmarkExport() might have to touch the filesystem 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (stat or access, for example), so this requires a thread with IO allowed. 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!BrowserThread::CurrentlyOn(BrowserThread::FILE)) { 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&BookmarksIOFunction::SelectFile, this, type)); 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Pre-populating the filename field in case this is a SELECT_SAVEAS_FILE 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // dialog. If not, there is no filename field in the dialog box. 9262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath default_path; 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type == ui::SelectFileDialog::SELECT_SAVEAS_FILE) 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default_path = GetDefaultFilepathForBookmarkExport(); 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(type == ui::SelectFileDialog::SELECT_OPEN_FILE); 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // After getting the |default_path|, ask the UI to display the file dialog. 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&BookmarksIOFunction::ShowSelectFileDialog, this, 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type, default_path)); 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BookmarksIOFunction::ShowSelectFileDialog( 9392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::SelectFileDialog::Type type, 9402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& default_path) { 9412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!dispatcher()) 9422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; // Extension was unloaded. 9432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Balanced in one of the three callbacks of SelectFileDialog: 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // either FileSelectionCanceled, MultiFilesSelected, or FileSelected 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddRef(); 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebContents* web_contents = dispatcher()->delegate()-> 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetAssociatedWebContents(); 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) select_file_dialog_ = ui::SelectFileDialog::Create( 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, new ChromeSelectFilePolicy(web_contents)); 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::SelectFileDialog::FileTypeInfo file_type_info; 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_type_info.extensions.resize(1); 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("html")); 9567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch gfx::NativeWindow owning_window = web_contents ? 957010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) platform_util::GetTopLevel(web_contents->GetNativeView()) 9587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch : NULL; 9595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_WIN) 9607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!owning_window && 9617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch chrome::GetActiveDesktop() == chrome::HOST_DESKTOP_TYPE_ASH) 9625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) owning_window = aura::RemoteWindowTreeHostWin::Instance()->GetAshWindow(); 9637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#endif 9642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |web_contents| can be NULL (for background pages), which is fine. In such 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a case if file-selection dialogs are forbidden by policy, we will not 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // show an InfoBar, which is better than letting one appear out of the blue. 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) select_file_dialog_->SelectFile(type, 968a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16(), 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default_path, 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &file_type_info, 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, 972c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath::StringType(), 9737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch owning_window, 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL); 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarksIOFunction::FileSelectionCanceled(void* params) { 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Release(); // Balanced in BookmarksIOFunction::SelectFile() 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarksIOFunction::MultiFilesSelected( 9822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::vector<base::FilePath>& files, void* params) { 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Release(); // Balanced in BookmarsIOFunction::SelectFile() 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Should not be able to select multiple files"; 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool BookmarksImportFunction::RunOnReady() { 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!EditBookmarksEnabled()) 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SelectFile(ui::SelectFileDialog::SELECT_OPEN_FILE); 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BookmarksImportFunction::FileSelected(const base::FilePath& path, 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index, 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* params) { 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_ANDROID) 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Android does not have support for the standard importers. 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(jgreenwald): remove ifdef once extensions are no longer built on 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Android. 1001c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Deletes itself. 1002eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ExternalProcessImporterHost* importer_host = new ExternalProcessImporterHost; 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) importer::SourceProfile source_profile; 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) source_profile.importer_type = importer::TYPE_BOOKMARKS_FILE; 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) source_profile.source_path = path; 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) importer_host->StartImportSettings(source_profile, 10071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) GetProfile(), 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) importer::FAVORITES, 10091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) new ProfileWriter(GetProfile())); 1010c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1011c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) importer::LogImporterUseToMetrics("BookmarksAPI", 1012c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) importer::TYPE_BOOKMARKS_FILE); 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Release(); // Balanced in BookmarksIOFunction::SelectFile() 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool BookmarksExportFunction::RunOnReady() { 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SelectFile(ui::SelectFileDialog::SELECT_SAVEAS_FILE); 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BookmarksExportFunction::FileSelected(const base::FilePath& path, 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index, 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* params) { 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_ANDROID) 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Android does not have support for the standard exporter. 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(jgreenwald): remove ifdef once extensions are no longer built on 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Android. 10291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) bookmark_html_writer::WriteBookmarks(GetProfile(), path, NULL); 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Release(); // Balanced in BookmarksIOFunction::SelectFile() 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace extensions 1035