- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / activity_log / activity_log_policy.cc
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.
4
5 #include "chrome/browser/extensions/activity_log/activity_log_policy.h"
6
7 #include <stdint.h>
8
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 "chrome/common/extensions/extension.h"
18 #include "content/public/browser/browser_thread.h"
19 #include "url/gurl.h"
20
21 using content::BrowserThread;
22
23 namespace constants = activity_log_constants;
24
25 namespace {
26 // Obsolete database tables: these should be dropped from the database if
27 // found.
28 const char* kObsoleteTables[] = {"activitylog_apis", "activitylog_blocked",
29                                  "activitylog_urls"};
30 }  // namespace
31
32 namespace extensions {
33
34 ActivityLogPolicy::ActivityLogPolicy(Profile* profile) {}
35
36 ActivityLogPolicy::~ActivityLogPolicy() {}
37
38 void ActivityLogPolicy::SetClockForTesting(scoped_ptr<base::Clock> clock) {
39   testing_clock_.reset(clock.release());
40 }
41
42 base::Time ActivityLogPolicy::Now() const {
43   if (testing_clock_)
44     return testing_clock_->Now();
45   else
46     return base::Time::Now();
47 }
48
49 ActivityLogDatabasePolicy::ActivityLogDatabasePolicy(
50     Profile* profile,
51     const base::FilePath& database_name)
52     : ActivityLogPolicy(profile) {
53   CHECK(profile);
54   base::FilePath profile_base_path = profile->GetPath();
55   db_ = new ActivityDatabase(this);
56   database_path_ = profile_base_path.Append(database_name);
57 }
58
59 void ActivityLogDatabasePolicy::Init() {
60   ScheduleAndForget(db_, &ActivityDatabase::Init, database_path_);
61 }
62
63 void ActivityLogDatabasePolicy::Flush() {
64   ScheduleAndForget(activity_database(),
65                     &ActivityDatabase::AdviseFlush,
66                     ActivityDatabase::kFlushImmediately);
67 }
68
69 sql::Connection* ActivityLogDatabasePolicy::GetDatabaseConnection() const {
70   return db_->GetSqlConnection();
71 }
72
73 // static
74 std::string ActivityLogPolicy::Util::Serialize(const base::Value* value) {
75   std::string value_as_text;
76   if (!value) {
77     value_as_text = "";
78   } else {
79     JSONStringValueSerializer serializer(&value_as_text);
80     serializer.SerializeAndOmitBinaryValues(*value);
81   }
82   return value_as_text;
83 }
84
85 // static
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);
93   }
94   if (action->arg_incognito()) {
95     action->set_arg_url(GURL());
96     action->set_arg_incognito(false);
97   }
98
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();
106
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));
111   }
112
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     DictionaryValue* details = NULL;
117     if (action->mutable_other()->GetDictionary(constants::kActionWebRequest,
118                                                &details)) {
119       DictionaryValue::Iterator details_iterator(*details);
120       while (!details_iterator.IsAtEnd()) {
121         details->SetBoolean(details_iterator.key(), true);
122         details_iterator.Advance();
123       }
124     }
125   }
126 }
127
128 // static
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<ListValue>());
135   }
136 }
137
138 // static
139 base::Time ActivityLogPolicy::Util::AddDays(const base::Time& base_date,
140                                             int days) {
141   // To allow for time zone changes, add an additional partial day then round
142   // down to midnight.
143   return (base_date + base::TimeDelta::FromDays(days) +
144           base::TimeDelta::FromHours(4)).LocalMidnight();
145 }
146
147 // static
148 void ActivityLogPolicy::Util::ComputeDatabaseTimeBounds(const base::Time& now,
149                                                         int days_ago,
150                                                         int64* early_bound,
151                                                         int64* late_bound) {
152   base::Time morning_midnight = now.LocalMidnight();
153   if (days_ago == 0) {
154       *early_bound = morning_midnight.ToInternalValue();
155       *late_bound = base::Time::Max().ToInternalValue();
156   } else {
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();
161   }
162 }
163
164 // static
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())) {
172         return false;
173       }
174     }
175   }
176   return true;
177 }
178
179 }  // namespace extensions