diff options
author | yfriedman@chromium.org <yfriedman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-14 13:40:32 +0000 |
---|---|---|
committer | yfriedman@chromium.org <yfriedman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-14 13:40:32 +0000 |
commit | 2eb48e684368d538564e253a6eb6c33f88132326 (patch) | |
tree | 9e77f55d0b0b9195daaa1bce6bdb01acb016cdc1 | |
parent | 03fae593b4ecd610248d6260262a556beaad8b6a (diff) | |
download | chromium_src-2eb48e684368d538564e253a6eb6c33f88132326.zip chromium_src-2eb48e684368d538564e253a6eb6c33f88132326.tar.gz chromium_src-2eb48e684368d538564e253a6eb6c33f88132326.tar.bz2 |
Implement initial of chrome.readingListPrivate api.
For experimentation with the dom distiller component, this provides a minimal API wrapping the functions of DomDistillerService.
Sketch proposal:
https://docs.google.com/a/google.com/document/d/1zLTKNAOkTyFpgeJqWg3Jn17Ayc-sYafyftBE6KUldV4/edit
BUG=288015
TBR=joi
Review URL: https://codereview.chromium.org/116553005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@244681 0039d316-1c4b-4281-b951-d872f2087c98
24 files changed, 417 insertions, 29 deletions
diff --git a/chrome/browser/extensions/api/reading_list_private/reading_list_private_api.cc b/chrome/browser/extensions/api/reading_list_private/reading_list_private_api.cc new file mode 100644 index 0000000..9f2919a --- /dev/null +++ b/chrome/browser/extensions/api/reading_list_private/reading_list_private_api.cc @@ -0,0 +1,80 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/extensions/api/reading_list_private/reading_list_private_api.h" + +#include <string> +#include <vector> + +#include "base/memory/linked_ptr.h" +#include "chrome/browser/dom_distiller/dom_distiller_service_factory.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/common/extensions/api/reading_list_private.h" +#include "components/dom_distiller/core/article_entry.h" +#include "components/dom_distiller/core/dom_distiller_service.h" + +namespace extensions { + +namespace AddEntry = api::reading_list_private::AddEntry; +namespace RemoveEntry = api::reading_list_private::RemoveEntry; +namespace GetEntries = api::reading_list_private::GetEntries; + +using api::reading_list_private::Entry; +using dom_distiller::ArticleEntry; +using dom_distiller::DomDistillerService; +using dom_distiller::DomDistillerServiceFactory; + +bool ReadingListPrivateAddEntryFunction::RunImpl() { + scoped_ptr<AddEntry::Params> params(AddEntry::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params); + GURL url_to_add(params->entry.url); + if (!url_to_add.is_valid()) { + error_ = "Invalid url specified."; + SendResponse(false); + return false; + } + + DomDistillerService* service = + DomDistillerServiceFactory::GetForBrowserContext(GetProfile()); + const std::string& id = service->AddToList(url_to_add, base::Bind( + &ReadingListPrivateAddEntryFunction::SendResponse, this)); + Entry new_entry; + new_entry.id = id; + results_ = AddEntry::Results::Create(new_entry); + return true; +} + +bool ReadingListPrivateRemoveEntryFunction::RunImpl() { + scoped_ptr<RemoveEntry::Params> params(RemoveEntry::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params); + DomDistillerService* service = + DomDistillerServiceFactory::GetForBrowserContext(GetProfile()); + scoped_ptr<ArticleEntry> entry(service->RemoveEntry(params->id)); + if (entry == NULL) { + results_ = make_scoped_ptr(new base::ListValue()); + } else { + Entry removed_entry; + removed_entry.id = entry->entry_id(); + results_ = RemoveEntry::Results::Create(removed_entry); + } + return true; +} + +bool ReadingListPrivateGetEntriesFunction::RunImpl() { + DomDistillerService* service = + DomDistillerServiceFactory::GetForBrowserContext(GetProfile()); + const std::vector<ArticleEntry>& entries = service->GetEntries(); + std::vector<linked_ptr<Entry> > result; + for (std::vector<ArticleEntry>::const_iterator i = entries.begin(); + i != entries.end(); + ++i) { + linked_ptr<Entry> e(new Entry); + e->id = i->entry_id(); + result.push_back(e); + } + results_ = GetEntries::Results::Create(result); + return true; +} + +} // namespace extensions diff --git a/chrome/browser/extensions/api/reading_list_private/reading_list_private_api.h b/chrome/browser/extensions/api/reading_list_private/reading_list_private_api.h new file mode 100644 index 0000000..305da61 --- /dev/null +++ b/chrome/browser/extensions/api/reading_list_private/reading_list_private_api.h @@ -0,0 +1,58 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_EXTENSIONS_API_READING_LIST_PRIVATE_READING_LIST_PRIVATE_API_H_ +#define CHROME_BROWSER_EXTENSIONS_API_READING_LIST_PRIVATE_READING_LIST_PRIVATE_API_H_ + +#include "base/values.h" +#include "chrome/browser/extensions/chrome_extension_function.h" +#include "chrome/common/extensions/api/reading_list_private.h" + +namespace content { +class WebContents; +} + +namespace extensions { + +class ReadingListPrivateAddEntryFunction : public ChromeAsyncExtensionFunction { + public: + DECLARE_EXTENSION_FUNCTION("readingListPrivate.addEntry", + READINGLISTPRIVATE_ADDENTRY) + + protected: + virtual ~ReadingListPrivateAddEntryFunction() {} + + // ExtensionFunction: + virtual bool RunImpl() OVERRIDE; +}; + +class ReadingListPrivateRemoveEntryFunction + : public ChromeSyncExtensionFunction { + public: + DECLARE_EXTENSION_FUNCTION("readingListPrivate.removeEntry", + READINGLISTPRIVATE_REMOVEENTRY) + + protected: + virtual ~ReadingListPrivateRemoveEntryFunction() {} + + // ExtensionFunction: + virtual bool RunImpl() OVERRIDE; +}; + +class ReadingListPrivateGetEntriesFunction + : public ChromeSyncExtensionFunction { + public: + DECLARE_EXTENSION_FUNCTION("readingListPrivate.getEntries", + READINGLISTPRIVATE_GETENTRIES) + + protected: + virtual ~ReadingListPrivateGetEntriesFunction() {} + + // ExtensionFunction: + virtual bool RunImpl() OVERRIDE; +}; + +} // namespace extensions + +#endif // CHROME_BROWSER_EXTENSIONS_API_READING_LIST_PRIVATE_READING_LIST_PRIVATE_API_H_ diff --git a/chrome/browser/extensions/api/reading_list_private/reading_list_private_apitest.cc b/chrome/browser/extensions/api/reading_list_private/reading_list_private_apitest.cc new file mode 100644 index 0000000..f2f10df --- /dev/null +++ b/chrome/browser/extensions/api/reading_list_private/reading_list_private_apitest.cc @@ -0,0 +1,47 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/dom_distiller/dom_distiller_service_factory.h" +#include "chrome/browser/extensions/api/reading_list_private/reading_list_private_api.h" +#include "chrome/browser/extensions/extension_apitest.h" +#include "chrome/browser/profiles/profile.h" +#include "components/dom_distiller/core/dom_distiller_service.h" +#include "components/dom_distiller/core/dom_distiller_store.h" +#include "components/dom_distiller/core/dom_distiller_test_util.h" +#include "components/dom_distiller/core/fake_db.h" +#include "components/dom_distiller/core/fake_distiller.h" + +using dom_distiller::test::FakeDB; +using dom_distiller::test::FakeDistiller; +using dom_distiller::test::util::CreateStoreWithFakeDB; +using dom_distiller::DomDistillerContextKeyedService; +using dom_distiller::DomDistillerService; +using dom_distiller::DistillerFactory; +using dom_distiller::DomDistillerStoreInterface; +using dom_distiller::test::MockDistillerFactory; + +class ReadingListPrivateApiTest : public ExtensionApiTest { + public: + static BrowserContextKeyedService* Build(content::BrowserContext* context) { + FakeDB* fake_db = new FakeDB(new FakeDB::EntryMap); + FakeDistiller* distiller = new FakeDistiller(true); + MockDistillerFactory* factory = new MockDistillerFactory(); + DomDistillerContextKeyedService* service = + new DomDistillerContextKeyedService( + scoped_ptr<DomDistillerStoreInterface>( + CreateStoreWithFakeDB(fake_db, new FakeDB::EntryMap)), + scoped_ptr<DistillerFactory>(factory)); + fake_db->InitCallback(true); + fake_db->LoadCallback(true); + EXPECT_CALL(*factory, CreateDistillerImpl()) + .WillOnce(testing::Return(distiller)); + return service; + } +}; + +IN_PROC_BROWSER_TEST_F(ReadingListPrivateApiTest, ReadingListPrivate) { + dom_distiller::DomDistillerServiceFactory::GetInstance()->SetTestingFactory( + profile(), &ReadingListPrivateApiTest::Build); + ASSERT_TRUE(RunComponentExtensionTest("reading_list_private")) << message_; +} diff --git a/chrome/browser/extensions/extension_function_histogram_value.h b/chrome/browser/extensions/extension_function_histogram_value.h index 864fa5c..c14cb1a 100644 --- a/chrome/browser/extensions/extension_function_histogram_value.h +++ b/chrome/browser/extensions/extension_function_histogram_value.h @@ -719,6 +719,9 @@ enum HistogramValue { BOOKMARKMANAGERPRIVATE_REDOINFO, MEDIAGALLERIES_ADDUSERSELECTEDFOLDER, PREFERENCESPRIVATE_GETSYNCCATEGORIESWITHOUTPASSPHRASE, + READINGLISTPRIVATE_ADDENTRY, + READINGLISTPRIVATE_REMOVEENTRY, + READINGLISTPRIVATE_GETENTRIES, ENUM_BOUNDARY // Last entry: Add new entries above. }; diff --git a/chrome/chrome_browser_extensions.gypi b/chrome/chrome_browser_extensions.gypi index 9fbc59a..1951dd8 100644 --- a/chrome/chrome_browser_extensions.gypi +++ b/chrome/chrome_browser_extensions.gypi @@ -450,6 +450,8 @@ 'browser/extensions/api/push_messaging/push_messaging_invalidation_handler.h', 'browser/extensions/api/push_messaging/push_messaging_invalidation_handler_delegate.h', 'browser/extensions/api/push_messaging/push_messaging_invalidation_mapper.h', + 'browser/extensions/api/reading_list_private/reading_list_private_api.cc', + 'browser/extensions/api/reading_list_private/reading_list_private_api.h', 'browser/extensions/api/runtime/runtime_api.cc', 'browser/extensions/api/runtime/runtime_api.h', 'browser/extensions/api/runtime/runtime_api_factory.cc', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 4579224..2f707fe 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -903,6 +903,7 @@ '../base/base.gyp:test_support_base', '../components/components.gyp:autofill_content_risk_proto', '../components/components.gyp:autofill_content_test_support', + '../components/components.gyp:dom_distiller_test_support', '../components/component_strings.gyp:component_strings', '../device/bluetooth/bluetooth.gyp:device_bluetooth_mocks', '../google_apis/google_apis.gyp:google_apis_test_support', @@ -1151,6 +1152,7 @@ 'browser/extensions/api/push_messaging/push_messaging_apitest.cc', 'browser/extensions/api/push_messaging/push_messaging_canary_test.cc', 'browser/extensions/api/push_messaging/sync_setup_helper.cc', + 'browser/extensions/api/reading_list_private/reading_list_private_apitest.cc', 'browser/extensions/api/runtime/runtime_apitest.cc', 'browser/extensions/api/serial/serial_apitest.cc', 'browser/extensions/api/sessions/sessions_apitest.cc', diff --git a/chrome/common/extensions/api/_api_features.json b/chrome/common/extensions/api/_api_features.json index 373b12f..6a44f58 100644 --- a/chrome/common/extensions/api/_api_features.json +++ b/chrome/common/extensions/api/_api_features.json @@ -508,6 +508,10 @@ "extension_types": ["platform_app"], "contexts": ["blessed_extension"] }, + "readingListPrivate": { + "dependencies": ["permission:readingListPrivate"], + "contexts": ["blessed_extension"] + }, "rtcPrivate": { "dependencies": ["permission:rtcPrivate"], "contexts": ["blessed_extension"] diff --git a/chrome/common/extensions/api/_permission_features.json b/chrome/common/extensions/api/_permission_features.json index 612a50d..4d1028d 100644 --- a/chrome/common/extensions/api/_permission_features.json +++ b/chrome/common/extensions/api/_permission_features.json @@ -709,6 +709,14 @@ "D7986543275120831B39EF28D1327552FC343960" // Chrome OS Recovery Tool ] }, + "readingListPrivate": { + "channel": "stable", + "extension_types": ["extension"], + "whitelist": [ + "D5736E4B5CF695CB93A2FB57E4FDC6E5AFAB6FE2", // http://crbug.com/312900 + "D57DE394F36DC1C3220E7604C575D29C51A6C495" // http://crbug.com/319444 + ] + }, "rtcPrivate": { "channel": "stable", "extension_types": ["extension", "legacy_packaged_app"], diff --git a/chrome/common/extensions/api/api.gyp b/chrome/common/extensions/api/api.gyp index 752a522..d9649a4 100644 --- a/chrome/common/extensions/api/api.gyp +++ b/chrome/common/extensions/api/api.gyp @@ -93,6 +93,7 @@ 'preferences_private.json', 'power.idl', 'push_messaging.idl', + 'reading_list_private.json', 'runtime.json', 'serial.idl', 'sessions.json', diff --git a/chrome/common/extensions/api/reading_list_private.json b/chrome/common/extensions/api/reading_list_private.json new file mode 100644 index 0000000..7e1979d --- /dev/null +++ b/chrome/common/extensions/api/reading_list_private.json @@ -0,0 +1,96 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +[ + { + "namespace": "readingListPrivate", + "description": "none", + "types": [ + { + "id": "Entry", + "type": "object", + "description": "An article entry from the reading list. May contain one or more pages.", + "properties": { + "id": { + "description": "A unique id for referring to the entry.", + "type": "string" + } + } + } + ], + "functions": [ + { + "name": "addEntry", + "type": "function", + "description": "Adds an entry to the reading list. The callback is invoked only once article distillation is complete.", + "parameters": [ + { + "type": "object", + "name": "entry", + "properties": { + "url": { + "description": "The url of the entry.", + "type": "string" + } + } + }, + { + "type": "function", + "name": "callback", + "optional": true, + "parameters": [ + { + "name": "result", + "$ref": "Entry", + "description": "The entry that was added." + } + ] + } + ] + }, + { + "name": "removeEntry", + "type": "function", + "description": "Removes an entry with the given entry id.", + "parameters": [ + { + "name": "id", + "type": "string", + "description": "A string containing an entry id." + }, + { + "type": "function", + "name": "callback", + "parameters": [ + { + "name": "result", + "$ref": "Entry", + "optional": true, + "description": "The entry that was removed or null if removal failed." + } + ] + } + ] + }, + { + "name": "getEntries", + "type": "function", + "description": "Gets all the entries currently stored in the reading list.", + "parameters": [ + { + "type": "function", + "name": "callback", + "parameters": [ + { + "name": "result", + "type": "array", + "items": {"$ref": "Entry"} + } + ] + } + ] + } + ] + } +] diff --git a/chrome/common/extensions/permissions/chrome_api_permissions.cc b/chrome/common/extensions/permissions/chrome_api_permissions.cc index 314da80..e939dc0 100644 --- a/chrome/common/extensions/permissions/chrome_api_permissions.cc +++ b/chrome/common/extensions/permissions/chrome_api_permissions.cc @@ -222,6 +222,8 @@ std::vector<APIPermissionInfo*> ChromeAPIPermissions::GetAllPermissions() APIPermissionInfo::kFlagCannotBeOptional }, { APIPermission::kImageWriterPrivate, "imageWriterPrivate", APIPermissionInfo::kFlagCannotBeOptional }, + { APIPermission::kReadingListPrivate, "readingListPrivate", + APIPermissionInfo::kFlagCannotBeOptional }, { APIPermission::kRtcPrivate, "rtcPrivate", APIPermissionInfo::kFlagCannotBeOptional }, { APIPermission::kTerminalPrivate, "terminalPrivate", diff --git a/chrome/common/extensions/permissions/permission_set_unittest.cc b/chrome/common/extensions/permissions/permission_set_unittest.cc index 346d56e..69be75c 100644 --- a/chrome/common/extensions/permissions/permission_set_unittest.cc +++ b/chrome/common/extensions/permissions/permission_set_unittest.cc @@ -749,6 +749,7 @@ TEST(PermissionsTest, PermissionMessages) { skip.insert(APIPermission::kPreferencesPrivate); skip.insert(APIPermission::kPrincipalsPrivate); skip.insert(APIPermission::kImageWriterPrivate); + skip.insert(APIPermission::kReadingListPrivate); skip.insert(APIPermission::kRtcPrivate); skip.insert(APIPermission::kStreamsPrivate); skip.insert(APIPermission::kSystemPrivate); diff --git a/chrome/test/data/extensions/api_test/reading_list_private/manifest.json b/chrome/test/data/extensions/api_test/reading_list_private/manifest.json new file mode 100644 index 0000000..8b70e3c --- /dev/null +++ b/chrome/test/data/extensions/api_test/reading_list_private/manifest.json @@ -0,0 +1,11 @@ +{ + "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDQcByy+eN9jzazWF/DPn7NW47sW7lgmpk6eKc0BQM18q8hvEM3zNm2n7HkJv/R6fU+X5mtqkDuKvq5skF6qqUF4oEyaleWDFhd1xFwV7JV+/DU7bZ00w2+6gzqsabkerFpoP33ZRIw7OviJenP0c0uWqDWF8EGSyMhB3txqhOtiQIDAQAC", + "name": "chrome.readingListPrivate", + "version": "0.1", + "manifest_version": 2, + "description": "end-to-end browser test for chrome.readingListPrivate API", + "background": { + "page": "test.html" + }, + "permissions": ["readingListPrivate"] +} diff --git a/chrome/test/data/extensions/api_test/reading_list_private/test.html b/chrome/test/data/extensions/api_test/reading_list_private/test.html new file mode 100644 index 0000000..1c89235 --- /dev/null +++ b/chrome/test/data/extensions/api_test/reading_list_private/test.html @@ -0,0 +1,7 @@ +<!doctype html> +<!-- + * Copyright 2013 The Chromium Authors. All rights reserved. Use of this + * source code is governed by a BSD-style license that can be found in the + * LICENSE file. +--> +<script src="test.js"></script> diff --git a/chrome/test/data/extensions/api_test/reading_list_private/test.js b/chrome/test/data/extensions/api_test/reading_list_private/test.js new file mode 100644 index 0000000..9317e55 --- /dev/null +++ b/chrome/test/data/extensions/api_test/reading_list_private/test.js @@ -0,0 +1,43 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Reading List Private API test for Chrome. +// browser_tests.exe --gtest_filter=ReadingListPrivateApiTest.* + +var pass = chrome.test.callbackPass; +var fail = chrome.test.callbackFail; +var assertEq = chrome.test.assertEq; +var assertFalse = chrome.test.assertFalse; +var assertTrue = chrome.test.assertTrue; +var readingList = chrome.readingListPrivate; + +var tests = [ + function addAndRemoveEntry() { + readingList.addEntry({url: "http://www.google.com"}, + pass(function(newEntry) { + readingList.getEntries(pass(function(entries) { + assertEq([newEntry], entries); + readingList.removeEntry(newEntry.id, pass(function(removedEntry) { + assertEq(removedEntry, newEntry), + readingList.getEntries(pass(function(entries) { + assertEq([], entries); + })); + })); + })); + })); + }, + + function addInvalidUrl() { + readingList.addEntry({url: "www.google.com"}, + fail("Invalid url specified.")); + }, + + function removeNonExistentEntry() { + readingList.removeEntry("lkj", pass(function(removedEntry) { + assertEq(undefined, removedEntry); + })); + } +]; + +chrome.test.runTests(tests); diff --git a/components/components_tests.gyp b/components/components_tests.gyp index d16e68b..291b548 100644 --- a/components/components_tests.gyp +++ b/components/components_tests.gyp @@ -31,12 +31,6 @@ 'dom_distiller/core/dom_distiller_model_unittest.cc', 'dom_distiller/core/dom_distiller_service_unittest.cc', 'dom_distiller/core/dom_distiller_store_unittest.cc', - 'dom_distiller/core/dom_distiller_test_util.cc', - 'dom_distiller/core/dom_distiller_test_util.h', - 'dom_distiller/core/fake_db.cc', - 'dom_distiller/core/fake_db.h', - 'dom_distiller/core/fake_distiller.cc', - 'dom_distiller/core/fake_distiller.h', 'dom_distiller/core/task_tracker_unittest.cc', 'json_schema/json_schema_validator_unittest.cc', 'json_schema/json_schema_validator_unittest_base.cc', @@ -97,6 +91,7 @@ # Dependencies of dom_distiller 'components.gyp:distilled_page_proto', 'components.gyp:dom_distiller_core', + 'components.gyp:dom_distiller_test_support', # Dependencies of encryptor 'components.gyp:encryptor', diff --git a/components/dom_distiller.gypi b/components/dom_distiller.gypi index 3966835..978fddf 100644 --- a/components/dom_distiller.gypi +++ b/components/dom_distiller.gypi @@ -89,6 +89,26 @@ ], }, { + 'target_name': 'dom_distiller_test_support', + 'type': 'static_library', + 'dependencies': [ + 'dom_distiller_core', + '../sync/sync.gyp:sync', + '../testing/gmock.gyp:gmock', + ], + 'include_dirs': [ + '..', + ], + 'sources': [ + 'dom_distiller/core/dom_distiller_test_util.cc', + 'dom_distiller/core/dom_distiller_test_util.h', + 'dom_distiller/core/fake_db.cc', + 'dom_distiller/core/fake_db.h', + 'dom_distiller/core/fake_distiller.cc', + 'dom_distiller/core/fake_distiller.h', + ], + }, + { 'target_name': 'distilled_page_proto', 'type': 'static_library', 'sources': [ diff --git a/components/dom_distiller/core/dom_distiller_service.cc b/components/dom_distiller/core/dom_distiller_service.cc index 65791c4f..797827b 100644 --- a/components/dom_distiller/core/dom_distiller_service.cc +++ b/components/dom_distiller/core/dom_distiller_service.cc @@ -87,19 +87,22 @@ std::vector<ArticleEntry> DomDistillerService::GetEntries() const { return store_->GetEntries(); } -void DomDistillerService::RemoveEntry( +scoped_ptr<ArticleEntry> DomDistillerService::RemoveEntry( const std::string& entry_id) { - ArticleEntry entry; - if (!store_->GetEntryById(entry_id, &entry)) { - return; + scoped_ptr<ArticleEntry> entry(new ArticleEntry); + if (!store_->GetEntryById(entry_id, entry.get())) { + return scoped_ptr<ArticleEntry>(); } - TaskTracker* task_tracker = GetTaskTrackerForEntry(entry); + TaskTracker* task_tracker = GetTaskTrackerForEntry(*entry); if (task_tracker != NULL) { task_tracker->CancelSaveCallbacks(); } - store_->RemoveEntry(entry); + if (store_->RemoveEntry(*entry)) { + return entry.Pass(); + } + return scoped_ptr<ArticleEntry>(); } scoped_ptr<ViewerHandle> DomDistillerService::ViewEntry( diff --git a/components/dom_distiller/core/dom_distiller_service.h b/components/dom_distiller/core/dom_distiller_service.h index d730cf6..ed045cd 100644 --- a/components/dom_distiller/core/dom_distiller_service.h +++ b/components/dom_distiller/core/dom_distiller_service.h @@ -51,7 +51,7 @@ class DomDistillerService { std::vector<ArticleEntry> GetEntries() const; // Removes the specified entry from the dom distiller store. - void RemoveEntry(const std::string& entry_id); + scoped_ptr<ArticleEntry> RemoveEntry(const std::string& entry_id); // Request to view an article by entry id. Returns a null pointer if no entry // with |entry_id| exists. The ViewerHandle should be destroyed before the diff --git a/components/dom_distiller/core/dom_distiller_service_unittest.cc b/components/dom_distiller/core/dom_distiller_service_unittest.cc index e010821..4719cd2 100644 --- a/components/dom_distiller/core/dom_distiller_service_unittest.cc +++ b/components/dom_distiller/core/dom_distiller_service_unittest.cc @@ -5,6 +5,7 @@ #include "components/dom_distiller/core/dom_distiller_service.h" #include "base/bind.h" +#include "base/callback.h" #include "base/containers/hash_tables.h" #include "base/message_loop/message_loop.h" #include "base/run_loop.h" @@ -90,7 +91,7 @@ class DomDistillerServiceTest : public testing::Test { }; TEST_F(DomDistillerServiceTest, TestViewEntry) { - FakeDistiller* distiller = new FakeDistiller(); + FakeDistiller* distiller = new FakeDistiller(false); EXPECT_CALL(*distiller_factory_, CreateDistillerImpl()) .WillOnce(Return(distiller)); @@ -115,7 +116,7 @@ TEST_F(DomDistillerServiceTest, TestViewEntry) { } TEST_F(DomDistillerServiceTest, TestViewUrl) { - FakeDistiller* distiller = new FakeDistiller(); + FakeDistiller* distiller = new FakeDistiller(false); EXPECT_CALL(*distiller_factory_, CreateDistillerImpl()) .WillOnce(Return(distiller)); @@ -133,8 +134,8 @@ TEST_F(DomDistillerServiceTest, TestViewUrl) { } TEST_F(DomDistillerServiceTest, TestMultipleViewUrl) { - FakeDistiller* distiller = new FakeDistiller(); - FakeDistiller* distiller2 = new FakeDistiller(); + FakeDistiller* distiller = new FakeDistiller(false); + FakeDistiller* distiller2 = new FakeDistiller(false); EXPECT_CALL(*distiller_factory_, CreateDistillerImpl()) .WillOnce(Return(distiller)) .WillOnce(Return(distiller2)); @@ -166,7 +167,7 @@ TEST_F(DomDistillerServiceTest, TestMultipleViewUrl) { } TEST_F(DomDistillerServiceTest, TestViewUrlCancelled) { - FakeDistiller* distiller = new FakeDistiller(); + FakeDistiller* distiller = new FakeDistiller(false); EXPECT_CALL(*distiller_factory_, CreateDistillerImpl()) .WillOnce(Return(distiller)); @@ -191,7 +192,7 @@ TEST_F(DomDistillerServiceTest, TestViewUrlCancelled) { } TEST_F(DomDistillerServiceTest, TestAddAndRemoveEntry) { - FakeDistiller* distiller = new FakeDistiller(); + FakeDistiller* distiller = new FakeDistiller(false); EXPECT_CALL(*distiller_factory_, CreateDistillerImpl()) .WillOnce(Return(distiller)); @@ -220,7 +221,7 @@ TEST_F(DomDistillerServiceTest, TestAddAndRemoveEntry) { } TEST_F(DomDistillerServiceTest, TestCancellation) { - FakeDistiller* distiller = new FakeDistiller(); + FakeDistiller* distiller = new FakeDistiller(false); MockDistillerObserver observer; service_->AddObserver(&observer); @@ -251,7 +252,7 @@ TEST_F(DomDistillerServiceTest, TestCancellation) { } TEST_F(DomDistillerServiceTest, TestMultipleObservers) { - FakeDistiller* distiller = new FakeDistiller(); + FakeDistiller* distiller = new FakeDistiller(false); EXPECT_CALL(*distiller_factory_, CreateDistillerImpl()) .WillOnce(Return(distiller)); @@ -297,7 +298,7 @@ TEST_F(DomDistillerServiceTest, TestMultipleObservers) { } TEST_F(DomDistillerServiceTest, TestMultipleCallbacks) { - FakeDistiller* distiller = new FakeDistiller(); + FakeDistiller* distiller = new FakeDistiller(false); EXPECT_CALL(*distiller_factory_, CreateDistillerImpl()) .WillOnce(Return(distiller)); @@ -329,7 +330,7 @@ TEST_F(DomDistillerServiceTest, TestMultipleCallbacks) { } TEST_F(DomDistillerServiceTest, TestMultipleCallbacksOnRemove) { - FakeDistiller* distiller = new FakeDistiller(); + FakeDistiller* distiller = new FakeDistiller(false); EXPECT_CALL(*distiller_factory_, CreateDistillerImpl()) .WillOnce(Return(distiller)); diff --git a/components/dom_distiller/core/fake_distiller.cc b/components/dom_distiller/core/fake_distiller.cc index 93659b3..3f1f976 100644 --- a/components/dom_distiller/core/fake_distiller.cc +++ b/components/dom_distiller/core/fake_distiller.cc @@ -14,7 +14,8 @@ namespace test { MockDistillerFactory::MockDistillerFactory() {} MockDistillerFactory::~MockDistillerFactory() {} -FakeDistiller::FakeDistiller() { +FakeDistiller::FakeDistiller(bool execute_callback) : + execute_callback_(execute_callback) { EXPECT_CALL(*this, Die()).Times(testing::AnyNumber()); } diff --git a/components/dom_distiller/core/fake_distiller.h b/components/dom_distiller/core/fake_distiller.h index ef9126c..dbb00d6 100644 --- a/components/dom_distiller/core/fake_distiller.h +++ b/components/dom_distiller/core/fake_distiller.h @@ -27,7 +27,7 @@ class MockDistillerFactory : public DistillerFactory { class FakeDistiller : public Distiller { public: - FakeDistiller(); + FakeDistiller(bool execute_callback); virtual ~FakeDistiller(); MOCK_METHOD0(Die, void()); @@ -35,6 +35,9 @@ class FakeDistiller : public Distiller { const DistillerCallback& callback) OVERRIDE { url_ = url; callback_ = callback; + if (execute_callback_) { + RunDistillerCallback(make_scoped_ptr(new DistilledPageProto)); + } } void RunDistillerCallback(scoped_ptr<DistilledPageProto> proto); @@ -46,6 +49,7 @@ class FakeDistiller : public Distiller { private: void RunDistillerCallbackInternal(scoped_ptr<DistilledPageProto> proto); + bool execute_callback_; GURL url_; DistillerCallback callback_; }; diff --git a/components/dom_distiller/core/task_tracker_unittest.cc b/components/dom_distiller/core/task_tracker_unittest.cc index 2d3ad8a..f659fc1 100644 --- a/components/dom_distiller/core/task_tracker_unittest.cc +++ b/components/dom_distiller/core/task_tracker_unittest.cc @@ -119,7 +119,7 @@ TEST_F(DomDistillerTaskTrackerTest, TestViewerCancelledWithSaveRequest) { TEST_F(DomDistillerTaskTrackerTest, TestViewerNotifiedOnDistillationComplete) { MockDistillerFactory distiller_factory; - FakeDistiller* distiller = new FakeDistiller(); + FakeDistiller* distiller = new FakeDistiller(true); EXPECT_CALL(distiller_factory, CreateDistillerImpl()) .WillOnce(Return(distiller)); TestCancelCallback cancel_callback; @@ -132,7 +132,6 @@ TEST_F(DomDistillerTaskTrackerTest, TestViewerNotifiedOnDistillationComplete) { EXPECT_CALL(viewer_delegate, OnArticleReady(_)); task_tracker.StartDistiller(&distiller_factory); - distiller->RunDistillerCallback(make_scoped_ptr(new DistilledPageProto)); base::RunLoop().RunUntilIdle(); EXPECT_FALSE(cancel_callback.Cancelled()); @@ -141,7 +140,7 @@ TEST_F(DomDistillerTaskTrackerTest, TestViewerNotifiedOnDistillationComplete) { TEST_F(DomDistillerTaskTrackerTest, TestSaveCallbackCalledOnDistillationComplete) { MockDistillerFactory distiller_factory; - FakeDistiller* distiller = new FakeDistiller(); + FakeDistiller* distiller = new FakeDistiller(true); EXPECT_CALL(distiller_factory, CreateDistillerImpl()) .WillOnce(Return(distiller)); TestCancelCallback cancel_callback; @@ -155,7 +154,6 @@ TEST_F(DomDistillerTaskTrackerTest, EXPECT_CALL(save_callback, Save(_, _, _)); task_tracker.StartDistiller(&distiller_factory); - distiller->RunDistillerCallback(make_scoped_ptr(new DistilledPageProto)); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(cancel_callback.Cancelled()); diff --git a/extensions/common/permissions/api_permission.h b/extensions/common/permissions/api_permission.h index 123a05a..4e33d3b 100644 --- a/extensions/common/permissions/api_permission.h +++ b/extensions/common/permissions/api_permission.h @@ -126,6 +126,7 @@ class APIPermission { kProxy, kPushMessaging, kImageWriterPrivate, + kReadingListPrivate, kRtcPrivate, kSearchProvider, kSerial, |