extension_sync_event_observer.cc revision 3551c9c881056c480085172ff9840cab31610854
1// Copyright (c) 2012 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/sync_file_system/extension_sync_event_observer.h"
6
7#include "chrome/browser/extensions/api/sync_file_system/sync_file_system_api_helpers.h"
8#include "chrome/browser/extensions/event_names.h"
9#include "chrome/browser/extensions/event_router.h"
10#include "chrome/browser/extensions/extension_service.h"
11#include "chrome/browser/extensions/extension_system.h"
12#include "chrome/browser/sync_file_system/sync_event_observer.h"
13#include "chrome/browser/sync_file_system/sync_file_system_service.h"
14#include "chrome/browser/sync_file_system/syncable_file_system_util.h"
15#include "chrome/common/extensions/api/sync_file_system.h"
16#include "webkit/browser/fileapi/file_system_url.h"
17#include "webkit/common/fileapi/file_system_util.h"
18
19using sync_file_system::SyncEventObserver;
20
21namespace extensions {
22
23ExtensionSyncEventObserver::ExtensionSyncEventObserver(
24    Profile* profile)
25    : profile_(profile),
26      sync_service_(NULL) {}
27
28void ExtensionSyncEventObserver::InitializeForService(
29    sync_file_system::SyncFileSystemService* sync_service) {
30  DCHECK(sync_service);
31  if (sync_service_ != NULL) {
32    DCHECK_EQ(sync_service_, sync_service);
33    return;
34  }
35  sync_service_ = sync_service;
36  sync_service_->AddSyncEventObserver(this);
37}
38
39ExtensionSyncEventObserver::~ExtensionSyncEventObserver() {}
40
41void ExtensionSyncEventObserver::Shutdown() {
42  if (sync_service_ != NULL)
43    sync_service_->RemoveSyncEventObserver(this);
44}
45
46std::string ExtensionSyncEventObserver::GetExtensionId(
47    const GURL& app_origin) {
48  const Extension* app = ExtensionSystem::Get(profile_)->extension_service()->
49      GetInstalledApp(app_origin);
50  if (!app) {
51    // The app is uninstalled or disabled.
52    return std::string();
53  }
54  return app->id();
55}
56
57void ExtensionSyncEventObserver::OnSyncStateUpdated(
58    const GURL& app_origin,
59    sync_file_system::SyncServiceState state,
60    const std::string& description) {
61  // Convert state and description into SyncState Object.
62  api::sync_file_system::ServiceInfo service_info;
63  service_info.state = SyncServiceStateToExtensionEnum(state);
64  service_info.description = description;
65  scoped_ptr<base::ListValue> params(
66      api::sync_file_system::OnServiceStatusChanged::Create(service_info));
67
68  BroadcastOrDispatchEvent(
69      app_origin,
70      api::sync_file_system::OnServiceStatusChanged::kEventName,
71      params.Pass());
72}
73
74void ExtensionSyncEventObserver::OnFileSynced(
75    const fileapi::FileSystemURL& url,
76    sync_file_system::SyncFileStatus status,
77    sync_file_system::SyncAction action,
78    sync_file_system::SyncDirection direction) {
79  scoped_ptr<base::ListValue> params(new base::ListValue());
80
81  // For now we always assume events come only for files (not directories).
82  params->Append(CreateDictionaryValueForFileSystemEntry(
83      url, sync_file_system::SYNC_FILE_TYPE_FILE));
84
85  // Status, SyncAction and any optional notes to go here.
86  api::sync_file_system::FileStatus status_enum =
87      SyncFileStatusToExtensionEnum(status);
88  api::sync_file_system::SyncAction action_enum =
89      SyncActionToExtensionEnum(action);
90  api::sync_file_system::SyncDirection direction_enum =
91      SyncDirectionToExtensionEnum(direction);
92  params->AppendString(api::sync_file_system::ToString(status_enum));
93  params->AppendString(api::sync_file_system::ToString(action_enum));
94  params->AppendString(api::sync_file_system::ToString(direction_enum));
95
96  BroadcastOrDispatchEvent(
97      url.origin(),
98      api::sync_file_system::OnFileStatusChanged::kEventName,
99      params.Pass());
100}
101
102void ExtensionSyncEventObserver::BroadcastOrDispatchEvent(
103    const GURL& app_origin,
104    const std::string& event_name,
105    scoped_ptr<base::ListValue> values) {
106  // Check to see whether the event should be broadcasted to all listening
107  // extensions or sent to a specific extension ID.
108  bool broadcast_mode = app_origin.is_empty();
109  EventRouter* event_router = ExtensionSystem::Get(profile_)->event_router();
110  DCHECK(event_router);
111
112  scoped_ptr<Event> event(new Event(event_name, values.Pass()));
113  event->restrict_to_profile = profile_;
114
115  // No app_origin, broadcast to all listening extensions for this event name.
116  if (broadcast_mode) {
117    event_router->BroadcastEvent(event.Pass());
118    return;
119  }
120
121  // Dispatch to single extension ID.
122  const std::string extension_id = GetExtensionId(app_origin);
123  if (extension_id.empty())
124    return;
125  event_router->DispatchEventToExtension(extension_id, event.Pass());
126}
127
128}  // namespace extensions
129