Commit 46258935 authored by pmarch@chromium.org's avatar pmarch@chromium.org

Introducing the activityLogPrivate.deleteActivities() API

call. The call takes an array of activity IDs (each activity
ID is a string) and deletes the matching activities form the
Activity Log database.

BUG=330210

Review URL: https://codereview.chromium.org/154053004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@251311 0039d316-1c4b-4281-b951-d872f2087c98
parent 05a79236
...@@ -660,6 +660,12 @@ void ActivityLog::GetFilteredActions( ...@@ -660,6 +660,12 @@ void ActivityLog::GetFilteredActions(
// DELETE ACTIONS. ------------------------------------------------------------- // DELETE ACTIONS. -------------------------------------------------------------
void ActivityLog::RemoveActions(const std::vector<int64>& action_ids) {
if (!database_policy_)
return;
database_policy_->RemoveActions(action_ids);
}
void ActivityLog::RemoveURLs(const std::vector<GURL>& restrict_urls) { void ActivityLog::RemoveURLs(const std::vector<GURL>& restrict_urls) {
if (!database_policy_) if (!database_policy_)
return; return;
......
...@@ -112,6 +112,10 @@ class ActivityLog : public BrowserContextKeyedService, ...@@ -112,6 +112,10 @@ class ActivityLog : public BrowserContextKeyedService,
static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
// Remove actions from the activity log database which IDs specified in the
// action_ids array.
void RemoveActions(const std::vector<int64>& action_ids);
// Clean up URLs from the activity log database. // Clean up URLs from the activity log database.
// If restrict_urls is empty then all URLs in the activity log database are // If restrict_urls is empty then all URLs in the activity log database are
// removed, otherwise only those in restrict_urls are removed. // removed, otherwise only those in restrict_urls are removed.
......
...@@ -177,6 +177,9 @@ class ActivityLogDatabasePolicy : public ActivityLogPolicy, ...@@ -177,6 +177,9 @@ class ActivityLogDatabasePolicy : public ActivityLogPolicy,
const base::Callback const base::Callback
<void(scoped_ptr<Action::ActionVector>)>& callback) = 0; <void(scoped_ptr<Action::ActionVector>)>& callback) = 0;
// Remove actions (rows) which IDs are in the action_ids array.
virtual void RemoveActions(const std::vector<int64>& action_ids) = 0;
// Clean the relevant URL data. The cleaning may need to be different for // Clean the relevant URL data. The cleaning may need to be different for
// different policies. If restrict_urls is empty then all URLs are removed. // different policies. If restrict_urls is empty then all URLs are removed.
virtual void RemoveURLs(const std::vector<GURL>& restrict_urls) = 0; virtual void RemoveURLs(const std::vector<GURL>& restrict_urls) = 0;
......
...@@ -518,6 +518,44 @@ scoped_ptr<Action::ActionVector> CountingPolicy::DoReadFilteredData( ...@@ -518,6 +518,44 @@ scoped_ptr<Action::ActionVector> CountingPolicy::DoReadFilteredData(
return actions.Pass(); return actions.Pass();
} }
void CountingPolicy::DoRemoveActions(const std::vector<int64>& action_ids) {
if (action_ids.empty())
return;
sql::Connection* db = GetDatabaseConnection();
if (!db) {
LOG(ERROR) << "Unable to connect to database";
return;
}
// Flush data first so the activity removal affects queued-up data as well.
activity_database()->AdviseFlush(ActivityDatabase::kFlushImmediately);
sql::Transaction transaction(db);
if (!transaction.Begin())
return;
std::string statement_str =
base::StringPrintf("DELETE FROM %s WHERE rowid = ?", kTableName);
sql::Statement statement(db->GetCachedStatement(
sql::StatementID(SQL_FROM_HERE), statement_str.c_str()));
for (size_t i = 0; i < action_ids.size(); i++) {
statement.Reset(true);
statement.BindInt64(0, action_ids[i]);
if (!statement.Run()) {
LOG(ERROR) << "Removing activities from database failed: "
<< statement.GetSQLStatement();
break;
}
}
CleanStringTables(db);
if (!transaction.Commit()) {
LOG(ERROR) << "Removing activities from database failed";
}
}
void CountingPolicy::DoRemoveURLs(const std::vector<GURL>& restrict_urls) { void CountingPolicy::DoRemoveURLs(const std::vector<GURL>& restrict_urls) {
sql::Connection* db = GetDatabaseConnection(); sql::Connection* db = GetDatabaseConnection();
if (!db) { if (!db) {
...@@ -694,6 +732,10 @@ void CountingPolicy::ReadFilteredData( ...@@ -694,6 +732,10 @@ void CountingPolicy::ReadFilteredData(
callback); callback);
} }
void CountingPolicy::RemoveActions(const std::vector<int64>& action_ids) {
ScheduleAndForget(this, &CountingPolicy::DoRemoveActions, action_ids);
}
void CountingPolicy::RemoveURLs(const std::vector<GURL>& restrict_urls) { void CountingPolicy::RemoveURLs(const std::vector<GURL>& restrict_urls) {
ScheduleAndForget(this, &CountingPolicy::DoRemoveURLs, restrict_urls); ScheduleAndForget(this, &CountingPolicy::DoRemoveURLs, restrict_urls);
} }
......
...@@ -45,6 +45,9 @@ class CountingPolicy : public ActivityLogDatabasePolicy { ...@@ -45,6 +45,9 @@ class CountingPolicy : public ActivityLogDatabasePolicy {
retention_time_ = delta; retention_time_ = delta;
} }
// Remove actions (rows) which IDs are specified in the action_ids array.
virtual void RemoveActions(const std::vector<int64>& action_ids) OVERRIDE;
// Clean the URL data stored for this policy. // Clean the URL data stored for this policy.
virtual void RemoveURLs(const std::vector<GURL>&) OVERRIDE; virtual void RemoveURLs(const std::vector<GURL>&) OVERRIDE;
...@@ -91,6 +94,10 @@ class CountingPolicy : public ActivityLogDatabasePolicy { ...@@ -91,6 +94,10 @@ class CountingPolicy : public ActivityLogDatabasePolicy {
const std::string& arg_url, const std::string& arg_url,
const int days_ago); const int days_ago);
// The implementation of RemoveActions; this must only run on the database
// thread.
void DoRemoveActions(const std::vector<int64>& action_ids);
// The implementation of RemoveURLs; this must only run on the database // The implementation of RemoveURLs; this must only run on the database
// thread. // thread.
void DoRemoveURLs(const std::vector<GURL>& restrict_urls); void DoRemoveURLs(const std::vector<GURL>& restrict_urls);
......
...@@ -296,6 +296,107 @@ class CountingPolicyTest : public testing::Test { ...@@ -296,6 +296,107 @@ class CountingPolicyTest : public testing::Test {
ASSERT_NE(-1, action.action_id()); ASSERT_NE(-1, action.action_id());
} }
// A helper function initializes the policy with a number of actions, calls
// RemoveActions on a policy object and then checks the result of the
// deletion.
void CheckRemoveActions(
ActivityLogDatabasePolicy* policy,
const std::vector<int64>& action_ids,
const base::Callback<void(scoped_ptr<Action::ActionVector>)>& checker) {
// Record some actions
scoped_refptr<Action> action = new Action(
"punky1", base::Time::Now(), Action::ACTION_DOM_ACCESS, "lets1");
action->mutable_args()->AppendString("vamoose1");
action->set_page_url(GURL("http://www.google1.com"));
action->set_page_title("Google1");
action->set_arg_url(GURL("http://www.args-url1.com"));
policy->ProcessAction(action);
// Record the same action twice, so there are multiple entries in the
// database.
policy->ProcessAction(action);
action = new Action(
"punky2", base::Time::Now(), Action::ACTION_API_CALL, "lets2");
action->mutable_args()->AppendString("vamoose2");
action->set_page_url(GURL("http://www.google2.com"));
action->set_page_title("Google2");
action->set_arg_url(GURL("http://www.args-url2.com"));
policy->ProcessAction(action);
// Record the same action twice, so there are multiple entries in the
// database.
policy->ProcessAction(action);
// Submit a request to delete actions.
policy->RemoveActions(action_ids);
// Check the result of the deletion. The checker function gets all
// activities in the database.
CheckReadData(policy, "", -1, checker);
// Clean database.
policy->DeleteDatabase();
}
static void AllActionsDeleted(scoped_ptr<Action::ActionVector> actions) {
ASSERT_EQ(0, static_cast<int>(actions->size()));
}
static void NoActionsDeleted(scoped_ptr<Action::ActionVector> actions) {
// These will be in the vector in reverse time order.
ASSERT_EQ(2, static_cast<int>(actions->size()));
CheckAction(*actions->at(0),
"punky2",
Action::ACTION_API_CALL,
"lets2",
"",
"http://www.google2.com/",
"Google2",
"http://www.args-url2.com/",
2);
ASSERT_EQ(2, actions->at(0)->action_id());
CheckAction(*actions->at(1),
"punky1",
Action::ACTION_DOM_ACCESS,
"lets1",
"",
"http://www.google1.com/",
"Google1",
"http://www.args-url1.com/",
2);
ASSERT_EQ(1, actions->at(1)->action_id());
}
static void Action1Deleted(scoped_ptr<Action::ActionVector> actions) {
// These will be in the vector in reverse time order.
ASSERT_EQ(1, static_cast<int>(actions->size()));
CheckAction(*actions->at(0),
"punky2",
Action::ACTION_API_CALL,
"lets2",
"",
"http://www.google2.com/",
"Google2",
"http://www.args-url2.com/",
2);
ASSERT_EQ(2, actions->at(0)->action_id());
}
static void Action2Deleted(scoped_ptr<Action::ActionVector> actions) {
// These will be in the vector in reverse time order.
ASSERT_EQ(1, static_cast<int>(actions->size()));
CheckAction(*actions->at(0),
"punky1",
Action::ACTION_DOM_ACCESS,
"lets1",
"",
"http://www.google1.com/",
"Google1",
"http://www.args-url1.com/",
2);
ASSERT_EQ(1, actions->at(0)->action_id());
}
protected: protected:
ExtensionService* extension_service_; ExtensionService* extension_service_;
scoped_ptr<TestingProfile> profile_; scoped_ptr<TestingProfile> profile_;
...@@ -1008,7 +1109,7 @@ TEST_F(CountingPolicyTest, RemoveExtensionData) { ...@@ -1008,7 +1109,7 @@ TEST_F(CountingPolicyTest, RemoveExtensionData) {
policy->Close(); policy->Close();
} }
TEST_F(CountingPolicyTest, DeleteActions) { TEST_F(CountingPolicyTest, DeleteDatabase) {
CountingPolicy* policy = new CountingPolicy(profile_.get()); CountingPolicy* policy = new CountingPolicy(profile_.get());
policy->Init(); policy->Init();
// Disable row expiration for this test by setting a time before any actions // Disable row expiration for this test by setting a time before any actions
...@@ -1152,4 +1253,50 @@ TEST_F(CountingPolicyTest, DuplicateRows) { ...@@ -1152,4 +1253,50 @@ TEST_F(CountingPolicyTest, DuplicateRows) {
policy->Close(); policy->Close();
} }
TEST_F(CountingPolicyTest, RemoveActions) {
ActivityLogDatabasePolicy* policy = new CountingPolicy(profile_.get());
policy->Init();
std::vector<int64> action_ids;
CheckRemoveActions(
policy, action_ids, base::Bind(&CountingPolicyTest::NoActionsDeleted));
action_ids.push_back(-1);
action_ids.push_back(-10);
action_ids.push_back(0);
action_ids.push_back(5);
action_ids.push_back(10);
CheckRemoveActions(
policy, action_ids, base::Bind(&CountingPolicyTest::NoActionsDeleted));
action_ids.clear();
for (int i = 0; i < 50; i++) {
action_ids.push_back(i + 3);
}
CheckRemoveActions(
policy, action_ids, base::Bind(&CountingPolicyTest::NoActionsDeleted));
action_ids.clear();
// CheckRemoveActions pushes two actions to the Activity Log database with IDs
// 1 and 2.
action_ids.push_back(1);
action_ids.push_back(2);
CheckRemoveActions(
policy, action_ids, base::Bind(&CountingPolicyTest::AllActionsDeleted));
action_ids.clear();
action_ids.push_back(1);
CheckRemoveActions(
policy, action_ids, base::Bind(&CountingPolicyTest::Action1Deleted));
action_ids.clear();
action_ids.push_back(2);
CheckRemoveActions(
policy, action_ids, base::Bind(&CountingPolicyTest::Action2Deleted));
action_ids.clear();
policy->Close();
}
} // namespace extensions } // namespace extensions
...@@ -220,6 +220,42 @@ scoped_ptr<Action::ActionVector> FullStreamUIPolicy::DoReadFilteredData( ...@@ -220,6 +220,42 @@ scoped_ptr<Action::ActionVector> FullStreamUIPolicy::DoReadFilteredData(
return actions.Pass(); return actions.Pass();
} }
void FullStreamUIPolicy::DoRemoveActions(const std::vector<int64>& action_ids) {
if (action_ids.empty())
return;
sql::Connection* db = GetDatabaseConnection();
if (!db) {
LOG(ERROR) << "Unable to connect to database";
return;
}
// Flush data first so the activity removal affects queued-up data as well.
activity_database()->AdviseFlush(ActivityDatabase::kFlushImmediately);
sql::Transaction transaction(db);
if (!transaction.Begin())
return;
std::string statement_str =
base::StringPrintf("DELETE FROM %s WHERE rowid = ?", kTableName);
sql::Statement statement(db->GetCachedStatement(
sql::StatementID(SQL_FROM_HERE), statement_str.c_str()));
for (size_t i = 0; i < action_ids.size(); i++) {
statement.Reset(true);
statement.BindInt64(0, action_ids[i]);
if (!statement.Run()) {
LOG(ERROR) << "Removing activities from database failed: "
<< statement.GetSQLStatement();
return;
}
}
if (!transaction.Commit()) {
LOG(ERROR) << "Removing activities from database failed";
}
}
void FullStreamUIPolicy::DoRemoveURLs(const std::vector<GURL>& restrict_urls) { void FullStreamUIPolicy::DoRemoveURLs(const std::vector<GURL>& restrict_urls) {
sql::Connection* db = GetDatabaseConnection(); sql::Connection* db = GetDatabaseConnection();
if (!db) { if (!db) {
...@@ -374,6 +410,10 @@ void FullStreamUIPolicy::ReadFilteredData( ...@@ -374,6 +410,10 @@ void FullStreamUIPolicy::ReadFilteredData(
callback); callback);
} }
void FullStreamUIPolicy::RemoveActions(const std::vector<int64>& action_ids) {
ScheduleAndForget(this, &FullStreamUIPolicy::DoRemoveActions, action_ids);
}
void FullStreamUIPolicy::RemoveURLs(const std::vector<GURL>& restrict_urls) { void FullStreamUIPolicy::RemoveURLs(const std::vector<GURL>& restrict_urls) {
ScheduleAndForget(this, &FullStreamUIPolicy::DoRemoveURLs, restrict_urls); ScheduleAndForget(this, &FullStreamUIPolicy::DoRemoveURLs, restrict_urls);
} }
......
...@@ -40,6 +40,9 @@ class FullStreamUIPolicy : public ActivityLogDatabasePolicy { ...@@ -40,6 +40,9 @@ class FullStreamUIPolicy : public ActivityLogDatabasePolicy {
virtual void Close() OVERRIDE; virtual void Close() OVERRIDE;
// Remove the actions stored for this policy according to the passed IDs.
virtual void RemoveActions(const std::vector<int64>& action_ids) OVERRIDE;
// Clean the URL data stored for this policy. // Clean the URL data stored for this policy.
virtual void RemoveURLs(const std::vector<GURL>& restrict_urls) OVERRIDE; virtual void RemoveURLs(const std::vector<GURL>& restrict_urls) OVERRIDE;
...@@ -73,6 +76,10 @@ class FullStreamUIPolicy : public ActivityLogDatabasePolicy { ...@@ -73,6 +76,10 @@ class FullStreamUIPolicy : public ActivityLogDatabasePolicy {
virtual scoped_refptr<Action> ProcessArguments( virtual scoped_refptr<Action> ProcessArguments(
scoped_refptr<Action> action) const; scoped_refptr<Action> action) const;
// The implementation of RemoveActions; this must only run on the database
// thread.
void DoRemoveActions(const std::vector<int64>& action_ids);
// The implementation of RemoveURLs; this must only run on the database // The implementation of RemoveURLs; this must only run on the database
// thread. // thread.
void DoRemoveURLs(const std::vector<GURL>& restrict_urls); void DoRemoveURLs(const std::vector<GURL>& restrict_urls);
......
...@@ -221,6 +221,139 @@ class FullStreamUIPolicyTest : public testing::Test { ...@@ -221,6 +221,139 @@ class FullStreamUIPolicyTest : public testing::Test {
ASSERT_NE(-1, action.action_id()); ASSERT_NE(-1, action.action_id());
} }
// A helper function initializes the policy with a number of actions, calls
// RemoveActions on a policy object and then checks the result of the
// deletion.
void CheckRemoveActions(
ActivityLogDatabasePolicy* policy,
const std::vector<int64>& action_ids,
const base::Callback<void(scoped_ptr<Action::ActionVector>)>& checker) {
// Record some actions
scoped_refptr<Action> action = new Action(
"punky1", base::Time::Now(), Action::ACTION_DOM_ACCESS, "lets1");
action->mutable_args()->AppendString("vamoose1");
action->set_page_url(GURL("http://www.google1.com"));
action->set_page_title("Google1");
action->set_arg_url(GURL("http://www.args-url1.com"));
policy->ProcessAction(action);
// Record the same action twice, so there are multiple entries in the
// database.
policy->ProcessAction(action);
action = new Action(
"punky2", base::Time::Now(), Action::ACTION_API_CALL, "lets2");
action->mutable_args()->AppendString("vamoose2");
action->set_page_url(GURL("http://www.google2.com"));
action->set_page_title("Google2");
action->set_arg_url(GURL("http://www.args-url2.com"));
policy->ProcessAction(action);
// Record the same action twice, so there are multiple entries in the
// database.
policy->ProcessAction(action);
// Submit a request to delete actions.
policy->RemoveActions(action_ids);
// Check the result of the deletion. The checker function gets all
// activities in the database.
CheckReadData(policy, "", -1, checker);
// Clean database.
policy->DeleteDatabase();
}
static void AllActionsDeleted(scoped_ptr<Action::ActionVector> actions) {
ASSERT_EQ(0, static_cast<int>(actions->size()));
}
static void NoActionsDeleted(scoped_ptr<Action::ActionVector> actions) {
// These will be in the vector in reverse time order.
ASSERT_EQ(4, static_cast<int>(actions->size()));
CheckAction(*actions->at(0),
"punky2",
Action::ACTION_API_CALL,
"lets2",
"[\"vamoose2\"]",
"http://www.google2.com/",
"Google2",
"http://www.args-url2.com/");
ASSERT_EQ(3, actions->at(0)->action_id());
CheckAction(*actions->at(1),
"punky2",
Action::ACTION_API_CALL,
"lets2",
"[\"vamoose2\"]",
"http://www.google2.com/",
"Google2",
"http://www.args-url2.com/");
ASSERT_EQ(4, actions->at(1)->action_id());
CheckAction(*actions->at(2),
"punky1",
Action::ACTION_DOM_ACCESS,
"lets1",
"[\"vamoose1\"]",
"http://www.google1.com/",
"Google1",
"http://www.args-url1.com/");
ASSERT_EQ(1, actions->at(2)->action_id());
CheckAction(*actions->at(3),
"punky1",
Action::ACTION_DOM_ACCESS,
"lets1",
"[\"vamoose1\"]",
"http://www.google1.com/",
"Google1",
"http://www.args-url1.com/");
ASSERT_EQ(2, actions->at(3)->action_id());
}
static void Action1Deleted(scoped_ptr<Action::ActionVector> actions) {
// These will be in the vector in reverse time order.
ASSERT_EQ(2, static_cast<int>(actions->size()));
CheckAction(*actions->at(0),
"punky2",
Action::ACTION_API_CALL,
"lets2",
"[\"vamoose2\"]",
"http://www.google2.com/",
"Google2",
"http://www.args-url2.com/");
ASSERT_EQ(3, actions->at(0)->action_id());
CheckAction(*actions->at(1),
"punky2",
Action::ACTION_API_CALL,
"lets2",
"[\"vamoose2\"]",
"http://www.google2.com/",
"Google2",
"http://www.args-url2.com/");
ASSERT_EQ(4, actions->at(1)->action_id());
}
static void Action2Deleted(scoped_ptr<Action::ActionVector> actions) {
// These will be in the vector in reverse time order.
ASSERT_EQ(2, static_cast<int>(actions->size()));
CheckAction(*actions->at(0),
"punky1",
Action::ACTION_DOM_ACCESS,
"lets1",
"[\"vamoose1\"]",
"http://www.google1.com/",
"Google1",
"http://www.args-url1.com/");
ASSERT_EQ(1, actions->at(0)->action_id());
CheckAction(*actions->at(1),
"punky1",
Action::ACTION_DOM_ACCESS,
"lets1",
"[\"vamoose1\"]",
"http://www.google1.com/",
"Google1",
"http://www.args-url1.com/");
ASSERT_EQ(2, actions->at(1)->action_id());
}
protected: protected:
ExtensionService* extension_service_; ExtensionService* extension_service_;
scoped_ptr<TestingProfile> profile_; scoped_ptr<TestingProfile> profile_;
...@@ -738,7 +871,7 @@ TEST_F(FullStreamUIPolicyTest, CapReturns) { ...@@ -738,7 +871,7 @@ TEST_F(FullStreamUIPolicyTest, CapReturns) {
policy->Close(); policy->Close();
} }
TEST_F(FullStreamUIPolicyTest, DeleteActions) { TEST_F(FullStreamUIPolicyTest, DeleteDatabase) {
ActivityLogDatabasePolicy* policy = new FullStreamUIPolicy(profile_.get()); ActivityLogDatabasePolicy* policy = new FullStreamUIPolicy(profile_.get());
policy->Init(); policy->Init();
scoped_refptr<const Extension> extension = scoped_refptr<const Extension> extension =
...@@ -790,4 +923,58 @@ TEST_F(FullStreamUIPolicyTest, DeleteActions) { ...@@ -790,4 +923,58 @@ TEST_F(FullStreamUIPolicyTest, DeleteActions) {
policy->Close(); policy->Close();
} }
TEST_F(FullStreamUIPolicyTest, RemoveActions) {
ActivityLogDatabasePolicy* policy = new FullStreamUIPolicy(profile_.get());
policy->Init();
std::vector<int64> action_ids;
CheckRemoveActions(policy,
action_ids,
base::Bind(&FullStreamUIPolicyTest::NoActionsDeleted));
action_ids.push_back(-1);
action_ids.push_back(-10);
action_ids.push_back(0);
action_ids.push_back(5);
action_ids.push_back(10);
CheckRemoveActions(policy,
action_ids,
base::Bind(&FullStreamUIPolicyTest::NoActionsDeleted));
action_ids.clear();
for (int i = 0; i < 50; i++) {
action_ids.push_back(i + 5);
}
CheckRemoveActions(policy,
action_ids,
base::Bind(&FullStreamUIPolicyTest::NoActionsDeleted));
action_ids.clear();
// CheckRemoveActions pushes four actions to the Activity Log database with
// IDs 1, 2, 3, and 4.
action_ids.push_back(1);
action_ids.push_back(2);
action_ids.push_back(3);
action_ids.push_back(4);
CheckRemoveActions(policy,
action_ids,
base::Bind(&FullStreamUIPolicyTest::AllActionsDeleted));
action_ids.clear();
action_ids.push_back(1);
action_ids.push_back(2);
CheckRemoveActions(
policy, action_ids, base::Bind(&FullStreamUIPolicyTest::Action1Deleted));
action_ids.clear();
action_ids.push_back(3);
action_ids.push_back(4);
CheckRemoveActions(
policy, action_ids, base::Bind(&FullStreamUIPolicyTest::Action2Deleted));
action_ids.clear();
policy->Close();
}
} // namespace extensions } // namespace extensions
...@@ -176,6 +176,25 @@ void ActivityLogPrivateGetExtensionActivitiesFunction::OnLookupCompleted( ...@@ -176,6 +176,25 @@ void ActivityLogPrivateGetExtensionActivitiesFunction::OnLookupCompleted(
SendResponse(true); SendResponse(true);
} }
bool ActivityLogPrivateDeleteActivitiesFunction::RunImpl() {
scoped_ptr<activity_log_private::DeleteActivities::Params> params(
activity_log_private::DeleteActivities::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params.get());
// Put the arguments in the right format.
std::vector<int64> action_ids;
int64 value;
for (size_t i = 0; i < params->activity_ids.size(); i++) {
if (base::StringToInt64(params->activity_ids[i], &value))
action_ids.push_back(value);
}
ActivityLog* activity_log = ActivityLog::GetInstance(GetProfile());
DCHECK(activity_log);
activity_log->RemoveActions(action_ids);
return true;
}
bool ActivityLogPrivateDeleteDatabaseFunction::RunImpl() { bool ActivityLogPrivateDeleteDatabaseFunction::RunImpl() {
ActivityLog* activity_log = ActivityLog::GetInstance(GetProfile()); ActivityLog* activity_log = ActivityLog::GetInstance(GetProfile());
DCHECK(activity_log); DCHECK(activity_log);
......
...@@ -77,6 +77,20 @@ class ActivityLogPrivateGetExtensionActivitiesFunction ...@@ -77,6 +77,20 @@ class ActivityLogPrivateGetExtensionActivitiesFunction
scoped_ptr<std::vector<scoped_refptr<Action> > > activities); scoped_ptr<std::vector<scoped_refptr<Action> > > activities);
}; };
// The implementation of activityLogPrivate.deleteActivities
class ActivityLogPrivateDeleteActivitiesFunction
: public ChromeAsyncExtensionFunction {
public:
DECLARE_EXTENSION_FUNCTION("activityLogPrivate.deleteActivities",
ACTIVITYLOGPRIVATE_DELETEACTIVITIES)
protected:
virtual ~ActivityLogPrivateDeleteActivitiesFunction() {}
// ExtensionFunction:
virtual bool RunImpl() OVERRIDE;
};
// The implementation of activityLogPrivate.deleteDatabase // The implementation of activityLogPrivate.deleteDatabase
class ActivityLogPrivateDeleteDatabaseFunction class ActivityLogPrivateDeleteDatabaseFunction
: public ChromeAsyncExtensionFunction { : public ChromeAsyncExtensionFunction {
......
...@@ -745,7 +745,8 @@ enum HistogramValue { ...@@ -745,7 +745,8 @@ enum HistogramValue {
WEBVIEW_GETZOOM, WEBVIEW_GETZOOM,
DEVELOPERPRIVATE_REQUESTFILESOURCE, DEVELOPERPRIVATE_REQUESTFILESOURCE,
DEVELOPERPRIVATE_OPENDEVTOOLS, DEVELOPERPRIVATE_OPENDEVTOOLS,
ENUM_BOUNDARY // Last entry: Add new entries above. ACTIVITYLOGPRIVATE_DELETEACTIVITIES,
ENUM_BOUNDARY // Last entry: Add new entries above.
}; };
} // namespace functions } // namespace functions
......
...@@ -79,6 +79,19 @@ ...@@ -79,6 +79,19 @@
} }
] ]
}, },
{
"name": "deleteActivities",
"type": "function",
"description": "Deletes activities in the ActivityLog database specified in the array of activity IDs.",
"parameters": [
{
"name": "activityIds",
"type": "array",
"items": { "type": "string" },
"description": "Erases only the activities which IDs are listed in the array."
}
]
},
{ {
"name": "deleteDatabase", "name": "deleteDatabase",
"type": "function", "type": "function",
......
...@@ -367,6 +367,41 @@ testCases.push({ ...@@ -367,6 +367,41 @@ testCases.push({
} }
}); });
testCases.push({
func: function deleteActivities() {
var activityIds = [];
var filter = new Object();
filter.extensionId = FRIEND_EXTENSION_ID;
filter.activityType = 'any';
filter.apiCall = 'tabs.executeScript';
chrome.activityLogPrivate.getExtensionActivities(filter, function(result) {
chrome.test.assertEq(6, result['activities'].length);
for (var i = 0; i < result['activities'].length; i++)
activityIds.push(result['activities'][i]['activityId']);
chrome.test.assertEq(6, activityIds.length);
chrome.activityLogPrivate.deleteActivities(['-1', '-2', '-3']);
chrome.activityLogPrivate.getExtensionActivities(filter,
function(result) {
chrome.test.assertEq(6, result['activities'].length);
chrome.activityLogPrivate.deleteActivities([activityIds[0]]);
chrome.activityLogPrivate.getExtensionActivities(filter,
function(result) {
chrome.test.assertEq(5, result['activities'].length);
for (var i = 0; i < result['activities'].length; i++)
chrome.test.assertFalse(activityIds[0] ==
result['activities'][i]['activityId']);
chrome.activityLogPrivate.deleteActivities(activityIds);
chrome.activityLogPrivate.getExtensionActivities(filter,
function(result) {
chrome.test.assertEq(0, result['activities'].length);
chrome.test.succeed();
});
});
});
});
}
});
testCases.push({ testCases.push({
func: function deleteGoogleUrls() { func: function deleteGoogleUrls() {
chrome.test.getConfig(function(config) { chrome.test.getConfig(function(config) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment