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/chromeos/system_logs/single_log_source.h" | |
| 42 #include "chrome/browser/extensions/api/feedback_private/log_source_resource.h" | |
| 43 #include "chrome/browser/extensions/api/feedback_private/single_log_source_facto ry.h" | |
| 44 #include "extensions/browser/api/api_resource_manager.h" | |
| 40 #endif // defined(OS_CHROMEOS) | 45 #endif // defined(OS_CHROMEOS) |
| 41 | 46 |
| 42 #if defined(OS_WIN) | 47 #if defined(OS_WIN) |
| 43 #include "base/feature_list.h" | 48 #include "base/feature_list.h" |
| 44 #include "chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_win.h" | 49 #include "chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_win.h" |
| 45 #endif | 50 #endif |
| 46 | 51 |
| 47 using extensions::api::feedback_private::SystemInformation; | 52 using extensions::api::feedback_private::SystemInformation; |
| 48 using feedback::FeedbackData; | 53 using feedback::FeedbackData; |
| 49 | 54 |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 75 using feedback_private::SystemInformation; | 80 using feedback_private::SystemInformation; |
| 76 using feedback_private::FeedbackInfo; | 81 using feedback_private::FeedbackInfo; |
| 77 using feedback_private::FeedbackFlow; | 82 using feedback_private::FeedbackFlow; |
| 78 | 83 |
| 79 using SystemInformationList = | 84 using SystemInformationList = |
| 80 std::vector<api::feedback_private::SystemInformation>; | 85 std::vector<api::feedback_private::SystemInformation>; |
| 81 | 86 |
| 82 static base::LazyInstance<BrowserContextKeyedAPIFactory<FeedbackPrivateAPI>>:: | 87 static base::LazyInstance<BrowserContextKeyedAPIFactory<FeedbackPrivateAPI>>:: |
| 83 DestructorAtExit g_factory = LAZY_INSTANCE_INITIALIZER; | 88 DestructorAtExit g_factory = LAZY_INSTANCE_INITIALIZER; |
| 84 | 89 |
| 90 #if defined(OS_CHROMEOS) | |
| 91 using extensions::api::feedback_private::LogSource; | |
| 92 using SingleLogSource = system_logs::SingleLogSource; | |
| 93 using SupportedSource = system_logs::SingleLogSource::SupportedSource; | |
| 94 using LogSourceResourceManager = ApiResourceManager<LogSourceResource>; | |
| 95 | |
| 96 // For managing API resources of type LogSourceResource. | |
| 97 static base::LazyInstance< | |
| 98 BrowserContextKeyedAPIFactory<LogSourceResourceManager>>::DestructorAtExit | |
| 99 g_log_source_resource_factory = LAZY_INSTANCE_INITIALIZER; | |
| 100 | |
| 101 // static | |
| 102 template <> | |
| 103 BrowserContextKeyedAPIFactory<LogSourceResourceManager>* | |
| 104 LogSourceResourceManager::GetFactoryInstance() { | |
|
tbarzic
2017/05/22 23:02:54
Can this be added to FeedbackAPI (similar to LogSo
Simon Que
2017/05/23 20:01:19
I don't think so. I assume you mean something like
tbarzic
2017/05/25 22:46:44
I was thinking something along the lines:
class F
Simon Que
2017/05/26 04:34:38
Done.
| |
| 105 return g_log_source_resource_factory.Pointer(); | |
| 106 } | |
| 107 | |
| 108 // Converts from api::feedback_private::LogSource to SupportedSource. | |
| 109 SupportedSource GetSupportedSourceType(LogSource source) { | |
| 110 switch (source) { | |
| 111 case api::feedback_private::LOG_SOURCE_MESSAGES: | |
| 112 return SupportedSource::kMessages; | |
| 113 case api::feedback_private::LOG_SOURCE_UI_LATEST: | |
| 114 return SupportedSource::kUiLatest; | |
| 115 case api::feedback_private::LOG_SOURCE_NONE: | |
| 116 DLOG(FATAL) << "Invalid log source type requested."; | |
| 117 return SingleLogSource::SupportedSource::kMessages; | |
| 118 } | |
| 119 } | |
| 120 #endif // defined(OS_CHROMEOS) | |
| 121 | |
| 85 // static | 122 // static |
| 86 BrowserContextKeyedAPIFactory<FeedbackPrivateAPI>* | 123 BrowserContextKeyedAPIFactory<FeedbackPrivateAPI>* |
| 87 FeedbackPrivateAPI::GetFactoryInstance() { | 124 FeedbackPrivateAPI::GetFactoryInstance() { |
| 88 return g_factory.Pointer(); | 125 return g_factory.Pointer(); |
| 89 } | 126 } |
| 90 | 127 |
| 91 FeedbackPrivateAPI::FeedbackPrivateAPI(content::BrowserContext* context) | 128 FeedbackPrivateAPI::FeedbackPrivateAPI(content::BrowserContext* context) |
| 92 : browser_context_(context), service_(new FeedbackService()) { | 129 : browser_context_(context), service_(new FeedbackService()) { |
| 93 } | 130 } |
| 94 | 131 |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 252 sys_info_entry.key = std::move(itr.first); | 289 sys_info_entry.key = std::move(itr.first); |
| 253 sys_info_entry.value = std::move(itr.second); | 290 sys_info_entry.value = std::move(itr.second); |
| 254 sys_info_list.emplace_back(std::move(sys_info_entry)); | 291 sys_info_list.emplace_back(std::move(sys_info_entry)); |
| 255 } | 292 } |
| 256 } | 293 } |
| 257 | 294 |
| 258 Respond(ArgumentList( | 295 Respond(ArgumentList( |
| 259 feedback_private::GetSystemInformation::Results::Create(sys_info_list))); | 296 feedback_private::GetSystemInformation::Results::Create(sys_info_list))); |
| 260 } | 297 } |
| 261 | 298 |
| 299 #if defined(OS_CHROMEOS) | |
| 300 namespace { | |
| 301 | |
| 302 // The minimum time between consecutive reads of a log source by a particular | |
| 303 // extension. | |
| 304 const int kDefaultRateLimitingTimeoutMs = 1000; | |
| 305 | |
| 306 // If this is null, then |kDefaultRateLimitingTimeoutMs| is used as the timeout. | |
| 307 const base::TimeDelta* g_rate_limiting_timeout = nullptr; | |
| 308 | |
| 309 } // namespace | |
|
tbarzic
2017/05/22 23:02:54
can you move this up, with the rest of the anonymo
Simon Que
2017/05/23 20:01:19
Done.
| |
| 310 | |
| 311 // static | |
| 312 void FeedbackPrivateReadLogSourceFunction::SetRateLimitingTimeoutForTesting( | |
| 313 const base::TimeDelta* timeout) { | |
| 314 g_rate_limiting_timeout = timeout; | |
| 315 } | |
| 316 #endif // defined(OS_CHROMEOS) | |
| 317 | |
| 318 ExtensionFunction::ResponseAction FeedbackPrivateReadLogSourceFunction::Run() { | |
| 319 #if defined(OS_CHROMEOS) | |
| 320 using Params = feedback_private::ReadLogSource::Params; | |
| 321 std::unique_ptr<Params> api_params = Params::Create(*args_); | |
| 322 | |
| 323 int reader_id = | |
| 324 api_params->params.reader_id ? *api_params->params.reader_id : 0; | |
| 325 LogSource source = api_params->params.source; | |
| 326 | |
| 327 LogSourceResourceManager* resource_manager = | |
| 328 LogSourceResourceManager::Get(browser_context()); | |
| 329 DCHECK(resource_manager); | |
| 330 | |
| 331 LogSourceResource* resource = nullptr; | |
| 332 // If the caller passed in a valid ID, look up the ID in the resource manager. | |
| 333 if (reader_id > 0) { | |
| 334 resource = resource_manager->Get(extension_id(), reader_id); | |
| 335 if (!resource) | |
| 336 return EmptyResponse(); | |
|
tbarzic
2017/05/22 23:02:54
I'd go with returning an error instead.
Simon Que
2017/05/23 20:01:18
Done.
| |
| 337 } | |
| 338 | |
| 339 LogSourceAccessManager* log_source_manager = | |
| 340 FeedbackPrivateAPI::GetFactoryInstance() | |
| 341 ->Get(browser_context()) | |
| 342 ->GetLogSourceAccessManager(); | |
| 343 DCHECK(log_source_manager); | |
| 344 | |
| 345 std::pair<LogSource, std::string> source_and_extension = | |
| 346 std::make_pair(source, extension_id()); | |
| 347 | |
| 348 // If caller passed in |reader_id| == 0, create a new SingleLogSource. | |
|
tbarzic
2017/05/22 23:02:54
I'd extract this and if (reader_id > 0) part to a
Simon Que
2017/05/23 20:01:19
Done.
| |
| 349 if (!resource) { | |
| 350 // Enforce the rules: Do not create a new SingleLogSource if there was | |
| 351 // already one created for |source_and_extension|. | |
| 352 if (!log_source_manager->AddExtension(source_and_extension)) | |
| 353 return EmptyResponse(); | |
| 354 | |
| 355 SupportedSource source_type = GetSupportedSourceType(source); | |
| 356 LogSourceResource* new_resource = new LogSourceResource( | |
| 357 extension_id(), | |
| 358 SingleLogSourceFactory::CreateSingleLogSource(source_type), | |
| 359 log_source_manager->GetUnregisterCallback(source_and_extension)); | |
| 360 reader_id = resource_manager->Add(new_resource); | |
|
tbarzic
2017/05/22 23:02:54
can you use unique_ptr as Add method argument (to
Simon Que
2017/05/23 20:01:19
Done.
| |
| 361 resource = new_resource; | |
| 362 } | |
| 363 | |
| 364 // Enforce the rules: rate-limit access to the source from the current | |
| 365 // extension. | |
| 366 base::TimeDelta timeout = | |
| 367 g_rate_limiting_timeout | |
| 368 ? *g_rate_limiting_timeout | |
| 369 : base::TimeDelta::FromMilliseconds(kDefaultRateLimitingTimeoutMs); | |
| 370 base::Time last_access_time = | |
| 371 log_source_manager->GetLastExtensionAccessTime(source_and_extension); | |
|
tbarzic
2017/05/22 23:02:54
can this be checked by log_source_manager->AccessS
Simon Que
2017/05/23 20:01:19
Done.
| |
| 372 if (base::Time::Now() < last_access_time + timeout) | |
| 373 return EmptyResponse(); | |
|
tbarzic
2017/05/22 23:02:54
return proper error
Simon Que
2017/05/23 20:01:19
This is not meant to be an error. The caller does
| |
| 374 | |
| 375 // Now we are ready to access the log source. | |
| 376 log_source_manager->AccessSourceFromExtension(source_and_extension); | |
| 377 | |
| 378 resource->GetLogSource()->Fetch( | |
| 379 base::Bind(&FeedbackPrivateReadLogSourceFunction::OnCompleted, this, | |
| 380 source, reader_id, api_params->params.incremental)); | |
| 381 | |
| 382 return RespondLater(); | |
| 383 #else | |
| 384 return EmptyResponse(); | |
|
tbarzic
2017/05/22 23:02:54
return RespondNow(Error("Not supported"));
Simon Que
2017/05/23 20:01:19
Done.
| |
| 385 #endif // defined(OS_CHROMEOS) | |
| 386 } | |
| 387 | |
| 388 AsyncExtensionFunction::ResponseAction | |
| 389 FeedbackPrivateReadLogSourceFunction::EmptyResponse() { | |
| 390 return RespondNow( | |
| 391 ArgumentList(feedback_private::ReadLogSource::Results::Create( | |
| 392 0, std::vector<std::string>()))); | |
| 393 } | |
| 394 | |
| 395 #if defined(OS_CHROMEOS) | |
| 396 void FeedbackPrivateReadLogSourceFunction::OnCompleted( | |
| 397 LogSource source, | |
| 398 int readerId, | |
|
tbarzic
2017/05/22 23:02:54
nit: reader_id
Simon Que
2017/05/23 20:01:19
Done.
| |
| 399 bool incremental, | |
| 400 system_logs::SystemLogsResponse* response) { | |
| 401 std::vector<std::string> result; | |
| 402 for (const std::pair<std::string, std::string>& pair : *response) { | |
| 403 // TODO(sque): Use std::move? | |
| 404 std::vector<std::string> new_lines = base::SplitString( | |
| 405 pair.second, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); | |
| 406 result.reserve(result.size() + new_lines.size()); | |
| 407 result.insert(result.end(), new_lines.begin(), new_lines.end()); | |
| 408 } | |
| 409 | |
| 410 // If the API call requested a non-incremental access, clean up the | |
| 411 // SingleLogSource by removing its API resource. | |
| 412 if (!incremental) { | |
| 413 LogSourceResourceManager::Get(browser_context()) | |
| 414 ->Remove(extension_id(), readerId); | |
| 415 // Must return readerId=0 when the resource has been deleted. | |
| 416 readerId = 0; | |
| 417 } | |
| 418 | |
| 419 Respond(ArgumentList( | |
| 420 feedback_private::ReadLogSource::Results::Create(readerId, result))); | |
| 421 } | |
| 422 #endif // defined(OS_CHROMEOS) | |
| 423 | |
| 262 bool FeedbackPrivateSendFeedbackFunction::RunAsync() { | 424 bool FeedbackPrivateSendFeedbackFunction::RunAsync() { |
| 263 std::unique_ptr<feedback_private::SendFeedback::Params> params( | 425 std::unique_ptr<feedback_private::SendFeedback::Params> params( |
| 264 feedback_private::SendFeedback::Params::Create(*args_)); | 426 feedback_private::SendFeedback::Params::Create(*args_)); |
| 265 EXTENSION_FUNCTION_VALIDATE(params); | 427 EXTENSION_FUNCTION_VALIDATE(params); |
| 266 | 428 |
| 267 const FeedbackInfo &feedback_info = params->feedback; | 429 const FeedbackInfo &feedback_info = params->feedback; |
| 268 | 430 |
| 269 // Populate feedback data. | 431 // Populate feedback data. |
| 270 scoped_refptr<FeedbackData> feedback_data(new FeedbackData()); | 432 scoped_refptr<FeedbackData> feedback_data(new FeedbackData()); |
| 271 feedback_data->set_context(GetProfile()); | 433 feedback_data->set_context(GetProfile()); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 358 case feedback_private::SRT_PROMPT_RESULT_CLOSED: | 520 case feedback_private::SRT_PROMPT_RESULT_CLOSED: |
| 359 base::RecordAction(base::UserMetricsAction("Feedback.SrtPromptClosed")); | 521 base::RecordAction(base::UserMetricsAction("Feedback.SrtPromptClosed")); |
| 360 break; | 522 break; |
| 361 default: | 523 default: |
| 362 return RespondNow(Error("Invalid arugment.")); | 524 return RespondNow(Error("Invalid arugment.")); |
| 363 } | 525 } |
| 364 return RespondNow(NoArguments()); | 526 return RespondNow(NoArguments()); |
| 365 } | 527 } |
| 366 | 528 |
| 367 } // namespace extensions | 529 } // namespace extensions |
| OLD | NEW |