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