Home | History | Annotate | Download | only in feedback_private
      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_service.h"
      6 
      7 #include "base/callback.h"
      8 #include "base/memory/weak_ptr.h"
      9 #include "base/strings/string_number_conversions.h"
     10 #include "chrome/browser/browser_process.h"
     11 #include "chrome/browser/profiles/profile.h"
     12 #include "chrome/common/chrome_content_client.h"
     13 #include "content/public/browser/browser_thread.h"
     14 
     15 using content::BrowserThread;
     16 using feedback::FeedbackData;
     17 
     18 namespace {
     19 
     20 void PopulateSystemInfo(
     21     extensions::SystemInformationList* sys_info_list,
     22     const std::string& key,
     23     const std::string& value) {
     24   base::DictionaryValue sys_info_value;
     25   sys_info_value.Set("key", new base::StringValue(key));
     26   sys_info_value.Set("value", new base::StringValue(value));
     27 
     28   linked_ptr<SystemInformation> sys_info(new SystemInformation());
     29   SystemInformation::Populate(sys_info_value, sys_info.get());
     30 
     31   sys_info_list->push_back(sys_info);
     32 }
     33 
     34 }  // namespace
     35 
     36 namespace extensions {
     37 
     38 FeedbackService::FeedbackService() {
     39 }
     40 
     41 FeedbackService::~FeedbackService() {
     42 }
     43 
     44 void FeedbackService::SendFeedback(
     45     Profile* profile,
     46     scoped_refptr<FeedbackData> feedback_data,
     47     const SendFeedbackCallback& callback) {
     48   send_feedback_callback_ = callback;
     49   feedback_data_ = feedback_data;
     50   feedback_data_->set_locale(g_browser_process->GetApplicationLocale());
     51   feedback_data_->set_user_agent(GetUserAgent());
     52 
     53   if (!feedback_data_->attached_file_uuid().empty()) {
     54     // Self-deleting object.
     55     BlobReader* attached_file_reader = new BlobReader(
     56         profile, feedback_data_->attached_file_uuid(),
     57         base::Bind(&FeedbackService::AttachedFileCallback,
     58                    GetWeakPtr()));
     59     attached_file_reader->Start();
     60   }
     61 
     62   if (!feedback_data_->screenshot_uuid().empty()) {
     63     // Self-deleting object.
     64     BlobReader* screenshot_reader = new BlobReader(
     65         profile, feedback_data_->screenshot_uuid(),
     66         base::Bind(&FeedbackService::ScreenshotCallback,
     67                    GetWeakPtr()));
     68     screenshot_reader->Start();
     69   }
     70 
     71   CompleteSendFeedback();
     72 }
     73 
     74 void FeedbackService::AttachedFileCallback(scoped_ptr<std::string> data,
     75                                            int64 /* total_blob_length */) {
     76   feedback_data_->set_attached_file_uuid(std::string());
     77   if (data)
     78     feedback_data_->AttachAndCompressFileData(data.Pass());
     79 
     80   CompleteSendFeedback();
     81 }
     82 
     83 void FeedbackService::ScreenshotCallback(scoped_ptr<std::string> data,
     84                                          int64 /* total_blob_length */) {
     85   feedback_data_->set_screenshot_uuid(std::string());
     86   if (data)
     87     feedback_data_->set_image(data.Pass());
     88 
     89   CompleteSendFeedback();
     90 }
     91 
     92 void FeedbackService::GetSystemInformation(
     93     const GetSystemInformationCallback& callback) {
     94   system_information_callback_ = callback;
     95 
     96   system_logs::ScrubbedSystemLogsFetcher* fetcher =
     97       new system_logs::ScrubbedSystemLogsFetcher();
     98   fetcher->Fetch(base::Bind(&FeedbackService::OnSystemLogsFetchComplete,
     99                             GetWeakPtr()));
    100 }
    101 
    102 
    103 void FeedbackService::OnSystemLogsFetchComplete(
    104     scoped_ptr<system_logs::SystemLogsResponse> sys_info_map) {
    105   SystemInformationList sys_info_list;
    106   if (!sys_info_map.get()) {
    107     system_information_callback_.Run(sys_info_list);
    108     return;
    109   }
    110 
    111   for (system_logs::SystemLogsResponse::iterator it = sys_info_map->begin();
    112        it != sys_info_map->end(); ++it)
    113     PopulateSystemInfo(&sys_info_list, it->first, it->second);
    114 
    115   system_information_callback_.Run(sys_info_list);
    116 }
    117 
    118 void FeedbackService::CompleteSendFeedback() {
    119   // A particular data collection is considered completed if,
    120   // a.) The blob URL is invalid - this will either happen because we never had
    121   //     a URL and never needed to read this data, or that the data read failed
    122   //     and we set it to invalid in the data read callback.
    123   // b.) The associated data object exists, meaning that the data has been read
    124   //     and the read callback has updated the associated data on the feedback
    125   //     object.
    126   bool attached_file_completed = feedback_data_->attached_file_uuid().empty();
    127   bool screenshot_completed = feedback_data_->screenshot_uuid().empty();
    128 
    129   if (screenshot_completed && attached_file_completed) {
    130     // Signal the feedback object that the data from the feedback page has been
    131     // filled - the object will manage sending of the actual report.
    132     feedback_data_->OnFeedbackPageDataComplete();
    133     // TODO(rkc): Change this once we have FeedbackData/Util refactored to
    134     // report the status of the report being sent.
    135     send_feedback_callback_.Run(true);
    136   }
    137 }
    138 
    139 }  // namespace extensions
    140