Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / media_galleries_private / media_galleries_private_api.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/media_galleries_private/media_galleries_private_api.h"
6
7 #include "base/basictypes.h"
8 #include "base/bind.h"
9 #include "base/files/file_path.h"
10 #include "base/lazy_instance.h"
11 #include "base/location.h"
12 #include "base/prefs/pref_service.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "chrome/browser/browser_process.h"
15 #include "chrome/browser/extensions/api/media_galleries_private/gallery_watch_manager.h"
16 #include "chrome/browser/extensions/api/media_galleries_private/media_galleries_private_event_router.h"
17 #include "chrome/browser/extensions/extension_util.h"
18 #include "chrome/browser/media_galleries/media_file_system_registry.h"
19 #include "chrome/browser/media_galleries/media_galleries_preferences.h"
20 #include "chrome/browser/profiles/profile.h"
21 #include "content/public/browser/browser_thread.h"
22 #include "content/public/browser/render_view_host.h"
23 #include "extensions/browser/event_router.h"
24 #include "extensions/browser/extension_function.h"
25 #include "extensions/browser/extension_system.h"
26
27 using base::DictionaryValue;
28 using base::ListValue;
29
30 namespace extensions {
31
32 namespace AddGalleryWatch =
33     extensions::api::media_galleries_private::AddGalleryWatch;
34 namespace RemoveGalleryWatch =
35     extensions::api::media_galleries_private::RemoveGalleryWatch;
36 namespace GetAllGalleryWatch =
37     extensions::api::media_galleries_private::GetAllGalleryWatch;
38 namespace media_galleries_private =
39     api::media_galleries_private;
40
41 namespace {
42
43 const char kInvalidGalleryIDError[] = "Invalid gallery ID";
44
45 // Handles the profile shutdown event on the file thread to clean up
46 // GalleryWatchManager.
47 void HandleProfileShutdownOnFileThread(void* profile_id) {
48   DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
49   GalleryWatchManager::OnProfileShutdown(profile_id);
50 }
51
52 // Returns true and sets |gallery_file_path| and |gallery_pref_id| if the
53 // |gallery_id| is valid and returns false otherwise.
54 bool GetGalleryFilePathAndId(const std::string& gallery_id,
55                              Profile* profile,
56                              const Extension* extension,
57                              base::FilePath* gallery_file_path,
58                              MediaGalleryPrefId* gallery_pref_id) {
59   MediaGalleryPrefId pref_id;
60   if (!base::StringToUint64(gallery_id, &pref_id))
61     return false;
62   MediaGalleriesPreferences* preferences =
63       g_browser_process->media_file_system_registry()->GetPreferences(profile);
64   base::FilePath file_path(
65       preferences->LookUpGalleryPathForExtension(pref_id, extension, false));
66   if (file_path.empty())
67     return false;
68   *gallery_pref_id = pref_id;
69   *gallery_file_path = file_path;
70   return true;
71 }
72
73 }  // namespace
74
75
76 ///////////////////////////////////////////////////////////////////////////////
77 //                      MediaGalleriesPrivateAPI                             //
78 ///////////////////////////////////////////////////////////////////////////////
79
80 MediaGalleriesPrivateAPI::MediaGalleriesPrivateAPI(
81     content::BrowserContext* context)
82     : profile_(Profile::FromBrowserContext(context)), weak_ptr_factory_(this) {
83   DCHECK(profile_);
84   EventRouter* event_router = EventRouter::Get(profile_);
85   event_router->RegisterObserver(
86       this, media_galleries_private::OnGalleryChanged::kEventName);
87 }
88
89 MediaGalleriesPrivateAPI::~MediaGalleriesPrivateAPI() {
90 }
91
92 void MediaGalleriesPrivateAPI::Shutdown() {
93   EventRouter::Get(profile_)->UnregisterObserver(this);
94   weak_ptr_factory_.InvalidateWeakPtrs();
95   content::BrowserThread::PostTask(
96       content::BrowserThread::FILE, FROM_HERE,
97       base::Bind(&HandleProfileShutdownOnFileThread, profile_));
98 }
99
100 static base::LazyInstance<
101     BrowserContextKeyedAPIFactory<MediaGalleriesPrivateAPI> > g_factory =
102     LAZY_INSTANCE_INITIALIZER;
103
104 // static
105 BrowserContextKeyedAPIFactory<MediaGalleriesPrivateAPI>*
106 MediaGalleriesPrivateAPI::GetFactoryInstance() {
107   return g_factory.Pointer();
108 }
109
110 // static
111 MediaGalleriesPrivateAPI* MediaGalleriesPrivateAPI::Get(
112     content::BrowserContext* context) {
113   return BrowserContextKeyedAPIFactory<MediaGalleriesPrivateAPI>::Get(context);
114 }
115
116 void MediaGalleriesPrivateAPI::OnListenerAdded(
117     const EventListenerInfo& details) {
118   // Make sure MediaGalleriesPreferences is initialized. After that,
119   // try to initialize the event router for the listener.
120   // This method is called synchronously with the message handler for the
121   // JS invocation.
122
123   MediaGalleriesPreferences* preferences =
124       g_browser_process->media_file_system_registry()->GetPreferences(profile_);
125   preferences->EnsureInitialized(base::Bind(
126       &MediaGalleriesPrivateAPI::MaybeInitializeEventRouterAndTracker,
127       weak_ptr_factory_.GetWeakPtr()));
128 }
129
130 MediaGalleriesPrivateEventRouter* MediaGalleriesPrivateAPI::GetEventRouter() {
131   MaybeInitializeEventRouterAndTracker();
132   return media_galleries_private_event_router_.get();
133 }
134
135 GalleryWatchStateTracker*
136 MediaGalleriesPrivateAPI::GetGalleryWatchStateTracker() {
137   MaybeInitializeEventRouterAndTracker();
138   return tracker_.get();
139 }
140
141 void MediaGalleriesPrivateAPI::MaybeInitializeEventRouterAndTracker() {
142   if (media_galleries_private_event_router_.get())
143     return;
144   media_galleries_private_event_router_.reset(
145       new MediaGalleriesPrivateEventRouter(profile_));
146   DCHECK(g_browser_process->media_file_system_registry()->
147              GetPreferences(profile_)->IsInitialized());
148   tracker_.reset(
149       new GalleryWatchStateTracker(profile_));
150 }
151
152 ///////////////////////////////////////////////////////////////////////////////
153 //              MediaGalleriesPrivateAddGalleryWatchFunction                 //
154 ///////////////////////////////////////////////////////////////////////////////
155 MediaGalleriesPrivateAddGalleryWatchFunction::
156 ~MediaGalleriesPrivateAddGalleryWatchFunction() {
157 }
158
159 bool MediaGalleriesPrivateAddGalleryWatchFunction::RunAsync() {
160   DCHECK(GetProfile());
161   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
162   if (!render_view_host() || !render_view_host()->GetProcess())
163     return false;
164
165   scoped_ptr<AddGalleryWatch::Params> params(
166       AddGalleryWatch::Params::Create(*args_));
167   EXTENSION_FUNCTION_VALIDATE(params.get());
168
169   MediaGalleriesPreferences* preferences =
170       g_browser_process->media_file_system_registry()->GetPreferences(
171           GetProfile());
172   preferences->EnsureInitialized(base::Bind(
173       &MediaGalleriesPrivateAddGalleryWatchFunction::OnPreferencesInit,
174       this,
175       params->gallery_id));
176
177   return true;
178 }
179
180 void MediaGalleriesPrivateAddGalleryWatchFunction::OnPreferencesInit(
181     const std::string& pref_id) {
182   base::FilePath gallery_file_path;
183   MediaGalleryPrefId gallery_pref_id = 0;
184   if (!GetGalleryFilePathAndId(pref_id,
185                                GetProfile(),
186                                extension(),
187                                &gallery_file_path,
188                                &gallery_pref_id)) {
189     error_ = kInvalidGalleryIDError;
190     HandleResponse(gallery_pref_id, false);
191     return;
192   }
193
194   MediaGalleriesPrivateEventRouter* router =
195       MediaGalleriesPrivateAPI::Get(GetProfile())->GetEventRouter();
196
197   // TODO(tommycli): The new GalleryWatchManager no longer checks that there is
198   // an event listener attached. There should be a check for that here.
199
200   DCHECK(router);
201   content::BrowserThread::PostTaskAndReplyWithResult(
202       content::BrowserThread::FILE,
203       FROM_HERE,
204       base::Bind(&GalleryWatchManager::SetupGalleryWatch,
205                  GetProfile(),
206                  gallery_pref_id,
207                  gallery_file_path,
208                  extension_id(),
209                  router->AsWeakPtr()),
210       base::Bind(&MediaGalleriesPrivateAddGalleryWatchFunction::HandleResponse,
211                  this,
212                  gallery_pref_id));
213 }
214
215 void MediaGalleriesPrivateAddGalleryWatchFunction::HandleResponse(
216     MediaGalleryPrefId gallery_id,
217     bool success) {
218   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
219   media_galleries_private::AddGalleryWatchResult result;
220   result.gallery_id = base::Uint64ToString(gallery_id);
221   result.success = success;
222   SetResult(result.ToValue().release());
223   if (success) {
224     DCHECK(g_browser_process->media_file_system_registry()
225                ->GetPreferences(GetProfile())
226                ->IsInitialized());
227     GalleryWatchStateTracker* state_tracker = MediaGalleriesPrivateAPI::Get(
228         GetProfile())->GetGalleryWatchStateTracker();
229     state_tracker->OnGalleryWatchAdded(extension_id(), gallery_id);
230   }
231   SendResponse(true);
232 }
233
234
235 ///////////////////////////////////////////////////////////////////////////////
236 //              MediaGalleriesPrivateRemoveGalleryWatchFunction              //
237 ///////////////////////////////////////////////////////////////////////////////
238
239 MediaGalleriesPrivateRemoveGalleryWatchFunction::
240 ~MediaGalleriesPrivateRemoveGalleryWatchFunction() {
241 }
242
243 bool MediaGalleriesPrivateRemoveGalleryWatchFunction::RunAsync() {
244   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
245   if (!render_view_host() || !render_view_host()->GetProcess())
246     return false;
247
248   scoped_ptr<RemoveGalleryWatch::Params> params(
249       RemoveGalleryWatch::Params::Create(*args_));
250   EXTENSION_FUNCTION_VALIDATE(params.get());
251
252   MediaGalleriesPreferences* preferences =
253       g_browser_process->media_file_system_registry()->GetPreferences(
254           GetProfile());
255   preferences->EnsureInitialized(base::Bind(
256       &MediaGalleriesPrivateRemoveGalleryWatchFunction::OnPreferencesInit,
257       this,
258       params->gallery_id));
259   return true;
260 }
261
262 void MediaGalleriesPrivateRemoveGalleryWatchFunction::OnPreferencesInit(
263     const std::string& pref_id) {
264   base::FilePath gallery_file_path;
265   MediaGalleryPrefId gallery_pref_id = 0;
266   if (!GetGalleryFilePathAndId(pref_id,
267                                GetProfile(),
268                                extension(),
269                                &gallery_file_path,
270                                &gallery_pref_id)) {
271     error_ = kInvalidGalleryIDError;
272     SendResponse(false);
273     return;
274   }
275
276   content::BrowserThread::PostTask(
277       content::BrowserThread::FILE,
278       FROM_HERE,
279       base::Bind(&GalleryWatchManager::RemoveGalleryWatch,
280                  GetProfile(),
281                  gallery_file_path,
282                  extension_id()));
283
284   GalleryWatchStateTracker* state_tracker = MediaGalleriesPrivateAPI::Get(
285       GetProfile())->GetGalleryWatchStateTracker();
286   state_tracker->OnGalleryWatchRemoved(extension_id(), gallery_pref_id);
287   SendResponse(true);
288 }
289
290 ///////////////////////////////////////////////////////////////////////////////
291 //              MediaGalleriesPrivateGetAllGalleryWatchFunction              //
292 ///////////////////////////////////////////////////////////////////////////////
293
294 MediaGalleriesPrivateGetAllGalleryWatchFunction::
295 ~MediaGalleriesPrivateGetAllGalleryWatchFunction() {
296 }
297
298 bool MediaGalleriesPrivateGetAllGalleryWatchFunction::RunAsync() {
299   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
300   if (!render_view_host() || !render_view_host()->GetProcess())
301     return false;
302
303   MediaGalleriesPreferences* preferences =
304       g_browser_process->media_file_system_registry()->GetPreferences(
305           GetProfile());
306   preferences->EnsureInitialized(base::Bind(
307       &MediaGalleriesPrivateGetAllGalleryWatchFunction::OnPreferencesInit,
308       this));
309   return true;
310 }
311
312 void MediaGalleriesPrivateGetAllGalleryWatchFunction::OnPreferencesInit() {
313   std::vector<std::string> result;
314   GalleryWatchStateTracker* state_tracker = MediaGalleriesPrivateAPI::Get(
315       GetProfile())->GetGalleryWatchStateTracker();
316   MediaGalleryPrefIdSet gallery_ids =
317       state_tracker->GetAllWatchedGalleryIDsForExtension(extension_id());
318   for (MediaGalleryPrefIdSet::const_iterator iter = gallery_ids.begin();
319        iter != gallery_ids.end(); ++iter) {
320     result.push_back(base::Uint64ToString(*iter));
321   }
322   results_ = GetAllGalleryWatch::Results::Create(result);
323   SendResponse(true);
324 }
325
326 ///////////////////////////////////////////////////////////////////////////////
327 //              MediaGalleriesPrivateRemoveAllGalleryWatchFunction           //
328 ///////////////////////////////////////////////////////////////////////////////
329
330 MediaGalleriesPrivateRemoveAllGalleryWatchFunction::
331 ~MediaGalleriesPrivateRemoveAllGalleryWatchFunction() {
332 }
333
334 bool MediaGalleriesPrivateRemoveAllGalleryWatchFunction::RunAsync() {
335   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
336   if (!render_view_host() || !render_view_host()->GetProcess())
337     return false;
338
339   MediaGalleriesPreferences* preferences =
340       g_browser_process->media_file_system_registry()->GetPreferences(
341           GetProfile());
342   preferences->EnsureInitialized(base::Bind(
343       &MediaGalleriesPrivateRemoveAllGalleryWatchFunction::OnPreferencesInit,
344       this));
345   return true;
346 }
347
348 void MediaGalleriesPrivateRemoveAllGalleryWatchFunction::OnPreferencesInit() {
349   MediaGalleriesPreferences* preferences =
350       g_browser_process->media_file_system_registry()->GetPreferences(
351           GetProfile());
352   GalleryWatchStateTracker* state_tracker = MediaGalleriesPrivateAPI::Get(
353       GetProfile())->GetGalleryWatchStateTracker();
354   state_tracker->RemoveAllGalleryWatchersForExtension(
355       extension_id(), preferences);
356   SendResponse(true);
357 }
358
359 }  // namespace extensions