Home | History | Annotate | Download | only in sync_file_system_internals
      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/ui/webui/sync_file_system_internals/sync_file_system_internals_handler.h"
      6 
      7 #include <vector>
      8 
      9 #include "base/bind.h"
     10 #include "base/bind_helpers.h"
     11 #include "base/values.h"
     12 #include "chrome/browser/drive/drive_notification_manager.h"
     13 #include "chrome/browser/drive/drive_notification_manager_factory.h"
     14 #include "chrome/browser/extensions/api/sync_file_system/sync_file_system_api_helpers.h"
     15 #include "chrome/browser/profiles/profile.h"
     16 #include "chrome/browser/sync_file_system/logger.h"
     17 #include "chrome/browser/sync_file_system/sync_file_system_service.h"
     18 #include "chrome/browser/sync_file_system/sync_file_system_service_factory.h"
     19 #include "chrome/browser/sync_file_system/sync_service_state.h"
     20 #include "chrome/common/extensions/api/sync_file_system.h"
     21 #include "content/public/browser/storage_partition.h"
     22 #include "content/public/browser/web_ui.h"
     23 #include "google_apis/drive/time_util.h"
     24 
     25 using drive::EventLogger;
     26 using sync_file_system::SyncFileSystemServiceFactory;
     27 using sync_file_system::SyncServiceState;
     28 
     29 namespace syncfs_internals {
     30 
     31 SyncFileSystemInternalsHandler::SyncFileSystemInternalsHandler(Profile* profile)
     32     : profile_(profile),
     33       observing_task_log_(false) {
     34   sync_file_system::SyncFileSystemService* sync_service =
     35       SyncFileSystemServiceFactory::GetForProfile(profile);
     36   if (sync_service)
     37     sync_service->AddSyncEventObserver(this);
     38 }
     39 
     40 SyncFileSystemInternalsHandler::~SyncFileSystemInternalsHandler() {
     41   sync_file_system::SyncFileSystemService* sync_service =
     42       SyncFileSystemServiceFactory::GetForProfile(profile_);
     43   if (!sync_service)
     44     return;
     45   sync_service->RemoveSyncEventObserver(this);
     46   if (observing_task_log_)
     47     sync_service->task_logger()->RemoveObserver(this);
     48 }
     49 
     50 void SyncFileSystemInternalsHandler::RegisterMessages() {
     51   web_ui()->RegisterMessageCallback(
     52       "getServiceStatus",
     53       base::Bind(&SyncFileSystemInternalsHandler::GetServiceStatus,
     54                  base::Unretained(this)));
     55   web_ui()->RegisterMessageCallback(
     56       "getLog",
     57       base::Bind(&SyncFileSystemInternalsHandler::GetLog,
     58                  base::Unretained(this)));
     59   web_ui()->RegisterMessageCallback(
     60       "clearLogs",
     61       base::Bind(&SyncFileSystemInternalsHandler::ClearLogs,
     62                  base::Unretained(this)));
     63   web_ui()->RegisterMessageCallback(
     64       "getNotificationSource",
     65       base::Bind(&SyncFileSystemInternalsHandler::GetNotificationSource,
     66                  base::Unretained(this)));
     67   web_ui()->RegisterMessageCallback(
     68       "observeTaskLog",
     69       base::Bind(&SyncFileSystemInternalsHandler::ObserveTaskLog,
     70                  base::Unretained(this)));
     71 }
     72 
     73 void SyncFileSystemInternalsHandler::OnSyncStateUpdated(
     74     const GURL& app_origin,
     75     sync_file_system::SyncServiceState state,
     76     const std::string& description) {
     77   std::string state_string = extensions::api::sync_file_system::ToString(
     78         extensions::SyncServiceStateToExtensionEnum(state));
     79   if (!description.empty())
     80     state_string += " (" + description + ")";
     81 
     82   // TODO(calvinlo): OnSyncStateUpdated should be updated to also provide the
     83   // notification mechanism (XMPP or Polling).
     84   web_ui()->CallJavascriptFunction("SyncService.onGetServiceStatus",
     85                                    base::StringValue(state_string));
     86 }
     87 
     88 void SyncFileSystemInternalsHandler::OnFileSynced(
     89     const storage::FileSystemURL& url,
     90     sync_file_system::SyncFileStatus status,
     91     sync_file_system::SyncAction action,
     92     sync_file_system::SyncDirection direction) {
     93 }
     94 
     95 void SyncFileSystemInternalsHandler::OnLogRecorded(
     96     const sync_file_system::TaskLogger::TaskLog& task_log) {
     97   base::DictionaryValue dict;
     98   int64 duration = (task_log.end_time - task_log.start_time).InMilliseconds();
     99   dict.SetInteger("duration", duration);
    100   dict.SetString("task_description", task_log.task_description);
    101   dict.SetString("result_description", task_log.result_description);
    102 
    103   scoped_ptr<base::ListValue> details(new base::ListValue);
    104   details->AppendStrings(task_log.details);
    105   dict.Set("details", details.release());
    106   web_ui()->CallJavascriptFunction("TaskLog.onTaskLogRecorded", dict);
    107 }
    108 
    109 void SyncFileSystemInternalsHandler::GetServiceStatus(
    110     const base::ListValue* args) {
    111   SyncServiceState state_enum = sync_file_system::SYNC_SERVICE_DISABLED;
    112   sync_file_system::SyncFileSystemService* sync_service =
    113       SyncFileSystemServiceFactory::GetForProfile(profile_);
    114   if (sync_service)
    115     state_enum = sync_service->GetSyncServiceState();
    116   const std::string state_string = extensions::api::sync_file_system::ToString(
    117       extensions::SyncServiceStateToExtensionEnum(state_enum));
    118   web_ui()->CallJavascriptFunction("SyncService.onGetServiceStatus",
    119                                    base::StringValue(state_string));
    120 }
    121 
    122 void SyncFileSystemInternalsHandler::GetNotificationSource(
    123     const base::ListValue* args) {
    124   drive::DriveNotificationManager* drive_notification_manager =
    125       drive::DriveNotificationManagerFactory::FindForBrowserContext(profile_);
    126   if (!drive_notification_manager)
    127     return;
    128   bool xmpp_enabled = drive_notification_manager->push_notification_enabled();
    129   std::string notification_source = xmpp_enabled ? "XMPP" : "Polling";
    130   web_ui()->CallJavascriptFunction("SyncService.onGetNotificationSource",
    131                                    base::StringValue(notification_source));
    132 }
    133 
    134 void SyncFileSystemInternalsHandler::GetLog(
    135     const base::ListValue* args) {
    136   const std::vector<EventLogger::Event> log =
    137       sync_file_system::util::GetLogHistory();
    138 
    139   int last_log_id_sent;
    140   if (!args->GetInteger(0, &last_log_id_sent))
    141     last_log_id_sent = -1;
    142 
    143   // Collate events which haven't been sent to WebUI yet.
    144   base::ListValue list;
    145   for (std::vector<EventLogger::Event>::const_iterator log_entry = log.begin();
    146        log_entry != log.end();
    147        ++log_entry) {
    148     if (log_entry->id <= last_log_id_sent)
    149       continue;
    150 
    151     base::DictionaryValue* dict = new base::DictionaryValue;
    152     dict->SetInteger("id", log_entry->id);
    153     dict->SetString("time",
    154         google_apis::util::FormatTimeAsStringLocaltime(log_entry->when));
    155     dict->SetString("logEvent", log_entry->what);
    156     list.Append(dict);
    157     last_log_id_sent = log_entry->id;
    158   }
    159   if (list.empty())
    160     return;
    161 
    162   web_ui()->CallJavascriptFunction("SyncService.onGetLog", list);
    163 }
    164 
    165 void SyncFileSystemInternalsHandler::ClearLogs(const base::ListValue* args) {
    166   sync_file_system::util::ClearLog();
    167 }
    168 
    169 void SyncFileSystemInternalsHandler::ObserveTaskLog(
    170     const base::ListValue* args) {
    171   sync_file_system::SyncFileSystemService* sync_service =
    172       SyncFileSystemServiceFactory::GetForProfile(profile_);
    173   if (!sync_service)
    174     return;
    175   if (!observing_task_log_) {
    176     observing_task_log_ = true;
    177     sync_service->task_logger()->AddObserver(this);
    178   }
    179 
    180   DCHECK(sync_service->task_logger());
    181   const sync_file_system::TaskLogger::LogList& log =
    182       sync_service->task_logger()->GetLog();
    183 
    184   for (sync_file_system::TaskLogger::LogList::const_iterator itr = log.begin();
    185        itr != log.end(); ++itr)
    186     OnLogRecorded(**itr);
    187 }
    188 
    189 }  // namespace syncfs_internals
    190