1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/extensions/activity_log/activity_log_policy.h"
9 #include "base/files/file_path.h"
10 #include "base/json/json_string_value_serializer.h"
11 #include "base/logging.h"
12 #include "base/strings/stringprintf.h"
13 #include "base/time/clock.h"
14 #include "base/time/time.h"
15 #include "chrome/browser/extensions/activity_log/activity_action_constants.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "content/public/browser/browser_thread.h"
18 #include "extensions/common/extension.h"
21 using content::BrowserThread
;
23 namespace constants
= activity_log_constants
;
26 // Obsolete database tables: these should be dropped from the database if
28 const char* const kObsoleteTables
[] = {"activitylog_apis",
29 "activitylog_blocked",
33 namespace extensions
{
35 ActivityLogPolicy::ActivityLogPolicy(Profile
* profile
) {}
37 ActivityLogPolicy::~ActivityLogPolicy() {}
39 void ActivityLogPolicy::SetClockForTesting(scoped_ptr
<base::Clock
> clock
) {
40 testing_clock_
.reset(clock
.release());
43 base::Time
ActivityLogPolicy::Now() const {
45 return testing_clock_
->Now();
47 return base::Time::Now();
50 ActivityLogDatabasePolicy::ActivityLogDatabasePolicy(
52 const base::FilePath
& database_name
)
53 : ActivityLogPolicy(profile
) {
55 base::FilePath profile_base_path
= profile
->GetPath();
56 db_
= new ActivityDatabase(this);
57 database_path_
= profile_base_path
.Append(database_name
);
60 void ActivityLogDatabasePolicy::Init() {
61 ScheduleAndForget(db_
, &ActivityDatabase::Init
, database_path_
);
64 void ActivityLogDatabasePolicy::Flush() {
65 ScheduleAndForget(activity_database(),
66 &ActivityDatabase::AdviseFlush
,
67 ActivityDatabase::kFlushImmediately
);
70 sql::Connection
* ActivityLogDatabasePolicy::GetDatabaseConnection() const {
71 return db_
->GetSqlConnection();
75 std::string
ActivityLogPolicy::Util::Serialize(const base::Value
* value
) {
76 std::string value_as_text
;
80 JSONStringValueSerializer
serializer(&value_as_text
);
81 serializer
.SerializeAndOmitBinaryValues(*value
);
87 void ActivityLogPolicy::Util::StripPrivacySensitiveFields(
88 scoped_refptr
<Action
> action
) {
89 // Clear incognito URLs/titles.
90 if (action
->page_incognito()) {
91 action
->set_page_url(GURL());
92 action
->set_page_title("");
93 action
->set_page_incognito(false);
95 if (action
->arg_incognito()) {
96 action
->set_arg_url(GURL());
97 action
->set_arg_incognito(false);
100 // Strip query parameters, username/password, etc., from URLs.
101 if (action
->page_url().is_valid() || action
->arg_url().is_valid()) {
102 url::Replacements
<char> url_sanitizer
;
103 url_sanitizer
.ClearUsername();
104 url_sanitizer
.ClearPassword();
105 url_sanitizer
.ClearQuery();
106 url_sanitizer
.ClearRef();
108 if (action
->page_url().is_valid())
109 action
->set_page_url(action
->page_url().ReplaceComponents(url_sanitizer
));
110 if (action
->arg_url().is_valid())
111 action
->set_arg_url(action
->arg_url().ReplaceComponents(url_sanitizer
));
114 // Clear WebRequest details; only keep a record of which types of
115 // modifications were performed.
116 if (action
->action_type() == Action::ACTION_WEB_REQUEST
) {
117 base::DictionaryValue
* details
= NULL
;
118 if (action
->mutable_other()->GetDictionary(constants::kActionWebRequest
,
120 base::DictionaryValue::Iterator
details_iterator(*details
);
121 while (!details_iterator
.IsAtEnd()) {
122 details
->SetBoolean(details_iterator
.key(), true);
123 details_iterator
.Advance();
130 void ActivityLogPolicy::Util::StripArguments(const ApiSet
& api_whitelist
,
131 scoped_refptr
<Action
> action
) {
132 if (api_whitelist
.find(
133 std::make_pair(action
->action_type(), action
->api_name())) ==
134 api_whitelist
.end()) {
135 action
->set_args(scoped_ptr
<base::ListValue
>());
140 base::Time
ActivityLogPolicy::Util::AddDays(const base::Time
& base_date
,
142 // To allow for time zone changes, add an additional partial day then round
144 return (base_date
+ base::TimeDelta::FromDays(days
) +
145 base::TimeDelta::FromHours(4)).LocalMidnight();
149 void ActivityLogPolicy::Util::ComputeDatabaseTimeBounds(const base::Time
& now
,
153 base::Time morning_midnight
= now
.LocalMidnight();
155 *early_bound
= morning_midnight
.ToInternalValue();
156 *late_bound
= base::Time::Max().ToInternalValue();
158 base::Time early_time
= Util::AddDays(morning_midnight
, -days_ago
);
159 base::Time late_time
= Util::AddDays(early_time
, 1);
160 *early_bound
= early_time
.ToInternalValue();
161 *late_bound
= late_time
.ToInternalValue();
166 bool ActivityLogPolicy::Util::DropObsoleteTables(sql::Connection
* db
) {
167 for (size_t i
= 0; i
< arraysize(kObsoleteTables
); i
++) {
168 const char* table_name
= kObsoleteTables
[i
];
169 if (db
->DoesTableExist(table_name
)) {
170 std::string drop_statement
=
171 base::StringPrintf("DROP TABLE %s", table_name
);
172 if (!db
->Execute(drop_statement
.c_str())) {
180 } // namespace extensions