Upstream version 5.34.92.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / image_writer_private / operation_manager.cc
1 // Copyright 2013 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 "base/lazy_instance.h"
6 #include "chrome/browser/browser_process.h"
7 #include "chrome/browser/chrome_notification_types.h"
8 #include "chrome/browser/extensions/api/image_writer_private/destroy_partitions_operation.h"
9 #include "chrome/browser/extensions/api/image_writer_private/error_messages.h"
10 #include "chrome/browser/extensions/api/image_writer_private/operation.h"
11 #include "chrome/browser/extensions/api/image_writer_private/operation_manager.h"
12 #include "chrome/browser/extensions/api/image_writer_private/write_from_file_operation.h"
13 #include "chrome/browser/extensions/api/image_writer_private/write_from_url_operation.h"
14 #include "chrome/browser/extensions/event_router_forwarder.h"
15 #include "chrome/browser/extensions/extension_host.h"
16 #include "chrome/browser/extensions/extension_service.h"
17 #include "chrome/browser/extensions/extension_system.h"
18 #include "chrome/browser/extensions/extension_system_factory.h"
19 #include "content/public/browser/browser_thread.h"
20 #include "content/public/browser/notification_service.h"
21 #include "extensions/browser/event_router.h"
22
23 namespace image_writer_api = extensions::api::image_writer_private;
24
25 namespace extensions {
26 namespace image_writer {
27
28 using content::BrowserThread;
29
30 OperationManager::OperationManager(Profile* profile)
31     : profile_(profile),
32       weak_factory_(this) {
33   registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
34                  content::Source<Profile>(profile_));
35   registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
36                  content::Source<Profile>(profile_));
37   registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED,
38                  content::Source<Profile>(profile_));
39   registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE,
40                  content::Source<Profile>(profile_));
41   registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED,
42                  content::Source<Profile>(profile_));
43 }
44
45 OperationManager::~OperationManager() {
46 }
47
48 void OperationManager::Shutdown() {
49   for (OperationMap::iterator iter = operations_.begin();
50        iter != operations_.end();
51        iter++) {
52     BrowserThread::PostTask(BrowserThread::FILE,
53                             FROM_HERE,
54                             base::Bind(&Operation::Abort,
55                                        iter->second));
56   }
57 }
58
59 void OperationManager::StartWriteFromUrl(
60     const ExtensionId& extension_id,
61     GURL url,
62     content::RenderViewHost* rvh,
63     const std::string& hash,
64     bool saveImageAsDownload,
65     const std::string& storage_unit_id,
66     const Operation::StartWriteCallback& callback) {
67   OperationMap::iterator existing_operation = operations_.find(extension_id);
68
69   if (existing_operation != operations_.end()) {
70     return callback.Run(false, error::kOperationAlreadyInProgress);
71   }
72
73   scoped_refptr<Operation> operation(
74       new WriteFromUrlOperation(weak_factory_.GetWeakPtr(),
75                                 extension_id,
76                                 rvh,
77                                 url,
78                                 hash,
79                                 saveImageAsDownload,
80                                 storage_unit_id));
81   operations_[extension_id] = operation;
82   BrowserThread::PostTask(BrowserThread::FILE,
83                           FROM_HERE,
84                           base::Bind(&Operation::Start, operation));
85   callback.Run(true, "");
86 }
87
88 void OperationManager::StartWriteFromFile(
89     const ExtensionId& extension_id,
90     const base::FilePath& path,
91     const std::string& storage_unit_id,
92     const Operation::StartWriteCallback& callback) {
93   OperationMap::iterator existing_operation = operations_.find(extension_id);
94
95   if (existing_operation != operations_.end()) {
96     return callback.Run(false, error::kOperationAlreadyInProgress);
97   }
98
99   scoped_refptr<Operation> operation(
100       new WriteFromFileOperation(weak_factory_.GetWeakPtr(),
101                                  extension_id,
102                                  path,
103                                  storage_unit_id));
104   operations_[extension_id] = operation;
105   BrowserThread::PostTask(BrowserThread::FILE,
106                           FROM_HERE,
107                           base::Bind(&Operation::Start, operation));
108   callback.Run(true, "");
109 }
110
111 void OperationManager::CancelWrite(
112     const ExtensionId& extension_id,
113     const Operation::CancelWriteCallback& callback) {
114   Operation* existing_operation = GetOperation(extension_id);
115
116   if (existing_operation == NULL) {
117     callback.Run(false, error::kNoOperationInProgress);
118   } else {
119     BrowserThread::PostTask(BrowserThread::FILE,
120                             FROM_HERE,
121                             base::Bind(&Operation::Cancel, existing_operation));
122     DeleteOperation(extension_id);
123     callback.Run(true, "");
124   }
125 }
126
127 void OperationManager::DestroyPartitions(
128     const ExtensionId& extension_id,
129     const std::string& storage_unit_id,
130     const Operation::StartWriteCallback& callback) {
131   OperationMap::iterator existing_operation = operations_.find(extension_id);
132
133   if (existing_operation != operations_.end()) {
134     return callback.Run(false, error::kOperationAlreadyInProgress);
135   }
136
137   scoped_refptr<Operation> operation(
138       new DestroyPartitionsOperation(weak_factory_.GetWeakPtr(),
139                                      extension_id,
140                                      storage_unit_id));
141   operations_[extension_id] = operation;
142   BrowserThread::PostTask(BrowserThread::FILE,
143                           FROM_HERE,
144                           base::Bind(&Operation::Start, operation));
145   callback.Run(true, "");
146 }
147
148 void OperationManager::OnProgress(const ExtensionId& extension_id,
149                                   image_writer_api::Stage stage,
150                                   int progress) {
151   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
152   DVLOG(2) << "progress - " << stage << " at " << progress << "%";
153
154   image_writer_api::ProgressInfo info;
155   info.stage = stage;
156   info.percent_complete = progress;
157
158   scoped_ptr<base::ListValue> args(
159       image_writer_api::OnWriteProgress::Create(info));
160   scoped_ptr<Event> event(new Event(
161       image_writer_api::OnWriteProgress::kEventName, args.Pass()));
162
163   ExtensionSystem::Get(profile_)->event_router()->
164       DispatchEventToExtension(extension_id, event.Pass());
165 }
166
167 void OperationManager::OnComplete(const ExtensionId& extension_id) {
168   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
169
170   scoped_ptr<base::ListValue> args(image_writer_api::OnWriteComplete::Create());
171   scoped_ptr<Event> event(new Event(
172       image_writer_api::OnWriteComplete::kEventName, args.Pass()));
173
174   ExtensionSystem::Get(profile_)->event_router()->
175       DispatchEventToExtension(extension_id, event.Pass());
176
177   DeleteOperation(extension_id);
178 }
179
180 void OperationManager::OnError(const ExtensionId& extension_id,
181                                image_writer_api::Stage stage,
182                                int progress,
183                                const std::string& error_message) {
184   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
185   image_writer_api::ProgressInfo info;
186
187   DLOG(ERROR) << "ImageWriter error: " << error_message;
188
189   info.stage = stage;
190   info.percent_complete = progress;
191
192   scoped_ptr<base::ListValue> args(
193       image_writer_api::OnWriteError::Create(info, error_message));
194   scoped_ptr<Event> event(new Event(
195       image_writer_api::OnWriteError::kEventName, args.Pass()));
196
197   ExtensionSystem::Get(profile_)->event_router()->
198       DispatchEventToExtension(extension_id, event.Pass());
199
200   DeleteOperation(extension_id);
201 }
202
203 Operation* OperationManager::GetOperation(const ExtensionId& extension_id) {
204   OperationMap::iterator existing_operation = operations_.find(extension_id);
205
206   if (existing_operation == operations_.end())
207     return NULL;
208   return existing_operation->second.get();
209 }
210
211 void OperationManager::DeleteOperation(const ExtensionId& extension_id) {
212   OperationMap::iterator existing_operation = operations_.find(extension_id);
213   if (existing_operation != operations_.end()) {
214     operations_.erase(existing_operation);
215   }
216 }
217
218 void OperationManager::Observe(int type,
219                                const content::NotificationSource& source,
220                                const content::NotificationDetails& details) {
221   switch (type) {
222     case chrome::NOTIFICATION_EXTENSION_UNINSTALLED: {
223       DeleteOperation(content::Details<const Extension>(details).ptr()->id());
224       break;
225     }
226     case chrome::NOTIFICATION_EXTENSION_UNLOADED: {
227       DeleteOperation(content::Details<const Extension>(details).ptr()->id());
228       break;
229     }
230     case chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED: {
231       DeleteOperation(content::Details<const Extension>(details).ptr()->id());
232       break;
233     }
234     case chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE: {
235       DeleteOperation(
236         content::Details<ExtensionHost>(details)->extension()->id());
237       break;
238     }
239     case chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED: {
240       DeleteOperation(
241         content::Details<ExtensionHost>(details)->extension()->id());
242       break;
243     }
244     default: {
245       NOTREACHED();
246       break;
247     }
248   }
249 }
250
251 OperationManager* OperationManager::Get(Profile* profile) {
252   return ProfileKeyedAPIFactory<OperationManager>::
253       GetForProfile(profile);
254 }
255
256 static base::LazyInstance<ProfileKeyedAPIFactory<OperationManager> >
257     g_factory = LAZY_INSTANCE_INITIALIZER;
258
259 ProfileKeyedAPIFactory<OperationManager>*
260     OperationManager::GetFactoryInstance() {
261   return g_factory.Pointer();
262 }
263
264
265 }  // namespace image_writer
266 }  // namespace extensions