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