Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / sync_file_system / extension_sync_event_observer.cc
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 "base/lazy_instance.h"
8 #include "chrome/browser/extensions/api/sync_file_system/sync_file_system_api_helpers.h"
9 #include "chrome/browser/sync_file_system/sync_event_observer.h"
10 #include "chrome/browser/sync_file_system/sync_file_system_service.h"
11 #include "chrome/browser/sync_file_system/sync_file_system_service_factory.h"
12 #include "chrome/browser/sync_file_system/syncable_file_system_util.h"
13 #include "chrome/common/extensions/api/sync_file_system.h"
14 #include "content/public/browser/browser_context.h"
15 #include "extensions/browser/event_router.h"
16 #include "extensions/browser/extension_registry.h"
17 #include "extensions/browser/extension_system_provider.h"
18 #include "extensions/browser/extensions_browser_client.h"
19 #include "extensions/common/extension_set.h"
20 #include "webkit/browser/fileapi/file_system_url.h"
21 #include "webkit/common/fileapi/file_system_util.h"
22
23 using sync_file_system::SyncEventObserver;
24
25 namespace extensions {
26
27 static base::LazyInstance<
28     BrowserContextKeyedAPIFactory<ExtensionSyncEventObserver> > g_factory =
29     LAZY_INSTANCE_INITIALIZER;
30
31 // static
32 BrowserContextKeyedAPIFactory<ExtensionSyncEventObserver>*
33 ExtensionSyncEventObserver::GetFactoryInstance() {
34   return g_factory.Pointer();
35 }
36
37 ExtensionSyncEventObserver::ExtensionSyncEventObserver(
38     content::BrowserContext* context)
39     : browser_context_(context), sync_service_(NULL) {}
40
41 void ExtensionSyncEventObserver::InitializeForService(
42     sync_file_system::SyncFileSystemService* sync_service) {
43   DCHECK(sync_service);
44   if (sync_service_ != NULL) {
45     DCHECK_EQ(sync_service_, sync_service);
46     return;
47   }
48   sync_service_ = sync_service;
49   sync_service_->AddSyncEventObserver(this);
50 }
51
52 ExtensionSyncEventObserver::~ExtensionSyncEventObserver() {}
53
54 void ExtensionSyncEventObserver::Shutdown() {
55   if (sync_service_ != NULL)
56     sync_service_->RemoveSyncEventObserver(this);
57 }
58
59 std::string ExtensionSyncEventObserver::GetExtensionId(
60     const GURL& app_origin) {
61   const Extension* app = ExtensionRegistry::Get(browser_context_)
62       ->enabled_extensions().GetAppByURL(app_origin);
63   if (!app) {
64     // The app is uninstalled or disabled.
65     return std::string();
66   }
67   return app->id();
68 }
69
70 void ExtensionSyncEventObserver::OnSyncStateUpdated(
71     const GURL& app_origin,
72     sync_file_system::SyncServiceState state,
73     const std::string& description) {
74   // Convert state and description into SyncState Object.
75   api::sync_file_system::ServiceInfo service_info;
76   service_info.state = SyncServiceStateToExtensionEnum(state);
77   service_info.description = description;
78   scoped_ptr<base::ListValue> params(
79       api::sync_file_system::OnServiceStatusChanged::Create(service_info));
80
81   BroadcastOrDispatchEvent(
82       app_origin,
83       api::sync_file_system::OnServiceStatusChanged::kEventName,
84       params.Pass());
85 }
86
87 void ExtensionSyncEventObserver::OnFileSynced(
88     const fileapi::FileSystemURL& url,
89     sync_file_system::SyncFileStatus status,
90     sync_file_system::SyncAction action,
91     sync_file_system::SyncDirection direction) {
92   scoped_ptr<base::ListValue> params(new base::ListValue());
93
94   // For now we always assume events come only for files (not directories).
95   scoped_ptr<base::DictionaryValue> entry(
96       CreateDictionaryValueForFileSystemEntry(
97           url, sync_file_system::SYNC_FILE_TYPE_FILE));
98   if (!entry)
99     return;
100   params->Append(entry.release());
101
102   // Status, SyncAction and any optional notes to go here.
103   api::sync_file_system::FileStatus status_enum =
104       SyncFileStatusToExtensionEnum(status);
105   api::sync_file_system::SyncAction action_enum =
106       SyncActionToExtensionEnum(action);
107   api::sync_file_system::SyncDirection direction_enum =
108       SyncDirectionToExtensionEnum(direction);
109   params->AppendString(api::sync_file_system::ToString(status_enum));
110   params->AppendString(api::sync_file_system::ToString(action_enum));
111   params->AppendString(api::sync_file_system::ToString(direction_enum));
112
113   BroadcastOrDispatchEvent(
114       url.origin(),
115       api::sync_file_system::OnFileStatusChanged::kEventName,
116       params.Pass());
117 }
118
119 void ExtensionSyncEventObserver::BroadcastOrDispatchEvent(
120     const GURL& app_origin,
121     const std::string& event_name,
122     scoped_ptr<base::ListValue> values) {
123   // Check to see whether the event should be broadcasted to all listening
124   // extensions or sent to a specific extension ID.
125   bool broadcast_mode = app_origin.is_empty();
126   EventRouter* event_router = EventRouter::Get(browser_context_);
127   DCHECK(event_router);
128
129   scoped_ptr<Event> event(new Event(event_name, values.Pass()));
130   event->restrict_to_browser_context = browser_context_;
131
132   // No app_origin, broadcast to all listening extensions for this event name.
133   if (broadcast_mode) {
134     event_router->BroadcastEvent(event.Pass());
135     return;
136   }
137
138   // Dispatch to single extension ID.
139   const std::string extension_id = GetExtensionId(app_origin);
140   if (extension_id.empty())
141     return;
142   event_router->DispatchEventToExtension(extension_id, event.Pass());
143 }
144
145 template <>
146 void BrowserContextKeyedAPIFactory<
147     ExtensionSyncEventObserver>::DeclareFactoryDependencies() {
148   DependsOn(sync_file_system::SyncFileSystemServiceFactory::GetInstance());
149   DependsOn(ExtensionsBrowserClient::Get()->GetExtensionSystemFactory());
150 }
151
152 }  // namespace extensions