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/feedback_private/feedback_private_api.h" 6 7 #include "base/lazy_instance.h" 8 #include "base/memory/scoped_ptr.h" 9 #include "base/strings/utf_string_conversions.h" 10 #include "base/values.h" 11 #include "chrome/browser/extensions/api/feedback_private/feedback_service.h" 12 #include "chrome/browser/extensions/event_names.h" 13 #include "chrome/browser/extensions/event_router.h" 14 #include "chrome/browser/extensions/extension_system.h" 15 #include "grit/generated_resources.h" 16 #include "ui/base/l10n/l10n_util.h" 17 #include "ui/webui/web_ui_util.h" 18 #include "url/url_util.h" 19 20 21 namespace extensions { 22 23 using api::feedback_private::SystemInformation; 24 using api::feedback_private::FeedbackInfo; 25 26 static base::LazyInstance<ProfileKeyedAPIFactory<FeedbackPrivateAPI> > 27 g_factory = LAZY_INSTANCE_INITIALIZER; 28 29 // static 30 ProfileKeyedAPIFactory<FeedbackPrivateAPI>* 31 FeedbackPrivateAPI::GetFactoryInstance() { 32 return &g_factory.Get(); 33 } 34 35 FeedbackPrivateAPI::FeedbackPrivateAPI(Profile* profile) 36 : profile_(profile), 37 service_(FeedbackService::CreateInstance()) { 38 } 39 40 FeedbackPrivateAPI::~FeedbackPrivateAPI() { 41 delete service_; 42 service_ = NULL; 43 } 44 45 FeedbackService* FeedbackPrivateAPI::GetService() const { 46 return service_; 47 } 48 49 void FeedbackPrivateAPI::RequestFeedback( 50 const std::string& description_template, 51 const std::string& category_tag, 52 const GURL& page_url) { 53 if (profile_ && ExtensionSystem::Get(profile_)->event_router()) { 54 FeedbackInfo info; 55 info.description = description_template; 56 info.category_tag = make_scoped_ptr(new std::string(category_tag)); 57 info.page_url = make_scoped_ptr(new std::string(page_url.spec())); 58 59 scoped_ptr<base::ListValue> args(new base::ListValue()); 60 args->Append(info.ToValue().release()); 61 62 scoped_ptr<Event> event( 63 new Event(event_names::kOnFeedbackRequested, args.Pass())); 64 ExtensionSystem::Get(profile_)->event_router()->BroadcastEvent( 65 event.Pass()); 66 } 67 } 68 69 bool FeedbackPrivateGetUserEmailFunction::RunImpl() { 70 FeedbackService* service = 71 FeedbackPrivateAPI::GetFactoryInstance()->GetForProfile( 72 profile())->GetService(); 73 DCHECK(service); 74 SetResult(base::Value::CreateStringValue(service->GetUserEmail())); 75 return true; 76 } 77 78 bool FeedbackPrivateGetSystemInformationFunction::RunImpl() { 79 FeedbackService* service = 80 FeedbackPrivateAPI::GetFactoryInstance()->GetForProfile( 81 profile())->GetService(); 82 DCHECK(service); 83 service->GetSystemInformation( 84 base::Bind( 85 &FeedbackPrivateGetSystemInformationFunction::OnCompleted, this)); 86 return true; 87 } 88 89 void FeedbackPrivateGetSystemInformationFunction::OnCompleted( 90 const SystemInformationList& sys_info) { 91 results_ = api::feedback_private::GetSystemInformation::Results::Create( 92 sys_info); 93 SendResponse(true); 94 } 95 96 bool FeedbackPrivateSendFeedbackFunction::RunImpl() { 97 scoped_ptr<api::feedback_private::SendFeedback::Params> params( 98 api::feedback_private::SendFeedback::Params::Create(*args_)); 99 EXTENSION_FUNCTION_VALIDATE(params.get()); 100 101 const FeedbackInfo &feedback_info = params->feedback; 102 103 std::string attached_file_url, screenshot_url; 104 if (feedback_info.attached_file.get() && 105 feedback_info.attached_file_blob_url.get() && 106 !feedback_info.attached_file_blob_url->empty()) { 107 attached_file_url = *feedback_info.attached_file_blob_url; 108 } 109 110 if (feedback_info.screenshot.get() && 111 feedback_info.screenshot_blob_url.get() && 112 !feedback_info.screenshot_blob_url->empty()) { 113 screenshot_url = *feedback_info.screenshot_blob_url; 114 } 115 116 // Populate feedback data. 117 scoped_refptr<FeedbackData> feedback_data(new FeedbackData()); 118 feedback_data->set_profile(profile_); 119 feedback_data->set_description(feedback_info.description); 120 121 if (feedback_info.category_tag.get()) 122 feedback_data->set_category_tag(*feedback_info.category_tag.get()); 123 if (feedback_info.page_url.get()) 124 feedback_data->set_page_url(*feedback_info.page_url.get()); 125 if (feedback_info.email.get()) 126 feedback_data->set_user_email(*feedback_info.email.get()); 127 128 if (!attached_file_url.empty()) { 129 feedback_data->set_attached_filename( 130 (*feedback_info.attached_file.get()).name); 131 feedback_data->set_attached_file_url(GURL(attached_file_url)); 132 } 133 134 if (!screenshot_url.empty()) 135 feedback_data->set_screenshot_url(GURL(screenshot_url)); 136 137 // TODO(rkc): Take this out of OS_CHROMEOS once we have FeedbackData and 138 // FeedbackUtil migrated to handle system logs for both Chrome and ChromeOS. 139 #if defined(OS_CHROMEOS) 140 scoped_ptr<chromeos::SystemLogsResponse> sys_logs( 141 new chromeos::SystemLogsResponse); 142 SystemInformationList* sys_info = feedback_info.system_information.get(); 143 if (sys_info) { 144 for (SystemInformationList::iterator it = sys_info->begin(); 145 it != sys_info->end(); ++it) 146 (*sys_logs.get())[it->get()->key] = it->get()->value; 147 } 148 feedback_data->set_sys_info(sys_logs.Pass()); 149 #endif 150 151 FeedbackService* service = FeedbackPrivateAPI::GetFactoryInstance()-> 152 GetForProfile(profile())->GetService(); 153 DCHECK(service); 154 service->SendFeedback(profile(), 155 feedback_data, base::Bind( 156 &FeedbackPrivateSendFeedbackFunction::OnCompleted, 157 this)); 158 return true; 159 } 160 161 void FeedbackPrivateSendFeedbackFunction::OnCompleted( 162 bool success) { 163 results_ = api::feedback_private::SendFeedback::Results::Create( 164 success ? api::feedback_private::STATUS_SUCCESS : 165 api::feedback_private::STATUS_DELAYED); 166 SendResponse(true); 167 } 168 169 } // namespace extensions 170