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/api/activity_log_private/activity_log_private_api.h" 6 7 #include "base/lazy_instance.h" 8 #include "base/prefs/pref_service.h" 9 #include "base/strings/string_number_conversions.h" 10 #include "base/values.h" 11 #include "chrome/browser/browser_process.h" 12 #include "chrome/browser/extensions/event_router_forwarder.h" 13 #include "chrome/browser/extensions/extension_service.h" 14 #include "chrome/common/extensions/api/activity_log_private.h" 15 #include "chrome/common/pref_names.h" 16 #include "content/public/browser/browser_context.h" 17 #include "extensions/browser/extension_system_provider.h" 18 #include "extensions/browser/extensions_browser_client.h" 19 #include "extensions/common/features/feature.h" 20 #include "extensions/common/features/feature_provider.h" 21 22 namespace extensions { 23 24 namespace activity_log_private = api::activity_log_private; 25 26 using api::activity_log_private::ActivityResultSet; 27 using api::activity_log_private::ExtensionActivity; 28 using api::activity_log_private::Filter; 29 30 static base::LazyInstance<BrowserContextKeyedAPIFactory<ActivityLogAPI> > 31 g_factory = LAZY_INSTANCE_INITIALIZER; 32 33 // static 34 BrowserContextKeyedAPIFactory<ActivityLogAPI>* 35 ActivityLogAPI::GetFactoryInstance() { 36 return g_factory.Pointer(); 37 } 38 39 template <> 40 void 41 BrowserContextKeyedAPIFactory<ActivityLogAPI>::DeclareFactoryDependencies() { 42 DependsOn(ExtensionsBrowserClient::Get()->GetExtensionSystemFactory()); 43 DependsOn(ActivityLog::GetFactoryInstance()); 44 } 45 46 ActivityLogAPI::ActivityLogAPI(content::BrowserContext* context) 47 : browser_context_(context), initialized_(false) { 48 if (!EventRouter::Get(browser_context_)) { // Check for testing. 49 DVLOG(1) << "ExtensionSystem event_router does not exist."; 50 return; 51 } 52 activity_log_ = extensions::ActivityLog::GetInstance(browser_context_); 53 DCHECK(activity_log_); 54 EventRouter::Get(browser_context_)->RegisterObserver( 55 this, activity_log_private::OnExtensionActivity::kEventName); 56 activity_log_->AddObserver(this); 57 initialized_ = true; 58 } 59 60 ActivityLogAPI::~ActivityLogAPI() { 61 } 62 63 void ActivityLogAPI::Shutdown() { 64 if (!initialized_) { // Check for testing. 65 DVLOG(1) << "ExtensionSystem event_router does not exist."; 66 return; 67 } 68 EventRouter::Get(browser_context_)->UnregisterObserver(this); 69 activity_log_->RemoveObserver(this); 70 } 71 72 // static 73 bool ActivityLogAPI::IsExtensionWhitelisted(const std::string& extension_id) { 74 return FeatureProvider::GetPermissionFeatures()-> 75 GetFeature("activityLogPrivate")->IsIdInWhitelist(extension_id); 76 } 77 78 void ActivityLogAPI::OnListenerAdded(const EventListenerInfo& details) { 79 // TODO(felt): Only observe activity_log_ events when we have a customer. 80 } 81 82 void ActivityLogAPI::OnListenerRemoved(const EventListenerInfo& details) { 83 // TODO(felt): Only observe activity_log_ events when we have a customer. 84 } 85 86 void ActivityLogAPI::OnExtensionActivity(scoped_refptr<Action> activity) { 87 scoped_ptr<base::ListValue> value(new base::ListValue()); 88 scoped_ptr<ExtensionActivity> activity_arg = 89 activity->ConvertToExtensionActivity(); 90 value->Append(activity_arg->ToValue().release()); 91 scoped_ptr<Event> event( 92 new Event(activity_log_private::OnExtensionActivity::kEventName, 93 value.Pass())); 94 event->restrict_to_browser_context = browser_context_; 95 EventRouter::Get(browser_context_)->BroadcastEvent(event.Pass()); 96 } 97 98 bool ActivityLogPrivateGetExtensionActivitiesFunction::RunAsync() { 99 scoped_ptr<activity_log_private::GetExtensionActivities::Params> params( 100 activity_log_private::GetExtensionActivities::Params::Create(*args_)); 101 EXTENSION_FUNCTION_VALIDATE(params.get()); 102 103 // Get the arguments in the right format. 104 scoped_ptr<Filter> filter; 105 filter.reset(¶ms.release()->filter); 106 Action::ActionType action_type = Action::ACTION_API_CALL; 107 switch (filter->activity_type) { 108 case Filter::ACTIVITY_TYPE_API_CALL: 109 action_type = Action::ACTION_API_CALL; 110 break; 111 case Filter::ACTIVITY_TYPE_API_EVENT: 112 action_type = Action::ACTION_API_EVENT; 113 break; 114 case Filter::ACTIVITY_TYPE_CONTENT_SCRIPT: 115 action_type = Action::ACTION_CONTENT_SCRIPT; 116 break; 117 case Filter::ACTIVITY_TYPE_DOM_ACCESS: 118 action_type = Action::ACTION_DOM_ACCESS; 119 break; 120 case Filter::ACTIVITY_TYPE_DOM_EVENT: 121 action_type = Action::ACTION_DOM_EVENT; 122 break; 123 case Filter::ACTIVITY_TYPE_WEB_REQUEST: 124 action_type = Action::ACTION_WEB_REQUEST; 125 break; 126 case Filter::ACTIVITY_TYPE_ANY: 127 default: 128 action_type = Action::ACTION_ANY; 129 } 130 std::string extension_id = 131 filter->extension_id.get() ? *filter->extension_id : std::string(); 132 std::string api_call = 133 filter->api_call.get() ? *filter->api_call : std::string(); 134 std::string page_url = 135 filter->page_url.get() ? *filter->page_url : std::string(); 136 std::string arg_url = 137 filter->arg_url.get() ? *filter->arg_url : std::string(); 138 int days_ago = -1; 139 if (filter->days_ago.get()) 140 days_ago = *filter->days_ago; 141 142 // Call the ActivityLog. 143 ActivityLog* activity_log = ActivityLog::GetInstance(GetProfile()); 144 DCHECK(activity_log); 145 activity_log->GetFilteredActions( 146 extension_id, 147 action_type, 148 api_call, 149 page_url, 150 arg_url, 151 days_ago, 152 base::Bind( 153 &ActivityLogPrivateGetExtensionActivitiesFunction::OnLookupCompleted, 154 this)); 155 156 return true; 157 } 158 159 void ActivityLogPrivateGetExtensionActivitiesFunction::OnLookupCompleted( 160 scoped_ptr<std::vector<scoped_refptr<Action> > > activities) { 161 // Convert Actions to ExtensionActivities. 162 std::vector<linked_ptr<ExtensionActivity> > result_arr; 163 for (std::vector<scoped_refptr<Action> >::iterator it = activities->begin(); 164 it != activities->end(); 165 ++it) { 166 result_arr.push_back( 167 make_linked_ptr(it->get()->ConvertToExtensionActivity().release())); 168 } 169 170 // Populate the return object. 171 scoped_ptr<ActivityResultSet> result_set(new ActivityResultSet); 172 result_set->activities = result_arr; 173 results_ = activity_log_private::GetExtensionActivities::Results::Create( 174 *result_set); 175 176 SendResponse(true); 177 } 178 179 bool ActivityLogPrivateDeleteActivitiesFunction::RunAsync() { 180 scoped_ptr<activity_log_private::DeleteActivities::Params> params( 181 activity_log_private::DeleteActivities::Params::Create(*args_)); 182 EXTENSION_FUNCTION_VALIDATE(params.get()); 183 184 // Put the arguments in the right format. 185 std::vector<int64> action_ids; 186 int64 value; 187 for (size_t i = 0; i < params->activity_ids.size(); i++) { 188 if (base::StringToInt64(params->activity_ids[i], &value)) 189 action_ids.push_back(value); 190 } 191 192 ActivityLog* activity_log = ActivityLog::GetInstance(GetProfile()); 193 DCHECK(activity_log); 194 activity_log->RemoveActions(action_ids); 195 return true; 196 } 197 198 bool ActivityLogPrivateDeleteDatabaseFunction::RunAsync() { 199 ActivityLog* activity_log = ActivityLog::GetInstance(GetProfile()); 200 DCHECK(activity_log); 201 activity_log->DeleteDatabase(); 202 return true; 203 } 204 205 bool ActivityLogPrivateDeleteUrlsFunction::RunAsync() { 206 scoped_ptr<activity_log_private::DeleteUrls::Params> params( 207 activity_log_private::DeleteUrls::Params::Create(*args_)); 208 EXTENSION_FUNCTION_VALIDATE(params.get()); 209 210 // Put the arguments in the right format. 211 std::vector<GURL> gurls; 212 std::vector<std::string> urls = *params->urls.get(); 213 for (std::vector<std::string>::iterator it = urls.begin(); 214 it != urls.end(); 215 ++it) { 216 gurls.push_back(GURL(*it)); 217 } 218 219 ActivityLog* activity_log = ActivityLog::GetInstance(GetProfile()); 220 DCHECK(activity_log); 221 activity_log->RemoveURLs(gurls); 222 return true; 223 } 224 225 } // namespace extensions 226