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.
5 #include "chrome/browser/extensions/api/sync_file_system/extension_sync_event_observer.h"
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 "storage/browser/fileapi/file_system_url.h"
21 #include "storage/common/fileapi/file_system_util.h"
23 using sync_file_system::SyncEventObserver
;
25 namespace extensions
{
27 static base::LazyInstance
<
28 BrowserContextKeyedAPIFactory
<ExtensionSyncEventObserver
> > g_factory
=
29 LAZY_INSTANCE_INITIALIZER
;
32 BrowserContextKeyedAPIFactory
<ExtensionSyncEventObserver
>*
33 ExtensionSyncEventObserver::GetFactoryInstance() {
34 return g_factory
.Pointer();
37 ExtensionSyncEventObserver::ExtensionSyncEventObserver(
38 content::BrowserContext
* context
)
39 : browser_context_(context
), sync_service_(NULL
) {}
41 void ExtensionSyncEventObserver::InitializeForService(
42 sync_file_system::SyncFileSystemService
* sync_service
) {
44 if (sync_service_
!= NULL
) {
45 DCHECK_EQ(sync_service_
, sync_service
);
48 sync_service_
= sync_service
;
49 sync_service_
->AddSyncEventObserver(this);
52 ExtensionSyncEventObserver::~ExtensionSyncEventObserver() {}
54 void ExtensionSyncEventObserver::Shutdown() {
55 if (sync_service_
!= NULL
)
56 sync_service_
->RemoveSyncEventObserver(this);
59 std::string
ExtensionSyncEventObserver::GetExtensionId(
60 const GURL
& app_origin
) {
61 const Extension
* app
= ExtensionRegistry::Get(browser_context_
)
62 ->enabled_extensions().GetAppByURL(app_origin
);
64 // The app is uninstalled or disabled.
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
));
81 BroadcastOrDispatchEvent(
82 app_origin
, events::SYNC_FILE_SYSTEM_ON_SERVICE_STATUS_CHANGED
,
83 api::sync_file_system::OnServiceStatusChanged::kEventName
, params
.Pass());
86 void ExtensionSyncEventObserver::OnFileSynced(
87 const storage::FileSystemURL
& url
,
88 sync_file_system::SyncFileType file_type
,
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());
94 scoped_ptr
<base::DictionaryValue
> entry(
95 CreateDictionaryValueForFileSystemEntry(url
, file_type
));
98 params
->Append(entry
.release());
100 // Status, SyncAction and any optional notes to go here.
101 api::sync_file_system::FileStatus status_enum
=
102 SyncFileStatusToExtensionEnum(status
);
103 api::sync_file_system::SyncAction action_enum
=
104 SyncActionToExtensionEnum(action
);
105 api::sync_file_system::SyncDirection direction_enum
=
106 SyncDirectionToExtensionEnum(direction
);
107 params
->AppendString(api::sync_file_system::ToString(status_enum
));
108 params
->AppendString(api::sync_file_system::ToString(action_enum
));
109 params
->AppendString(api::sync_file_system::ToString(direction_enum
));
111 BroadcastOrDispatchEvent(
112 url
.origin(), events::SYNC_FILE_SYSTEM_ON_FILE_STATUS_CHANGED
,
113 api::sync_file_system::OnFileStatusChanged::kEventName
, params
.Pass());
116 void ExtensionSyncEventObserver::BroadcastOrDispatchEvent(
117 const GURL
& app_origin
,
118 events::HistogramValue histogram_value
,
119 const std::string
& event_name
,
120 scoped_ptr
<base::ListValue
> values
) {
121 // Check to see whether the event should be broadcasted to all listening
122 // extensions or sent to a specific extension ID.
123 bool broadcast_mode
= app_origin
.is_empty();
124 EventRouter
* event_router
= EventRouter::Get(browser_context_
);
125 DCHECK(event_router
);
127 scoped_ptr
<Event
> event(
128 new Event(histogram_value
, event_name
, values
.Pass()));
129 event
->restrict_to_browser_context
= browser_context_
;
131 // No app_origin, broadcast to all listening extensions for this event name.
132 if (broadcast_mode
) {
133 event_router
->BroadcastEvent(event
.Pass());
137 // Dispatch to single extension ID.
138 const std::string extension_id
= GetExtensionId(app_origin
);
139 if (extension_id
.empty())
141 event_router
->DispatchEventToExtension(extension_id
, event
.Pass());
145 void BrowserContextKeyedAPIFactory
<
146 ExtensionSyncEventObserver
>::DeclareFactoryDependencies() {
147 DependsOn(sync_file_system::SyncFileSystemServiceFactory::GetInstance());
148 DependsOn(ExtensionsBrowserClient::Get()->GetExtensionSystemFactory());
151 } // namespace extensions