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* kObsoleteTables
[] = {"activitylog_apis", "activitylog_blocked",
32 namespace extensions
{
34 ActivityLogPolicy::ActivityLogPolicy(Profile
* profile
) {}
36 ActivityLogPolicy::~ActivityLogPolicy() {}
38 void ActivityLogPolicy::SetClockForTesting(scoped_ptr
<base::Clock
> clock
) {
39 testing_clock_
.reset(clock
.release());
42 base::Time
ActivityLogPolicy::Now() const {
44 return testing_clock_
->Now();
46 return base::Time::Now();
49 ActivityLogDatabasePolicy::ActivityLogDatabasePolicy(
51 const base::FilePath
& database_name
)
52 : ActivityLogPolicy(profile
) {
54 base::FilePath profile_base_path
= profile
->GetPath();
55 db_
= new ActivityDatabase(this);
56 database_path_
= profile_base_path
.Append(database_name
);
59 void ActivityLogDatabasePolicy::Init() {
60 ScheduleAndForget(db_
, &ActivityDatabase::Init
, database_path_
);
63 void ActivityLogDatabasePolicy::Flush() {
64 ScheduleAndForget(activity_database(),
65 &ActivityDatabase::AdviseFlush
,
66 ActivityDatabase::kFlushImmediately
);
69 sql::Connection
* ActivityLogDatabasePolicy::GetDatabaseConnection() const {
70 return db_
->GetSqlConnection();
74 std::string
ActivityLogPolicy::Util::Serialize(const base::Value
* value
) {
75 std::string value_as_text
;
79 JSONStringValueSerializer
serializer(&value_as_text
);
80 serializer
.SerializeAndOmitBinaryValues(*value
);
86 void ActivityLogPolicy::Util::StripPrivacySensitiveFields(
87 scoped_refptr
<Action
> action
) {
88 // Clear incognito URLs/titles.
89 if (action
->page_incognito()) {
90 action
->set_page_url(GURL());
91 action
->set_page_title("");
92 action
->set_page_incognito(false);
94 if (action
->arg_incognito()) {
95 action
->set_arg_url(GURL());
96 action
->set_arg_incognito(false);
99 // Strip query parameters, username/password, etc., from URLs.
100 if (action
->page_url().is_valid() || action
->arg_url().is_valid()) {
101 url_canon::Replacements
<char> url_sanitizer
;
102 url_sanitizer
.ClearUsername();
103 url_sanitizer
.ClearPassword();
104 url_sanitizer
.ClearQuery();
105 url_sanitizer
.ClearRef();
107 if (action
->page_url().is_valid())
108 action
->set_page_url(action
->page_url().ReplaceComponents(url_sanitizer
));
109 if (action
->arg_url().is_valid())
110 action
->set_arg_url(action
->arg_url().ReplaceComponents(url_sanitizer
));
113 // Clear WebRequest details; only keep a record of which types of
114 // modifications were performed.
115 if (action
->action_type() == Action::ACTION_WEB_REQUEST
) {
116 base::DictionaryValue
* details
= NULL
;
117 if (action
->mutable_other()->GetDictionary(constants::kActionWebRequest
,
119 base::DictionaryValue::Iterator
details_iterator(*details
);
120 while (!details_iterator
.IsAtEnd()) {
121 details
->SetBoolean(details_iterator
.key(), true);
122 details_iterator
.Advance();
129 void ActivityLogPolicy::Util::StripArguments(const ApiSet
& api_whitelist
,
130 scoped_refptr
<Action
> action
) {
131 if (api_whitelist
.find(
132 std::make_pair(action
->action_type(), action
->api_name())) ==
133 api_whitelist
.end()) {
134 action
->set_args(scoped_ptr
<base::ListValue
>());
139 base::Time
ActivityLogPolicy::Util::AddDays(const base::Time
& base_date
,
141 // To allow for time zone changes, add an additional partial day then round
143 return (base_date
+ base::TimeDelta::FromDays(days
) +
144 base::TimeDelta::FromHours(4)).LocalMidnight();
148 void ActivityLogPolicy::Util::ComputeDatabaseTimeBounds(const base::Time
& now
,
152 base::Time morning_midnight
= now
.LocalMidnight();
154 *early_bound
= morning_midnight
.ToInternalValue();
155 *late_bound
= base::Time::Max().ToInternalValue();
157 base::Time early_time
= Util::AddDays(morning_midnight
, -days_ago
);
158 base::Time late_time
= Util::AddDays(early_time
, 1);
159 *early_bound
= early_time
.ToInternalValue();
160 *late_bound
= late_time
.ToInternalValue();
165 bool ActivityLogPolicy::Util::DropObsoleteTables(sql::Connection
* db
) {
166 for (size_t i
= 0; i
< arraysize(kObsoleteTables
); i
++) {
167 const char* table_name
= kObsoleteTables
[i
];
168 if (db
->DoesTableExist(table_name
)) {
169 std::string drop_statement
=
170 base::StringPrintf("DROP TABLE %s", table_name
);
171 if (!db
->Execute(drop_statement
.c_str())) {
179 } // namespace extensions