OLD | NEW |
---|---|
(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 | |
OLD | NEW |