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