Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/extensions/api/feedback_private/feedback_private_api.h" | 5 #include "chrome/browser/extensions/api/feedback_private/feedback_private_api.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <utility> | 9 #include <utility> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 29 #include "chrome/grit/generated_resources.h" | 29 #include "chrome/grit/generated_resources.h" |
| 30 #include "components/feedback/tracing_manager.h" | 30 #include "components/feedback/tracing_manager.h" |
| 31 #include "components/signin/core/browser/signin_manager.h" | 31 #include "components/signin/core/browser/signin_manager.h" |
| 32 #include "components/strings/grit/components_strings.h" | 32 #include "components/strings/grit/components_strings.h" |
| 33 #include "extensions/browser/event_router.h" | 33 #include "extensions/browser/event_router.h" |
| 34 #include "ui/base/l10n/l10n_util.h" | 34 #include "ui/base/l10n/l10n_util.h" |
| 35 #include "ui/base/webui/web_ui_util.h" | 35 #include "ui/base/webui/web_ui_util.h" |
| 36 #include "url/url_util.h" | 36 #include "url/url_util.h" |
| 37 | 37 |
| 38 #if defined(OS_CHROMEOS) | 38 #if defined(OS_CHROMEOS) |
| 39 #include "base/strings/string_split.h" | |
| 39 #include "chrome/browser/chromeos/arc/arc_util.h" | 40 #include "chrome/browser/chromeos/arc/arc_util.h" |
| 41 #include "chrome/browser/extensions/api/feedback_private/log_source_resource.h" | |
| 42 #include "chrome/browser/extensions/api/feedback_private/single_log_source_facto ry.h" | |
| 43 #include "extensions/browser/api/api_resource_manager.h" | |
| 40 #endif // defined(OS_CHROMEOS) | 44 #endif // defined(OS_CHROMEOS) |
| 41 | 45 |
| 42 #if defined(OS_WIN) | 46 #if defined(OS_WIN) |
| 43 #include "base/feature_list.h" | 47 #include "base/feature_list.h" |
| 44 #include "chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_win.h" | 48 #include "chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_win.h" |
| 45 #endif | 49 #endif |
| 46 | 50 |
| 47 using extensions::api::feedback_private::SystemInformation; | 51 using extensions::api::feedback_private::SystemInformation; |
| 48 using feedback::FeedbackData; | 52 using feedback::FeedbackData; |
| 49 | 53 |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 75 using feedback_private::SystemInformation; | 79 using feedback_private::SystemInformation; |
| 76 using feedback_private::FeedbackInfo; | 80 using feedback_private::FeedbackInfo; |
| 77 using feedback_private::FeedbackFlow; | 81 using feedback_private::FeedbackFlow; |
| 78 | 82 |
| 79 using SystemInformationList = | 83 using SystemInformationList = |
| 80 std::vector<api::feedback_private::SystemInformation>; | 84 std::vector<api::feedback_private::SystemInformation>; |
| 81 | 85 |
| 82 static base::LazyInstance<BrowserContextKeyedAPIFactory<FeedbackPrivateAPI>>:: | 86 static base::LazyInstance<BrowserContextKeyedAPIFactory<FeedbackPrivateAPI>>:: |
| 83 DestructorAtExit g_factory = LAZY_INSTANCE_INITIALIZER; | 87 DestructorAtExit g_factory = LAZY_INSTANCE_INITIALIZER; |
| 84 | 88 |
| 89 #if defined(OS_CHROMEOS) | |
| 90 using feedback_private::LogSource; | |
| 91 using SingleLogSource = system_logs::SingleLogSource; | |
| 92 using SupportedSource = system_logs::SingleLogSource::SupportedSource; | |
| 93 | |
| 94 // Converts from feedback_private::LogSource to SupportedSource. | |
| 95 SupportedSource GetSupportedSourceType(LogSource source) { | |
| 96 switch (source) { | |
| 97 case feedback_private::LOG_SOURCE_MESSAGES: | |
| 98 return SupportedSource::kMessages; | |
| 99 case feedback_private::LOG_SOURCE_UI_LATEST: | |
| 100 return SupportedSource::kUiLatest; | |
| 101 case feedback_private::LOG_SOURCE_NONE: | |
| 102 DLOG(FATAL) << "Invalid log source type requested."; | |
| 103 return SingleLogSource::SupportedSource::kMessages; | |
| 104 } | |
|
tbarzic
2017/06/01 19:23:45
NOTREACHED() << "Unknown log source type.";
return
Simon Que
2017/06/01 21:49:09
Done.
| |
| 105 } | |
| 106 #endif // defined(OS_CHROMEOS) | |
| 107 | |
| 85 // static | 108 // static |
| 86 BrowserContextKeyedAPIFactory<FeedbackPrivateAPI>* | 109 BrowserContextKeyedAPIFactory<FeedbackPrivateAPI>* |
| 87 FeedbackPrivateAPI::GetFactoryInstance() { | 110 FeedbackPrivateAPI::GetFactoryInstance() { |
| 88 return g_factory.Pointer(); | 111 return g_factory.Pointer(); |
| 89 } | 112 } |
| 90 | 113 |
| 91 FeedbackPrivateAPI::FeedbackPrivateAPI(content::BrowserContext* context) | 114 FeedbackPrivateAPI::FeedbackPrivateAPI(content::BrowserContext* context) |
| 92 : browser_context_(context), service_(new FeedbackService()) { | 115 : browser_context_(context), |
| 93 } | 116 service_(new FeedbackService()), |
| 117 log_source_access_manager_(new LogSourceAccessManager) {} | |
| 94 | 118 |
| 95 FeedbackPrivateAPI::~FeedbackPrivateAPI() { | 119 FeedbackPrivateAPI::~FeedbackPrivateAPI() { |
| 96 delete service_; | 120 delete service_; |
| 97 service_ = NULL; | 121 service_ = NULL; |
| 98 } | 122 } |
| 99 | 123 |
| 100 FeedbackService* FeedbackPrivateAPI::GetService() const { | 124 FeedbackService* FeedbackPrivateAPI::GetService() const { |
| 101 return service_; | 125 return service_; |
| 102 } | 126 } |
| 103 | 127 |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 258 sys_info_entry.key = std::move(itr.first); | 282 sys_info_entry.key = std::move(itr.first); |
| 259 sys_info_entry.value = std::move(itr.second); | 283 sys_info_entry.value = std::move(itr.second); |
| 260 sys_info_list.emplace_back(std::move(sys_info_entry)); | 284 sys_info_list.emplace_back(std::move(sys_info_entry)); |
| 261 } | 285 } |
| 262 } | 286 } |
| 263 | 287 |
| 264 Respond(ArgumentList( | 288 Respond(ArgumentList( |
| 265 feedback_private::GetSystemInformation::Results::Create(sys_info_list))); | 289 feedback_private::GetSystemInformation::Results::Create(sys_info_list))); |
| 266 } | 290 } |
| 267 | 291 |
| 292 ExtensionFunction::ResponseAction FeedbackPrivateReadLogSourceFunction::Run() { | |
| 293 #if defined(OS_CHROMEOS) | |
| 294 using Params = feedback_private::ReadLogSource::Params; | |
| 295 std::unique_ptr<Params> api_params = Params::Create(*args_); | |
| 296 | |
| 297 int reader_id = | |
| 298 api_params->params.reader_id ? *api_params->params.reader_id : 0; | |
| 299 LogSource source = api_params->params.source; | |
| 300 | |
| 301 SingleLogSource* log_source = GetOrCreateSingleLogSource(&reader_id, source); | |
| 302 if (!log_source) { | |
| 303 return RespondNow( | |
| 304 Error("Unable to get existing or create new log source.")); | |
| 305 } | |
| 306 | |
| 307 // Enforce the rules: rate-limit access to the source from the current | |
| 308 // extension. If not enough time has elapsed since the last access, do not | |
| 309 // read from the source, but instead return an empty response. From the | |
| 310 // caller's perspective, there is no new data. There is no need for the caller | |
| 311 // to keep track of the time since last access. | |
| 312 LogSourceAccessManager* log_source_manager = | |
| 313 FeedbackPrivateAPI::GetFactoryInstance() | |
| 314 ->Get(browser_context()) | |
| 315 ->log_source_access_manager(); | |
| 316 DCHECK(log_source_manager); | |
|
tbarzic
2017/06/01 19:23:45
I don't think you need dcheck here
Simon Que
2017/06/01 21:49:09
Done.
| |
| 317 if (!log_source_manager->AccessSourceFromExtension( | |
| 318 LogSourceAccessManager::SourceAndExtension(source, extension_id()))) { | |
| 319 return RespondNow( | |
| 320 ArgumentList(feedback_private::ReadLogSource::Results::Create( | |
| 321 0, std::vector<std::string>()))); | |
| 322 } | |
| 323 | |
| 324 // Now we are ready to access the log source. | |
| 325 log_source->Fetch( | |
| 326 base::Bind(&FeedbackPrivateReadLogSourceFunction::OnCompleted, this, | |
| 327 source, reader_id, api_params->params.incremental)); | |
| 328 | |
| 329 return RespondLater(); | |
| 330 #else | |
| 331 return RespondNow(Error("API function is not supported.")); | |
|
tbarzic
2017/06/01 19:23:45
Can you add a NOTREACHED now that you've restricte
Simon Que
2017/06/01 21:49:09
Done.
| |
| 332 #endif // defined(OS_CHROMEOS) | |
| 333 } | |
| 334 | |
| 335 #if defined(OS_CHROMEOS) | |
| 336 SingleLogSource* | |
| 337 FeedbackPrivateReadLogSourceFunction::GetOrCreateSingleLogSource( | |
| 338 int* reader_id, | |
| 339 LogSource source) { | |
| 340 ApiResourceManager<LogSourceResource>* resource_manager = | |
| 341 ApiResourceManager<LogSourceResource>::Get(browser_context()); | |
| 342 DCHECK(resource_manager); | |
| 343 | |
| 344 LogSourceResource* resource = nullptr; | |
| 345 // If the caller passed in a valid ID, look up the ID in the resource manager. | |
| 346 if (*reader_id > 0) { | |
| 347 resource = resource_manager->Get(extension_id(), *reader_id); | |
| 348 return resource ? resource->GetLogSource() : nullptr; | |
| 349 } | |
| 350 | |
| 351 LogSourceAccessManager* log_source_manager = | |
| 352 FeedbackPrivateAPI::GetFactoryInstance() | |
| 353 ->Get(browser_context()) | |
| 354 ->log_source_access_manager(); | |
| 355 DCHECK(log_source_manager); | |
| 356 | |
| 357 LogSourceAccessManager::SourceAndExtension source_and_extension( | |
| 358 source, extension_id()); | |
| 359 | |
| 360 // If caller passed in |reader_id| == 0, create a new SingleLogSource. | |
| 361 | |
| 362 // Enforce the rules: Do not create a new SingleLogSource if there was | |
| 363 // already one created for |source_and_extension|. | |
| 364 if (!log_source_manager->AddExtension(source_and_extension)) | |
| 365 return nullptr; | |
| 366 | |
| 367 SupportedSource source_type = GetSupportedSourceType(source); | |
| 368 std::unique_ptr<LogSourceResource> new_resource = | |
| 369 base::MakeUnique<LogSourceResource>( | |
| 370 extension_id(), | |
| 371 SingleLogSourceFactory::CreateSingleLogSource(source_type).release(), | |
|
tbarzic
2017/06/01 19:23:45
I wonder if design here would be simpler if more l
Simon Que
2017/06/01 21:49:09
I like the idea. But your description still leaves
tbarzic
2017/06/01 21:57:23
Yes, depending on browser context would probably b
| |
| 372 log_source_manager->GetUnregisterCallback(source_and_extension)); | |
| 373 resource = new_resource.get(); | |
| 374 *reader_id = resource_manager->Add(new_resource.release()); | |
| 375 | |
| 376 return resource->GetLogSource(); | |
| 377 } | |
| 378 | |
| 379 void FeedbackPrivateReadLogSourceFunction::OnCompleted( | |
| 380 LogSource source, | |
| 381 int reader_id, | |
| 382 bool incremental, | |
| 383 system_logs::SystemLogsResponse* response) { | |
| 384 std::vector<std::string> result; | |
| 385 for (const std::pair<std::string, std::string>& pair : *response) { | |
| 386 // TODO(sque): Use std::move? | |
| 387 std::vector<std::string> new_lines = base::SplitString( | |
| 388 pair.second, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); | |
| 389 result.reserve(result.size() + new_lines.size()); | |
| 390 result.insert(result.end(), new_lines.begin(), new_lines.end()); | |
| 391 } | |
| 392 | |
| 393 // If the API call requested a non-incremental access, clean up the | |
| 394 // SingleLogSource by removing its API resource. | |
| 395 if (!incremental) { | |
|
tbarzic
2017/06/01 19:23:45
Can you update the comment to note that incrementa
Simon Que
2017/06/01 21:49:09
Done.
| |
| 396 ApiResourceManager<LogSourceResource>::Get(browser_context()) | |
| 397 ->Remove(extension_id(), reader_id); | |
| 398 // Must return reader_id=0 when the resource has been deleted. | |
| 399 reader_id = 0; | |
|
tbarzic
2017/06/01 19:23:45
Instead of changing |reader_id|, can you introduce
Simon Que
2017/06/01 21:49:09
Done.
I'd normally agree with -1 over 0, but 0 is
tbarzic
2017/06/01 21:57:23
Acknowledged.
| |
| 400 } | |
| 401 | |
| 402 Respond(ArgumentList( | |
| 403 feedback_private::ReadLogSource::Results::Create(reader_id, result))); | |
| 404 } | |
| 405 | |
| 406 #endif // defined(OS_CHROMEOS) | |
| 407 | |
| 268 bool FeedbackPrivateSendFeedbackFunction::RunAsync() { | 408 bool FeedbackPrivateSendFeedbackFunction::RunAsync() { |
| 269 std::unique_ptr<feedback_private::SendFeedback::Params> params( | 409 std::unique_ptr<feedback_private::SendFeedback::Params> params( |
| 270 feedback_private::SendFeedback::Params::Create(*args_)); | 410 feedback_private::SendFeedback::Params::Create(*args_)); |
| 271 EXTENSION_FUNCTION_VALIDATE(params); | 411 EXTENSION_FUNCTION_VALIDATE(params); |
| 272 | 412 |
| 273 const FeedbackInfo &feedback_info = params->feedback; | 413 const FeedbackInfo &feedback_info = params->feedback; |
| 274 | 414 |
| 275 // Populate feedback data. | 415 // Populate feedback data. |
| 276 scoped_refptr<FeedbackData> feedback_data(new FeedbackData()); | 416 scoped_refptr<FeedbackData> feedback_data(new FeedbackData()); |
| 277 feedback_data->set_context(GetProfile()); | 417 feedback_data->set_context(GetProfile()); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 364 case feedback_private::SRT_PROMPT_RESULT_CLOSED: | 504 case feedback_private::SRT_PROMPT_RESULT_CLOSED: |
| 365 base::RecordAction(base::UserMetricsAction("Feedback.SrtPromptClosed")); | 505 base::RecordAction(base::UserMetricsAction("Feedback.SrtPromptClosed")); |
| 366 break; | 506 break; |
| 367 default: | 507 default: |
| 368 return RespondNow(Error("Invalid arugment.")); | 508 return RespondNow(Error("Invalid arugment.")); |
| 369 } | 509 } |
| 370 return RespondNow(NoArguments()); | 510 return RespondNow(NoArguments()); |
| 371 } | 511 } |
| 372 | 512 |
| 373 } // namespace extensions | 513 } // namespace extensions |
| OLD | NEW |