Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(234)

Side by Side Diff: chrome/browser/extensions/activity_log/fullstream_ui_policy.cc

Issue 15573003: New architecture of the activity logging: Policies for summarization (and compression) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed Adrienne's final comments. Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright $YEAR 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 "base/files/file_path.h"
6 #include "base/json/json_string_value_serializer.h"
7 #include "base/logging.h"
8 #include "base/string16.h"
9 #include "chrome/browser/extensions/activity_log/activity_database.h"
10 #include "chrome/browser/extensions/activity_log/api_actions.h"
11 #include "chrome/browser/extensions/activity_log/blocked_actions.h"
12 #include "chrome/browser/extensions/activity_log/dom_actions.h"
13 #include "chrome/browser/extensions/activity_log/fullstream_ui_policy.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/common/chrome_constants.h"
16 #include "chrome/common/extensions/extension.h"
17 #include "googleurl/src/gurl.h"
18 #include "sql/error_delegate_util.h"
19
20 using base::Callback;
21 using base::FilePath;
22 using base::Time;
23 using base::Unretained;
24 using content::BrowserThread;
25
26 namespace {
27
28 // Key strings for passing parameters to the ProcessAction member function.
29 const char kKeyReason[] = "fsuip.reason";
30 const char kKeyDomainAction[] = "fsuip.domact";
31 const char kKeyURLTitle[] = "fsuip.urltitle";
32 const char kKeyDetailsString[] = "fsuip.details";
33
34 } // End of namespace anonymous
35
36 namespace extensions {
37
38 // TODO(dbabic) This would be a fine error handler for all sql-based policies,
39 // so it would make sense to introduce another class in the hierarchy,
40 // SQLiteBasedPolicy as a super class of FullStreamUIPolicy and move this
41 // error handler (as well as other SQLite-related functionality) there.
42
43 // This handles errors from the database.
44 class KillActivityDatabaseErrorDelegate : public sql::ErrorDelegate {
45 public:
46 explicit KillActivityDatabaseErrorDelegate(FullStreamUIPolicy* backend)
47 : backend_(backend),
48 scheduled_death_(false) {}
49
50 virtual int OnError(int error,
51 sql::Connection* connection,
52 sql::Statement* stmt) OVERRIDE {
53 if (!scheduled_death_ && sql::IsErrorCatastrophic(error)) {
54 ScheduleDeath();
55 }
56 return error;
57 }
58
59 // Schedules death if an error wasn't already reported.
60 void ScheduleDeath() {
61 if (!scheduled_death_) {
62 scheduled_death_ = true;
63 backend_->KillActivityLogDatabase();
64 }
65 }
66
67 bool scheduled_death() const {
68 return scheduled_death_;
69 }
70
71 private:
72 FullStreamUIPolicy* backend_;
73 bool scheduled_death_;
74
75 DISALLOW_COPY_AND_ASSIGN(KillActivityDatabaseErrorDelegate);
76 };
77
78 FullStreamUIPolicy::FullStreamUIPolicy(
79 Profile* profile,
80 content::BrowserThread::ID thread_id)
81 : ActivityLogPolicy(profile, thread_id) {
82 // We normally dispatch DB requests to the DB thread, but the thread might
83 // not exist if we are under test conditions. Substitute the UI thread for
84 // this case.
85 if (BrowserThread::IsMessageLoopValid(BrowserThread::DB)) {
86 dispatch_thread_ = BrowserThread::DB;
87 } else {
88 LOG(ERROR) << "BrowserThread::DB does not exist, running on UI thread!";
89 dispatch_thread_ = BrowserThread::UI;
90 }
91
92 db_ = new ActivityDatabase();
93 FilePath database_name = profile_base_path_.Append(
94 chrome::kExtensionActivityLogFilename);
95 KillActivityDatabaseErrorDelegate* error_delegate =
96 new KillActivityDatabaseErrorDelegate(this);
97 db_->SetErrorDelegate(error_delegate);
98 ScheduleAndForget(db_, &ActivityDatabase::Init, database_name);
99 }
100
101 FullStreamUIPolicy::~FullStreamUIPolicy() {
102 ScheduleAndForget(db_, &ActivityDatabase::Close);
103 }
104
105 // Get data as a set of key-value pairs. The keys are policy-specific.
106 void FullStreamUIPolicy::ReadData(
107 const std::string& extension_id,
108 const int day,
109 const Callback
110 <void(scoped_ptr<std::vector<scoped_refptr<Action> > >)>& callback)
111 const {
112 BrowserThread::PostTaskAndReplyWithResult(
113 dispatch_thread_,
114 FROM_HERE,
115 base::Bind(&ActivityDatabase::GetActions, Unretained(db_),
116 extension_id, day),
117 callback);
118 }
119
120 void FullStreamUIPolicy::SetSaveStateOnRequestOnly() {
121 db_->SetBatchModeForTesting(false);
122 ActivityLogPolicy::SetSaveStateOnRequestOnly();
123 }
124
125 void FullStreamUIPolicy::GetKey(ActivityLogPolicy::KeyType key_ty,
126 std::string* key) const {
127 DCHECK(key && "Unexpected NULL pointer.");
128 switch (key_ty) {
129 case PARAM_KEY_REASON:
130 *key = kKeyReason;
131 break;
132 case PARAM_KEY_DOM_ACTION:
133 *key = kKeyDomainAction;
134 break;
135 case PARAM_KEY_URL_TITLE:
136 *key = kKeyURLTitle;
137 break;
138 case PARAM_KEY_DETAILS_STRING:
139 *key = kKeyDetailsString;
140 break;
141 default:
142 *key = "";
143 }
144 }
145
146 void FullStreamUIPolicy::KillActivityLogDatabase() {
147 ScheduleAndForget(db_, &ActivityDatabase::KillDatabase);
148 }
149
150 void FullStreamUIPolicy::ProcessArguments(
151 ActionType action_type,
152 const std::string& name,
153 const ListValue* args,
154 std::stringstream& processed_args) const {
155 if (args) {
156 ListValue::const_iterator it = args->begin();
157 for (; it != args->end(); ++it) {
158 std::string arg;
159 JSONStringValueSerializer serializer(&arg);
160 if (serializer.SerializeAndOmitBinaryValues(**it)) {
161 if (it != args->begin()) {
162 processed_args << ", ";
163 }
164 processed_args << arg;
Matt Perry 2013/05/30 18:55:32 I doubt the efficiency of stringstream vs string m
dbabic 2013/05/30 21:51:25 I checked the GCC 4.9 source, and string::append d
Matt Perry 2013/05/30 22:00:27 That's surprising - the SGI docs [ http://www.sgi.
dbabic 2013/05/30 22:15:45 I believe that SGI docs are correct, it's O(N) for
Matt Perry 2013/05/30 22:46:21 Then it depends on what N refers to. If N is the l
dbabic 2013/05/30 22:54:41 Done.
dbabic 2013/05/30 23:01:18 Just noticed this... At least the way it's impleme
165 }
Matt Perry 2013/05/30 22:00:27 On second thought - can I ask why you don't just r
dbabic 2013/05/30 22:15:45 I don't know the answer to that. I copied the prev
Matt Perry 2013/05/30 22:46:21 Sounds good. It looks like the JSONSerializer will
dbabic 2013/05/30 22:54:41 Done.
166 }
167 }
168 }
169
170 void FullStreamUIPolicy::ProcessWebRequestModifications(
171 DictionaryValue& details,
172 std::string& details_string) const {
173 JSONStringValueSerializer serializer(&details_string);
174 serializer.Serialize(details);
175 }
176
177 void FullStreamUIPolicy::ProcessAction(
178 ActionType action_type,
179 const Extension& extension,
180 const std::string& name,
181 const GURL* url_param,
182 const ListValue* args,
183 const DictionaryValue* details) {
184 std::stringstream concatenated_args;
185 ProcessArguments(action_type, name, args, concatenated_args);
186 const Time now = Time::Now();
187 // TODO(dbabic,felt) Drop the dummy string in the next revision
188 const std::string dummy;
189 GURL url_obj;
190 if (url_param) {
191 url_obj = *url_param;
192 }
193 scoped_refptr<Action> action;
194
195 switch (action_type) {
196 case ACTION_API: {
197 action = new APIAction(
198 extension.id(),
199 now,
200 APIAction::CALL,
201 name,
202 concatenated_args.str(),
203 dummy); // TODO(dbabic,felt) Drop in the next revision
204 break;
205 }
206 case ACTION_EVENT: {
207 action = new APIAction(
208 extension.id(),
209 now,
210 APIAction::EVENT_CALLBACK,
211 name,
212 concatenated_args.str(),
213 dummy); // TODO(dbabic,felt) Drop in the next revision
214 break;
215 }
216 case ACTION_BLOCKED: {
217 std::string key;
218 int reason = 0;
219 if (details) {
220 GetKey(PARAM_KEY_REASON, &key);
221 details->GetInteger(key, &reason);
222 }
223
224 action = new BlockedAction(
225 extension.id(),
226 now,
227 name,
228 concatenated_args.str(),
229 static_cast<BlockedAction::Reason>(reason),
230 dummy); // TODO(dbabic,felt) Drop in the next revision
231 break;
232 }
233 case ACTION_DOM: {
234 std::string key;
235 string16 value;
236 DOMAction::DOMActionType action_type = DOMAction::MODIFIED;
237
238 if (details) {
239 int action_id = 0;
240 GetKey(PARAM_KEY_DOM_ACTION, &key);
241 details->GetInteger(key, &action_id);
242 action_type = static_cast<DOMAction::DOMActionType>(action_id);
243 GetKey(PARAM_KEY_URL_TITLE, &key);
244 details->GetString(key, &value);
245 }
246
247 action = new DOMAction(
248 extension.id(),
249 now,
250 action_type,
251 url_obj,
252 value,
253 name,
254 concatenated_args.str(),
255 dummy); // TODO(dbabic,felt) Drop in the next revision
256 break;
257 }
258 case ACTION_WEB_REQUEST: {
259 std::string key;
260 std::string details_string;
261 if (details) {
262 scoped_ptr<DictionaryValue> copy_of_details(details->DeepCopy());
263 GetKey(PARAM_KEY_DETAILS_STRING, &key);
264 ProcessWebRequestModifications(*copy_of_details.get(), details_string);
265 }
266
267 action = new DOMAction(
268 extension.id(),
269 now,
270 DOMAction::WEBREQUEST,
271 url_obj,
272 string16(),
273 name,
274 details_string,
275 dummy); // TODO(dbabic,felt) Drop in the next revision
276 break;
277 }
278 default:
279 NOTREACHED();
280 }
281
282 ScheduleAndForget(db_, &ActivityDatabase::RecordAction, action);
283 }
284
285 } // End of namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698